[PATCH 2/2] ARM: AM33xx: PRM: Implement REBOOT_COLD
A. Sverdlin
alexander.sverdlin at siemens.com
Wed Feb 21 07:45:51 PST 2024
From: Alexander Sverdlin <alexander.sverdlin at siemens.com>
Historically AM33xx performed warm software reset even though requested
(and default) was REBOOT_COLD. Reflect the de-facto default mode in
/sys/kernel/reboot/mode correctly and implement the real REBOOT_COLD
(if configured explicitly).
Tested-by: Matthias Michel <matthias.michel at siemens.com>
Signed-off-by: Alexander Sverdlin <alexander.sverdlin at siemens.com>
---
arch/arm/mach-omap2/am33xx-restart.c | 3 ++-
arch/arm/mach-omap2/board-generic.c | 6 ++++++
arch/arm/mach-omap2/prm-regbits-33xx.h | 1 +
arch/arm/mach-omap2/prm.h | 1 +
arch/arm/mach-omap2/prm33xx.c | 18 ++++++++++++++----
arch/arm/mach-omap2/prm_common.c | 6 ++++++
6 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-omap2/am33xx-restart.c b/arch/arm/mach-omap2/am33xx-restart.c
index ef2f18a56b658..199845f4b12e4 100644
--- a/arch/arm/mach-omap2/am33xx-restart.c
+++ b/arch/arm/mach-omap2/am33xx-restart.c
@@ -18,7 +18,8 @@
*/
void am33xx_restart(enum reboot_mode mode, const char *cmd)
{
- /* TODO: Handle mode and cmd if necessary */
+ /* TODO: Handle cmd if necessary */
+ prm_reboot_mode = mode;
omap_prm_reset_system();
}
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index fde6ccb3df6eb..68e0baad2bbf6 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -246,6 +246,12 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
.init_time = omap_init_time_of,
.dt_compat = am33xx_boards_compat,
.restart = am33xx_restart,
+ /*
+ * Historically am33xx supported only REBOOT_WARM even though default
+ * reboot_mode was REBOOT_COLD. Reflect legacy de-facto behaviour in
+ * SYSFS.
+ */
+ .reboot_mode = REBOOT_WARM,
MACHINE_END
#endif
diff --git a/arch/arm/mach-omap2/prm-regbits-33xx.h b/arch/arm/mach-omap2/prm-regbits-33xx.h
index 3748c5266ae12..9b97f8c76cd17 100644
--- a/arch/arm/mach-omap2/prm-regbits-33xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-33xx.h
@@ -15,6 +15,7 @@
#define AM33XX_GFX_MEM_STATEST_MASK (0x3 << 4)
#define AM33XX_GLOBAL_WARM_SW_RST_MASK (1 << 1)
#define AM33XX_RST_GLOBAL_WARM_SW_MASK (1 << 0)
+#define AM33XX_RST_GLOBAL_COLD_SW_MASK (1 << 1)
#define AM33XX_PRUSS_MEM_ONSTATE_MASK (0x3 << 5)
#define AM33XX_PRUSS_MEM_RETSTATE_MASK (1 << 7)
#define AM33XX_PRUSS_MEM_STATEST_MASK (0x3 << 23)
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index fc45a7ed09bb3..fc53a27eed013 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -15,6 +15,7 @@
# ifndef __ASSEMBLER__
extern struct omap_domain_base prm_base;
extern u16 prm_features;
+extern enum reboot_mode prm_reboot_mode;
int omap_prcm_init(void);
int omap2_prcm_base_init(void);
# endif
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index 4a462310a4b09..505d685d6792e 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/reboot.h>
#include "powerdomain.h"
#include "prm33xx.h"
@@ -318,10 +319,19 @@ static int am33xx_check_vcvp(void)
*
* Immediately reboots the device through warm reset.
*/
-static void am33xx_prm_global_warm_sw_reset(void)
+static void am33xx_prm_global_sw_reset(void)
{
- am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK,
- AM33XX_RST_GLOBAL_WARM_SW_MASK,
+ /*
+ * Historically AM33xx performed warm reset for all requested reboot_mode.
+ * Keep this behaviour unchanged for all except newly added REBOOT_COLD.
+ */
+ u32 mask = AM33XX_RST_GLOBAL_WARM_SW_MASK;
+
+ if (prm_reboot_mode == REBOOT_COLD)
+ mask = AM33XX_RST_GLOBAL_COLD_SW_MASK;
+
+ am33xx_prm_rmw_reg_bits(mask,
+ mask,
AM33XX_PRM_DEVICE_MOD,
AM33XX_PRM_RSTCTRL_OFFSET);
@@ -382,7 +392,7 @@ static struct prm_ll_data am33xx_prm_ll_data = {
.assert_hardreset = am33xx_prm_assert_hardreset,
.deassert_hardreset = am33xx_prm_deassert_hardreset,
.is_hardreset_asserted = am33xx_prm_is_hardreset_asserted,
- .reset_system = am33xx_prm_global_warm_sw_reset,
+ .reset_system = am33xx_prm_global_sw_reset,
};
int __init am33xx_prm_init(const struct omap_prcm_init_data *data)
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index fd896f2295a11..f8771bdb5f068 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -66,6 +66,12 @@ struct omap_domain_base prm_base;
u16 prm_features;
+/*
+ * Platforms that implement different reboot modes can store the requested
+ * mode here.
+ */
+enum reboot_mode prm_reboot_mode;
+
/*
* prm_ll_data: function pointers to SoC-specific implementations of
* common PRM functions
--
2.43.0
More information about the linux-arm-kernel
mailing list