Skip to content

Commit

Permalink
[MIPS] Workaround for RM7000 WAIT instruction aka erratum 38
Browse files Browse the repository at this point in the history
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
Ralf Baechle committed Jul 20, 2007
1 parent 17099b1 commit 5a81299
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion arch/mips/kernel/cpu-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand All @@ -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;
Expand Down

0 comments on commit 5a81299

Please sign in to comment.