diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-28 16:43:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-28 16:43:12 -0400 |
commit | a410963ba4c0c768302f0298e258b1ee940e8316 (patch) | |
tree | f262f101a5bf752ce14775da080aed5fbaf73f0e /drivers/i2c/busses/i2c-omap.c | |
parent | f7da9cdf45cbbad5029d4858dcbc0134e06084ed (diff) | |
parent | 5db20c49e2d6581797c17057e068d89d6677aa24 (diff) |
Merge branch 'i2c-embedded/for-next' of git://git.pengutronix.de/git/wsa/linux
Pull embedded i2c changes from Wolfram Sang:
"Changes for the "embedded" part of the I2C subsystem:
- lots of devicetree conversions of drivers (and preparations for
that)
- big cleanups for drivers for OMAP, Tegra, Nomadik, Blackfin
- Rafael's struct dev_pm_ops conversion patches for I2C
- usual driver cleanups and fixes
All patches have been in linux-next for an apropriate time and all
patches touching files outside of i2c-folders should have proper acks
from the maintainers."
* 'i2c-embedded/for-next' of git://git.pengutronix.de/git/wsa/linux: (60 commits)
Revert "i2c: tegra: convert normal suspend/resume to *_noirq"
I2C: MV64XYZ: Add Device Tree support
i2c: stu300: use devm managed resources
i2c: i2c-ocores: support for 16bit and 32bit IO
V4L/DVB: mfd: use reg_shift instead of regstep
i2c: i2c-ocores: Use reg-shift property
i2c: i2c-ocores: DT bindings and minor fixes.
i2c: mv64xxxx: remove EXPERIMENTAL tag
i2c-s3c2410: Use plain pm_runtime_put()
i2c: s3c2410: Fix pointer type passed to of_match_node()
i2c: mxs: Set I2C timing registers for mxs-i2c
i2c: i2c-bfin-twi: Move blackfin TWI register access Macro to head file.
i2c: i2c-bfin-twi: Move TWI peripheral pin request array to platform data.
i2c:i2c-bfin-twi: include twi head file
i2c:i2c-bfin-twi: TWI fails to restart next transfer in high system load.
i2c: i2c-bfin-twi: Tighten condition when failing I2C transfer if MEN bit is reset unexpectedly.
i2c: i2c-bfin-twi: Break dead waiting loop if i2c device misbehaves.
i2c: i2c-bfin-twi: Improve the patch for bug "Illegal i2c bus lock upon certain transfer scenarios".
i2c: i2c-bfin-twi: Illegal i2c bus lock upon certain transfer scenarios.
i2c-mv64xxxx: allow more than one driver instance
...
Conflicts:
drivers/i2c/busses/i2c-nomadik.c
Diffstat (limited to 'drivers/i2c/busses/i2c-omap.c')
-rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 155 |
1 files changed, 77 insertions, 78 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index c2148332de0f..6849635b268a 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -49,8 +49,8 @@ | |||
49 | 49 | ||
50 | /* I2C controller revisions present on specific hardware */ | 50 | /* I2C controller revisions present on specific hardware */ |
51 | #define OMAP_I2C_REV_ON_2430 0x36 | 51 | #define OMAP_I2C_REV_ON_2430 0x36 |
52 | #define OMAP_I2C_REV_ON_3430 0x3C | 52 | #define OMAP_I2C_REV_ON_3430_3530 0x3C |
53 | #define OMAP_I2C_REV_ON_3530_4430 0x40 | 53 | #define OMAP_I2C_REV_ON_3630_4430 0x40 |
54 | 54 | ||
55 | /* timeout waiting for the controller to respond */ | 55 | /* timeout waiting for the controller to respond */ |
56 | #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) | 56 | #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) |
@@ -173,7 +173,7 @@ enum { | |||
173 | 173 | ||
174 | /* Errata definitions */ | 174 | /* Errata definitions */ |
175 | #define I2C_OMAP_ERRATA_I207 (1 << 0) | 175 | #define I2C_OMAP_ERRATA_I207 (1 << 0) |
176 | #define I2C_OMAP3_1P153 (1 << 1) | 176 | #define I2C_OMAP_ERRATA_I462 (1 << 1) |
177 | 177 | ||
178 | struct omap_i2c_dev { | 178 | struct omap_i2c_dev { |
179 | struct device *dev; | 179 | struct device *dev; |
@@ -269,47 +269,6 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) | |||
269 | (i2c_dev->regs[reg] << i2c_dev->reg_shift)); | 269 | (i2c_dev->regs[reg] << i2c_dev->reg_shift)); |
270 | } | 270 | } |
271 | 271 | ||
272 | static void omap_i2c_unidle(struct omap_i2c_dev *dev) | ||
273 | { | ||
274 | if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { | ||
275 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); | ||
276 | omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); | ||
277 | omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate); | ||
278 | omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate); | ||
279 | omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate); | ||
280 | omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, dev->syscstate); | ||
281 | omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate); | ||
282 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * Don't write to this register if the IE state is 0 as it can | ||
287 | * cause deadlock. | ||
288 | */ | ||
289 | if (dev->iestate) | ||
290 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); | ||
291 | } | ||
292 | |||
293 | static void omap_i2c_idle(struct omap_i2c_dev *dev) | ||
294 | { | ||
295 | u16 iv; | ||
296 | |||
297 | dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); | ||
298 | if (dev->dtrev == OMAP_I2C_IP_VERSION_2) | ||
299 | omap_i2c_write_reg(dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1); | ||
300 | else | ||
301 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); | ||
302 | |||
303 | if (dev->rev < OMAP_I2C_OMAP1_REV_2) { | ||
304 | iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */ | ||
305 | } else { | ||
306 | omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate); | ||
307 | |||
308 | /* Flush posted write */ | ||
309 | omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); | ||
310 | } | ||
311 | } | ||
312 | |||
313 | static int omap_i2c_init(struct omap_i2c_dev *dev) | 272 | static int omap_i2c_init(struct omap_i2c_dev *dev) |
314 | { | 273 | { |
315 | u16 psc = 0, scll = 0, sclh = 0, buf = 0; | 274 | u16 psc = 0, scll = 0, sclh = 0, buf = 0; |
@@ -346,7 +305,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
346 | omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, | 305 | omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, |
347 | SYSC_AUTOIDLE_MASK); | 306 | SYSC_AUTOIDLE_MASK); |
348 | 307 | ||
349 | } else if (dev->rev >= OMAP_I2C_REV_ON_3430) { | 308 | } else if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) { |
350 | dev->syscstate = SYSC_AUTOIDLE_MASK; | 309 | dev->syscstate = SYSC_AUTOIDLE_MASK; |
351 | dev->syscstate |= SYSC_ENAWAKEUP_MASK; | 310 | dev->syscstate |= SYSC_ENAWAKEUP_MASK; |
352 | dev->syscstate |= (SYSC_IDLEMODE_SMART << | 311 | dev->syscstate |= (SYSC_IDLEMODE_SMART << |
@@ -468,11 +427,6 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
468 | /* Take the I2C module out of reset: */ | 427 | /* Take the I2C module out of reset: */ |
469 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); | 428 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); |
470 | 429 | ||
471 | dev->errata = 0; | ||
472 | |||
473 | if (dev->flags & OMAP_I2C_FLAG_APPLY_ERRATA_I207) | ||
474 | dev->errata |= I2C_OMAP_ERRATA_I207; | ||
475 | |||
476 | /* Enable interrupts */ | 430 | /* Enable interrupts */ |
477 | dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | | 431 | dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | |
478 | OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK | | 432 | OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK | |
@@ -514,7 +468,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, | |||
514 | struct i2c_msg *msg, int stop) | 468 | struct i2c_msg *msg, int stop) |
515 | { | 469 | { |
516 | struct omap_i2c_dev *dev = i2c_get_adapdata(adap); | 470 | struct omap_i2c_dev *dev = i2c_get_adapdata(adap); |
517 | int r; | 471 | unsigned long timeout; |
518 | u16 w; | 472 | u16 w; |
519 | 473 | ||
520 | dev_dbg(dev->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", | 474 | dev_dbg(dev->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", |
@@ -536,7 +490,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, | |||
536 | w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR; | 490 | w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR; |
537 | omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w); | 491 | omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w); |
538 | 492 | ||
539 | init_completion(&dev->cmd_complete); | 493 | INIT_COMPLETION(dev->cmd_complete); |
540 | dev->cmd_err = 0; | 494 | dev->cmd_err = 0; |
541 | 495 | ||
542 | w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; | 496 | w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; |
@@ -584,12 +538,10 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, | |||
584 | * REVISIT: We should abort the transfer on signals, but the bus goes | 538 | * REVISIT: We should abort the transfer on signals, but the bus goes |
585 | * into arbitration and we're currently unable to recover from it. | 539 | * into arbitration and we're currently unable to recover from it. |
586 | */ | 540 | */ |
587 | r = wait_for_completion_timeout(&dev->cmd_complete, | 541 | timeout = wait_for_completion_timeout(&dev->cmd_complete, |
588 | OMAP_I2C_TIMEOUT); | 542 | OMAP_I2C_TIMEOUT); |
589 | dev->buf_len = 0; | 543 | dev->buf_len = 0; |
590 | if (r < 0) | 544 | if (timeout == 0) { |
591 | return r; | ||
592 | if (r == 0) { | ||
593 | dev_err(dev->dev, "controller timed out\n"); | 545 | dev_err(dev->dev, "controller timed out\n"); |
594 | omap_i2c_init(dev); | 546 | omap_i2c_init(dev); |
595 | return -ETIMEDOUT; | 547 | return -ETIMEDOUT; |
@@ -630,7 +582,9 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |||
630 | int i; | 582 | int i; |
631 | int r; | 583 | int r; |
632 | 584 | ||
633 | pm_runtime_get_sync(dev->dev); | 585 | r = pm_runtime_get_sync(dev->dev); |
586 | if (IS_ERR_VALUE(r)) | ||
587 | return r; | ||
634 | 588 | ||
635 | r = omap_i2c_wait_for_bb(dev); | 589 | r = omap_i2c_wait_for_bb(dev); |
636 | if (r < 0) | 590 | if (r < 0) |
@@ -767,11 +721,11 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id) | |||
767 | #endif | 721 | #endif |
768 | 722 | ||
769 | /* | 723 | /* |
770 | * OMAP3430 Errata 1.153: When an XRDY/XDR is hit, wait for XUDF before writing | 724 | * OMAP3430 Errata i462: When an XRDY/XDR is hit, wait for XUDF before writing |
771 | * data to DATA_REG. Otherwise some data bytes can be lost while transferring | 725 | * data to DATA_REG. Otherwise some data bytes can be lost while transferring |
772 | * them from the memory to the I2C interface. | 726 | * them from the memory to the I2C interface. |
773 | */ | 727 | */ |
774 | static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err) | 728 | static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err) |
775 | { | 729 | { |
776 | unsigned long timeout = 10000; | 730 | unsigned long timeout = 10000; |
777 | 731 | ||
@@ -779,7 +733,6 @@ static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err) | |||
779 | if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { | 733 | if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { |
780 | omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY | | 734 | omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY | |
781 | OMAP_I2C_STAT_XDR)); | 735 | OMAP_I2C_STAT_XDR)); |
782 | *err |= OMAP_I2C_STAT_XUDF; | ||
783 | return -ETIMEDOUT; | 736 | return -ETIMEDOUT; |
784 | } | 737 | } |
785 | 738 | ||
@@ -792,6 +745,7 @@ static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err) | |||
792 | return 0; | 745 | return 0; |
793 | } | 746 | } |
794 | 747 | ||
748 | *err |= OMAP_I2C_STAT_XUDF; | ||
795 | return 0; | 749 | return 0; |
796 | } | 750 | } |
797 | 751 | ||
@@ -930,8 +884,8 @@ complete: | |||
930 | break; | 884 | break; |
931 | } | 885 | } |
932 | 886 | ||
933 | if ((dev->errata & I2C_OMAP3_1P153) && | 887 | if ((dev->errata & I2C_OMAP_ERRATA_I462) && |
934 | errata_omap3_1p153(dev, &stat, &err)) | 888 | errata_omap3_i462(dev, &stat, &err)) |
935 | goto complete; | 889 | goto complete; |
936 | 890 | ||
937 | omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); | 891 | omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); |
@@ -1048,6 +1002,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1048 | } | 1002 | } |
1049 | 1003 | ||
1050 | platform_set_drvdata(pdev, dev); | 1004 | platform_set_drvdata(pdev, dev); |
1005 | init_completion(&dev->cmd_complete); | ||
1051 | 1006 | ||
1052 | dev->reg_shift = (dev->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3; | 1007 | dev->reg_shift = (dev->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3; |
1053 | 1008 | ||
@@ -1057,12 +1012,19 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1057 | dev->regs = (u8 *)reg_map_ip_v1; | 1012 | dev->regs = (u8 *)reg_map_ip_v1; |
1058 | 1013 | ||
1059 | pm_runtime_enable(dev->dev); | 1014 | pm_runtime_enable(dev->dev); |
1060 | pm_runtime_get_sync(dev->dev); | 1015 | r = pm_runtime_get_sync(dev->dev); |
1016 | if (IS_ERR_VALUE(r)) | ||
1017 | goto err_free_mem; | ||
1061 | 1018 | ||
1062 | dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; | 1019 | dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; |
1063 | 1020 | ||
1064 | if (dev->rev <= OMAP_I2C_REV_ON_3430) | 1021 | dev->errata = 0; |
1065 | dev->errata |= I2C_OMAP3_1P153; | 1022 | |
1023 | if (dev->flags & OMAP_I2C_FLAG_APPLY_ERRATA_I207) | ||
1024 | dev->errata |= I2C_OMAP_ERRATA_I207; | ||
1025 | |||
1026 | if (dev->rev <= OMAP_I2C_REV_ON_3430_3530) | ||
1027 | dev->errata |= I2C_OMAP_ERRATA_I462; | ||
1066 | 1028 | ||
1067 | if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) { | 1029 | if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) { |
1068 | u16 s; | 1030 | u16 s; |
@@ -1079,7 +1041,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1079 | 1041 | ||
1080 | dev->fifo_size = (dev->fifo_size / 2); | 1042 | dev->fifo_size = (dev->fifo_size / 2); |
1081 | 1043 | ||
1082 | if (dev->rev >= OMAP_I2C_REV_ON_3530_4430) | 1044 | if (dev->rev >= OMAP_I2C_REV_ON_3630_4430) |
1083 | dev->b_hw = 0; /* Disable hardware fixes */ | 1045 | dev->b_hw = 0; /* Disable hardware fixes */ |
1084 | else | 1046 | else |
1085 | dev->b_hw = 1; /* Enable hardware fixes */ | 1047 | dev->b_hw = 1; /* Enable hardware fixes */ |
@@ -1095,7 +1057,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1095 | 1057 | ||
1096 | isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr : | 1058 | isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr : |
1097 | omap_i2c_isr; | 1059 | omap_i2c_isr; |
1098 | r = request_irq(dev->irq, isr, 0, pdev->name, dev); | 1060 | r = request_irq(dev->irq, isr, IRQF_NO_SUSPEND, pdev->name, dev); |
1099 | 1061 | ||
1100 | if (r) { | 1062 | if (r) { |
1101 | dev_err(dev->dev, "failure requesting irq %i\n", dev->irq); | 1063 | dev_err(dev->dev, "failure requesting irq %i\n", dev->irq); |
@@ -1105,8 +1067,6 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1105 | dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id, | 1067 | dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id, |
1106 | dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed); | 1068 | dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed); |
1107 | 1069 | ||
1108 | pm_runtime_put(dev->dev); | ||
1109 | |||
1110 | adap = &dev->adapter; | 1070 | adap = &dev->adapter; |
1111 | i2c_set_adapdata(adap, dev); | 1071 | i2c_set_adapdata(adap, dev); |
1112 | adap->owner = THIS_MODULE; | 1072 | adap->owner = THIS_MODULE; |
@@ -1126,6 +1086,8 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1126 | 1086 | ||
1127 | of_i2c_register_devices(adap); | 1087 | of_i2c_register_devices(adap); |
1128 | 1088 | ||
1089 | pm_runtime_put(dev->dev); | ||
1090 | |||
1129 | return 0; | 1091 | return 0; |
1130 | 1092 | ||
1131 | err_free_irq: | 1093 | err_free_irq: |
@@ -1134,6 +1096,7 @@ err_unuse_clocks: | |||
1134 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); | 1096 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); |
1135 | pm_runtime_put(dev->dev); | 1097 | pm_runtime_put(dev->dev); |
1136 | iounmap(dev->base); | 1098 | iounmap(dev->base); |
1099 | pm_runtime_disable(&pdev->dev); | ||
1137 | err_free_mem: | 1100 | err_free_mem: |
1138 | platform_set_drvdata(pdev, NULL); | 1101 | platform_set_drvdata(pdev, NULL); |
1139 | kfree(dev); | 1102 | kfree(dev); |
@@ -1143,17 +1106,23 @@ err_release_region: | |||
1143 | return r; | 1106 | return r; |
1144 | } | 1107 | } |
1145 | 1108 | ||
1146 | static int | 1109 | static int __devexit omap_i2c_remove(struct platform_device *pdev) |
1147 | omap_i2c_remove(struct platform_device *pdev) | ||
1148 | { | 1110 | { |
1149 | struct omap_i2c_dev *dev = platform_get_drvdata(pdev); | 1111 | struct omap_i2c_dev *dev = platform_get_drvdata(pdev); |
1150 | struct resource *mem; | 1112 | struct resource *mem; |
1113 | int ret; | ||
1151 | 1114 | ||
1152 | platform_set_drvdata(pdev, NULL); | 1115 | platform_set_drvdata(pdev, NULL); |
1153 | 1116 | ||
1154 | free_irq(dev->irq, dev); | 1117 | free_irq(dev->irq, dev); |
1155 | i2c_del_adapter(&dev->adapter); | 1118 | i2c_del_adapter(&dev->adapter); |
1119 | ret = pm_runtime_get_sync(&pdev->dev); | ||
1120 | if (IS_ERR_VALUE(ret)) | ||
1121 | return ret; | ||
1122 | |||
1156 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); | 1123 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); |
1124 | pm_runtime_put(&pdev->dev); | ||
1125 | pm_runtime_disable(&pdev->dev); | ||
1157 | iounmap(dev->base); | 1126 | iounmap(dev->base); |
1158 | kfree(dev); | 1127 | kfree(dev); |
1159 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1128 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -1161,13 +1130,26 @@ omap_i2c_remove(struct platform_device *pdev) | |||
1161 | return 0; | 1130 | return 0; |
1162 | } | 1131 | } |
1163 | 1132 | ||
1133 | #ifdef CONFIG_PM | ||
1164 | #ifdef CONFIG_PM_RUNTIME | 1134 | #ifdef CONFIG_PM_RUNTIME |
1165 | static int omap_i2c_runtime_suspend(struct device *dev) | 1135 | static int omap_i2c_runtime_suspend(struct device *dev) |
1166 | { | 1136 | { |
1167 | struct platform_device *pdev = to_platform_device(dev); | 1137 | struct platform_device *pdev = to_platform_device(dev); |
1168 | struct omap_i2c_dev *_dev = platform_get_drvdata(pdev); | 1138 | struct omap_i2c_dev *_dev = platform_get_drvdata(pdev); |
1139 | u16 iv; | ||
1140 | |||
1141 | _dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG); | ||
1142 | |||
1143 | omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, 0); | ||
1169 | 1144 | ||
1170 | omap_i2c_idle(_dev); | 1145 | if (_dev->rev < OMAP_I2C_OMAP1_REV_2) { |
1146 | iv = omap_i2c_read_reg(_dev, OMAP_I2C_IV_REG); /* Read clears */ | ||
1147 | } else { | ||
1148 | omap_i2c_write_reg(_dev, OMAP_I2C_STAT_REG, _dev->iestate); | ||
1149 | |||
1150 | /* Flush posted write */ | ||
1151 | omap_i2c_read_reg(_dev, OMAP_I2C_STAT_REG); | ||
1152 | } | ||
1171 | 1153 | ||
1172 | return 0; | 1154 | return 0; |
1173 | } | 1155 | } |
@@ -1177,23 +1159,40 @@ static int omap_i2c_runtime_resume(struct device *dev) | |||
1177 | struct platform_device *pdev = to_platform_device(dev); | 1159 | struct platform_device *pdev = to_platform_device(dev); |
1178 | struct omap_i2c_dev *_dev = platform_get_drvdata(pdev); | 1160 | struct omap_i2c_dev *_dev = platform_get_drvdata(pdev); |
1179 | 1161 | ||
1180 | omap_i2c_unidle(_dev); | 1162 | if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { |
1163 | omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); | ||
1164 | omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate); | ||
1165 | omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate); | ||
1166 | omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate); | ||
1167 | omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate); | ||
1168 | omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate); | ||
1169 | omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate); | ||
1170 | omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); | ||
1171 | } | ||
1172 | |||
1173 | /* | ||
1174 | * Don't write to this register if the IE state is 0 as it can | ||
1175 | * cause deadlock. | ||
1176 | */ | ||
1177 | if (_dev->iestate) | ||
1178 | omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate); | ||
1181 | 1179 | ||
1182 | return 0; | 1180 | return 0; |
1183 | } | 1181 | } |
1182 | #endif /* CONFIG_PM_RUNTIME */ | ||
1184 | 1183 | ||
1185 | static struct dev_pm_ops omap_i2c_pm_ops = { | 1184 | static struct dev_pm_ops omap_i2c_pm_ops = { |
1186 | .runtime_suspend = omap_i2c_runtime_suspend, | 1185 | SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend, |
1187 | .runtime_resume = omap_i2c_runtime_resume, | 1186 | omap_i2c_runtime_resume, NULL) |
1188 | }; | 1187 | }; |
1189 | #define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops) | 1188 | #define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops) |
1190 | #else | 1189 | #else |
1191 | #define OMAP_I2C_PM_OPS NULL | 1190 | #define OMAP_I2C_PM_OPS NULL |
1192 | #endif | 1191 | #endif /* CONFIG_PM */ |
1193 | 1192 | ||
1194 | static struct platform_driver omap_i2c_driver = { | 1193 | static struct platform_driver omap_i2c_driver = { |
1195 | .probe = omap_i2c_probe, | 1194 | .probe = omap_i2c_probe, |
1196 | .remove = omap_i2c_remove, | 1195 | .remove = __devexit_p(omap_i2c_remove), |
1197 | .driver = { | 1196 | .driver = { |
1198 | .name = "omap_i2c", | 1197 | .name = "omap_i2c", |
1199 | .owner = THIS_MODULE, | 1198 | .owner = THIS_MODULE, |