summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonghwa Lee <jonghwa3.lee@samsung.com>2014-04-22 13:56:18 +0900
committerJonghwa Lee <jonghwa3.lee@samsung.com>2014-04-24 13:33:59 +0900
commitd8fcaa2332ec9393be2553c5ab7dd0af690f74a0 (patch)
tree077102aa7c79aba3e137d9d22a917e5700a42ecd
parentbba75455d47e71e0662c06508035333445481375 (diff)
downloadlinux-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.c38
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,