patch-2.1.9 linux/arch/sparc/kernel/irq.c
Next file: linux/arch/sparc/kernel/process.c
Previous file: linux/arch/sparc/kernel/ioport.c
Back to the patch index
Back to the overall index
- Lines: 164
- Date:
Sat Nov 9 10:11:40 1996
- Orig file:
v2.1.8/linux/arch/sparc/kernel/irq.c
- Orig date:
Mon May 6 12:26:03 1996
diff -u --recursive --new-file v2.1.8/linux/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.44 1996/04/25 06:08:46 davem Exp $
+/* $Id: irq.c,v 1.53 1996/10/16 12:30:18 zaitcev Exp $
* arch/sparc/kernel/irq.c: Interrupt request handling routines. On the
* Sparc the IRQ's are basically 'cast in stone'
* and you are supposed to probe the prom's device
@@ -19,6 +19,7 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/malloc.h>
+#include <linux/random.h>
#include <asm/ptrace.h>
#include <asm/processor.h>
@@ -32,6 +33,7 @@
#include <asm/traps.h>
#include <asm/irq.h>
#include <asm/io.h>
+#include <asm/pgtable.h>
/*
* Dave Redman (djhr@tadpole.co.uk)
@@ -158,7 +160,7 @@
return;
}
- save_flags(flags); cli();
+ save_and_cli(flags);
if (action && tmp)
tmp->next = action->next;
else
@@ -184,11 +186,13 @@
printk("IO device interrupt, irq = %d\n", irq);
printk("PC = %08lx NPC = %08lx FP=%08lx\n", regs->pc,
regs->npc, regs->u_regs[14]);
- printk("Expecting: ");
- for (i = 0; i < 16; i++)
- if (action->handler)
- prom_printf("[%s:%d:0x%x] ", action->name, (int) i,
- (unsigned int) action->handler);
+ if (action) {
+ printk("Expecting: ");
+ for (i = 0; i < 16; i++)
+ if (action->handler)
+ prom_printf("[%s:%d:0x%x] ", action->name,
+ (int) i, (unsigned int) action->handler);
+ }
printk("AIEEE\n");
panic("bogus interrupt received");
}
@@ -204,46 +208,12 @@
#if 0
printk("I<%d,%d,%d>", smp_processor_id(), irq, smp_proc_in_lock[smp_processor_id()]);
#endif
- while (action) {
- if (!action->handler)
- unexpected_irq(irq, action->dev_id, regs);
- else
- action->handler(irq, action->dev_id, regs);
- action = action->next;
- }
-}
-
-/*
- * do_IRQ handles IRQ's that have been installed without the
- * SA_INTERRUPT flag: it uses the full signal-handling return
- * and runs with other interrupts enabled. All relatively slow
- * IRQ's should use this format: notably the keyboard/timer
- * routines.
- */
-asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
-{
- struct irqaction * action;
- unsigned int cpu_irq;
-
- cpu_irq = irq & NR_IRQS;
- action = *(cpu_irq + irq_action);
- kstat.interrupts[cpu_irq]++;
- while (action) {
+ do {
+ if (!action || !action->handler)
+ unexpected_irq(irq, 0, regs);
action->handler(irq, action->dev_id, regs);
action = action->next;
- }
-}
-
-/*
- * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return
- * stuff - the handler is also running with interrupts disabled unless
- * it explicitly enables them later.
- */
-asmlinkage void do_fast_IRQ(int irq)
-{
- kstat.interrupts[irq&NR_IRQS]++;
- printk("Got FAST_IRQ number %04lx\n", (long unsigned int) irq);
- return;
+ } while (action);
}
/* Fast IRQ's on the Sparc can only have one routine attached to them,
@@ -256,6 +226,10 @@
struct irqaction *action;
unsigned long flags;
unsigned int cpu_irq;
+#ifdef __SMP__
+ struct tt_entry *trap_table;
+ extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3;
+#endif
cpu_irq = irq & NR_IRQS;
if(cpu_irq > 14)
@@ -273,7 +247,7 @@
return -EBUSY;
}
- save_flags(flags); cli();
+ save_and_cli(flags);
/* If this is flagged as statically allocated then we use our
* private struct which is never freed.
@@ -295,12 +269,27 @@
}
/* Dork with trap table if we get this far. */
- sparc_ttable[SP_TRAP_IRQ1+(cpu_irq-1)].inst_one =
- SPARC_BRANCH((unsigned long) handler,
- (unsigned long) &sparc_ttable[SP_TRAP_IRQ1+(irq-1)].inst_one);
- sparc_ttable[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two = SPARC_RD_PSR_L0;
- sparc_ttable[SP_TRAP_IRQ1+(cpu_irq-1)].inst_three = SPARC_NOP;
- sparc_ttable[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
+#define INSTANTIATE(table) \
+ table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_one = SPARC_RD_PSR_L0; \
+ table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two = \
+ SPARC_BRANCH((unsigned long) handler, \
+ (unsigned long) &table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two);\
+ table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_three = SPARC_RD_WIM_L3; \
+ table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
+
+ INSTANTIATE(sparc_ttable)
+#ifdef __SMP__
+ trap_table = &trapbase_cpu1; INSTANTIATE(trap_table)
+ trap_table = &trapbase_cpu2; INSTANTIATE(trap_table)
+ trap_table = &trapbase_cpu3; INSTANTIATE(trap_table)
+#endif
+#undef INSTANTIATE
+ /*
+ * XXX Correct thing whould be to flush only I- and D-cache lines
+ * which contain the handler in question. But as of time of the
+ * writing we have no CPU-neutral interface to fine-grained flushes.
+ */
+ flush_cache_all();
action->handler = handler;
action->flags = irqflags;
@@ -342,7 +331,7 @@
}
}
- save_flags(flags); cli();
+ save_and_cli(flags);
/* If this is flagged as statically allocated then we use our
* private struct which is never freed.
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov