aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorKevin Hilman <khilman@ti.com>2011-05-17 10:31:38 -0400
committerBen Dooks <ben-linux@fluff.org>2011-10-29 04:37:09 -0400
commitfab67afb543c734c23be0ebfc16f31814df2da79 (patch)
tree5cca96aa3534377043c7490c7851cbd963079ee3 /drivers/i2c
parent7f4b08eeeedd90d97c8c581d048074e0c2643bec (diff)
I2C: OMAP: remove dev->idle, use usage counting provided by runtime PM
Current usage of runtime PM is not quite correct. The actual idle/unidle of the I2C hardware should not happen until the runtime PM callbacks are called. Therefore, change omap_i2c_[un]idle() functions to only be called from the runtime PM callbacks (when usage count transitions to/from zero.) Also, the runtime PM core does usage counting and replaces functionality currently managed by the dev->idle flag. Remove usage of dev->idle in favor of using runtime PM, and checking status using pm_runtime_suspended(). Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-omap.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index cddb29c15314..a43d0023446a 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -194,7 +194,6 @@ struct omap_i2c_dev {
194 */ 194 */
195 u8 rev; 195 u8 rev;
196 unsigned b_hw:1; /* bad h/w fixes */ 196 unsigned b_hw:1; /* bad h/w fixes */
197 unsigned idle:1;
198 u16 iestate; /* Saved interrupt register */ 197 u16 iestate; /* Saved interrupt register */
199 u16 pscstate; 198 u16 pscstate;
200 u16 scllstate; 199 u16 scllstate;
@@ -269,12 +268,8 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
269{ 268{
270 struct omap_i2c_bus_platform_data *pdata; 269 struct omap_i2c_bus_platform_data *pdata;
271 270
272 WARN_ON(!dev->idle);
273
274 pdata = dev->dev->platform_data; 271 pdata = dev->dev->platform_data;
275 272
276 pm_runtime_get_sync(dev->dev);
277
278 if (pdata->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { 273 if (pdata->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
279 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); 274 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
280 omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); 275 omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
@@ -285,7 +280,6 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
285 omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate); 280 omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
286 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); 281 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
287 } 282 }
288 dev->idle = 0;
289 283
290 /* 284 /*
291 * Don't write to this register if the IE state is 0 as it can 285 * Don't write to this register if the IE state is 0 as it can
@@ -300,8 +294,6 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
300 struct omap_i2c_bus_platform_data *pdata; 294 struct omap_i2c_bus_platform_data *pdata;
301 u16 iv; 295 u16 iv;
302 296
303 WARN_ON(dev->idle);
304
305 pdata = dev->dev->platform_data; 297 pdata = dev->dev->platform_data;
306 298
307 dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); 299 dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
@@ -315,12 +307,9 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
315 } else { 307 } else {
316 omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate); 308 omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
317 309
318 /* Flush posted write before the dev->idle store occurs */ 310 /* Flush posted write */
319 omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); 311 omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
320 } 312 }
321 dev->idle = 1;
322
323 pm_runtime_put_sync(dev->dev);
324} 313}
325 314
326static int omap_i2c_init(struct omap_i2c_dev *dev) 315static int omap_i2c_init(struct omap_i2c_dev *dev)
@@ -644,7 +633,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
644 int i; 633 int i;
645 int r; 634 int r;
646 635
647 omap_i2c_unidle(dev); 636 pm_runtime_get_sync(dev->dev);
648 637
649 r = omap_i2c_wait_for_bb(dev); 638 r = omap_i2c_wait_for_bb(dev);
650 if (r < 0) 639 if (r < 0)
@@ -667,7 +656,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
667 656
668 omap_i2c_wait_for_bb(dev); 657 omap_i2c_wait_for_bb(dev);
669out: 658out:
670 omap_i2c_idle(dev); 659 pm_runtime_put(dev->dev);
671 return r; 660 return r;
672} 661}
673 662
@@ -727,7 +716,7 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id)
727 struct omap_i2c_dev *dev = dev_id; 716 struct omap_i2c_dev *dev = dev_id;
728 u16 iv, w; 717 u16 iv, w;
729 718
730 if (dev->idle) 719 if (pm_runtime_suspended(dev->dev))
731 return IRQ_NONE; 720 return IRQ_NONE;
732 721
733 iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); 722 iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
@@ -819,7 +808,7 @@ omap_i2c_isr(int this_irq, void *dev_id)
819 808
820 pdata = dev->dev->platform_data; 809 pdata = dev->dev->platform_data;
821 810
822 if (dev->idle) 811 if (pm_runtime_suspended(dev->dev))
823 return IRQ_NONE; 812 return IRQ_NONE;
824 813
825 bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); 814 bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
@@ -1021,7 +1010,6 @@ omap_i2c_probe(struct platform_device *pdev)
1021 } 1010 }
1022 1011
1023 dev->speed = speed; 1012 dev->speed = speed;
1024 dev->idle = 1;
1025 dev->dev = &pdev->dev; 1013 dev->dev = &pdev->dev;
1026 dev->irq = irq->start; 1014 dev->irq = irq->start;
1027 dev->base = ioremap(mem->start, resource_size(mem)); 1015 dev->base = ioremap(mem->start, resource_size(mem));
@@ -1040,7 +1028,7 @@ omap_i2c_probe(struct platform_device *pdev)
1040 dev->regs = (u8 *)reg_map_ip_v1; 1028 dev->regs = (u8 *)reg_map_ip_v1;
1041 1029
1042 pm_runtime_enable(dev->dev); 1030 pm_runtime_enable(dev->dev);
1043 omap_i2c_unidle(dev); 1031 pm_runtime_get_sync(dev->dev);
1044 1032
1045 dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; 1033 dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
1046 1034
@@ -1087,7 +1075,7 @@ omap_i2c_probe(struct platform_device *pdev)
1087 dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id, 1075 dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id,
1088 pdata->rev, dev->rev >> 4, dev->rev & 0xf, dev->speed); 1076 pdata->rev, dev->rev >> 4, dev->rev & 0xf, dev->speed);
1089 1077
1090 omap_i2c_idle(dev); 1078 pm_runtime_put(dev->dev);
1091 1079
1092 adap = &dev->adapter; 1080 adap = &dev->adapter;
1093 i2c_set_adapdata(adap, dev); 1081 i2c_set_adapdata(adap, dev);
@@ -1111,7 +1099,7 @@ err_free_irq:
1111 free_irq(dev->irq, dev); 1099 free_irq(dev->irq, dev);
1112err_unuse_clocks: 1100err_unuse_clocks:
1113 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); 1101 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
1114 omap_i2c_idle(dev); 1102 pm_runtime_put(dev->dev);
1115 iounmap(dev->base); 1103 iounmap(dev->base);
1116err_free_mem: 1104err_free_mem:
1117 platform_set_drvdata(pdev, NULL); 1105 platform_set_drvdata(pdev, NULL);
@@ -1140,12 +1128,43 @@ omap_i2c_remove(struct platform_device *pdev)
1140 return 0; 1128 return 0;
1141} 1129}
1142 1130
1131#ifdef CONFIG_PM_RUNTIME
1132static int omap_i2c_runtime_suspend(struct device *dev)
1133{
1134 struct platform_device *pdev = to_platform_device(dev);
1135 struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
1136
1137 omap_i2c_idle(_dev);
1138
1139 return 0;
1140}
1141
1142static int omap_i2c_runtime_resume(struct device *dev)
1143{
1144 struct platform_device *pdev = to_platform_device(dev);
1145 struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
1146
1147 omap_i2c_unidle(_dev);
1148
1149 return 0;
1150}
1151
1152static struct dev_pm_ops omap_i2c_pm_ops = {
1153 .runtime_suspend = omap_i2c_runtime_suspend,
1154 .runtime_resume = omap_i2c_runtime_resume,
1155};
1156#define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops)
1157#else
1158#define OMAP_I2C_PM_OPS NULL
1159#endif
1160
1143static struct platform_driver omap_i2c_driver = { 1161static struct platform_driver omap_i2c_driver = {
1144 .probe = omap_i2c_probe, 1162 .probe = omap_i2c_probe,
1145 .remove = omap_i2c_remove, 1163 .remove = omap_i2c_remove,
1146 .driver = { 1164 .driver = {
1147 .name = "omap_i2c", 1165 .name = "omap_i2c",
1148 .owner = THIS_MODULE, 1166 .owner = THIS_MODULE,
1167 .pm = OMAP_I2C_PM_OPS,
1149 }, 1168 },
1150}; 1169};
1151 1170