[PATCH 2/2] watchdog: pscrr: add watchdog pretimeout reason tracking

From: Faruque Ansari

Date: Tue Jul 14 2026 - 05:55:40 EST


A watchdog pretimeout fires before the actual reset, giving the kernel
a brief window to record what happened. Without this change that
window goes unused and the next boot sees PSCR_UNKNOWN, making it
impossible to tell a watchdog-driven reset from any other cause.

Call set_psc_reason(PSCR_WATCHDOG_PRETIMEOUT) at the top of
watchdog_notify_pretimeout() so the reason is recorded as soon as the
pretimeout is signalled, before any governor action runs.

Signed-off-by: Faruque Ansari <faruque.ansari@xxxxxxxxxxxxxxxx>
---
drivers/power/reset/pscrr.c | 3 ++-
drivers/watchdog/watchdog_pretimeout.c | 3 +++
include/linux/power/power_on_reason.h | 1 +
include/linux/reboot.h | 1 +
kernel/reboot.c | 1 +
5 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/power/reset/pscrr.c b/drivers/power/reset/pscrr.c
index b5906f127e88..36642cf9f27c 100644
--- a/drivers/power/reset/pscrr.c
+++ b/drivers/power/reset/pscrr.c
@@ -149,7 +149,8 @@ static int pscrr_panic_notifier(struct notifier_block *nb,
if (!backend || !backend->ops || !backend->ops->write_reason)
return NOTIFY_OK;

- set_psc_reason(PSCR_KERNEL_PANIC);
+ if (get_psc_reason() != PSCR_WATCHDOG_PRETIMEOUT)
+ set_psc_reason(PSCR_KERNEL_PANIC);
ret = backend->ops->write_reason(get_psc_reason());
if (ret)
pr_err("PSCRR: Failed to store reason %d (%s) at panic, err=%pe\n",
diff --git a/drivers/watchdog/watchdog_pretimeout.c b/drivers/watchdog/watchdog_pretimeout.c
index 02e09b9e396d..ea48d4eca4aa 100644
--- a/drivers/watchdog/watchdog_pretimeout.c
+++ b/drivers/watchdog/watchdog_pretimeout.c
@@ -4,6 +4,7 @@
*/

#include <linux/list.h>
+#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
@@ -103,6 +104,8 @@ void watchdog_notify_pretimeout(struct watchdog_device *wdd)
{
unsigned long flags;

+ set_psc_reason(PSCR_WATCHDOG_PRETIMEOUT);
+
spin_lock_irqsave(&pretimeout_lock, flags);
if (!wdd->gov) {
spin_unlock_irqrestore(&pretimeout_lock, flags);
diff --git a/include/linux/power/power_on_reason.h b/include/linux/power/power_on_reason.h
index 4ac1bdfdc211..c5846c0ccde4 100644
--- a/include/linux/power/power_on_reason.h
+++ b/include/linux/power/power_on_reason.h
@@ -20,5 +20,6 @@
#define POWER_ON_REASON_OVER_TEMPERATURE "over temperature"
#define POWER_ON_REASON_EC_PANIC "EC panic"
#define POWER_ON_REASON_KERNEL_PANIC "kernel panic"
+#define POWER_ON_REASON_WATCHDOG_PRETIMEOUT "watchdog pretimeout"

#endif /* POWER_ON_REASON_H */
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index a492b1652038..fccbffc9dbef 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -237,6 +237,7 @@ enum psc_reason {
PSCR_OVER_TEMPERATURE,
PSCR_EC_PANIC,
PSCR_KERNEL_PANIC,
+ PSCR_WATCHDOG_PRETIMEOUT,

/* Number of reasons */
PSCR_REASON_COUNT,
diff --git a/kernel/reboot.c b/kernel/reboot.c
index f1df52f8773a..629002a951c2 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -1066,6 +1066,7 @@ static const char * const pscr_reason_strs[] = {
[PSCR_OVER_TEMPERATURE] = POWER_ON_REASON_OVER_TEMPERATURE,
[PSCR_EC_PANIC] = POWER_ON_REASON_EC_PANIC,
[PSCR_KERNEL_PANIC] = POWER_ON_REASON_KERNEL_PANIC,
+ [PSCR_WATCHDOG_PRETIMEOUT] = POWER_ON_REASON_WATCHDOG_PRETIMEOUT,
};

/**

--
2.34.1