diff options
author | Tom Rini <trini@konsulko.com> | 2022-03-08 07:37:00 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-03-08 07:37:00 -0500 |
commit | 2d4e9174c677ea65222fcfe1c79e87e1baff9c36 (patch) | |
tree | affd5b4846cdb2ba5e233e6d9a95c0439fe264af | |
parent | 9c53621df16387342d0cfcbedabd0b0fd3d19bd3 (diff) | |
parent | 817e153fe546c2da9df8e8affc94d12036815659 (diff) | |
download | u-boot-WIP/08Mar2022.zip u-boot-WIP/08Mar2022.tar.gz u-boot-WIP/08Mar2022.tar.bz2 |
Merge https://source.denx.de/u-boot/custodians/u-boot-watchdogWIP/08Mar2022
- Update MAINTAINERS file (Stefan)
- wdt-uclass.c: add a property u-boot, noautostart (Philippe)
- armada_37xx: Probe driver also when watchdog is already running (Pali)
- rti_wdt: Add 10% safety margin to clock frequency (Jan)
-rw-r--r-- | MAINTAINERS | 8 | ||||
-rw-r--r-- | drivers/watchdog/armada-37xx-wdt.c | 17 | ||||
-rw-r--r-- | drivers/watchdog/rti_wdt.c | 14 | ||||
-rw-r--r-- | drivers/watchdog/wdt-uclass.c | 7 |
4 files changed, 28 insertions, 18 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 0f39bc6..82fc49e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1326,6 +1326,14 @@ F: include/virtio*.h F: test/dm/virtio.c F: doc/develop/driver-model/virtio.rst +WATCHDOG +M: Stefan Roese <sr@denx.de> +S: Maintained +T: git https://source.denx.de/u-boot/custodians/u-boot-watchdog.git +F: cmd/wdt.c +F: drivers/watchdog/ +F: include/watchdog*.h + X86 M: Simon Glass <sjg@chromium.org> M: Bin Meng <bmeng.cn@gmail.com> diff --git a/drivers/watchdog/armada-37xx-wdt.c b/drivers/watchdog/armada-37xx-wdt.c index 2e119b9..bacebbc 100644 --- a/drivers/watchdog/armada-37xx-wdt.c +++ b/drivers/watchdog/armada-37xx-wdt.c @@ -58,13 +58,11 @@ static void counter_disable(struct a37xx_wdt *priv, int id) clrbits_le32(priv->reg + CNTR_CTRL(id), CNTR_CTRL_ENABLE); } -static int init_counter(struct a37xx_wdt *priv, int id, u32 mode, u32 trig_src) +static void init_counter(struct a37xx_wdt *priv, int id, u32 mode, u32 trig_src) { u32 reg; reg = readl(priv->reg + CNTR_CTRL(id)); - if (reg & CNTR_CTRL_ACTIVE) - return -EBUSY; reg &= ~(CNTR_CTRL_MODE_MASK | CNTR_CTRL_PRESCALE_MASK | CNTR_CTRL_TRIG_SRC_MASK); @@ -79,8 +77,6 @@ static int init_counter(struct a37xx_wdt *priv, int id, u32 mode, u32 trig_src) reg |= trig_src; writel(reg, priv->reg + CNTR_CTRL(id)); - - return 0; } static int a37xx_wdt_reset(struct udevice *dev) @@ -116,16 +112,9 @@ static int a37xx_wdt_expire_now(struct udevice *dev, ulong flags) static int a37xx_wdt_start(struct udevice *dev, u64 ms, ulong flags) { struct a37xx_wdt *priv = dev_get_priv(dev); - int err; - - err = init_counter(priv, 0, CNTR_CTRL_MODE_ONESHOT, 0); - if (err < 0) - return err; - err = init_counter(priv, 1, CNTR_CTRL_MODE_HWSIG, - CNTR_CTRL_TRIG_SRC_PREV_CNTR); - if (err < 0) - return err; + init_counter(priv, 0, CNTR_CTRL_MODE_ONESHOT, 0); + init_counter(priv, 1, CNTR_CTRL_MODE_HWSIG, CNTR_CTRL_TRIG_SRC_PREV_CNTR); priv->timeout = ms * priv->clk_rate / 1000 / CNTR_CTRL_PRESCALE_MIN; diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c index 253286d..8d93f19 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c @@ -41,7 +41,7 @@ struct rti_wdt_priv { phys_addr_t regs; - unsigned int clk_khz; + unsigned int clk_hz; }; #ifdef CONFIG_WDT_K3_RTI_LOAD_FW @@ -139,7 +139,7 @@ static int rti_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) if (ret < 0) return ret; - timer_margin = timeout_ms * priv->clk_khz / 1000; + timer_margin = timeout_ms * priv->clk_hz / 1000; timer_margin >>= WDT_PRELOAD_SHIFT; if (timer_margin > WDT_PRELOAD_MAX) timer_margin = WDT_PRELOAD_MAX; @@ -185,7 +185,15 @@ static int rti_wdt_probe(struct udevice *dev) if (ret) return ret; - priv->clk_khz = clk_get_rate(&clk); + priv->clk_hz = clk_get_rate(&clk); + + /* + * If watchdog is running at 32k clock, it is not accurate. + * Adjust frequency down in this case so that it does not expire + * earlier than expected. + */ + if (priv->clk_hz < 32768) + priv->clk_hz = priv->clk_hz * 9 / 10; return 0; } diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c index 6d0f473..dbf5564 100644 --- a/drivers/watchdog/wdt-uclass.c +++ b/drivers/watchdog/wdt-uclass.c @@ -36,6 +36,8 @@ struct wdt_priv { ulong next_reset; /* Whether watchdog_start() has been called on the device. */ bool running; + /* No autostart */ + bool noautostart; }; static void init_watchdog_dev(struct udevice *dev) @@ -52,7 +54,7 @@ static void init_watchdog_dev(struct udevice *dev) dev->name); } - if (!IS_ENABLED(CONFIG_WATCHDOG_AUTOSTART)) { + if (!IS_ENABLED(CONFIG_WATCHDOG_AUTOSTART) || priv->noautostart) { printf("WDT: Not starting %s\n", dev->name); return; } @@ -256,16 +258,19 @@ static int wdt_pre_probe(struct udevice *dev) * indicated by a hw_margin_ms property. */ ulong reset_period = 1000; + bool noautostart = false; struct wdt_priv *priv; if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { timeout = dev_read_u32_default(dev, "timeout-sec", timeout); reset_period = dev_read_u32_default(dev, "hw_margin_ms", 4 * reset_period) / 4; + noautostart = dev_read_bool(dev, "u-boot,noautostart"); } priv = dev_get_uclass_priv(dev); priv->timeout = timeout; priv->reset_period = reset_period; + priv->noautostart = noautostart; /* * Pretend this device was last reset "long" ago so the first * watchdog_reset will actually call its ->reset method. |