Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: Idle: Break r4k_wait into two functions and fix it.

local_irq_enable() may expand into very different code, so it rather should
stay in C. Also this keeps the assembler code size constant which keeps
the rollback code simple. So it's best to split r4k_wait into two parts,
one C and one assembler.

Finally add the local_irq_enable() to r4k_wait to ensure the WAIT
instruction in __r4k_wait() will work properly.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

+11 -4
+2 -1
arch/mips/include/asm/idle.h
··· 4 4 #include <linux/linkage.h> 5 5 6 6 extern void (*cpu_wait)(void); 7 - extern asmlinkage void r4k_wait(void); 7 + extern void r4k_wait(void); 8 + extern asmlinkage void __r4k_wait(void); 8 9 extern void r4k_wait_irqoff(void); 9 10 extern void __pastwait(void); 10 11
+3 -3
arch/mips/kernel/genex.S
··· 122 122 __FINIT 123 123 124 124 .align 5 /* 32 byte rollback region */ 125 - LEAF(r4k_wait) 125 + LEAF(__r4k_wait) 126 126 .set push 127 127 .set noreorder 128 128 /* start of rollback region */ ··· 146 146 jr ra 147 147 nop 148 148 .set pop 149 - END(r4k_wait) 149 + END(__r4k_wait) 150 150 151 151 .macro BUILD_ROLLBACK_PROLOGUE handler 152 152 FEXPORT(rollback_\handler) 153 153 .set push 154 154 .set noat 155 155 MFC0 k0, CP0_EPC 156 - PTR_LA k1, r4k_wait 156 + PTR_LA k1, __r4k_wait 157 157 ori k0, 0x1f /* 32 byte rollback region */ 158 158 xori k0, 0x1f 159 159 bne k0, k1, 9f
+6
arch/mips/kernel/idle.c
··· 45 45 local_irq_enable(); 46 46 } 47 47 48 + void r4k_wait(void) 49 + { 50 + local_irq_enable(); 51 + __r4k_wait(); 52 + } 53 + 48 54 /* 49 55 * This variant is preferable as it allows testing need_resched and going to 50 56 * sleep depending on the outcome atomically. Unfortunately the "It is