summaryrefslogtreecommitdiff
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2013-01-28 13:04:15 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 12:58:36 -0700
commit4695bbb98e2ceb1d776d4f54a6f95d25ea219e0a (patch)
tree4372d7293669ceb120eb128e9d07ce46a48e4848 /drivers/watchdog
parent2e669350d1b0b690886760ac9034079c0763c44f (diff)
watchdog: max77660: implement suspend/resume of watchdog timer
Implement suspend/resume of MAX77660 system watchdog timer: - Keep enabling if wakeup enable. - Disable watchdog timer in suspend and re-enable in resume if wakeup from watchdog timer is not enabled and timeout is set. Change-Id: I90ee8c43e11f947ec71370a9095357b229f89d36 Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-on: http://git-master/r/194547
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/max77660_sys_wdt.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/watchdog/max77660_sys_wdt.c b/drivers/watchdog/max77660_sys_wdt.c
index d6cb1ef246c1..138b59aba351 100644
--- a/drivers/watchdog/max77660_sys_wdt.c
+++ b/drivers/watchdog/max77660_sys_wdt.c
@@ -31,6 +31,7 @@
#include <linux/module.h>
#include <linux/mfd/max77660/max77660-core.h>
#include <linux/platform_device.h>
+#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/watchdog.h>
@@ -40,6 +41,7 @@ struct max77660_sys_wdt {
struct watchdog_device wdt_dev;
struct device *dev;
struct device *parent;
+ int timeout;
int irq;
};
@@ -114,6 +116,7 @@ static int max77660_sys_wdt_set_timeout(struct watchdog_device *wdt_dev,
dev_err(wdt->dev, "GLOBAL_CFG2 update failed: %d\n", ret);
return ret;
}
+ wdt->timeout = timeout;
return 0;
}
@@ -221,10 +224,47 @@ static int __devexit max77660_sys_wdt_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int max77660_sys_wdt_suspend(struct device *dev)
+{
+ struct max77660_sys_wdt *wdt = dev_get_drvdata(dev);
+ int ret;
+
+ if (device_may_wakeup(dev)) {
+ enable_irq_wake(wdt->irq);
+ } else if (wdt->timeout > 0) {
+ ret = max77660_sys_wdt_stop(&wdt->wdt_dev);
+ if (ret < 0)
+ dev_err(wdt->dev, "wdt stop failed: %d\n", ret);
+ }
+ return 0;
+}
+
+static int max77660_sys_wdt_resume(struct device *dev)
+{
+ struct max77660_sys_wdt *wdt = dev_get_drvdata(dev);
+ int ret;
+
+ if (device_may_wakeup(dev)) {
+ disable_irq_wake(wdt->irq);
+ } else if (wdt->timeout > 0) {
+ ret = max77660_sys_wdt_start(&wdt->wdt_dev);
+ if (ret < 0)
+ dev_err(wdt->dev, "wdt start failed: %d\n", ret);
+ }
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops max77660_sys_wdt_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(max77660_sys_wdt_suspend, max77660_sys_wdt_resume)
+};
+
static struct platform_driver max77660_sys_wdt_driver = {
.driver = {
.name = "max77660-sys-wdt",
.owner = THIS_MODULE,
+ .pm = &max77660_sys_wdt_pm_ops,
},
.probe = max77660_sys_wdt_probe,
.remove = __devexit_p(max77660_sys_wdt_remove),