diff options
author | Javier Martinez Canillas <javier.martinez@collabora.co.uk> | 2014-07-04 16:24:05 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2014-07-21 11:54:27 -0400 |
commit | 2b52b5d5f25108739954f0c544dfe72f08a3aacc (patch) | |
tree | 2b99a30619f13ae2220c46e39c80af5d48629036 /drivers/mfd/max77686.c | |
parent | 6f1c1e71d933f58a6248f1681aededdd407f32a8 (diff) |
mfd: max77686: Add power management support
The driver doesn't have PM operations defined so add a suspend
and resume function handlers to allow the PMIC IRQ to wakeup
the system when it is put into a sleep state.
Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd/max77686.c')
-rw-r--r-- | drivers/mfd/max77686.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index 3cb41d02cd3d..a38e9ee1a0d9 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c | |||
@@ -240,10 +240,50 @@ static const struct i2c_device_id max77686_i2c_id[] = { | |||
240 | }; | 240 | }; |
241 | MODULE_DEVICE_TABLE(i2c, max77686_i2c_id); | 241 | MODULE_DEVICE_TABLE(i2c, max77686_i2c_id); |
242 | 242 | ||
243 | #ifdef CONFIG_PM_SLEEP | ||
244 | static int max77686_suspend(struct device *dev) | ||
245 | { | ||
246 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
247 | struct max77686_dev *max77686 = i2c_get_clientdata(i2c); | ||
248 | |||
249 | if (device_may_wakeup(dev)) | ||
250 | enable_irq_wake(max77686->irq); | ||
251 | |||
252 | /* | ||
253 | * IRQ must be disabled during suspend because if it happens | ||
254 | * while suspended it will be handled before resuming I2C. | ||
255 | * | ||
256 | * When device is woken up from suspend (e.g. by RTC wake alarm), | ||
257 | * an interrupt occurs before resuming I2C bus controller. | ||
258 | * Interrupt handler tries to read registers but this read | ||
259 | * will fail because I2C is still suspended. | ||
260 | */ | ||
261 | disable_irq(max77686->irq); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int max77686_resume(struct device *dev) | ||
267 | { | ||
268 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
269 | struct max77686_dev *max77686 = i2c_get_clientdata(i2c); | ||
270 | |||
271 | if (device_may_wakeup(dev)) | ||
272 | disable_irq_wake(max77686->irq); | ||
273 | |||
274 | enable_irq(max77686->irq); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | #endif /* CONFIG_PM_SLEEP */ | ||
279 | |||
280 | static SIMPLE_DEV_PM_OPS(max77686_pm, max77686_suspend, max77686_resume); | ||
281 | |||
243 | static struct i2c_driver max77686_i2c_driver = { | 282 | static struct i2c_driver max77686_i2c_driver = { |
244 | .driver = { | 283 | .driver = { |
245 | .name = "max77686", | 284 | .name = "max77686", |
246 | .owner = THIS_MODULE, | 285 | .owner = THIS_MODULE, |
286 | .pm = &max77686_pm, | ||
247 | .of_match_table = of_match_ptr(max77686_pmic_dt_match), | 287 | .of_match_table = of_match_ptr(max77686_pmic_dt_match), |
248 | }, | 288 | }, |
249 | .probe = max77686_i2c_probe, | 289 | .probe = max77686_i2c_probe, |