[PATCH 2/2] firmware: imx: sm-misc: Print boot/shutdown reasons

Peng Fan (OSS) posted 2 patches 1 month, 1 week ago
[PATCH 2/2] firmware: imx: sm-misc: Print boot/shutdown reasons
Posted by Peng Fan (OSS) 1 month, 1 week ago
From: Peng Fan <peng.fan@nxp.com>

Add reset reason string table for i.MX95 and introduce a helper
(scmi_imx_misc_get_reason) to query and print both system and LM
(Logical Machine) reset reasons via the SCMI MISC protocol.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/firmware/imx/sm-misc.c | 73 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/drivers/firmware/imx/sm-misc.c b/drivers/firmware/imx/sm-misc.c
index 0a8ada329c9de3c1627da241bf142fa91a8085d7..16b5ff833d21274403a4c55abe2fa1f49fce3e73 100644
--- a/drivers/firmware/imx/sm-misc.c
+++ b/drivers/firmware/imx/sm-misc.c
@@ -18,6 +18,29 @@ static const struct scmi_imx_misc_proto_ops *imx_misc_ctrl_ops;
 static struct scmi_protocol_handle *ph;
 struct notifier_block scmi_imx_misc_ctrl_nb;
 
+static const char * const rst_imx95[] = {
+	"cm33_lockup", "cm33_swreq", "cm7_lockup", "cm7_swreq", "fccu",
+	"jtag_sw", "ele", "tempsense", "wdog1", "wdog2", "wdog3", "wdog4",
+	"wdog5", "jtag", "cm33_exc", "bbm", "sw", "sm_err", "fusa_sreco",
+	"pmic", "unused", "unused", "unused", "unused", "unused", "unused",
+	"unused", "unused", "unused", "unused", "unused", "por",
+};
+
+static const char * const rst_imx94[] = {
+	"cm33_lockup", "cm33_swreq", "cm70_lockup", "cm70_swreq", "fccu",
+	"jtag_sw", "ele", "tempsense", "wdog1", "wdog2", "wdog3", "wdog4",
+	"wdog5", "jtag", "wdog6", "wdog7", "wdog8", "wo_netc", "cm33s_lockup",
+	"cm33s_swreq", "cm71_lockup", "cm71_swreq", "cm33_exc", "bbm", "sw",
+	"sm_err", "fusa_sreco", "pmic", "unused", "unused", "unused", "por",
+};
+
+static const struct of_device_id allowlist[] = {
+	{ .compatible = "fsl,imx952", .data = rst_imx95 },
+	{ .compatible = "fsl,imx95", .data = rst_imx95 },
+	{ .compatible = "fsl,imx94", .data = rst_imx94 },
+	{ /* Sentinel */ }
+};
+
 int scmi_imx_misc_ctrl_set(u32 id, u32 val)
 {
 	if (!ph)
@@ -75,6 +98,54 @@ static void scmi_imx_misc_put(void *p)
 	debugfs_remove((struct dentry *)p);
 }
 
