watchdog: dw_wdt: pat the watchdog before enabling it
[pandora-kernel.git] / drivers / watchdog / dw_wdt.c
index b34a2e4..3dde6de 100644 (file)
@@ -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)
 {