aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-08-26 05:40:50 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-09-09 11:32:52 -0400
commite7d48fa2b5fbc7f74bb7ef4a8d7e080b0e831ef0 (patch)
treec90aeb47ebd226beb030cb655a55cf429039063d /drivers/i2c
parent387fa6a5eca021ed5bef5454413b7cdfda74ba41 (diff)
[I2C] pxa: provide late suspend and early resume hooks
Properly hook the I2C driver into the PM code; the previous fix for this (ece5f7b3c4fde70a1ae4add7372ebca5c90bc34d) worked around the platform where I2C is required to be available early during resume. It has been found to be sufficient to use the early resume hook for this function, so the original hack can die. Leave the hack in place for the PIO transfer handler though. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-pxa.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 57fbffd1ccc..518b57c795c 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -909,12 +909,6 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num
909 struct pxa_i2c *i2c = adap->algo_data; 909 struct pxa_i2c *i2c = adap->algo_data;
910 int ret, i; 910 int ret, i;
911 911
912 /* If the I2C controller is disabled we need to reset it (probably due
913 to a suspend/resume destroying state). We do this here as we can then
914 avoid worrying about resuming the controller before its users. */
915 if (!(readl(_ICR(i2c)) & ICR_IUE))
916 i2c_pxa_reset(i2c);
917
918 for (i = adap->retries; i >= 0; i--) { 912 for (i = adap->retries; i >= 0; i--) {
919 ret = i2c_pxa_do_xfer(i2c, msgs, num); 913 ret = i2c_pxa_do_xfer(i2c, msgs, num);
920 if (ret != I2C_RETRY) 914 if (ret != I2C_RETRY)
@@ -1085,9 +1079,33 @@ static int __exit i2c_pxa_remove(struct platform_device *dev)
1085 return 0; 1079 return 0;
1086} 1080}
1087 1081
1082#ifdef CONFIG_PM
1083static int i2c_pxa_suspend_late(struct platform_device *dev, pm_message_t state)
1084{
1085 struct pxa_i2c *i2c = platform_get_drvdata(dev);
1086 clk_disable(i2c->clk);
1087 return 0;
1088}
1089
1090static int i2c_pxa_resume_early(struct platform_device *dev)
1091{
1092 struct pxa_i2c *i2c = platform_get_drvdata(dev);
1093
1094 clk_enable(i2c->clk);
1095 i2c_pxa_reset(i2c);
1096
1097 return 0;
1098}
1099#else
1100#define i2c_pxa_suspend_late NULL
1101#define i2c_pxa_resume_early NULL
1102#endif
1103
1088static struct platform_driver i2c_pxa_driver = { 1104static struct platform_driver i2c_pxa_driver = {
1089 .probe = i2c_pxa_probe, 1105 .probe = i2c_pxa_probe,
1090 .remove = __exit_p(i2c_pxa_remove), 1106 .remove = __exit_p(i2c_pxa_remove),
1107 .suspend_late = i2c_pxa_suspend_late,
1108 .resume_early = i2c_pxa_resume_early,
1091 .driver = { 1109 .driver = {
1092 .name = "pxa2xx-i2c", 1110 .name = "pxa2xx-i2c",
1093 .owner = THIS_MODULE, 1111 .owner = THIS_MODULE,