[PATCH v2] watchdog: sbsa_gwdt: add early_enable module parameter
Guenter Roeck
linux at roeck-us.net
Wed Aug 12 22:11:07 PDT 2026
On Thu, Aug 13, 2026 at 11:48:56AM +0800, Zexin Wang wrote:
> 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>
> ---
Change log goes here.
> .../watchdog/watchdog-parameters.rst | 2 ++
> drivers/watchdog/sbsa_gwdt.c | 23 +++++++++++++++++--
> 2 files changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst
> index 502cb6adbeda..47867a621ada 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:
As pointed out by Sashiko, bad alignment (tab instead of four spaces).
> + Watchdog is started on module insertion (default=0)
>
> -------------------------------------------------
>
> diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
> index e04d42cc7774..ed913be3d1cb 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,27 @@ 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);
> + dev_info(dev, "Watchdog early enabled.\n");
Unnecessary noise (it is also reported below).
> + }
> +
> watchdog_stop_on_reboot(wdd);
> ret = devm_watchdog_register_device(dev, wdd);
> - if (ret)
> + if (ret) {
> + dev_err(dev, "Failed to register watchdog: %d\n", ret);
Unrelated and unnecessary addition.
> + if (early_action) {
> + clear_bit(WDOG_HW_RUNNING, &wdd->status);
Pointless. The watchdog was not registered.
> + 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;
> }
More information about the linux-arm-kernel
mailing list