patch-2.0.7 linux/arch/alpha/kernel/irq.c
Next file: linux/arch/alpha/kernel/lca.c
Previous file: linux/arch/alpha/kernel/bios32.c
Back to the patch index
Back to the overall index
- Lines: 110
- Date:
Mon Jul 15 09:47:41 1996
- Orig file:
v2.0.6/linux/arch/alpha/kernel/irq.c
- Orig date:
Wed Jul 10 15:20:24 1996
diff -u --recursive --new-file v2.0.6/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
@@ -35,9 +35,9 @@
/*
* Shadow-copy of masked interrupts.
* The bits are used as follows:
- * 0.. 7 first ISA PIC (irq level 0..7)
- * 8..15 second ISA PIC (irq level 8..15)
- * Systems with 32 PCI interrupt lines (e.g., Alcor):
+ * 0.. 7 first (E)ISA PIC (irq level 0..7)
+ * 8..15 second (E)ISA PIC (irq level 8..15)
+ * Systems with PCI interrupt lines managed by GRU (e.g., Alcor, XLT):
* 16..47 PCI interrupts 0..31 (int at GRU_INT_MASK)
* Mikasa:
* 16..31 PCI interrupts 0..15 (short at I/O port 536)
@@ -60,8 +60,7 @@
#if NR_IRQS == 48
default:
/* note inverted sense of mask bits: */
- *(unsigned int *)GRU_INT_MASK = ~(mask >> 16);
- mb();
+ *(unsigned int *)GRU_INT_MASK = ~(mask >> 16); mb();
break;
#elif NR_IRQS == 33
@@ -166,17 +165,12 @@
}
/* .. then the master */
outb(0xE0 | irq, 0x20);
+#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
+ /* on ALCOR/XLT, need to dismiss interrupt via GRU */
+ *(int *)GRU_INT_CLEAR = 0x80000000; mb();
+ *(int *)GRU_INT_CLEAR = 0x00000000; mb();
+#endif /* ALCOR || XLT */
}
-#if 0
- /* This is not needed since all interrupt are level-sensitive */
-#if defined(CONFIG_ALPHA_ALCOR)
- /* on ALCOR, need to dismiss interrupt via GRU */
- *(int *)GRU_INT_CLEAR = 0x80000000;
- mb();
- *(int *)GRU_INT_CLEAR = 0x00000000;
- mb();
-#endif /* CONFIG_ALPHA_ALCOR */
-#endif
}
int request_irq(unsigned int irq,
@@ -413,6 +407,42 @@
#endif
}
+#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
+/* we have to conditionally compile this because of GRU_xxx symbols */
+static inline void alcor_and_xlt_device_interrupt(unsigned long vector,
+ struct pt_regs * regs)
+{
+ unsigned long pld;
+ unsigned int i;
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+
+ /* read the interrupt summary register of the GRU */
+ pld = (*(unsigned int *)GRU_INT_REQ) & GRU_INT_REQ_BITS;
+
+#if 0
+ printk("[0x%08lx/0x%04x]", pld, inb(0x20) | (inb(0xA0) << 8));
+#endif
+
+ /*
+ * Now for every possible bit set, work through them and call
+ * the appropriate interrupt handler.
+ */
+ while (pld) {
+ i = ffz(~pld);
+ pld &= pld - 1; /* clear least bit set */
+ if (i == 31) {
+ isa_device_interrupt(vector, regs);
+ } else {
+ device_interrupt(16 + i, 16 + i, regs);
+ }
+ }
+ restore_flags(flags);
+}
+#endif /* ALCOR || XLT */
+
static inline void cabriolet_and_eb66p_device_interrupt(unsigned long vector,
struct pt_regs * regs)
{
@@ -655,6 +685,8 @@
#if defined(CONFIG_ALPHA_JENSEN) || defined(CONFIG_ALPHA_NONAME) || \
defined(CONFIG_ALPHA_P2K) || defined(CONFIG_ALPHA_SRM)
srm_device_interrupt(vector, ®s);
+#elif NR_IRQS == 48
+ alcor_and_xlt_device_interrupt(vector, ®s);
#elif NR_IRQS == 33
cabriolet_and_eb66p_device_interrupt(vector, ®s);
#elif defined(CONFIG_ALPHA_MIKASA)
@@ -684,9 +716,8 @@
dma_outb(0, DMA1_CLR_MASK_REG);
dma_outb(0, DMA2_CLR_MASK_REG);
#if NR_IRQS == 48
- *(unsigned int *)GRU_INT_MASK = ~(irq_mask >> 16); /* invert */
- mb();
- enable_irq(16 + 31); /* enable EISA PIC cascade */
+ *(unsigned int *)GRU_INT_MASK = ~(irq_mask >> 16); mb();/* invert */
+ enable_irq(16 + 31); /* enable (E)ISA PIC cascade */
#elif NR_IRQS == 33
outl(irq_mask >> 16, 0x804);
enable_irq(16 + 4); /* enable SIO cascade */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov