diff options
author | Jonghwa Lee <jonghwa3.lee@samsung.com> | 2014-04-22 13:56:18 +0900 |
---|---|---|
committer | Jonghwa Lee <jonghwa3.lee@samsung.com> | 2014-04-24 13:33:59 +0900 |
commit | d8fcaa2332ec9393be2553c5ab7dd0af690f74a0 (patch) | |
tree | 077102aa7c79aba3e137d9d22a917e5700a42ecd | |
parent | bba75455d47e71e0662c06508035333445481375 (diff) | |
download | linux-3.10-d8fcaa2332ec9393be2553c5ab7dd0af690f74a0.tar.gz linux-3.10-d8fcaa2332ec9393be2553c5ab7dd0af690f74a0.tar.bz2 linux-3.10-d8fcaa2332ec9393be2553c5ab7dd0af690f74a0.zip |
mfd: max77686: Add suspend/resume callback function for alarm wake-up.
While system is resuming, Max77686's Alarm IRQ should be handled after resuming
of i2c controller. It disables IRQ in suspend callback funtion and enables
it in resume callback to postpone handling.
Change-Id: I69f5af2f8b63748853d0ba8a67f0cbb661e1ffcd
Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
-rw-r--r-- | drivers/mfd/max77686.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index 06e5c92d8a0..ba1f8b832c5 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c @@ -31,6 +31,7 @@ #include <linux/mfd/max77686.h> #include <linux/mfd/max77686-private.h> #include <linux/err.h> +#include <linux/interrupt.h> #define I2C_ADDR_RTC (0x0C >> 1) @@ -151,6 +152,8 @@ static int max77686_i2c_probe(struct i2c_client *i2c, if (ret < 0) goto err_mfd; + device_init_wakeup(max77686->dev, 1); + return ret; err_mfd: @@ -178,10 +181,45 @@ static const struct i2c_device_id max77686_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, max77686_i2c_id); +#ifdef CONFIG_PM_SLEEP +static int max77686_suspend(struct device *dev) +{ + struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct max77686_dev *max77686 = i2c_get_clientdata(i2c); + + if (device_may_wakeup(dev)) + enable_irq_wake(max77686->irq); + + /* + * To prevent RTC alarm irq being handled before resuming + * I2C controller, it needs to disable irq during suspend. + */ + disable_irq(max77686->irq); + + return 0; +} + +static int max77686_resume(struct device *dev) +{ + struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct max77686_dev *max77686 = i2c_get_clientdata(i2c); + + if (device_may_wakeup(dev)) + disable_irq_wake(max77686->irq); + + enable_irq(max77686->irq); + + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + +SIMPLE_DEV_PM_OPS(max77686_pm, max77686_suspend, max77686_resume); + static struct i2c_driver max77686_i2c_driver = { .driver = { .name = "max77686", .owner = THIS_MODULE, + .pm = &max77686_pm, .of_match_table = of_match_ptr(max77686_pmic_dt_match), }, .probe = max77686_i2c_probe, |