summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Norris <briannorris@chromium.org>2018-03-09 17:49:21 -0800
committerTao Huang <huangtao@rock-chips.com>2019-03-12 16:09:22 +0800
commitda72a45cf789251335775337921e47d0dbde6004 (patch)
tree7e7cfe4926b08328c41c6fc494886beb407617de
parentc7acb7de6674ce5fb109215e74d7f88eb9c791a8 (diff)
FROMLIST: watchdog: dw: save/restore control and timeout across suspend/resume
Some platforms lose this state in suspend. It should be safe to do this unconditionally. Signed-off-by: Brian Norris <briannorris@chromium.org> Reviewed-by: Guenter Roeck <linux@roeck-us.net> (am from https://patchwork.kernel.org/patch/10273165/) Conflicts: small context changes BUG=b:74204857 TEST=force watchdog event before/after suspend/resume on kevin and scarlet; check timing Reviewed-on: https://chromium-review.googlesource.com/958089 Commit-Ready: Brian Norris <briannorris@chromium.org> Tested-by: Brian Norris <briannorris@chromium.org> Reviewed-by: Guenter Roeck <groeck@chromium.org> Change-Id: I7a0e4d6c87ed3eeb3c41d9dcff014fd5f7cddef5 Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
-rw-r--r--drivers/watchdog/dw_wdt.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index a2edcef2c13d..7b1984d18448 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -68,6 +68,9 @@ static struct {
struct timer_list timer;
int expect_close;
struct notifier_block restart_handler;
+ /* Save/restore */
+ u32 control;
+ u32 timeout;
} dw_wdt;
static inline int dw_wdt_is_enabled(void)
@@ -301,6 +304,9 @@ static int dw_wdt_release(struct inode *inode, struct file *filp)
#ifdef CONFIG_PM_SLEEP
static int dw_wdt_suspend(struct device *dev)
{
+ dw_wdt.control = readl(dw_wdt.regs + WDOG_CONTROL_REG_OFFSET);
+ dw_wdt.timeout = readl(dw_wdt.regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
+
clk_disable_unprepare(dw_wdt.clk);
return 0;
@@ -313,6 +319,9 @@ static int dw_wdt_resume(struct device *dev)
if (err)
return err;
+ writel(dw_wdt.timeout, dw_wdt.regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
+ writel(dw_wdt.control, dw_wdt.regs + WDOG_CONTROL_REG_OFFSET);
+
dw_wdt_keepalive();
return 0;