Linux MIPS Architecture development
 help / color / mirror / Atom feed
* [PATCH 0/3] Fix MT7621 restart deadlock
@ 2026-04-05 23:59 Rany Hany
  2026-04-05 23:59 ` [PATCH 1/3] MIPS: Stop secondary CPUs before platform restart/halt/poweroff Rany Hany
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Rany Hany @ 2026-04-05 23:59 UTC (permalink / raw)
  To: linux-mips; +Cc: Rany Hany, Thomas Bogendoerfer

These patches fix an issue on some MT7621 devices where the reboot
hangs. They were submitted to OpenWrt and have been merged.

The first two patches aren't particularly remarkable as they just
align MIPS with ARM behavior and are required for the full fix.

The last patch is the most interesting as it uses CPC to transition
the CPU to clock off state. It is not clear to me why this is required
but without it it ends up hanging. Initially only flushing d-cache
and using TCHalt was attempted but ClkOff appears to be necessary. 

This fix was only tested on ASUS RT-AX53U as I don't have other
MT7621 devices with this problem.

Unrelated note:

Sorry I had to resend this as my Thunderbird client was not properly
setup for this. I used imap-send which just caused issues. I am not
sure how I previously setup Thunderbird so that it groups the patches
in one thread.

In any case, I ended up just using send-email as I didn't want to mess
with Thunderbird again.

Rany Hany (3):
  MIPS: Stop secondary CPUs before platform restart/halt/poweroff
  MIPS: SMP: Wait for secondary CPUs to stop in smp_send_stop()
  MIPS: SMP: Properly stop secondary CPUs for restart

 arch/mips/kernel/reset.c | 19 ++++++-----
 arch/mips/kernel/smp.c   | 68 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 78 insertions(+), 9 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 6+ messages in thread
* [PATCH 3/3] MIPS: SMP: Properly stop secondary CPUs for restart
@ 2026-04-05 23:23 Rany Hany
  0 siblings, 0 replies; 6+ messages in thread
From: Rany Hany @ 2026-04-05 23:23 UTC (permalink / raw)
  To: linux-mips; +Cc: Thomas Bogendoerfer

Some MT7621 devices deadlock in the platform restart callback unless
the other CPUs are stopped by clocking them off.

This fixes restart deadlocks on those MT7621, although the exact
reason why this is required is still unclear.

Signed-off-by: Rany Hany <rany_hany@riseup.net>
---
 arch/mips/kernel/smp.c | 58 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 8d2932e81..e50208c4a 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -32,6 +32,7 @@
 #include <asm/processor.h>
 #include <asm/idle.h>
 #include <asm/r4k-timer.h>
+#include <asm/r4kcache.h>
 #include <asm/mips-cps.h>
 #include <asm/mmu_context.h>
 #include <asm/time.h>
@@ -413,6 +414,8 @@ asmlinkage void start_secondary(void)
 	cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
 }
 
+static atomic_t core_stop_count[NR_CPUS];
+
 static void stop_this_cpu(void *dummy)
 {
 	/*
@@ -422,13 +425,66 @@ static void stop_this_cpu(void *dummy)
 	set_cpu_online(smp_processor_id(), false);
 	calculate_cpu_foreign_map();
 	local_irq_disable();
-	while (1);
+
+	if (mips_cm_present() && r4k_blast_dcache) {
+		unsigned int core = cpu_core(&current_cpu_data);
+
+		if (atomic_dec_and_test(&core_stop_count[core])) {
+			/* Flush data cache */
+			r4k_blast_dcache();
+			__sync();
+
+			if (mips_cm_revision() < CM_REV_CM3) {
+				/* Restrict coherence to own core first */
+				write_gcr_cl_coherence(1 << core);
+				read_gcr_cl_coherence();
+				__sync();
+			}
+
+			/* Disable coherence */
+			write_gcr_cl_coherence(0);
+			read_gcr_cl_coherence();
+
+			/* Gate the core clock */
+			if (mips_cpc_present())
+				write_cpc_cl_cmd(CPC_Cx_CMD_CLOCKOFF);
+		}
+	}
+
+	if (cpu_has_mipsmt) {
+		/* The last active VPE on the core will gate the core clock
+		 * and all other remaining VPEs will halt this TC instead.
+		 *
+		 * Note that on systems without CPC, this will be the
+		 * only way to shutdown the CPU.
+		 */
+		write_c0_tchalt(TCHALT_H);
+		instruction_hazard();
+	}
+
+	while (1)
+		cpu_relax();
 }
 
 void smp_send_stop(void)
 {
+	static unsigned long stop_in_progress;
 	unsigned long timeout;
 
+	if (test_and_set_bit(0, &stop_in_progress))
+		return;
+
+	if (mips_cm_present()) {
+		unsigned int cpu;
+
+		for_each_online_cpu(cpu) {
+			unsigned int core;
+
+			core = cpu_core(&cpu_data[cpu]);
+			atomic_inc(&core_stop_count[core]);
+		}
+	}
+
 	smp_call_function(stop_this_cpu, NULL, 0);
 
 	/* Wait up to 1s for other CPUs to stop */
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-05-05  6:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-05 23:59 [PATCH 0/3] Fix MT7621 restart deadlock Rany Hany
2026-04-05 23:59 ` [PATCH 1/3] MIPS: Stop secondary CPUs before platform restart/halt/poweroff Rany Hany
2026-04-05 23:59 ` [PATCH 2/3] MIPS: SMP: Wait for secondary CPUs to stop in smp_send_stop() Rany Hany
2026-04-05 23:59 ` [PATCH 3/3] MIPS: SMP: Properly stop secondary CPUs for restart Rany Hany
2026-05-05  6:48   ` Thomas Bogendoerfer
  -- strict thread matches above, loose matches on Subject: below --
2026-04-05 23:23 Rany Hany

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox