MIPS: Idle: Break r4k_wait into two functions and fix it.
authorRalf Baechle <ralf@linux-mips.org>
Tue, 21 May 2013 15:33:32 +0000 (17:33 +0200)
committerRalf Baechle <ralf@linux-mips.org>
Tue, 21 May 2013 23:34:28 +0000 (01:34 +0200)
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>
arch/mips/include/asm/idle.h
arch/mips/kernel/genex.S
arch/mips/kernel/idle.c

index be6f807c1e3f8e01b442d572cd1ea8e9ddb476c0..d192158886b1e5b5e56b71e895a38c2bec6e2497 100644 (file)
@@ -4,7 +4,8 @@
 #include <linux/linkage.h>
 
 extern void (*cpu_wait)(void);
-extern asmlinkage void r4k_wait(void);
+extern void r4k_wait(void);
+extern asmlinkage void __r4k_wait(void);
 extern void r4k_wait_irqoff(void);
 extern void __pastwait(void);
 
index 9098829bfcb0cea7c08c51e4b0d95a337fcbf5bb..31fa856829cbf2620521317e5247d42b9e3fb087 100644 (file)
@@ -122,7 +122,7 @@ handle_vcei:
        __FINIT
 
        .align  5       /* 32 byte rollback region */
-LEAF(r4k_wait)
+LEAF(__r4k_wait)
        .set    push
        .set    noreorder
        /* start of rollback region */
@@ -146,14 +146,14 @@ LEAF(r4k_wait)
        jr      ra
        nop
        .set    pop
-       END(r4k_wait)
+       END(__r4k_wait)
 
        .macro  BUILD_ROLLBACK_PROLOGUE handler
        FEXPORT(rollback_\handler)
        .set    push
        .set    noat
        MFC0    k0, CP0_EPC
-       PTR_LA  k1, r4k_wait
+       PTR_LA  k1, __r4k_wait
        ori     k0, 0x1f        /* 32 byte rollback region */
        xori    k0, 0x1f
        bne     k0, k1, 9f
index 985cc02786e3d7ab3d49a4305502487fe0d46ca4..3b09b888afa9a1df7a3ff7e09814c80855da74d4 100644 (file)
@@ -45,6 +45,12 @@ static void r39xx_wait(void)
        local_irq_enable();
 }
 
+void r4k_wait(void)
+{
+       local_irq_enable();
+       __r4k_wait();
+}
+
 /*
  * This variant is preferable as it allows testing need_resched and going to
  * sleep depending on the outcome atomically.  Unfortunately the "It is