summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/irq.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-03-07 15:45:24 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-03-07 15:45:24 +0000
commit9f9f3e6e8548a596697778337110a423c384b6f3 (patch)
tree5dd4b290ef532cf5ecb058e1a92cd3435afeac8c /arch/sparc64/kernel/irq.c
parentd5c9a365ee7d2fded249aa5abfc5e89587583029 (diff)
Merge with Linux 2.3.49.
Diffstat (limited to 'arch/sparc64/kernel/irq.c')
-rw-r--r--arch/sparc64/kernel/irq.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index ed9e49685..d2bc6baf5 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.84 2000/02/25 05:44:41 davem Exp $
+/* $Id: irq.c,v 1.85 2000/03/02 02:00:24 davem Exp $
* irq.c: UltraSparc IRQ handling/init/registry.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -955,7 +955,7 @@ int probe_irq_off(unsigned long mask)
void init_timers(void (*cfunc)(int, void *, struct pt_regs *),
unsigned long *clock)
{
- unsigned long flags;
+ unsigned long pstate;
extern unsigned long timer_tick_offset;
int node, err;
#ifdef __SMP__
@@ -978,31 +978,57 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *),
prom_halt();
}
- save_and_cli(flags);
+ /* Guarentee that the following sequences execute
+ * uninterrupted.
+ */
+ __asm__ __volatile__("rdpr %%pstate, %0\n\t"
+ "wrpr %0, %1, %%pstate"
+ : "=r" (pstate)
+ : "i" (PSTATE_IE));
/* Set things up so user can access tick register for profiling
- * purposes.
+ * purposes. Also workaround BB_ERRATA_1 by doing a dummy
+ * read back of %tick after writing it.
*/
__asm__ __volatile__("
sethi %%hi(0x80000000), %%g1
- sllx %%g1, 32, %%g1
- rd %%tick, %%g2
+ ba,pt %%xcc, 1f
+ sllx %%g1, 32, %%g1
+ .align 64
+ 1: rd %%tick, %%g2
add %%g2, 6, %%g2
andn %%g2, %%g1, %%g2
wrpr %%g2, 0, %%tick
-" : /* no outputs */
+ rdpr %%tick, %%g0"
+ : /* no outputs */
: /* no inputs */
: "g1", "g2");
+ /* Workaround for Spitfire Errata (#54 I think??), I discovered
+ * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
+ * number 103640.
+ *
+ * On Blackbird writes to %tick_cmpr can fail, the
+ * workaround seems to be to execute the wr instruction
+ * at the start of an I-cache line, and perform a dummy
+ * read back from %tick_cmpr right after writing to it. -DaveM
+ */
__asm__ __volatile__("
rd %%tick, %%g1
- add %%g1, %0, %%g1
- wr %%g1, 0x0, %%tick_cmpr"
+ ba,pt %%xcc, 1f
+ add %%g1, %0, %%g1
+ .align 64
+ 1: wr %%g1, 0x0, %%tick_cmpr
+ rd %%tick_cmpr, %%g0"
: /* no outputs */
: "r" (timer_tick_offset)
: "g1");
- restore_flags(flags);
+ /* Restore PSTATE_IE. */
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
+ : /* no outputs */
+ : "r" (pstate));
+
sti();
}