aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2009-08-14 06:48:59 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-08-23 05:03:19 -0400
commitf1a3b994f9dfd12111dc034402aed256fac66dfe (patch)
tree3b19f55fb74932a0c4e9b17b79f960302f4d1637 /drivers
parent6a93dde1e8216f7af9b2551a60fb1a5eeac4a89f (diff)
i2c: Runtime PM for SuperH Mobile I2C
This patch modifies the SuperH Mobile I2C driver to support Runtime PM. These changes is all that is needed for proper Runtime PM support in this driver. Driver callbacks for Runtime PM are empty because the device registers are always re-initialized after pm_runtime_get_sync(). Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index 820487d0d5c7..86a9d4e81472 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -28,6 +28,7 @@
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/err.h> 30#include <linux/err.h>
31#include <linux/pm_runtime.h>
31#include <linux/clk.h> 32#include <linux/clk.h>
32#include <linux/io.h> 33#include <linux/io.h>
33 34
@@ -165,7 +166,8 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
165 u_int32_t denom; 166 u_int32_t denom;
166 u_int32_t tmp; 167 u_int32_t tmp;
167 168
168 /* Make sure the clock is enabled */ 169 /* Wake up device and enable clock */
170 pm_runtime_get_sync(pd->dev);
169 clk_enable(pd->clk); 171 clk_enable(pd->clk);
170 172
171 /* Get clock rate after clock is enabled */ 173 /* Get clock rate after clock is enabled */
@@ -213,8 +215,9 @@ static void deactivate_ch(struct sh_mobile_i2c_data *pd)
213 /* Disable channel */ 215 /* Disable channel */
214 iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); 216 iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
215 217
216 /* Disable clock */ 218 /* Disable clock and mark device as idle */
217 clk_disable(pd->clk); 219 clk_disable(pd->clk);
220 pm_runtime_put_sync(pd->dev);
218} 221}
219 222
220static unsigned char i2c_op(struct sh_mobile_i2c_data *pd, 223static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
@@ -572,6 +575,19 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
572 goto err_irq; 575 goto err_irq;
573 } 576 }
574 577
578 /* Enable Runtime PM for this device.
579 *
580 * Also tell the Runtime PM core to ignore children
581 * for this device since it is valid for us to suspend
582 * this I2C master driver even though the slave devices
583 * on the I2C bus may not be suspended.
584 *
585 * The state of the I2C hardware bus is unaffected by
586 * the Runtime PM state.
587 */
588 pm_suspend_ignore_children(&dev->dev, true);
589 pm_runtime_enable(&dev->dev);
590
575 /* setup the private data */ 591 /* setup the private data */
576 adap = &pd->adap; 592 adap = &pd->adap;
577 i2c_set_adapdata(adap, pd); 593 i2c_set_adapdata(adap, pd);
@@ -614,14 +630,33 @@ static int sh_mobile_i2c_remove(struct platform_device *dev)
614 iounmap(pd->reg); 630 iounmap(pd->reg);
615 sh_mobile_i2c_hook_irqs(dev, 0); 631 sh_mobile_i2c_hook_irqs(dev, 0);
616 clk_put(pd->clk); 632 clk_put(pd->clk);
633 pm_runtime_disable(&dev->dev);
617 kfree(pd); 634 kfree(pd);
618 return 0; 635 return 0;
619} 636}
620 637
638static int sh_mobile_i2c_runtime_nop(struct device *dev)
639{
640 /* Runtime PM callback shared between ->runtime_suspend()
641 * and ->runtime_resume(). Simply returns success.
642 *
643 * This driver re-initializes all registers after
644 * pm_runtime_get_sync() anyway so there is no need
645 * to save and restore registers here.
646 */
647 return 0;
648}
649
650static struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = {
651 .runtime_suspend = sh_mobile_i2c_runtime_nop,
652 .runtime_resume = sh_mobile_i2c_runtime_nop,
653};
654
621static struct platform_driver sh_mobile_i2c_driver = { 655static struct platform_driver sh_mobile_i2c_driver = {
622 .driver = { 656 .driver = {
623 .name = "i2c-sh_mobile", 657 .name = "i2c-sh_mobile",
624 .owner = THIS_MODULE, 658 .owner = THIS_MODULE,
659 .pm = &sh_mobile_i2c_dev_pm_ops,
625 }, 660 },
626 .probe = sh_mobile_i2c_probe, 661 .probe = sh_mobile_i2c_probe,
627 .remove = sh_mobile_i2c_remove, 662 .remove = sh_mobile_i2c_remove,