From adaa0b6c49795551b07576e952dfa94c3ccded51 Mon Sep 17 00:00:00 2001 From: Petri Gynther <pgynther@google.com> Date: Mon, 19 Oct 2015 11:44:24 -0700 Subject: MIPS: Switch BMIPS5000 to use r4k_wait_irqoff() BCM7425 CPU Interface Zephyr Processor, pages 5-309 and 5-310 BCM7428B0 CPU Interface Zephyr Processor, pages 5-337 and 5-338 WAIT instruction: Thread enters wait state. No instructions are executed until an interrupt occurs. The processor's clocks are stopped if both threads are in idle mode. Description: Execution of this instruction puts the thread into wait state, an idle mode in which no instructions are fetched or executed. The thread remains in wait state until an interrupt occurs that is not masked by the interrupt mask field in the Status register. Then, if interrupts are enabled by the IE bit in the Status register, the interrupt is serviced. The ERET instruction returns to the instruction following the WAIT instruction. If interrupts are disabled, the processor resumes executing instructions with the next sequential instruction. Programming notes: The WAIT instruction should be executed while interrupts are disabled by the IE bit in the Status register. This avoids a potential timing hazard, which occurs if an interrupt is taken between testing the counter and executing the WAIT instruction. In this hazard case, the interrupt will have been completed before the WAIT instruction is executed, so the processor will remain indefinitely in wait state until the next interrupt. Signed-off-by: Petri Gynther <pgynther@google.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Cc: cernekee@gmail.com Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/11322/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org> --- arch/mips/kernel/idle.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/mips/kernel/idle.c') diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index ab1478d5a4db..d636c70fef19 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c @@ -160,7 +160,6 @@ void __init check_wait(void) case CPU_BMIPS3300: case CPU_BMIPS4350: case CPU_BMIPS4380: - case CPU_BMIPS5000: case CPU_CAVIUM_OCTEON: case CPU_CAVIUM_OCTEON_PLUS: case CPU_CAVIUM_OCTEON2: @@ -171,7 +170,9 @@ void __init check_wait(void) case CPU_XLP: cpu_wait = r4k_wait; break; - + case CPU_BMIPS5000: + cpu_wait = r4k_wait_irqoff; + break; case CPU_RM7000: cpu_wait = rm7k_wait_irqoff; break; -- cgit From 5b10a0e84b4ebe02a7018846e882caa112b4ffc6 Mon Sep 17 00:00:00 2001 From: Paul Burton <paul.burton@imgtec.com> Date: Tue, 22 Sep 2015 11:24:20 -0700 Subject: MIPS: Always use r4k_wait_irqoff for MIPSr6 Prior to release 6 of the MIPS architecture it has been implementation dependent whether masked interrupts cause a wait instruction to return, so the kernel has effectively had to maintain a whitelist of cores upon which it is safe to use the r4k_wait_irqoff cpu_wait implementation. With MIPSr6 this is no longer implementation dependent and r4k_wait_irqoff can always be used. Remove the existing I6400 case which will no longer ever be hit, and was incorrect anyway since I6400 & r6 in general doesn't have the WII bit. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Cc: linux-mips@linux-mips.org Cc: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> Cc: linux-kernel@vger.kernel.org Cc: James Hogan <james.hogan@imgtec.com> Cc: Markos Chandras <markos.chandras@imgtec.com> Patchwork: https://patchwork.linux-mips.org/patch/11210/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org> --- arch/mips/kernel/idle.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch/mips/kernel/idle.c') diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index ab1478d5a4db..3e2b0b6c3b08 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c @@ -134,6 +134,16 @@ void __init check_wait(void) return; } + /* + * MIPSr6 specifies that masked interrupts should unblock an executing + * wait instruction, and thus that it is safe for us to use + * r4k_wait_irqoff. Yippee! + */ + if (cpu_has_mips_r6) { + cpu_wait = r4k_wait_irqoff; + return; + } + switch (current_cpu_type()) { case CPU_R3081: case CPU_R3081E: @@ -196,7 +206,6 @@ void __init check_wait(void) case CPU_INTERAPTIV: case CPU_M5150: case CPU_QEMU_GENERIC: - case CPU_I6400: cpu_wait = r4k_wait; if (read_c0_config7() & MIPS_CONF7_WII) cpu_wait = r4k_wait_irqoff; -- cgit From bf463f2f7510771db180908507005379850dade0 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno <aurelien@aurel32.net> Date: Sat, 5 Sep 2015 18:47:31 +0200 Subject: MIPS: idle: add case for CPU_5KE While the 5KE processors have never been taped out, they exists though a CP0.PRId and experimental RTLs or QEMU implementations. Add a case entry in the idle code, as they can use the standard idle loop like the 5K processors. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/11099/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org> --- arch/mips/kernel/idle.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/mips/kernel/idle.c') diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index 3e2b0b6c3b08..35af61530de1 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c @@ -165,6 +165,7 @@ void __init check_wait(void) case CPU_4KEC: case CPU_4KSC: case CPU_5KC: + case CPU_5KE: case CPU_25KF: case CPU_PR4450: case CPU_BMIPS3300: -- cgit