Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 163508
b: refs/heads/master
c: f1a3b99
h: refs/heads/master
v: v3
  • Loading branch information
Magnus Damm authored and Paul Mundt committed Aug 23, 2009
1 parent ad420b1 commit f829898
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6a93dde1e8216f7af9b2551a60fb1a5eeac4a89f
refs/heads/master: f1a3b994f9dfd12111dc034402aed256fac66dfe
39 changes: 37 additions & 2 deletions trunk/drivers/i2c/busses/i2c-sh_mobile.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/pm_runtime.h>
#include <linux/clk.h>
#include <linux/io.h>

Expand Down Expand Up @@ -165,7 +166,8 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
u_int32_t denom;
u_int32_t tmp;

/* Make sure the clock is enabled */
/* Wake up device and enable clock */
pm_runtime_get_sync(pd->dev);
clk_enable(pd->clk);

/* Get clock rate after clock is enabled */
Expand Down Expand Up @@ -213,8 +215,9 @@ static void deactivate_ch(struct sh_mobile_i2c_data *pd)
/* Disable channel */
iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));

/* Disable clock */
/* Disable clock and mark device as idle */
clk_disable(pd->clk);
pm_runtime_put_sync(pd->dev);
}

static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
Expand Down Expand Up @@ -572,6 +575,19 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
goto err_irq;
}

/* Enable Runtime PM for this device.
*
* Also tell the Runtime PM core to ignore children
* for this device since it is valid for us to suspend
* this I2C master driver even though the slave devices
* on the I2C bus may not be suspended.
*
* The state of the I2C hardware bus is unaffected by
* the Runtime PM state.
*/
pm_suspend_ignore_children(&dev->dev, true);
pm_runtime_enable(&dev->dev);

/* setup the private data */
adap = &pd->adap;
i2c_set_adapdata(adap, pd);
Expand Down Expand Up @@ -614,14 +630,33 @@ static int sh_mobile_i2c_remove(struct platform_device *dev)
iounmap(pd->reg);
sh_mobile_i2c_hook_irqs(dev, 0);
clk_put(pd->clk);
pm_runtime_disable(&dev->dev);
kfree(pd);
return 0;
}

static int sh_mobile_i2c_runtime_nop(struct device *dev)
{
/* Runtime PM callback shared between ->runtime_suspend()
* and ->runtime_resume(). Simply returns success.
*
* This driver re-initializes all registers after
* pm_runtime_get_sync() anyway so there is no need
* to save and restore registers here.
*/
return 0;
}

static struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = {
.runtime_suspend = sh_mobile_i2c_runtime_nop,
.runtime_resume = sh_mobile_i2c_runtime_nop,
};

static struct platform_driver sh_mobile_i2c_driver = {
.driver = {
.name = "i2c-sh_mobile",
.owner = THIS_MODULE,
.pm = &sh_mobile_i2c_dev_pm_ops,
},
.probe = sh_mobile_i2c_probe,
.remove = sh_mobile_i2c_remove,
Expand Down

0 comments on commit f829898

Please sign in to comment.