+static int scmi_imx_misc_get_reason(struct scmi_device *sdev)
+{
+	struct scmi_imx_misc_reset_reason boot, shutdown;
+	const char **rst;
+	bool system = true;
+	int ret;
+
+	if (!of_machine_device_match(allowlist))
+		return 0;
+
+	rst = (const char **)of_machine_get_match_data(allowlist);
+
+	ret = imx_misc_ctrl_ops->misc_reset_reason(ph, system, &boot, &shutdown, NULL);
+	if (!ret) {
+		if (boot.valid)
+			dev_info(&sdev->dev, "%s Boot reason: %s, origin: %d, errid: %d\n",
+				 system ? "SYS" : "LM", rst[boot.reason],
+				 boot.orig_valid ? boot.origin : -1,
+				 boot.err_valid ? boot.errid : -1);
+		if (shutdown.valid)
+			dev_info(&sdev->dev, "%s shutdown reason: %s, origin: %d, errid: %d\n",
+				 system ? "SYS" : "LM", rst[shutdown.reason],
+				 shutdown.orig_valid ? shutdown.origin : -1,
+				 shutdown.err_valid ? shutdown.errid : -1);
+	} else {
+		dev_err(&sdev->dev, "Failed to get system reset reason: %d\n", ret);
+	}
+
+	system = false;
+	ret = imx_misc_ctrl_ops->misc_reset_reason(ph, system, &boot, &shutdown, NULL);
+	if (!ret) {
+		if (boot.valid)
+			dev_info(&sdev->dev, "%s Boot reason: %s, origin: %d, errid: %d\n",
+				 system ? "SYS" : "LM", rst[boot.reason],
+				 boot.orig_valid ? boot.origin : -1,
+				 boot.err_valid ? boot.errid : -1);
+		if (shutdown.valid)
+			dev_info(&sdev->dev, "%s shutdown reason: %s, origin: %d, errid: %d\n",
+				 system ? "SYS" : "LM", rst[shutdown.reason],
+				 shutdown.orig_valid ? shutdown.origin : -1,
+				 shutdown.err_valid ? shutdown.errid : -1);
+	} else {
+		dev_err(&sdev->dev, "Failed to get lm reset reason: %d\n", ret);
+	}
+
+	return 0;
+}
+
 static int scmi_imx_misc_ctrl_probe(struct scmi_device *sdev)
 {
 	const struct scmi_handle *handle = sdev->handle;
@@ -133,6 +204,8 @@ static int scmi_imx_misc_ctrl_probe(struct scmi_device *sdev)
 	scmi_imx_dentry = debugfs_create_dir("scmi_imx", NULL);
 	debugfs_create_file("syslog", 0444, scmi_imx_dentry, &sdev->dev, &syslog_fops);
 
+	scmi_imx_misc_get_reason(sdev);
+
 	return devm_add_action_or_reset(&sdev->dev, scmi_imx_misc_put, scmi_imx_dentry);
 }
 

-- 
2.37.1
Re: [PATCH 2/2] firmware: imx: sm-misc: Print boot/shutdown reasons
Posted by Alexander Stein 1 month, 1 week ago
Hi,

