summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/watchdog/dw_wdt.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index b34a2e4e4e43..3dde6de117fa 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -96,6 +96,12 @@ static inline void dw_wdt_set_next_heartbeat(void)
dw_wdt.next_heartbeat = jiffies + dw_wdt_get_top() * HZ;
}
+static void dw_wdt_keepalive(void)
+{
+ writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt.regs +
+ WDOG_COUNTER_RESTART_REG_OFFSET);
+}
+
static int dw_wdt_set_top(unsigned top_s)
{
int i, top_val = DW_WDT_MAX_TOP;
@@ -110,21 +116,27 @@ static int dw_wdt_set_top(unsigned top_s)
break;
}
- /* Set the new value in the watchdog. */
+ /*
+ * Set the new value in the watchdog. Some versions of dw_wdt
+ * have have TOPINIT in the TIMEOUT_RANGE register (as per
+ * CP_WDT_DUAL_TOP in WDT_COMP_PARAMS_1). On those we
+ * effectively get a pat of the watchdog right here.
+ */
writel(top_val | top_val << WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT,
dw_wdt.regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
+ /*
+ * Add an explicit pat to handle versions of the watchdog that
+ * don't have TOPINIT. This won't hurt on versions that have
+ * it.
+ */
+ dw_wdt_keepalive();
+
dw_wdt_set_next_heartbeat();
return dw_wdt_top_in_seconds(top_val);
}
-static void dw_wdt_keepalive(void)
-{
- writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt.regs +
- WDOG_COUNTER_RESTART_REG_OFFSET);
-}
-
static int dw_wdt_restart_handle(struct notifier_block *this,
unsigned long mode, void *cmd)
{