diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2013-01-28 13:04:15 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 12:58:36 -0700 |
commit | 4695bbb98e2ceb1d776d4f54a6f95d25ea219e0a (patch) | |
tree | 4372d7293669ceb120eb128e9d07ce46a48e4848 /drivers/watchdog | |
parent | 2e669350d1b0b690886760ac9034079c0763c44f (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.c | 40 |
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), |