Am Donnerstag, 5. März 2026, 02:56:45 CET schrieb Peng Fan (OSS):
> From: Peng Fan <peng.fan@nxp.com>
> 
> Add reset reason string table for i.MX95 and introduce a helper
> (scmi_imx_misc_get_reason) to query and print both system and LM
> (Logical Machine) reset reasons via the SCMI MISC protocol.
> 
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
>  drivers/firmware/imx/sm-misc.c | 73 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 73 insertions(+)
> 
> diff --git a/drivers/firmware/imx/sm-misc.c b/drivers/firmware/imx/sm-misc.c
> index 0a8ada329c9de3c1627da241bf142fa91a8085d7..16b5ff833d21274403a4c55abe2fa1f49fce3e73 100644
> --- a/drivers/firmware/imx/sm-misc.c
> +++ b/drivers/firmware/imx/sm-misc.c
> @@ -18,6 +18,29 @@ static const struct scmi_imx_misc_proto_ops *imx_misc_ctrl_ops;
>  static struct scmi_protocol_handle *ph;
>  struct notifier_block scmi_imx_misc_ctrl_nb;
>  
> +static const char * const rst_imx95[] = {
> +	"cm33_lockup", "cm33_swreq", "cm7_lockup", "cm7_swreq", "fccu",
> +	"jtag_sw", "ele", "tempsense", "wdog1", "wdog2", "wdog3", "wdog4",
> +	"wdog5", "jtag", "cm33_exc", "bbm", "sw", "sm_err", "fusa_sreco",
> +	"pmic", "unused", "unused", "unused", "unused", "unused", "unused",
> +	"unused", "unused", "unused", "unused", "unused", "por",
> +};
> +
> +static const char * const rst_imx94[] = {
> +	"cm33_lockup", "cm33_swreq", "cm70_lockup", "cm70_swreq", "fccu",
> +	"jtag_sw", "ele", "tempsense", "wdog1", "wdog2", "wdog3", "wdog4",
> +	"wdog5", "jtag", "wdog6", "wdog7", "wdog8", "wo_netc", "cm33s_lockup",
> +	"cm33s_swreq", "cm71_lockup", "cm71_swreq", "cm33_exc", "bbm", "sw",
> +	"sm_err", "fusa_sreco", "pmic", "unused", "unused", "unused", "por",
> +};
> +
> +static const struct of_device_id allowlist[] = {
> +	{ .compatible = "fsl,imx952", .data = rst_imx95 },
> +	{ .compatible = "fsl,imx95", .data = rst_imx95 },
> +	{ .compatible = "fsl,imx94", .data = rst_imx94 },
> +	{ /* Sentinel */ }
> +};
> +
>  int scmi_imx_misc_ctrl_set(u32 id, u32 val)
>  {
>  	if (!ph)
> @@ -75,6 +98,54 @@ static void scmi_imx_misc_put(void *p)
>  	debugfs_remove((struct dentry *)p);
>  }
>  
> +static int scmi_imx_misc_get_reason(struct scmi_device *sdev)
> +{
> +	struct scmi_imx_misc_reset_reason boot, shutdown;
> +	const char **rst;
> +	bool system = true;
> +	int ret;
> +
> +	if (!of_machine_device_match(allowlist))
> +		return 0;
> +
> +	rst = (const char **)of_machine_get_match_data(allowlist);
> +
> +	ret = imx_misc_ctrl_ops->misc_reset_reason(ph, system, &boot, &shutdown, NULL);
> +	if (!ret) {
> +		if (boot.valid)
> +			dev_info(&sdev->dev, "%s Boot reason: %s, origin: %d, errid: %d\n",
> +				 system ? "SYS" : "LM", rst[boot.reason],
> +				 boot.orig_valid ? boot.origin : -1,
> +				 boot.err_valid ? boot.errid : -1);
> +		if (shutdown.valid)
> +			dev_info(&sdev->dev, "%s shutdown reason: %s, origin: %d, errid: %d\n",
> +				 system ? "SYS" : "LM", rst[shutdown.reason],
> +				 shutdown.orig_valid ? shutdown.origin : -1,
> +				 shutdown.err_valid ? shutdown.errid : -1);
> +	} else {
> +		dev_err(&sdev->dev, "Failed to get system reset reason: %d\n", ret);
> +	}
> +
> +	system = false;
> +	ret = imx_misc_ctrl_ops->misc_reset_reason(ph, system, &boot, &shutdown, NULL);
> +	if (!ret) {
> +		if (boot.valid)
> +			dev_info(&sdev->dev, "%s Boot reason: %s, origin: %d, errid: %d\n",
> +				 system ? "SYS" : "LM", rst[boot.reason],
> +				 boot.orig_valid ? boot.origin : -1,
> +				 boot.err_valid ? boot.errid : -1);
> +		if (shutdown.valid)
> +			dev_info(&sdev->dev, "%s shutdown reason: %s, origin: %d, errid: %d\n",
> +				 system ? "SYS" : "LM", rst[shutdown.reason],
> +				 shutdown.orig_valid ? shutdown.origin : -1,
> +				 shutdown.err_valid ? shutdown.errid : -1);

Is there a way to query this from userspace programs instead of printing into kernel log?

Best regards,
Alexander

> +	} else {
> +		dev_err(&sdev->dev, "Failed to get lm reset reason: %d\n", ret);
> +	}
> +
> +	return 0;
> +}
> +
>  static int scmi_imx_misc_ctrl_probe(struct scmi_device *sdev)
>  {
>  	const struct scmi_handle *handle = sdev->handle;
> @@ -133,6 +204,8 @@ static int scmi_imx_misc_ctrl_probe(struct scmi_device *sdev)
>  	scmi_imx_dentry = debugfs_create_dir("scmi_imx", NULL);
>  	debugfs_create_file("syslog", 0444, scmi_imx_dentry, &sdev->dev, &syslog_fops);
>  
> +	scmi_imx_misc_get_reason(sdev);
> +
>  	return devm_add_action_or_reset(&sdev->dev, scmi_imx_misc_put, scmi_imx_dentry);
>  }
>  
> 
> 


