On Wed, 12 Feb 2020 14:05:40 +0300, Mika Westerberg wrote: > If the BIOS default timeout for the watchdog is too small userspace may > not have enough time to configure new timeout after opening the device > before the system is already reset. For this reason program default > timeout of 30 seconds in the driver probe and allow userspace to change > this from command line or through module parameter (wdat_wdt.timeout). > > Reported-by: Jean Delvare <jdelvare@xxxxxxx> > Signed-off-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx> > --- > drivers/watchdog/wdat_wdt.c | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c > index 2132018f031d..7b0257163522 100644 > --- a/drivers/watchdog/wdat_wdt.c > +++ b/drivers/watchdog/wdat_wdt.c > @@ -54,6 +54,13 @@ module_param(nowayout, bool, 0); > MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" > __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); > > +#define WDAT_DEFAULT_TIMEOUT 30 > + > +static int timeout = WDAT_DEFAULT_TIMEOUT; > +module_param(timeout, int, 0); > +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" > + __MODULE_STRING(WDAT_DEFAULT_TIMEOUT) ")"); > + > static int wdat_wdt_read(struct wdat_wdt *wdat, > const struct wdat_instruction *instr, u32 *value) > { > @@ -308,6 +315,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) > struct device *dev = &pdev->dev; > const struct acpi_wdat_entry *entries; > const struct acpi_table_wdat *tbl; > + int default_timeout = timeout; > struct wdat_wdt *wdat; > struct resource *res; > void __iomem **regs; > @@ -438,6 +446,22 @@ static int wdat_wdt_probe(struct platform_device *pdev) > > platform_set_drvdata(pdev, wdat); > > + /* > + * Set initial timeout so that userspace has time to configure > + * the watchdog properly after it has opened the device. In some > + * cases the BIOS default is too short and causes immediate reboot. > + */ > + default_timeout = timeout; You have already done that at variable declaration time. > + if (timeout < wdat->wdd.min_hw_heartbeat_ms || > + timeout > wdat->wdd.max_hw_heartbeat_ms) Comparing seconds to milliseconds is unlikely to give the expected result. > + default_timeout = WDAT_DEFAULT_TIMEOUT; > + else > + default_timeout = timeout; You have already done that twice ;-) > + > + ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); You must pass "default_timeout" here, not "timeout", else the check before serves no purpose. It might be less confusing to not introduce a separate variable and just tweak timeout in place? > + if (ret) > + return ret; > + > watchdog_set_nowayout(&wdat->wdd, nowayout); > return devm_watchdog_register_device(dev, &wdat->wdd); > } -- Jean Delvare SUSE L3 Support