[PATCH v4] watchdog: sbsa_gwdt: add early_enable module parameter
Zexin Wang
ot_zexin.wang at mediatek.com
Sun Aug 16 19:37:49 PDT 2026
On SBSA platforms using standard UEFI firmware (such as EDK II), the
watchdog timer is often enabled during early boot stages but explicitly
disabled by the firmware before handing over control to the OS (e.g.,
during ExitBootServices). This is done to prevent unintended resets
while the OS is loading, assuming the OS watchdog driver will take over.
However, this leaves a protection gap. If the system hangs between the
firmware handover and the userspace watchdog daemon startup, the hardware
watchdog will not fire to recover the system. For safety-critical systems
that require continuous hardware watchdog protection from the earliest
possible moment, this gap is problematic.
Add an 'early_enable' module parameter to allow the kernel driver to
re-enable the watchdog immediately during probe if it was left disabled
by the firmware. By setting the WDOG_HW_RUNNING status bit, the watchdog
core is instructed that the hardware is active. As a result, the core's
pre-userspace handler (controlled by 'handle_boot_enabled') will
automatically issue periodic keepalives until userspace opens the device.
This bridges the protection gap seamlessly without requiring firmware
modifications and without risking unintended resets during kernel boot.
The parameter defaults to false to preserve the traditional behavior.
Signed-off-by: Zexin Wang <ot_zexin.wang at mediatek.com>
---
Changes in v4:
- Remove unnecessary dev_info() log message
- Remove dev_err() on register failure
- Remove clear_bit(WDOG_HW_RUNNING) on register failure
Changes in v3:
- Fix indentation of `early_enable` in watchdog-parameters.rst to ensure
it renders as a separate parameter rather than part of `nowayout`'s
description.
Changes in v2:
- Rename `force_enable` to `early_enable` as suggested by Guenter.
- Update commit message to explain the UEFI handover gap motivation.
- Add documentation for the new parameter.
.../watchdog/watchdog-parameters.rst | 2 ++
drivers/watchdog/sbsa_gwdt.c | 19 +++++++++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst
index 502cb6adbeda..348229ffcb43 100644
--- a/Documentation/watchdog/watchdog-parameters.rst
+++ b/Documentation/watchdog/watchdog-parameters.rst
@@ -515,6 +515,8 @@ sbsa_gwdt:
nowayout:
Watchdog cannot be stopped once started
(default=kernel config parameter)
+ early_enable:
+ Watchdog is started on module insertion (default=0)
-------------------------------------------------
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
index e04d42cc7774..3c5bfd8641c6 100644
--- a/drivers/watchdog/sbsa_gwdt.c
+++ b/drivers/watchdog/sbsa_gwdt.c
@@ -122,6 +122,11 @@ MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+static bool early_enable;
+module_param(early_enable, bool, 0);
+MODULE_PARM_DESC(early_enable,
+ "Watchdog is started on module insertion (default=0)");
+
/*
* Arm Base System Architecture 1.0 introduces watchdog v1 which
* increases the length watchdog offset register to 48 bits.
@@ -296,6 +301,7 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
struct sbsa_gwdt *gwdt;
int ret, irq;
u32 status;
+ bool early_action;
gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
if (!gwdt)
@@ -386,14 +392,23 @@ static int sbsa_gwdt_probe(struct platform_device *pdev)
*/
sbsa_gwdt_set_timeout(wdd, wdd->timeout);
+ early_action = early_enable && !(status & SBSA_GWDT_WCS_EN);
+ if (early_action) {
+ sbsa_gwdt_start(wdd);
+ set_bit(WDOG_HW_RUNNING, &wdd->status);
+ }
+
watchdog_stop_on_reboot(wdd);
ret = devm_watchdog_register_device(dev, wdd);
- if (ret)
+ if (ret) {
+ if (early_action)
+ sbsa_gwdt_stop(wdd);
return ret;
+ }
dev_info(dev, "Initialized with %ds timeout @ %u Hz, action=%d.%s\n",
wdd->timeout, gwdt->clk, action,
- status & SBSA_GWDT_WCS_EN ? " [enabled]" : "");
+ watchdog_hw_running(wdd) ? " [enabled]" : "");
return 0;
}
--
2.45.2
More information about the Linux-mediatek
mailing list