diff mbox series

[v2,4/4] board: freescale: p1_p2_rdb_pc: Turn off watchdog before reset

Message ID 20220801133146.11481-4-pali@kernel.org
State Accepted
Commit 44366be10a9386a8887124a77a7d06169c3aa1f3
Delegated to: Marek Behun
Headers show
Series [v2,1/4] board: freescale: p1_p2_rdb_pc: Add workaround for board reset reboot loop | expand

Commit Message

Pali Rohár Aug. 1, 2022, 1:31 p.m. UTC
P1/P2 RDB boards have external max6370 watchdog connected to CPLD and this
watchdog is not deactivated on board reset. So if it is active during board
reset, it can trigger another reset when CPU is booting U-Boot. To prevent
possible infinite reset loop caused by external watchdog, turn it off
before reset.

Do it via a new board_reset_prepare() callback which is called from
do_reset() function before any reset sequence.

Signed-off-by: Pali Rohár <pali@kernel.org>
---
 arch/powerpc/cpu/mpc85xx/cpu.c              |  4 ++++
 board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c | 12 ++++++++++++
 2 files changed, 16 insertions(+)
diff mbox series

Patch

diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c
index c63c17286811..015bd3661c59 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu.c
@@ -43,6 +43,7 @@  __board_reset(void)
 {
 	/* Do nothing */
 }
+void board_reset_prepare(void) __attribute__((weak, alias("__board_reset")));
 void board_reset(void) __attribute__((weak, alias("__board_reset")));
 void board_reset_last(void) __attribute__((weak, alias("__board_reset")));
 
@@ -323,6 +324,9 @@  int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 #else
 	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 
+	/* Call board-specific preparation for reset */
+	board_reset_prepare();
+
 	/* Attempt board-specific reset */
 	board_reset();
 
diff --git a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
index 4bcb05bed9b8..42409a864854 100644
--- a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
+++ b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
@@ -83,6 +83,18 @@  struct cpld_data {
 #define CPLD_FXS_LED	0x0F
 #define CPLD_SYS_RST	0x00
 
+void board_reset_prepare(void)
+{
+	/*
+	 * During reset preparation, turn off external watchdog.
+	 * This ensures that external watchdog does not trigger
+	 * another reset or possible infinite reset loop.
+	 */
+	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
+	out_8(&cpld_data->wd_cfg, CPLD_WD_CFG);
+	in_8(&cpld_data->wd_cfg); /* Read back to sync write */
+}
+
 void board_reset_last(void)
 {
 	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);