-- 
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
http://www.tq-group.com/
Re: [PATCH 2/2] firmware: imx: sm-misc: Print boot/shutdown reasons
Posted by Peng Fan 1 month, 1 week ago
Hi Alexander,

Thanks for giving a look.

On Thu, Mar 05, 2026 at 08:44:26AM +0100, Alexander Stein wrote:
>Hi,
>
>Am Donnerstag, 5. März 2026, 02:56:45 CET schrieb Peng Fan (OSS):
>> From: Peng Fan <peng.fan@nxp.com>
>> 
>> Add reset reason string table for i.MX95 and introduce a helper
>> (scmi_imx_misc_get_reason) to query and print both system and LM
>> (Logical Machine) reset reasons via the SCMI MISC protocol.
>> 
>> Signed-off-by: Peng Fan <peng.fan@nxp.com>
>> ---
[...]
>> +		if (boot.valid)
>> +			dev_info(&sdev->dev, "%s Boot reason: %s, origin: %d, errid: %d\n",
>> +				 system ? "SYS" : "LM", rst[boot.reason],
>> +				 boot.orig_valid ? boot.origin : -1,
>> +				 boot.err_valid ? boot.errid : -1);
>> +		if (shutdown.valid)
>> +			dev_info(&sdev->dev, "%s shutdown reason: %s, origin: %d, errid: %d\n",
>> +				 system ? "SYS" : "LM", rst[shutdown.reason],
>> +				 shutdown.orig_valid ? shutdown.origin : -1,
>> +				 shutdown.err_valid ? shutdown.errid : -1);
>
>Is there a way to query this from userspace programs instead of printing into kernel log?

I not add sysfs or debugfs to get the information in this patchset, since our
customer only want the information could be shown in kernel boot log.

But I could add also sysfs interface to allow userspace get the information if
you need this feature.

Regards,
Peng

