diff options
Diffstat (limited to 'arch/mips/kernel/idle.c')
| -rw-r--r-- | arch/mips/kernel/idle.c | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index 3b09b888afa..09ce4598075 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c @@ -18,6 +18,7 @@ #include <linux/sched.h> #include <asm/cpu.h> #include <asm/cpu-info.h> +#include <asm/cpu-type.h> #include <asm/idle.h> #include <asm/mipsregs.h> @@ -63,7 +64,7 @@ void r4k_wait_irqoff(void) if (!need_resched()) __asm__( " .set push \n" - " .set mips3 \n" + " .set arch=r4000 \n" " wait \n" " .set pop \n"); local_irq_enable(); @@ -81,7 +82,7 @@ static void rm7k_wait_irqoff(void) if (!need_resched()) __asm__( " .set push \n" - " .set mips3 \n" + " .set arch=r4000 \n" " .set noat \n" " mfc0 $1, $12 \n" " sync \n" @@ -93,26 +94,27 @@ static void rm7k_wait_irqoff(void) } /* - * The Au1xxx wait is available only if using 32khz counter or - * external timer source, but specifically not CP0 Counter. - * alchemy/common/time.c may override cpu_wait! + * Au1 'wait' is only useful when the 32kHz counter is used as timer, + * since coreclock (and the cp0 counter) stops upon executing it. Only an + * interrupt can wake it, so they must be enabled before entering idle modes. */ static void au1k_wait(void) { + unsigned long c0status = read_c0_status() | 1; /* irqs on */ + __asm__( - " .set mips3 \n" + " .set arch=r4000 \n" " cache 0x14, 0(%0) \n" " cache 0x14, 32(%0) \n" " sync \n" - " nop \n" + " mtc0 %1, $12 \n" /* wr c0status */ " wait \n" " nop \n" " nop \n" " nop \n" " nop \n" " .set mips0 \n" - : : "r" (au1k_wait)); - local_irq_enable(); + : : "r" (au1k_wait), "r" (c0status)); } static int __initdata nowait; @@ -135,7 +137,7 @@ void __init check_wait(void) return; } - switch (c->cputype) { + switch (current_cpu_type()) { case CPU_R3081: case CPU_R3081E: cpu_wait = r3081_wait; @@ -165,6 +167,7 @@ void __init check_wait(void) case CPU_CAVIUM_OCTEON: case CPU_CAVIUM_OCTEON_PLUS: case CPU_CAVIUM_OCTEON2: + case CPU_CAVIUM_OCTEON3: case CPU_JZRISC: case CPU_LOONGSON1: case CPU_XLR: @@ -181,6 +184,11 @@ void __init check_wait(void) case CPU_24K: case CPU_34K: case CPU_1004K: + case CPU_1074K: + case CPU_INTERAPTIV: + case CPU_PROAPTIV: + case CPU_P5600: + case CPU_M5150: cpu_wait = r4k_wait; if (read_c0_config7() & MIPS_CONF7_WII) cpu_wait = r4k_wait_irqoff; @@ -216,29 +224,26 @@ void __init check_wait(void) cpu_wait = r4k_wait; */ break; - case CPU_RM9000: - if ((c->processor_id & 0x00ff) >= 0x40) - cpu_wait = r4k_wait; - break; default: break; } } -static void smtc_idle_hook(void) -{ -#ifdef CONFIG_MIPS_MT_SMTC - void smtc_idle_loop_hook(void); - - smtc_idle_loop_hook(); -#endif -} - void arch_cpu_idle(void) { - smtc_idle_hook(); if (cpu_wait) cpu_wait(); else local_irq_enable(); } + +#ifdef CONFIG_CPU_IDLE + +int mips_cpuidle_wait_enter(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + arch_cpu_idle(); + return index; +} + +#endif |
