aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-omap.c
diff options
context:
space:
mode:
authorKevin Hilman <khilman@ti.com>2011-01-27 19:18:41 -0500
committerBen Dooks <ben-linux@fluff.org>2011-02-22 18:53:44 -0500
commitadf6e07922255937c8bfeea777d19502b4c9a2be (patch)
tree5aeee4e126ee83567e12e437084766602eae942d /drivers/i2c/busses/i2c-omap.c
parentf10820e49585f281706ac07570a9e1652bdb5dd9 (diff)
i2c-omap: fix static suspend vs. runtime suspend
When runtime PM is enabled, each OMAP i2c device is suspended after each i2c xfer. However, there are two cases when the static suspend methods must be used to ensure the devices are suspended: 1) runtime PM is disabled, either at compile time or dynamically via /sys/devices/.../power/control. 2) an i2c client driver uses i2c during it's suspend callback, thus leaving the i2c driver active (NOTE: runtime suspend transitions are disabled during system suspend, so i2c activity during system suspend will runtime resume the device, but not runtime (re)suspend it.) Since the actual work to suspend the device is handled by the subsytem, call the bus methods to take care of it. NOTE: This takes care of a known suspend problem on OMAP3 where the TWL RTC driver does i2c xfers during its suspend path leaving the i2c driver in an active state (since runtime suspend transistions are disabled.) Signed-off-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'drivers/i2c/busses/i2c-omap.c')
-rw-r--r--drivers/i2c/busses/i2c-omap.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index b605ff3a1fa0..0541df90b9fb 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1137,12 +1137,40 @@ omap_i2c_remove(struct platform_device *pdev)
1137 return 0; 1137 return 0;
1138} 1138}
1139 1139
1140#ifdef CONFIG_SUSPEND
1141static int omap_i2c_suspend(struct device *dev)
1142{
1143 if (!pm_runtime_suspended(dev))
1144 if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend)
1145 dev->bus->pm->runtime_suspend(dev);
1146
1147 return 0;
1148}
1149
1150static int omap_i2c_resume(struct device *dev)
1151{
1152 if (!pm_runtime_suspended(dev))
1153 if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume)
1154 dev->bus->pm->runtime_resume(dev);
1155
1156 return 0;
1157}
1158
1159static struct dev_pm_ops omap_i2c_pm_ops = {
1160 .suspend = omap_i2c_suspend,
1161 .resume = omap_i2c_resume,
1162};
1163#else
1164#define omap_i2c_pm_ops NULL
1165#endif
1166
1140static struct platform_driver omap_i2c_driver = { 1167static struct platform_driver omap_i2c_driver = {
1141 .probe = omap_i2c_probe, 1168 .probe = omap_i2c_probe,
1142 .remove = omap_i2c_remove, 1169 .remove = omap_i2c_remove,
1143 .driver = { 1170 .driver = {
1144 .name = "omap_i2c", 1171 .name = "omap_i2c",
1145 .owner = THIS_MODULE, 1172 .owner = THIS_MODULE,
1173 .pm = &omap_i2c_pm_ops,
1146 }, 1174 },
1147}; 1175};
1148 1176