* [PATCH 0/2] power: reset: pscrr: record reset cause on panic and watchdog pretimeout
@ 2026-07-14 9:52 Faruque Ansari
2026-07-14 9:52 ` [PATCH 1/2] power: reset: pscrr: add kernel panic reason tracking Faruque Ansari
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Faruque Ansari @ 2026-07-14 9:52 UTC (permalink / raw)
To: Sebastian Reichel, Wim Van Sebroeck, Guenter Roeck, Benson Leung,
Tzung-Bi Shih, Oleksij Rempel, Srinivas Kandagatla,
Daniel Lezcano
Cc: linux-pm, linux-kernel, linux-watchdog, linux-arm-msm, kernel,
avaneesh.dwivedi, Umang Chheda, Faruque Ansari
This series extends the Power State Change Reason Register (PSCRR)[1]
framework to capture two additional reset causes.
1. Kernel panic — a panic notifier writes PSCR_KERNEL_PANIC to NVMEM
before the system resets, so the next boot can distinguish a panic
from other reset causes.
2. Watchdog pretimeout — set_psc_reason(PSCR_WATCHDOG_PRETIMEOUT) is
called from watchdog_notify_pretimeout(), when the watchdog fire its
pre-reset notification before resetting the system, so the reason gets
saved and we know its was a watchdog timeout that caused the reset.
[1] https://lore.kernel.org/lkml/20250618120255.3141862-1-o.rempel@pengutronix.de/
To: Sebastian Reichel <sre@kernel.org>
To: Wim Van Sebroeck <wim@linux-watchdog.org>
To: Guenter Roeck <linux@roeck-us.net>
To: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
To: Benson Leung <bleung@chromium.org>
To: Tzung-Bi Shih <tzungbi@kernel.org>
To: Daniel Lezcano <daniel.lezcano@linaro.org>
To: Oleksij Rempel <o.rempel@pengutronix.de>
Cc: linux-pm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-watchdog@vger.kernel.org
Cc: linux-arm-msm@vger.org
Cc: kernel@pengutronix.de
Cc: Liam Girdwood" <lgirdwood@gmail.com>
Cc: Mark Brown" <broonie@kernel.org>
Cc: Rafael J. Wysocki" <rafael@kernel.org>
Cc: Zhang Rui" <rui.zhang@intel.com>
Cc: Lukasz Luba" <lukasz.luba@arm.com>
Cc: Søren Andersen" <san@skov.dk>
Cc: Guenter Roeck" <groeck@chromium.org>
Cc: Matti Vaittinen" <mazziesaccount@gmail.com>
Cc: Ahmad Fatoum" <a.fatoum@pengutronix.de>
Cc: Andrew Morton" <akpm@linux-foundation.org>
Cc: avaneesh.dwivedi@oss.qualcomm.com
Cc: Umang Chheda <umang.chheda@oss.qualcomm.com>
Signed-off-by: Faruque Ansari <faruque.ansari@oss.qualcomm.com>
---
Faruque Ansari (2):
power: reset: pscrr: add kernel panic reason tracking
watchdog: pscrr: add watchdog pretimeout reason tracking
drivers/power/reset/pscrr.c | 33 +++++++++++++++++++++++++++++++++
drivers/watchdog/watchdog_pretimeout.c | 3 +++
include/linux/power/power_on_reason.h | 2 ++
include/linux/reboot.h | 2 ++
kernel/reboot.c | 2 ++
5 files changed, 42 insertions(+)
---
base-commit: 9696e3e0e12695f18c26e339bc609a2d56b51c5a
change-id: 20260714-pscrr-reboot-reason-2b4e16ccb6b8
Best regards,
--
Faruque Ansari <faruque.ansari@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] power: reset: pscrr: add kernel panic reason tracking
2026-07-14 9:52 [PATCH 0/2] power: reset: pscrr: record reset cause on panic and watchdog pretimeout Faruque Ansari
@ 2026-07-14 9:52 ` Faruque Ansari
2026-07-14 9:52 ` [PATCH 2/2] watchdog: pscrr: add watchdog pretimeout " Faruque Ansari
2026-07-15 6:20 ` [PATCH 0/2] power: reset: pscrr: record reset cause on panic and watchdog pretimeout Oleksij Rempel
2 siblings, 0 replies; 4+ messages in thread
From: Faruque Ansari @ 2026-07-14 9:52 UTC (permalink / raw)
To: Sebastian Reichel, Wim Van Sebroeck, Guenter Roeck, Benson Leung,
Tzung-Bi Shih, Oleksij Rempel, Srinivas Kandagatla,
Daniel Lezcano
Cc: linux-pm, linux-kernel, linux-watchdog, linux-arm-msm, kernel,
avaneesh.dwivedi, Umang Chheda, Faruque Ansari
Without this change, a kernel panic leaves no trace in NVMEM — the
system resets silently and the next boot sees PSCR_UNKNOWN, making
post-mortem diagnosis harder.
Add a panic notifier so the recorded shutdown reason survives a kernel
panic and is available for inspection on the next boot. Also introduce
PSCR_KERNEL_PANIC as a dedicated reason code with its human-readable
string so userspace and bootloaders can distinguish a panic-driven reset
from other reset causes.
Signed-off-by: Faruque Ansari <faruque.ansari@oss.qualcomm.com>
---
drivers/power/reset/pscrr.c | 32 ++++++++++++++++++++++++++++++++
include/linux/power/power_on_reason.h | 1 +
include/linux/reboot.h | 1 +
kernel/reboot.c | 1 +
4 files changed, 35 insertions(+)
diff --git a/drivers/power/reset/pscrr.c b/drivers/power/reset/pscrr.c
index 92e8ef97421c..b5906f127e88 100644
--- a/drivers/power/reset/pscrr.c
+++ b/drivers/power/reset/pscrr.c
@@ -60,6 +60,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/notifier.h>
+#include <linux/panic_notifier.h>
#include <linux/power/power_on_reason.h>
#include <linux/pscrr.h>
#include <linux/reboot.h>
@@ -78,6 +79,7 @@ struct pscrr_core {
/* Kobject for sysfs */
struct kobject *kobj;
struct notifier_block reboot_nb;
+ struct notifier_block panic_nb;
};
static struct pscrr_core g_pscrr = {
@@ -136,6 +138,30 @@ static int pscrr_reboot_notifier(struct notifier_block *nb,
return NOTIFY_OK;
}
+static int pscrr_panic_notifier(struct notifier_block *nb,
+ unsigned long action, void *unused)
+{
+ int ret;
+ struct pscrr_backend *backend;
+
+ backend = g_pscrr.backend;
+
+ if (!backend || !backend->ops || !backend->ops->write_reason)
+ return NOTIFY_OK;
+
+ 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",
+ get_psc_reason(), psc_reason_to_str(get_psc_reason()),
+ ERR_PTR(ret));
+ else
+ pr_debug("PSCRR: Stored reason %d (%s) at panic.\n",
+ get_psc_reason(), psc_reason_to_str(get_psc_reason()));
+
+ return NOTIFY_OK;
+}
+
/*----------------------------------------------------------------------*/
/* Sysfs Interface */
/*----------------------------------------------------------------------*/
@@ -349,6 +375,10 @@ int pscrr_core_init(const struct pscrr_backend_ops *ops)
goto err_free;
}
+ /* Setup the panic notifier to persist reason on kernel panic */
+ g_pscrr.panic_nb.notifier_call = pscrr_panic_notifier;
+ atomic_notifier_chain_register(&panic_notifier_list, &g_pscrr.panic_nb);
+
/* Create a kobject and sysfs group under /sys/kernel/pscrr */
g_pscrr.kobj = kobject_create_and_add("pscrr", kernel_kobj);
if (!g_pscrr.kobj) {
@@ -371,6 +401,7 @@ int pscrr_core_init(const struct pscrr_backend_ops *ops)
err_kobj_put:
kobject_put(g_pscrr.kobj);
err_unreg_reboot:
+ atomic_notifier_chain_unregister(&panic_notifier_list, &g_pscrr.panic_nb);
unregister_reboot_notifier(&g_pscrr.reboot_nb);
err_free:
kfree(g_pscrr.backend);
@@ -391,6 +422,7 @@ void pscrr_core_exit(void)
kobject_put(g_pscrr.kobj);
}
+ atomic_notifier_chain_unregister(&panic_notifier_list, &g_pscrr.panic_nb);
unregister_reboot_notifier(&g_pscrr.reboot_nb);
kfree(g_pscrr.backend);
diff --git a/include/linux/power/power_on_reason.h b/include/linux/power/power_on_reason.h
index bf9501792696..4ac1bdfdc211 100644
--- a/include/linux/power/power_on_reason.h
+++ b/include/linux/power/power_on_reason.h
@@ -19,5 +19,6 @@
#define POWER_ON_REASON_REGULATOR_FAILURE "regulator failure"
#define POWER_ON_REASON_OVER_TEMPERATURE "over temperature"
#define POWER_ON_REASON_EC_PANIC "EC panic"
+#define POWER_ON_REASON_KERNEL_PANIC "kernel panic"
#endif /* POWER_ON_REASON_H */
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 6477910c6a9e..a492b1652038 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -236,6 +236,7 @@ enum psc_reason {
PSCR_REGULATOR_FAILURE,
PSCR_OVER_TEMPERATURE,
PSCR_EC_PANIC,
+ PSCR_KERNEL_PANIC,
/* Number of reasons */
PSCR_REASON_COUNT,
diff --git a/kernel/reboot.c b/kernel/reboot.c
index 61e0027b7550..f1df52f8773a 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -1065,6 +1065,7 @@ static const char * const pscr_reason_strs[] = {
[PSCR_REGULATOR_FAILURE] = POWER_ON_REASON_REGULATOR_FAILURE,
[PSCR_OVER_TEMPERATURE] = POWER_ON_REASON_OVER_TEMPERATURE,
[PSCR_EC_PANIC] = POWER_ON_REASON_EC_PANIC,
+ [PSCR_KERNEL_PANIC] = POWER_ON_REASON_KERNEL_PANIC,
};
/**
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] watchdog: pscrr: add watchdog pretimeout reason tracking
2026-07-14 9:52 [PATCH 0/2] power: reset: pscrr: record reset cause on panic and watchdog pretimeout Faruque Ansari
2026-07-14 9:52 ` [PATCH 1/2] power: reset: pscrr: add kernel panic reason tracking Faruque Ansari
@ 2026-07-14 9:52 ` Faruque Ansari
2026-07-15 6:20 ` [PATCH 0/2] power: reset: pscrr: record reset cause on panic and watchdog pretimeout Oleksij Rempel
2 siblings, 0 replies; 4+ messages in thread
From: Faruque Ansari @ 2026-07-14 9:52 UTC (permalink / raw)
To: Sebastian Reichel, Wim Van Sebroeck, Guenter Roeck, Benson Leung,
Tzung-Bi Shih, Oleksij Rempel, Srinivas Kandagatla,
Daniel Lezcano
Cc: linux-pm, linux-kernel, linux-watchdog, linux-arm-msm, kernel,
avaneesh.dwivedi, Umang Chheda, Faruque Ansari
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@oss.qualcomm.com>
---
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
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] power: reset: pscrr: record reset cause on panic and watchdog pretimeout
2026-07-14 9:52 [PATCH 0/2] power: reset: pscrr: record reset cause on panic and watchdog pretimeout Faruque Ansari
2026-07-14 9:52 ` [PATCH 1/2] power: reset: pscrr: add kernel panic reason tracking Faruque Ansari
2026-07-14 9:52 ` [PATCH 2/2] watchdog: pscrr: add watchdog pretimeout " Faruque Ansari
@ 2026-07-15 6:20 ` Oleksij Rempel
2 siblings, 0 replies; 4+ messages in thread
From: Oleksij Rempel @ 2026-07-15 6:20 UTC (permalink / raw)
To: Faruque Ansari
Cc: Sebastian Reichel, Wim Van Sebroeck, Guenter Roeck, Benson Leung,
Tzung-Bi Shih, Srinivas Kandagatla, Daniel Lezcano, linux-pm,
linux-kernel, linux-watchdog, linux-arm-msm, kernel,
avaneesh.dwivedi, Umang Chheda
Hi Faruque,
On Tue, Jul 14, 2026 at 03:22:33PM +0530, Faruque Ansari wrote:
> This series extends the Power State Change Reason Register (PSCRR)[1]
> framework to capture two additional reset causes.
>
> 1. Kernel panic — a panic notifier writes PSCR_KERNEL_PANIC to NVMEM
> before the system resets, so the next boot can distinguish a panic
> from other reset causes.
>
> 2. Watchdog pretimeout — set_psc_reason(PSCR_WATCHDOG_PRETIMEOUT) is
> called from watchdog_notify_pretimeout(), when the watchdog fire its
> pre-reset notification before resetting the system, so the reason gets
> saved and we know its was a watchdog timeout that caused the reset.
Thank you, LGTM!
Right now I'm on a netdev conference, will need to take a closer look
after it.
Best Regards,
Oleksij
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-07-15 6:20 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14 9:52 [PATCH 0/2] power: reset: pscrr: record reset cause on panic and watchdog pretimeout Faruque Ansari
2026-07-14 9:52 ` [PATCH 1/2] power: reset: pscrr: add kernel panic reason tracking Faruque Ansari
2026-07-14 9:52 ` [PATCH 2/2] watchdog: pscrr: add watchdog pretimeout " Faruque Ansari
2026-07-15 6:20 ` [PATCH 0/2] power: reset: pscrr: record reset cause on panic and watchdog pretimeout Oleksij Rempel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox