On Mon, 2025-02-17 at 21:33 -0800, Guenter Roeck wrote: > On 2/17/25 19:16, Heyi Guo wrote: > > Aspeed watchdog uses counting down logic, so the value set to register > > should be the value of subtracting pretimeout from total timeout. > > > > Fixes: 9ec0b7e06835 ("watchdog: aspeed: Enable pre-timeout interrupt") > > > > Signed-off-by: Heyi Guo <guoheyi@xxxxxxxxxxxxxxxxx> > > > > Cc: Wim Van Sebroeck <wim@xxxxxxxxxxxxxxxxxx> > > Cc: Guenter Roeck <linux@xxxxxxxxxxxx> > > Cc: Joel Stanley <joel@xxxxxxxxx> > > Cc: Andrew Jeffery <andrew@xxxxxxxxxxxxxxxxxxxx> > > Cc: Eddie James <eajames@xxxxxxxxxxxxx> > > --- > > drivers/watchdog/aspeed_wdt.c | 7 +++++++ > > 1 file changed, 7 insertions(+) > > > > diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c > > index b4773a6aaf8c..520d8aba12a5 100644 > > --- a/drivers/watchdog/aspeed_wdt.c > > +++ b/drivers/watchdog/aspeed_wdt.c > > @@ -187,6 +187,13 @@ static int aspeed_wdt_set_pretimeout(struct watchdog_device *wdd, > > u32 actual = pretimeout * WDT_RATE_1MHZ; > > u32 s = wdt->cfg->irq_shift; > > u32 m = wdt->cfg->irq_mask; > > + u32 reload = readl(wdt->base + WDT_RELOAD_VALUE); > > + > > It is unusual to use a register value here and not the configured timeout > value. I would have assumed that pretimeout is compared against wdt->timout, > not against the register value, and that the multiplication with WDT_RATE_1MHZ > is done after validation. This needs an explanation. +1 > > > + if (actual >= reload) > > + return -EINVAL; > > + > > On top of that, you'll also need to explain why watchdog_pretimeout_invalid() > and with it the validation in watchdog_set_pretimeout() does not work for this > watchdog and why this extra validation is necessary. +1 as well. Further, the logic looks broken regardless for the AST2400 where there's no pretimeout support. aspeed_wdt_set_pretimeout() should error out if wdt->cfg->irq_mask is 0. Andrew