From da72a45cf789251335775337921e47d0dbde6004 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 9 Mar 2018 17:49:21 -0800 Subject: 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 Reviewed-by: Guenter Roeck (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 Tested-by: Brian Norris Reviewed-by: Guenter Roeck Change-Id: I7a0e4d6c87ed3eeb3c41d9dcff014fd5f7cddef5 Signed-off-by: Jeffy Chen --- drivers/watchdog/dw_wdt.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') 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; -- cgit v1.2.3