aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/kernel/cpu-probe.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-20 12:01:59 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-20 12:01:59 -0700
commit02d6112cd7d75bf30685ee4b2e9dc0291b4d3133 (patch)
treeb1715624dadae286cac16deb5a634a33f4a46aa6 /arch/mips/kernel/cpu-probe.c
parent0b1937ac0ef1541c0ea44e6f81c33d2f59803957 (diff)
parent941091024ef0f2f7e09eb81201d293ac18833cc8 (diff)
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: [MIPS] User stack pointer randomisation [MIPS] Remove unused include/asm-mips/gfx.h [MIPS] Remove unused include/asm-mips/ds1216.h [MIPS] Workaround for RM7000 WAIT instruction aka erratum 38 [MIPS] Make support for weakly ordered LL/SC a config option. [MIPS] Disable UserLocal runtime detection on platforms which never have it. [MIPS] Disable MT runtime detection on platforms which never support MT.
Diffstat (limited to 'arch/mips/kernel/cpu-probe.c')
-rw-r--r--arch/mips/kernel/cpu-probe.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index c6b8b074a81..06448a9656d 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -75,6 +75,27 @@ static void r4k_wait_irqoff(void)
local_irq_enable();
}
+/*
+ * The RM7000 variant has to handle erratum 38. The workaround is to not
+ * have any pending stores when the WAIT instruction is executed.
+ */
+static void rm7k_wait_irqoff(void)
+{
+ local_irq_disable();
+ if (!need_resched())
+ __asm__(
+ " .set push \n"
+ " .set mips3 \n"
+ " .set noat \n"
+ " mfc0 $1, $12 \n"
+ " sync \n"
+ " mtc0 $1, $12 # stalls until W stage \n"
+ " wait \n"
+ " mtc0 $1, $12 # stalls until W stage \n"
+ " .set pop \n");
+ local_irq_enable();
+}
+
/* The Au1xxx wait is available only if using 32khz counter or
* external timer source, but specifically not CP0 Counter. */
int allow_au1k_wait;
@@ -132,7 +153,6 @@ static inline void check_wait(void)
case CPU_R4700:
case CPU_R5000:
case CPU_NEVADA:
- case CPU_RM7000:
case CPU_4KC:
case CPU_4KEC:
case CPU_4KSC:
@@ -142,6 +162,10 @@ static inline void check_wait(void)
cpu_wait = r4k_wait;
break;
+ case CPU_RM7000:
+ cpu_wait = rm7k_wait_irqoff;
+ break;
+
case CPU_24K:
case CPU_34K:
cpu_wait = r4k_wait;