[PATCH] watchdog: gunyah_wdt: Re-enable the watchdog on resume
From: Stanislav Aleksandrov
Date: Mon Nov 09 2026 - 03:27:10 EST
gunyah_wdt_suspend() disables an active watchdog, and
gunyah_wdt_resume() enables it again with gunyah_wdt_start(). start()
first disables the watchdog, which fails with -EINVAL when it is
already disabled. start() ignores that only while the watchdog is
inactive, but on resume it is still active for the watchdog core, so
start() returns before it enables the watchdog:
gunyah-wdt gunyah-wdt: gunyah_wdt_start: Failed to stop gunyah wdt -22
So after every system suspend, the watchdog is left disabled.
Move setting the timeout and enabling the watchdog into
gunyah_wdt_enable(), and call it on resume, where the watchdog is
already disabled.
Tested on the Samsung Galaxy XR (Qualcomm Halliday) with s2idle and
deep suspend.
Fixes: ca316e145c35 ("watchdog: Add driver for Gunyah Watchdog")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Stanislav Aleksandrov <lightofmysoul@xxxxxxxxx>
---
gunyah_wdt binds on the Samsung Galaxy XR (Qualcomm Halliday) with this
SCM patch:
https://lore.kernel.org/r/20261109-qcom-scm-gunyah-uid-v1-1-2776343f9a3b@xxxxxxxxx
This work was made together with Claude.
Reviewed and tested on my Galaxy XR. Without this patch the watchdog
doesn't bite after a suspend. With it, it bites again after both s2idle
and deep suspend.
---
drivers/watchdog/gunyah_wdt.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/drivers/watchdog/gunyah_wdt.c b/drivers/watchdog/gunyah_wdt.c
index 557a78306d18..348c7ccddde0 100644
--- a/drivers/watchdog/gunyah_wdt.c
+++ b/drivers/watchdog/gunyah_wdt.c
@@ -62,19 +62,12 @@ static int gunyah_wdt_call(unsigned long func_id, unsigned long arg1,
return gunyah_error_remap(res.a0);
}
-static int gunyah_wdt_start(struct watchdog_device *wdd)
+static int gunyah_wdt_enable(struct watchdog_device *wdd)
{
- unsigned int timeout_ms;
+ unsigned int timeout_ms = wdd->timeout * 1000;
struct device *dev = wdd->parent;
int ret;
- ret = gunyah_wdt_call(GUNYAH_WDT_CONTROL, WDT_CTRL_DISABLE, 0);
- if (ret && watchdog_active(wdd)) {
- dev_err(dev, "%s: Failed to stop gunyah wdt %d\n", __func__, ret);
- return ret;
- }
-
- timeout_ms = wdd->timeout * 1000;
ret = gunyah_wdt_call(GUNYAH_WDT_SET_TIME, timeout_ms, timeout_ms);
if (ret) {
dev_err(dev, "%s: Failed to set timeout for gunyah wdt %d\n",
@@ -89,6 +82,20 @@ static int gunyah_wdt_start(struct watchdog_device *wdd)
return ret;
}
+static int gunyah_wdt_start(struct watchdog_device *wdd)
+{
+ struct device *dev = wdd->parent;
+ int ret;
+
+ ret = gunyah_wdt_call(GUNYAH_WDT_CONTROL, WDT_CTRL_DISABLE, 0);
+ if (ret && watchdog_active(wdd)) {
+ dev_err(dev, "%s: Failed to stop gunyah wdt %d\n", __func__, ret);
+ return ret;
+ }
+
+ return gunyah_wdt_enable(wdd);
+}
+
static int gunyah_wdt_stop(struct watchdog_device *wdd)
{
return gunyah_wdt_call(GUNYAH_WDT_CONTROL, WDT_CTRL_DISABLE, 0);
@@ -224,7 +231,7 @@ static int gunyah_wdt_resume(struct device *dev)
struct watchdog_device *wdd = dev_get_drvdata(dev);
if (watchdog_active(wdd))
- gunyah_wdt_start(wdd);
+ gunyah_wdt_enable(wdd);
return 0;
}
---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20261109-gunyah-wdt-resume-25bac9cc43ae
Best regards,
--
Stanislav Aleksandrov <lightofmysoul@xxxxxxxxx>