patch-2.1.73 linux/arch/mips/sgi/kernel/indy_int.c
Next file: linux/arch/mips/sgi/kernel/indy_mc.c
Previous file: linux/arch/mips/sgi/kernel/indy_hpc.c
Back to the patch index
Back to the overall index
- Lines: 182
- Date:
Wed Dec 10 10:31:10 1997
- Orig file:
v2.1.72/linux/arch/mips/sgi/kernel/indy_int.c
- Orig date:
Mon Jul 7 08:18:54 1997
diff -u --recursive --new-file v2.1.72/linux/arch/mips/sgi/kernel/indy_int.c linux/arch/mips/sgi/kernel/indy_int.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: indy_int.c,v 1.2 1997/06/30 15:53:01 ralf Exp $
+ * $Id: indy_int.c,v 1.4 1997/09/20 19:20:15 root Exp $
*/
#include <linux/config.h>
@@ -260,13 +260,6 @@
atomic_t __mips_bh_counter;
-#ifdef __SMP__
-#error Send superfluous SMP boxes to ralf@uni-koblenz.de
-#else
-#define irq_enter(cpu, irq) (++local_irq_count[cpu])
-#define irq_exit(cpu, irq) (--local_irq_count[cpu])
-#endif
-
/*
* do_IRQ handles IRQ's that have been installed without the
* SA_INTERRUPT flag: it uses the full signal-handling return
@@ -276,43 +269,49 @@
*/
asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
- struct irqaction * action = *(irq + irq_action);
+ struct irqaction *action;
+ int do_random, cpu;
- lock_kernel();
+ cpu = smp_processor_id();
+ irq_enter(cpu, irq);
kstat.interrupts[irq]++;
- printk("Got irq %d, press a key.", irq);
- prom_getchar();
- romvec->imode();
- while (action) {
- if (action->flags & SA_SAMPLE_RANDOM)
- add_interrupt_randomness(irq);
- action->handler(irq, action->dev_id, regs);
- action = action->next;
- }
- unlock_kernel();
-}
-
-/*
- * 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)
-{
- struct irqaction * action = *(irq + irq_action);
- lock_kernel();
printk("Got irq %d, press a key.", irq);
prom_getchar();
romvec->imode();
- kstat.interrupts[irq]++;
- while (action) {
- if (action->flags & SA_SAMPLE_RANDOM)
+
+ /*
+ * mask and ack quickly, we don't want the irq controller
+ * thinking we're snobs just because some other CPU has
+ * disabled global interrupts (we have already done the
+ * INT_ACK cycles, it's too late to try to pretend to the
+ * controller that we aren't taking the interrupt).
+ *
+ * Commented out because we've already done this in the
+ * machinespecific part of the handler. It's reasonable to
+ * do this here in a highlevel language though because that way
+ * we could get rid of a good part of duplicated code ...
+ */
+ /* mask_and_ack_irq(irq); */
+
+ action = *(irq + irq_action);
+ if (action) {
+ if (!(action->flags & SA_INTERRUPT))
+ __sti();
+ action = *(irq + irq_action);
+ do_random = 0;
+ do {
+ do_random |= action->flags;
+ action->handler(irq, action->dev_id, regs);
+ action = action->next;
+ } while (action);
+ if (do_random & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
- action->handler(irq, action->dev_id, NULL);
- action = action->next;
- }
- unlock_kernel();
+ __cli();
+ }
+ irq_exit(cpu, irq);
+
+ /* unmasking and bottom half handling is done magically for us. */
}
int request_local_irq(unsigned int lirq, void (*func)(int, void *, struct pt_regs *),
@@ -419,10 +418,6 @@
void init_IRQ(void)
{
- int i;
-
- for (i = 0; i < 16 ; i++)
- set_int_vector(i, 0);
irq_setup();
}
@@ -431,7 +426,7 @@
struct irqaction *action;
unsigned char mask = ioc_icontrol->istat0;
unsigned char mask2 = 0;
- int irq;
+ int irq, cpu = smp_processor_id();;
mask &= ioc_icontrol->imask0;
if(mask & ISTAT0_LIO2) {
@@ -443,13 +438,11 @@
irq = lc0msk_to_irqnr[mask];
action = local_irq_action[irq];
}
-#if 0
- printk("local0_dispatch: got irq %d mask %2x mask2 %2x\n",
- irq, mask, mask2);
- prom_getchar();
-#endif
+
+ irq_enter(cpu, irq);
kstat.interrupts[irq + 16]++;
action->handler(irq, action->dev_id, regs);
+ irq_exit(cpu, irq);
}
void indy_local1_irqdispatch(struct pt_regs *regs)
@@ -457,7 +450,7 @@
struct irqaction *action;
unsigned char mask = ioc_icontrol->istat1;
unsigned char mask2 = 0;
- int irq;
+ int irq, cpu = smp_processor_id();;
mask &= ioc_icontrol->imask1;
if(mask & ISTAT1_LIO3) {
@@ -470,23 +463,24 @@
irq = lc1msk_to_irqnr[mask];
action = local_irq_action[irq];
}
-#if 0
- printk("local1_dispatch: got irq %d mask %2x mask2 %2x\n",
- irq, mask, mask2);
- prom_getchar();
-#endif
+ irq_enter(cpu, irq);
kstat.interrupts[irq + 24]++;
action->handler(irq, action->dev_id, regs);
+ irq_exit(cpu, irq);
}
void indy_buserror_irq(struct pt_regs *regs)
{
- kstat.interrupts[6]++;
+ int cpu = smp_processor_id();
+ int irq = 6;
+
+ irq_enter(cpu, irq);
+ kstat.interrupts[irq]++;
printk("Got a bus error IRQ, shouldn't happen yet\n");
show_regs(regs);
printk("Spinning...\n");
- while(1)
- ;
+ while(1);
+ irq_exit(cpu, irq);
}
/* Misc. crap just to keep the kernel linking... */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov