mfd: max77686: Add suspend/resume callback function for alarm wake-up.
authorJonghwa Lee <jonghwa3.lee@samsung.com>
Tue, 22 Apr 2014 04:56:18 +0000 (13:56 +0900)
committerChanho Park <chanho61.park@samsung.com>
Tue, 18 Nov 2014 02:47:30 +0000 (11:47 +0900)
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>
drivers/mfd/max77686.c

index 94ba140..436a0c1 100644 (file)
@@ -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)
 
@@ -155,6 +156,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:
@@ -182,10 +185,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,