From: Peng Fan Date: Thu, 5 Mar 2026 01:56:45 +0000 (+0800) Subject: firmware: imx: sm-misc: Print boot/shutdown reasons X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c17216c1a92241d622d2208cfebf62556c818789;p=thirdparty%2Fkernel%2Flinux.git firmware: imx: sm-misc: Print boot/shutdown reasons 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 Link: https://patch.msgid.link/20260305-scmi-imx-reset-v1-2-18de78978ba9@nxp.com Acked-by: Frank Li Signed-off-by: Sudeep Holla --- diff --git a/drivers/firmware/imx/sm-misc.c b/drivers/firmware/imx/sm-misc.c index 0a8ada329c9de..16b5ff833d212 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); }