diff options
author | Manuel Lauss <mano@roarinelk.homelinux.net> | 2008-07-14 16:38:33 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-14 16:38:33 -0400 |
commit | 2373c1801afd06d3a206376902b39a98458c9cfb (patch) | |
tree | 1ff3b59acd452891aa00cc0cfcc4015fe2a88378 /drivers/i2c/busses | |
parent | 392a0408fdc4c9069c32a9a02b0088eae76c4618 (diff) |
i2c-ocores: basic PM support
Basic PM support: reinit the core on resume, disable it on suspend.
Signed-off-by: Manuel Lauss <mano@roarinelk.homelinux.net>
Acked-by: Peter Korsgaard <jacmet@sunsite.dk>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r-- | drivers/i2c/busses/i2c-ocores.c | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 51ca79bf6480..e5193bf75483 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c | |||
@@ -29,6 +29,7 @@ struct ocores_i2c { | |||
29 | int pos; | 29 | int pos; |
30 | int nmsgs; | 30 | int nmsgs; |
31 | int state; /* see STATE_ */ | 31 | int state; /* see STATE_ */ |
32 | int clock_khz; | ||
32 | }; | 33 | }; |
33 | 34 | ||
34 | /* registers */ | 35 | /* registers */ |
@@ -173,8 +174,7 @@ static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
173 | return -ETIMEDOUT; | 174 | return -ETIMEDOUT; |
174 | } | 175 | } |
175 | 176 | ||
176 | static void ocores_init(struct ocores_i2c *i2c, | 177 | static void ocores_init(struct ocores_i2c *i2c) |
177 | struct ocores_i2c_platform_data *pdata) | ||
178 | { | 178 | { |
179 | int prescale; | 179 | int prescale; |
180 | u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); | 180 | u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); |
@@ -182,7 +182,7 @@ static void ocores_init(struct ocores_i2c *i2c, | |||
182 | /* make sure the device is disabled */ | 182 | /* make sure the device is disabled */ |
183 | oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); | 183 | oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); |
184 | 184 | ||
185 | prescale = (pdata->clock_khz / (5*100)) - 1; | 185 | prescale = (i2c->clock_khz / (5*100)) - 1; |
186 | oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); | 186 | oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); |
187 | oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); | 187 | oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); |
188 | 188 | ||
@@ -248,7 +248,8 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev) | |||
248 | } | 248 | } |
249 | 249 | ||
250 | i2c->regstep = pdata->regstep; | 250 | i2c->regstep = pdata->regstep; |
251 | ocores_init(i2c, pdata); | 251 | i2c->clock_khz = pdata->clock_khz; |
252 | ocores_init(i2c); | ||
252 | 253 | ||
253 | init_waitqueue_head(&i2c->wait); | 254 | init_waitqueue_head(&i2c->wait); |
254 | ret = request_irq(res2->start, ocores_isr, 0, pdev->name, i2c); | 255 | ret = request_irq(res2->start, ocores_isr, 0, pdev->name, i2c); |
@@ -312,13 +313,40 @@ static int __devexit ocores_i2c_remove(struct platform_device* pdev) | |||
312 | return 0; | 313 | return 0; |
313 | } | 314 | } |
314 | 315 | ||
316 | #ifdef CONFIG_PM | ||
317 | static int ocores_i2c_suspend(struct platform_device *pdev, pm_message_t state) | ||
318 | { | ||
319 | struct ocores_i2c *i2c = platform_get_drvdata(pdev); | ||
320 | u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); | ||
321 | |||
322 | /* make sure the device is disabled */ | ||
323 | oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static int ocores_i2c_resume(struct platform_device *pdev) | ||
329 | { | ||
330 | struct ocores_i2c *i2c = platform_get_drvdata(pdev); | ||
331 | |||
332 | ocores_init(i2c); | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | #else | ||
337 | #define ocores_i2c_suspend NULL | ||
338 | #define ocores_i2c_resume NULL | ||
339 | #endif | ||
340 | |||
315 | /* work with hotplug and coldplug */ | 341 | /* work with hotplug and coldplug */ |
316 | MODULE_ALIAS("platform:ocores-i2c"); | 342 | MODULE_ALIAS("platform:ocores-i2c"); |
317 | 343 | ||
318 | static struct platform_driver ocores_i2c_driver = { | 344 | static struct platform_driver ocores_i2c_driver = { |
319 | .probe = ocores_i2c_probe, | 345 | .probe = ocores_i2c_probe, |
320 | .remove = __devexit_p(ocores_i2c_remove), | 346 | .remove = __devexit_p(ocores_i2c_remove), |
321 | .driver = { | 347 | .suspend = ocores_i2c_suspend, |
348 | .resume = ocores_i2c_resume, | ||
349 | .driver = { | ||
322 | .owner = THIS_MODULE, | 350 | .owner = THIS_MODULE, |
323 | .name = "ocores-i2c", | 351 | .name = "ocores-i2c", |
324 | }, | 352 | }, |