| From 78e0c00e315105c45ee15d75fc0b600ba7c03529 Mon Sep 17 00:00:00 2001 |
| From: Mika Westerberg <mika.westerberg@linux.intel.com> |
| Date: Wed, 12 Feb 2020 17:59:41 +0300 |
| Subject: [PATCH] ACPI: watchdog: Set default timeout in probe |
| |
| commit cabe17d0173ab04bd3f87b8199ae75f43f1ea473 upstream. |
| |
| 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@suse.de> |
| Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> |
| Reviewed-by: Jean Delvare <jdelvare@suse.de> |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c |
| index 1ce39de917f0..88c5e6361aa0 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) |
| { |
| @@ -438,6 +445,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. |
| + */ |
| + if (timeout * 1000 < wdat->wdd.min_hw_heartbeat_ms || |
| + timeout * 1000 > wdat->wdd.max_hw_heartbeat_ms) { |
| + dev_warn(dev, "Invalid timeout %d given, using %d\n", |
| + timeout, WDAT_DEFAULT_TIMEOUT); |
| + timeout = WDAT_DEFAULT_TIMEOUT; |
| + } |
| + |
| + ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); |
| + if (ret) |
| + return ret; |
| + |
| watchdog_set_nowayout(&wdat->wdd, nowayout); |
| return devm_watchdog_register_device(dev, &wdat->wdd); |
| } |
| -- |
| 2.7.4 |
| |