[PATCH 1/2] firmware: xilinx: Add support for GET_LAST_RESET_REASON IOCTL

From: Ronak Jain
Date: Tue Nov 21 2023 - 06:21:17 EST


Add GET_LAST_RESET_REASON IOCTL support to check the last reset
reason.

As per the current code base in the firmware, the firmware clears
all reset reasons, except the latest system reset reason. Also, the
reset reason can not be completely cleared as the ROM need to know if
the last reset was due to the system reset or not.

Hence, the firmware clears all POR and sys resets except the latest
so the next reset reason can be uniquely identified and the same can
be checked by the end user by calling the IOCTL API.

The current supported reset reasons as below.

1. PM_RESET_REASON_EXT_POR - The POR button was pressed outside of
the system
2. PM_RESET_REASON_SW_POR - An internal POR was caused by software
3. PM_RESET_REASON_SLR_POR - One of the other SSIT slices caused a POR
4. PM_RESET_REASON_ERR_POR - An error caused a POR
5. PM_RESET_REASON_DAP_SRST - JTAG TAP initiated system reset
6. PM_RESET_REASON_ERR_SRST - Error initiated system reset
7. PM_RESET_REASON_SW_SRST - Software initiated system reset
8. PM_RESET_REASON_SLR_SRST - One of the other SSIT slices caused a
system reset

Signed-off-by: Ronak Jain <ronak.jain@xxxxxxx>
---
drivers/firmware/xilinx/zynqmp.c | 7 +++++++
include/linux/firmware/xlnx-zynqmp.h | 8 ++++++++
2 files changed, 15 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index b0d22d4455d9..5815d1e94407 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -909,6 +909,13 @@ int zynqmp_pm_set_tapdelay_bypass(u32 index, u32 value)
}
EXPORT_SYMBOL_GPL(zynqmp_pm_set_tapdelay_bypass);

+int zynqmp_pm_get_last_reset_reason(u32 *reset_reason)
+{
+ return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_GET_LAST_RESET_REASON, 0,
+ 0, reset_reason);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_get_last_reset_reason);
+
/**
* zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status
* @value: Status value to be written
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index d1ea3898564c..2d8c5e88391b 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -190,6 +190,8 @@ enum pm_ioctl_id {
/* Set healthy bit value */
IOCTL_SET_BOOT_HEALTH_STATUS = 17,
IOCTL_OSPI_MUX_SELECT = 21,
+ /* IOCTL to get last reset reason */
+ IOCTL_GET_LAST_RESET_REASON = 23,
/* Register SGI to ATF */
IOCTL_REGISTER_SGI = 25,
/* Runtime feature configuration */
@@ -585,6 +587,7 @@ int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode);
int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value);
int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
u32 value);
+int zynqmp_pm_get_last_reset_reason(u32 *reset_reason);
#else
static inline int zynqmp_pm_get_api_version(u32 *version)
{
@@ -909,6 +912,11 @@ static inline int zynqmp_pm_set_gem_config(u32 node,
return -ENODEV;
}

+static inline int zynqmp_pm_get_last_reset_reason(u32 *reset_reason)
+{
+ return -ENODEV;
+}
+
#endif

#endif /* __FIRMWARE_ZYNQMP_H__ */
--
2.25.1