static int dw_wdt_set_top(unsigned top_s) { int i, top_val = DW_WDT_MAX_TOP; /* * Iterate over the timeout values until we find the closest match. We * always look for >=. */ for (i = 0; i <= DW_WDT_MAX_TOP; ++i) if (dw_wdt_top_in_seconds(i) >= top_s) { top_val = i; break; } /* * 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_ping(unsigned long data) { if (time_before(jiffies, dw_wdt.next_heartbeat) || (!nowayout && !dw_wdt.in_use)) { dw_wdt_keepalive(); mod_timer(&dw_wdt.timer, jiffies + WDT_TIMEOUT); } else pr_crit("keepalive missed, machine will reset\n"); }
static int dw_wdt_resume(struct device *dev) { int err = clk_enable(dw_wdt.clk); if (err) return err; dw_wdt_keepalive(); return 0; }