static inline void ath79_wdt_enable(void) { ath79_wdt_keepalive(); ath79_wdt_wr(WDOG_REG_CTRL, WDOG_CTRL_ACTION_FCR); /* flush write */ ath79_wdt_rr(WDOG_REG_CTRL); }
static int ath79_wdt_probe(struct platform_device *pdev) { struct resource *res; u32 ctrl; int err; if (wdt_base) return -EBUSY; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(wdt_base)) return PTR_ERR(wdt_base); wdt_clk = devm_clk_get(&pdev->dev, "wdt"); if (IS_ERR(wdt_clk)) return PTR_ERR(wdt_clk); err = clk_enable(wdt_clk); if (err) return err; wdt_freq = clk_get_rate(wdt_clk); if (!wdt_freq) { err = -EINVAL; goto err_clk_disable; } max_timeout = (0xfffffffful / wdt_freq); if (timeout < 1 || timeout > max_timeout) { timeout = max_timeout; dev_info(&pdev->dev, "timeout value must be 0 < timeout < %d, using %d\n", max_timeout, timeout); } ctrl = ath79_wdt_rr(WDOG_REG_CTRL); boot_status = (ctrl & WDOG_CTRL_LAST_RESET) ? WDIOF_CARDRESET : 0; err = misc_register(&ath79_wdt_miscdev); if (err) { dev_err(&pdev->dev, "unable to register misc device, err=%d\n", err); goto err_clk_disable; } return 0; err_clk_disable: clk_disable(wdt_clk); return err; }
static inline void ath79_wdt_enable(void) { ath79_wdt_keepalive(); /* * Updating the TIMER register requires a few microseconds * on the AR934x SoCs at least. Use a small delay to ensure * that the TIMER register is updated within the hardware * before enabling the watchdog. */ udelay(2); ath79_wdt_wr(WDOG_REG_CTRL, WDOG_CTRL_ACTION_FCR); /* flush write */ ath79_wdt_rr(WDOG_REG_CTRL); }
static inline void ath79_wdt_disable(void) { ath79_wdt_wr(WDOG_REG_CTRL, WDOG_CTRL_ACTION_NONE); /* flush write */ ath79_wdt_rr(WDOG_REG_CTRL); }
static inline void ath79_wdt_keepalive(void) { ath79_wdt_wr(WDOG_REG_TIMER, wdt_freq * timeout); /* flush write */ ath79_wdt_rr(WDOG_REG_TIMER); }