>
>Best regards,
>Alexander
>
>> +	} else {
>> +		dev_err(&sdev->dev, "Failed to get lm reset reason: %d\n", ret);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  static int scmi_imx_misc_ctrl_probe(struct scmi_device *sdev)
>>  {
>>  	const struct scmi_handle *handle = sdev->handle;
>> @@ -133,6 +204,8 @@ static int scmi_imx_misc_ctrl_probe(struct scmi_device *sdev)
>>  	scmi_imx_dentry = debugfs_create_dir("scmi_imx", NULL);
>>  	debugfs_create_file("syslog", 0444, scmi_imx_dentry, &sdev->dev, &syslog_fops);
>>  
>> +	scmi_imx_misc_get_reason(sdev);
>> +
>>  	return devm_add_action_or_reset(&sdev->dev, scmi_imx_misc_put, scmi_imx_dentry);
>>  }
>>  
>> 
>> 
>
>
>-- 
>TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
>Amtsgericht München, HRB 105018
>Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
>http://www.tq-group.com/
>
>
Re: [PATCH 2/2] firmware: imx: sm-misc: Print boot/shutdown reasons
Posted by Oleksij Rempel 1 month, 1 week ago
Hi all,

On Thu, Mar 05, 2026 at 06:22:15PM +0800, Peng Fan wrote:
> Hi Alexander,
>
> Thanks for giving a look.
>
> On Thu, Mar 05, 2026 at 08:44:26AM +0100, Alexander Stein wrote:
> >Hi,
> >
> >Am Donnerstag, 5. März 2026, 02:56:45 CET schrieb Peng Fan (OSS):
> >> From: Peng Fan <peng.fan@nxp.com>
> >>
> >> Add reset reason string table for i.MX95 and introduce a helper
> >> (scmi_imx_misc_get_reason) to query and print both system and LM
> >> (Logical Machine) reset reasons via the SCMI MISC protocol.
> >>
> >> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> >> ---
> [...]
> >> +		if (boot.valid)
> >> +			dev_info(&sdev->dev, "%s Boot reason: %s, origin: %d, errid: %d\n",
> >> +				 system ? "SYS" : "LM", rst[boot.reason],
> >> +				 boot.orig_valid ? boot.origin : -1,
> >> +				 boot.err_valid ? boot.errid : -1);
> >> +		if (shutdown.valid)
> >> +			dev_info(&sdev->dev, "%s shutdown reason: %s, origin: %d, errid: %d\n",
> >> +				 system ? "SYS" : "LM", rst[shutdown.reason],
> >> +				 shutdown.orig_valid ? shutdown.origin : -1,
> >> +				 shutdown.err_valid ? shutdown.errid : -1);
> >
> >Is there a way to query this from userspace programs instead of printing into kernel log?
>
> I not add sysfs or debugfs to get the information in this patchset, since our
> customer only want the information could be shown in kernel boot log.
>
> But I could add also sysfs interface to allow userspace get the information if
> you need this feature.

I started to working on corresponding framework:
https://lore.kernel.org/all/20250618120255.3141862-1-o.rempel@pengutronix.de/

but it is stalled due to devicetree decisions. I wont to respin the
discussion tomorrow

Best Regards,
Oleksij
Re: [PATCH 2/2] firmware: imx: sm-misc: Print boot/shutdown reasons
Posted by Peng Fan 1 month ago
On Thu, Mar 05, 2026 at 11:48:31AM +0100, Oleksij Rempel wrote:
>Hi all,
>
>On Thu, Mar 05, 2026 at 06:22:15PM +0800, Peng Fan wrote:
>> Hi Alexander,
>>
>> Thanks for giving a look.
>>
>> On Thu, Mar 05, 2026 at 08:44:26AM +0100, Alexander Stein wrote:
>> >Hi,
>> >
>> >Am Donnerstag, 5. März 2026, 02:56:45 CET schrieb Peng Fan (OSS):
>> >> From: Peng Fan <peng.fan@nxp.com>
>> >>
>> >> Add reset reason string table for i.MX95 and introduce a helper
>> >> (scmi_imx_misc_get_reason) to query and print both system and LM
>> >> (Logical Machine) reset reasons via the SCMI MISC protocol.
>> >>
>> >> Signed-off-by: Peng Fan <peng.fan@nxp.com>
>> >> ---
>> [...]
>> >> +		if (boot.valid)
>> >> +			dev_info(&sdev->dev, "%s Boot reason: %s, origin: %d, errid: %d\n",
>> >> +				 system ? "SYS" : "LM", rst[boot.reason],
>> >> +				 boot.orig_valid ? boot.origin : -1,
>> >> +				 boot.err_valid ? boot.errid : -1);
>> >> +		if (shutdown.valid)
>> >> +			dev_info(&sdev->dev, "%s shutdown reason: %s, origin: %d, errid: %d\n",
>> >> +				 system ? "SYS" : "LM", rst[shutdown.reason],
>> >> +				 shutdown.orig_valid ? shutdown.origin : -1,
>> >> +				 shutdown.err_valid ? shutdown.errid : -1);
>> >
>> >Is there a way to query this from userspace programs instead of printing into kernel log?
>>
>> I not add sysfs or debugfs to get the information in this patchset, since our
>> customer only want the information could be shown in kernel boot log.
>>
>> But I could add also sysfs interface to allow userspace get the information if
>> you need this feature.
>
>I started to working on corresponding framework:
>https://lore.kernel.org/all/20250618120255.3141862-1-o.rempel@pengutronix.de/

Thanks for sharing the thread.

>
>but it is stalled due to devicetree decisions. I wont to respin the
>discussion tomorrow

TBH, I have not look into the details. If the generic framework could land
into linux kernel, we could use this in i.MX SCMI reset reason. But I would
not add dependency for now, so I will still just keep printing the log into
kernel log.

Thanks,
Peng

>
>Best Regards,
>Oleksij