* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.