[PATCH] watchdog: stm32_iwdg: Base pretimeout on timeout when not specified
Benjamin Frost <[email protected]>
| Newsgroups | org.kernel.vger.linux-watchdog |
|---|---|
| Message-ID | <[email protected]> |
When pretimeout was already set and timeout was later changed, the value for pretimeout would be clamped to its upper limit if it wasn't also changed, causing the pretimeout to fire constantly. This is fixed by introducing a local `pretimeout` variable to hold the effective value, either from wdd->pretimeout if set, or the 3/4 timeout fallback otherwise. This leaves wdd->pretimeout untouched, ensuring the pretimeout is always recalculated relative to the current timeout when not explicitly specified. Signed-off-by: Benjamin Frost <[email protected]> --- drivers/watchdog/stm32_iwdg.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c index b356a272ff9a..a38e204129ff 100644 --- a/drivers/watchdog/stm32_iwdg.c +++ b/drivers/watchdog/stm32_iwdg.c @@ -97,17 +97,19 @@ static inline void reg_write(void __iomem *base, u32 reg, u32 val) static int stm32_iwdg_start(struct watchdog_device *wdd) { struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); - u32 tout, ptot, presc, iwdg_rlr, iwdg_ewcr, iwdg_pr, iwdg_sr; + u32 tout, ptot, presc, iwdg_rlr, iwdg_ewcr, iwdg_pr, iwdg_sr, pretimeout; int ret; dev_dbg(wdd->parent, "%s\n", __func__); - if (!wdd->pretimeout) - wdd->pretimeout = 3 * wdd->timeout / 4; + if (wdd->pretimeout) + pretimeout = wdd->pretimeout; + else + pretimeout = 3 * wdd->timeout / 4; tout = clamp_t(unsigned int, wdd->timeout, wdd->min_timeout, wdd->max_hw_heartbeat_ms / 1000); - ptot = clamp_t(unsigned int, tout - wdd->pretimeout, + ptot = clamp_t(unsigned int, tout - pretimeout, wdd->min_timeout, tout); presc = DIV_ROUND_UP(tout * wdt->rate, RLR_MAX + 1); -- 2.54.0