diff options
author | Tom Rini | 2020-04-15 08:30:16 -0400 |
---|---|---|
committer | Tom Rini | 2020-04-15 08:30:16 -0400 |
commit | 9cb3ce2558ba1fc058dfb26a07fc02603773a211 (patch) | |
tree | d8359bfc34d7c2425b89dfa8cf7f8ed32b7be2c9 | |
parent | 142a07f2a44262d76fec609e1fcde51794a456eb (diff) | |
parent | 19a159f94ac1532ec12cf14a96c9daf172ade988 (diff) |
Merge branch 'master' of git://git.denx.de/u-boot-marvell
- Common: honour hw_margin_ms property (Rasmus)
- sp805_wdt: get platform clock from dt (Rayagonda)
-rw-r--r-- | drivers/watchdog/sp805_wdt.c | 15 | ||||
-rw-r--r-- | drivers/watchdog/wdt-uclass.c | 44 | ||||
-rw-r--r-- | include/wdt.h | 37 |
3 files changed, 57 insertions, 39 deletions
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index ca3ccbe76cb..65fd2384f12 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -7,6 +7,7 @@ #include <asm/io.h> #include <common.h> +#include <clk.h> #include <dm/device.h> #include <dm/fdtaddr.h> #include <dm/read.h> @@ -34,6 +35,7 @@ DECLARE_GLOBAL_DATA_PTR; struct sp805_wdt_priv { void __iomem *reg; + unsigned long clk_rate; }; static int sp805_wdt_reset(struct udevice *dev) @@ -63,8 +65,13 @@ static int sp805_wdt_start(struct udevice *dev, u64 timeout, ulong flags) * set 120s, the gd->bus_clk is less than 1145MHz, the load_value will * not overflow. */ - load_value = (gd->bus_clk) / - (2 * 1000 * SYS_FSL_WDT_CLK_DIV) * load_time; + if (gd->bus_clk) { + load_value = (gd->bus_clk) / + (2 * 1000 * SYS_FSL_WDT_CLK_DIV) * load_time; + } else { + /* platform provide clk */ + load_value = (timeout / 2) * (priv->clk_rate / 1000); + } writel(UNLOCK, priv->reg + WDTLOCK); writel(load_value, priv->reg + WDTLOAD); @@ -105,11 +112,15 @@ static int sp805_wdt_probe(struct udevice *dev) static int sp805_wdt_ofdata_to_platdata(struct udevice *dev) { struct sp805_wdt_priv *priv = dev_get_priv(dev); + struct clk clk; priv->reg = (void __iomem *)dev_read_addr(dev); if (IS_ERR(priv->reg)) return PTR_ERR(priv->reg); + if (!clk_get_by_index(dev, 0, &clk)) + priv->clk_rate = clk_get_rate(&clk); + return 0; } diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c index d9e4dc7cb8a..4cdb7bd64cd 100644 --- a/drivers/watchdog/wdt-uclass.c +++ b/drivers/watchdog/wdt-uclass.c @@ -14,6 +14,48 @@ DECLARE_GLOBAL_DATA_PTR; +#define WATCHDOG_TIMEOUT_SECS (CONFIG_WATCHDOG_TIMEOUT_MSECS / 1000) + +/* + * Reset every 1000ms, or however often is required as indicated by a + * hw_margin_ms property. + */ +static ulong reset_period = 1000; + +int initr_watchdog(void) +{ + u32 timeout = WATCHDOG_TIMEOUT_SECS; + + /* + * Init watchdog: This will call the probe function of the + * watchdog driver, enabling the use of the device + */ + if (uclass_get_device_by_seq(UCLASS_WDT, 0, + (struct udevice **)&gd->watchdog_dev)) { + debug("WDT: Not found by seq!\n"); + if (uclass_get_device(UCLASS_WDT, 0, + (struct udevice **)&gd->watchdog_dev)) { + printf("WDT: Not found!\n"); + return 0; + } + } + + if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { + timeout = dev_read_u32_default(gd->watchdog_dev, "timeout-sec", + WATCHDOG_TIMEOUT_SECS); + reset_period = dev_read_u32_default(gd->watchdog_dev, + "hw_margin_ms", + 4 * reset_period) / 4; + } + + wdt_start(gd->watchdog_dev, timeout * 1000, 0); + gd->flags |= GD_FLG_WDT_READY; + printf("WDT: Started with%s servicing (%ds timeout)\n", + IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", timeout); + + return 0; +} + int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) { const struct wdt_ops *ops = device_get_ops(dev); @@ -85,7 +127,7 @@ void watchdog_reset(void) /* Do not reset the watchdog too often */ now = get_timer(0); if (time_after(now, next_reset)) { - next_reset = now + 1000; /* reset every 1000ms */ + next_reset = now + reset_period; wdt_reset(gd->watchdog_dev); } } diff --git a/include/wdt.h b/include/wdt.h index dd83dfdd320..aea5abc7680 100644 --- a/include/wdt.h +++ b/include/wdt.h @@ -106,41 +106,6 @@ struct wdt_ops { int (*expire_now)(struct udevice *dev, ulong flags); }; -#if CONFIG_IS_ENABLED(WDT) -#ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS -#define CONFIG_WATCHDOG_TIMEOUT_MSECS (60 * 1000) -#endif -#define WATCHDOG_TIMEOUT_SECS (CONFIG_WATCHDOG_TIMEOUT_MSECS / 1000) - -static inline int initr_watchdog(void) -{ - u32 timeout = WATCHDOG_TIMEOUT_SECS; - - /* - * Init watchdog: This will call the probe function of the - * watchdog driver, enabling the use of the device - */ - if (uclass_get_device_by_seq(UCLASS_WDT, 0, - (struct udevice **)&gd->watchdog_dev)) { - debug("WDT: Not found by seq!\n"); - if (uclass_get_device(UCLASS_WDT, 0, - (struct udevice **)&gd->watchdog_dev)) { - printf("WDT: Not found!\n"); - return 0; - } - } - - if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { - timeout = dev_read_u32_default(gd->watchdog_dev, "timeout-sec", - WATCHDOG_TIMEOUT_SECS); - } - wdt_start(gd->watchdog_dev, timeout * 1000, 0); - gd->flags |= GD_FLG_WDT_READY; - printf("WDT: Started with%s servicing (%ds timeout)\n", - IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", timeout); - - return 0; -} -#endif +int initr_watchdog(void); #endif /* _WDT_H_ */ |