static void wdt_enable(void) { spin_lock(&io_lock); if (wdt_clk) clk_set_rate(wdt_clk, 1); /* stop counter, initiate counter reset */ __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base)); /*wait for reset to complete. 100% guarantee event */ while (__raw_readl(WDTIM_COUNTER(wdt_base))) cpu_relax(); /* internal and external reset, stop after that */ __raw_writel(M_RES2 | STOP_COUNT0 | RESET_COUNT0, WDTIM_MCTRL(wdt_base)); /* configure match output */ __raw_writel(MATCH_OUTPUT_HIGH, WDTIM_EMR(wdt_base)); /* clear interrupt, just in case */ __raw_writel(MATCH_INT, WDTIM_INT(wdt_base)); /* the longest pulse period 65541/(13*10^6) seconds ~ 5 ms. */ __raw_writel(0xFFFF, WDTIM_PULSE(wdt_base)); __raw_writel(heartbeat * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base)); /*enable counter, stop when debugger active */ __raw_writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base)); spin_unlock(&io_lock); }
static int pnx4008_restart_handler(struct watchdog_device *wdd, unsigned long mode, void *cmd) { const char *boot_cmd = cmd; /* * Verify if a "cmd" passed from the userspace program rebooting * the system; if available, handle it. * - For details, see the 'reboot' syscall in kernel/reboot.c * - If the received "cmd" is not supported, use the default mode. */ if (boot_cmd) { if (boot_cmd[0] == 'h') mode = REBOOT_HARD; else if (boot_cmd[0] == 's') mode = REBOOT_SOFT; } if (mode == REBOOT_SOFT) { /* Force match output active */ writel(EXT_MATCH0, WDTIM_EMR(wdt_base)); /* Internal reset on match output (RESOUT_N not asserted) */ writel(M_RES1, WDTIM_MCTRL(wdt_base)); } else { /* Instant assert of RESETOUT_N with pulse length 1mS */ writel(13000, WDTIM_PULSE(wdt_base)); writel(M_RES2 | RESFRC1 | RESFRC2, WDTIM_MCTRL(wdt_base)); } /* Wait for watchdog to reset system */ mdelay(1000); return NOTIFY_DONE; }
static int pnx4008_wdt_start(struct watchdog_device *wdd) { spin_lock(&io_lock); /* stop counter, initiate counter reset */ writel(RESET_COUNT, WDTIM_CTRL(wdt_base)); /*wait for reset to complete. 100% guarantee event */ while (readl(WDTIM_COUNTER(wdt_base))) cpu_relax(); /* internal and external reset, stop after that */ writel(M_RES2 | STOP_COUNT0 | RESET_COUNT0, WDTIM_MCTRL(wdt_base)); /* configure match output */ writel(MATCH_OUTPUT_HIGH, WDTIM_EMR(wdt_base)); /* clear interrupt, just in case */ writel(MATCH_INT, WDTIM_INT(wdt_base)); /* the longest pulse period 65541/(13*10^6) seconds ~ 5 ms. */ writel(0xFFFF, WDTIM_PULSE(wdt_base)); writel(wdd->timeout * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base)); /*enable counter, stop when debugger active */ writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base)); spin_unlock(&io_lock); return 0; }