patch-2.0.34 linux/arch/alpha/kernel/irq.c
Next file: linux/arch/alpha/kernel/lca.c
Previous file: linux/arch/alpha/kernel/head.S
Back to the patch index
Back to the overall index
- Lines: 839
- Date:
Wed Jun 3 15:17:46 1998
- Orig file:
v2.0.33/linux/arch/alpha/kernel/irq.c
- Orig date:
Mon Oct 13 08:28:55 1997
diff -u --recursive --new-file v2.0.33/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
@@ -27,6 +27,7 @@
#include <asm/dma.h>
extern void timer_interrupt(struct pt_regs * regs);
+extern void cserve_update_hw(unsigned long, unsigned long);
#if NR_IRQS > 64
# error Unable to handle more than 64 irq levels.
@@ -42,7 +43,8 @@
* 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)
+ * or PYXIS (e.g. Miata, PC164-LX)
+ * 16..47 PCI interrupts 0..31 (xxx_INT_MASK reg)
* Mikasa:
* 16..31 PCI interrupts 0..15 (short at I/O port 536)
* Other systems (not Mikasa) with 16 PCI interrupt lines:
@@ -50,13 +52,43 @@
* 24..31 PCI interrupts 8..15 (char at I/O port 27)
* Systems with 17 PCI interrupt lines (e.g., Cabriolet and eb164):
* 16..32 PCI interrupts 0..31 (int at I/O port 804)
+ * Takara:
+ * 16..19 PCI interrupts A thru D
+ * For SABLE, which is really baroque, we manage 40 IRQ's, but the
+ * hardware really only supports 24, not via normal ISA PIC,
+ * but cascaded custom 8259's, etc.
+ * 0-7 (char at 536)
+ * 8-15 (char at 53a)
+ * 16-23 (char at 53c)
*/
static unsigned long irq_mask = ~0UL;
+#ifdef CONFIG_ALPHA_SABLE
+/* note that the vector reported by the SRM PALcode corresponds to the
+ interrupt mask bits, but we have to manage via more normal IRQs */
+static char sable_irq_to_mask[NR_IRQS] = {
+ -1, 6, -1, 8, 15, 12, 7, 9, /* pseudo PIC 0-7 */
+ -1, 16, 17, 18, 3, -1, 21, 22, /* pseudo PIC 8-15 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 0-7 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 8-15 */
+ 2, 1, 0, 4, 5, -1, -1, -1, /* pseudo PCI */
+ };
+#define IRQ_TO_MASK(irq) (sable_irq_to_mask[(irq)])
+static char sable_mask_to_irq[NR_IRQS] = {
+ 34, 33, 32, 12, 35, 36, 1, 6, /* mask 0-7 */
+ 3, 7, -1, -1, 5, -1, -1, 4, /* mask 8-15 */
+ 9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23 */
+ };
+#else /* CONFIG_ALPHA_SABLE */
+#define IRQ_TO_MASK(irq) (irq)
+#endif /* CONFIG_ALPHA_SABLE */
/*
* Update the hardware with the irq mask passed in MASK. The function
* exploits the fact that it is known that only bit IRQ has changed.
+ *
+ * There deliberately isn't a case in here for the Takara since it
+ * wouldn't work anyway because the interrupt controller is bizarre.
*/
static void update_hw(unsigned long irq, unsigned long mask)
{
@@ -65,32 +97,111 @@
mask |= 0x7ff00000UL << 16;
#endif
switch (irq) {
-#if NR_IRQS == 48
- default:
+
+#ifdef CONFIG_ALPHA_SABLE
+ /* SABLE does everything different, so we manage it that way... :-( */
+ /* the "irq" argument is really the mask bit number */
+ case 0 ... 7:
+ outb(mask, 0x537);
+ break;
+ case 8 ... 15:
+ outb(mask >> 8, 0x53b);
+ break;
+ case 16 ... 23:
+ outb(mask >> 16, 0x53d);
+ break;
+#else /* SABLE */
+
+#if defined(CONFIG_ALPHA_NORITAKE)
+ /* note inverted sense of mask bits: */
+ case 16 ... 31:
+ outw(~(mask >> 16), 0x54a);
+ break;
+ case 32 ... 47:
+ outw(~(mask >> 32), 0x54c);
+ break;
+#endif /* NORITAKE */
+
+#if defined(CONFIG_ALPHA_MIATA)
+ case 16 ... 47:
+ { unsigned long temp;
+ /* note inverted sense of mask bits: */
+ /* make CERTAIN none of the bogus ints get enabled */
+ *(unsigned long *)PYXIS_INT_MASK =
+ ~((long)mask >> 16) & ~0x400000000000063bUL; mb();
+ temp = *(unsigned long *)PYXIS_INT_MASK;
+ break;
+ }
+#endif /* MIATA */
+
+#if defined(CONFIG_ALPHA_RUFFIAN)
+ case 16 ... 47:
+ { unsigned long temp;
+ /* note inverted sense of mask bits: */
+ /* make CERTAIN none of the bogus ints get enabled */
+ *(unsigned long *)PYXIS_INT_MASK =
+ ~((long)mask >> 16) & 0x00000000ffffffbfUL; mb();
+ temp = *(unsigned long *)PYXIS_INT_MASK;
+ break;
+ }
+#endif /* RUFFIAN */
+
+#if defined(CONFIG_ALPHA_SX164)
+ case 16 ... 39:
+#if defined(CONFIG_ALPHA_SRM)
+ cserve_update_hw(irq, mask);
+ break;
+#else
+ { unsigned long temp;
+ /* make CERTAIN none of the bogus ints get enabled */
+ *(unsigned long *)PYXIS_INT_MASK =
+ ~((long)mask >> 16) & ~0x000000000000003bUL; mb();
+ temp = *(unsigned long *)PYXIS_INT_MASK;
+ break;
+ }
+#endif /* SRM */
+#endif /* SX164 */
+
+#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
+ case 16 ... 47:
/* note inverted sense of mask bits: */
*(unsigned int *)GRU_INT_MASK = ~(mask >> 16); mb();
break;
+#endif /* ALCOR || XLT */
-#elif NR_IRQS == 33
- default:
- outl(mask >> 16, 0x804);
+#if defined(CONFIG_ALPHA_CABRIOLET) || \
+ defined(CONFIG_ALPHA_EB66P) || \
+ defined(CONFIG_ALPHA_EB164) || \
+ defined(CONFIG_ALPHA_PC164) || \
+ defined(CONFIG_ALPHA_LX164)
+#if defined(CONFIG_ALPHA_SRM)
+ case 16 ... 34:
+ cserve_update_hw(irq, mask);
+ break;
+#else /* SRM */
+ case 16 ... 34:
+ outl(irq_mask >> 16, 0x804);
break;
+#endif /* SRM */
+#endif /* CABRIO || EB66P || EB164 || PC164 || LX164 */
-#elif defined(CONFIG_ALPHA_MIKASA)
- default:
+#if defined(CONFIG_ALPHA_MIKASA)
+ case 16 ... 31:
outw(~(mask >> 16), 0x536); /* note invert */
break;
+#endif /* MIKASA */
-#elif NR_IRQS == 32
+#if defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
case 16 ... 23:
outb(mask >> 16, 0x26);
break;
-
- default:
+ case 24 ... 31:
outb(mask >> 24, 0x27);
break;
-#endif
+#endif /* EB66 || EB64P */
+
/* handle ISA irqs last---fast devices belong on PCI... */
+ /* this is common for all except SABLE! */
case 0 ... 7: /* ISA PIC1 */
outb(mask, 0x21);
@@ -99,7 +210,10 @@
case 8 ...15: /* ISA PIC2 */
outb(mask >> 8, 0xA1);
break;
- }
+
+#endif /* SABLE */
+
+ } /* end switch (irq) */
}
static inline void mask_irq(unsigned long irq)
@@ -120,7 +234,7 @@
save_flags(flags);
cli();
- mask_irq(irq_nr);
+ mask_irq(IRQ_TO_MASK(irq_nr));
restore_flags(flags);
}
@@ -130,7 +244,7 @@
save_flags(flags);
cli();
- unmask_irq(irq_nr);
+ unmask_irq(IRQ_TO_MASK(irq_nr));
restore_flags(flags);
}
@@ -164,7 +278,32 @@
static inline void ack_irq(int irq)
{
+#ifdef CONFIG_ALPHA_SABLE
+ /* note that the "irq" here is really the mask bit number */
+ switch (irq) {
+ case 0 ... 7:
+ outb(0xE0 | (irq - 0), 0x536);
+ outb(0xE0 | 1, 0x534); /* slave 0 */
+ break;
+ case 8 ... 15:
+ outb(0xE0 | (irq - 8), 0x53a);
+ outb(0xE0 | 3, 0x534); /* slave 1 */
+ break;
+ case 16 ... 24:
+ outb(0xE0 | (irq - 16), 0x53c);
+ outb(0xE0 | 4, 0x534); /* slave 2 */
+ break;
+ }
+#else /* CONFIG_ALPHA_SABLE */
if (irq < 16) {
+#if defined(CONFIG_ALPHA_RUFFIAN)
+ /* ack pyxis ISA interrupt */
+ *(unsigned long *)PYXIS_INT_REQ = (0x01UL << 7);
+ if (irq > 7) {
+ outb(0x20,0xa0);
+ }
+ outb(0x20,0x20);
+#else /* RUFFIAN */
/* ACK the interrupt making it the lowest priority */
/* First the slave .. */
if (irq > 7) {
@@ -178,7 +317,16 @@
*(int *)GRU_INT_CLEAR = 0x80000000; mb();
*(int *)GRU_INT_CLEAR = 0x00000000; mb();
#endif /* ALCOR || XLT */
+#endif /* RUFFIAN */
}
+#if defined(CONFIG_ALPHA_RUFFIAN)
+ else {
+ /* ack pyxis int */
+ *(unsigned long *)PYXIS_INT_REQ = (1UL << (irq-16));
+ }
+#endif /* RUFFIAN */
+
+#endif /* CONFIG_ALPHA_SABLE */
}
int request_irq(unsigned int irq,
@@ -236,7 +384,7 @@
*p = action;
if (!shared)
- unmask_irq(irq);
+ unmask_irq(IRQ_TO_MASK(irq));
restore_flags(flags);
return 0;
@@ -264,7 +412,7 @@
cli();
*p = action->next;
if (!irq[irq_action])
- mask_irq(irq);
+ mask_irq(IRQ_TO_MASK(irq));
restore_flags(flags);
kfree(action);
return;
@@ -323,25 +471,39 @@
struct irqaction * action;
if ((unsigned) irq > NR_IRQS) {
- printk("device_interrupt: unexpected interrupt %d\n", irq);
+ printk("device_interrupt: illegal interrupt %d\n", irq);
+ return;
+ }
+
+#if defined(CONFIG_ALPHA_RUFFIAN)
+ /* RUFFIAN uses ISA IRQ #0 to deliver clock ticks */
+ if (irq == 0) {
+ timer_interrupt(regs);
+ ack_irq(0);
return;
}
+#endif /* RUFFIAN */
kstat.interrupts[irq]++;
action = irq_action[irq];
+
/*
* For normal interrupts, we mask it out, and then ACK it.
* This way another (more timing-critical) interrupt can
* come through while we're doing this one.
*
- * Note! A irq without a handler gets masked and acked, but
+ * Note! An irq without a handler gets masked and acked, but
* never unmasked. The autoirq stuff depends on this (it looks
* at the masks before and after doing the probing).
*/
mask_irq(ack);
ack_irq(ack);
- if (!action)
+ if (!action) {
+#if 1
+ printk("device_interrupt: unexpected interrupt %d\n", irq);
+#endif
return;
+ }
if (action->flags & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
do {
@@ -365,6 +527,8 @@
# define IACK_SC LCA_IACK_SC
#elif defined(CONFIG_ALPHA_CIA)
# define IACK_SC CIA_IACK_SC
+#elif defined(CONFIG_ALPHA_PYXIS)
+# define IACK_SC PYXIS_IACK_SC
#else
/*
* This is bogus but necessary to get it to compile
@@ -554,8 +718,185 @@
restore_flags(flags);
}
+#if defined(CONFIG_ALPHA_MIATA) || defined(CONFIG_ALPHA_SX164)
+/* we have to conditionally compile this because of PYXIS_xxx symbols */
+static inline void miata_device_interrupt(unsigned long vector,
+ struct pt_regs * regs)
+{
+ unsigned long pld, tmp;
+ unsigned int i;
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+
+ /* read the interrupt summary register of PYXIS */
+ pld = (*(volatile unsigned long *)PYXIS_INT_REQ);
+
+#if 0
+ printk("[0x%08lx/0x%08lx/0x%04x]", pld,
+ *(volatile unsigned long *)PYXIS_INT_MASK,
+ inb(0x20) | (inb(0xA0) << 8));
+#endif
+
+#ifdef CONFIG_ALPHA_MIATA
+ /* for now, AND off any bits we are not interested in: */
+ /* HALT (2), timer (6), ISA Bridge (7), 21142 (8) */
+ /* then all the PCI slots/INTXs (12-31) */
+/* maybe HALT should only be used for SRM console boots? */
+ pld &= 0x00000000fffff9c4UL;
+#endif /* MIATA */
+#ifdef CONFIG_ALPHA_SX164
+ /* for now, AND off any bits we are not interested in: */
+ /* HALT (2), timer (6), ISA Bridge (7) */
+ /* then all the PCI slots/INTXs (8-23) */
+/* HALT should only be used for SRM console boots */
+ pld &= 0x0000000000ffffc0UL;
+#endif /* SX164 */
+
+ /*
+ * 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 == 7) {
+ isa_device_interrupt(vector, regs);
+ } else if (i == 6)
+ continue;
+ else { /* if not timer int */
+ device_interrupt(16 + i, 16 + i, regs);
+ }
+ *(unsigned long *)PYXIS_INT_REQ = 1UL << i; mb();
+ tmp = *(volatile unsigned long *)PYXIS_INT_REQ;
+ }
+ restore_flags(flags);
+}
+#endif /* MIATA || SX164 */
+
+static inline void noritake_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 registers */
+ /* read the interrupt summary registers of NORITAKE */
+ pld = ((unsigned long) inw(0x544) << 32) |
+ ((unsigned long) inw(0x542) << 16) |
+ ((unsigned long) inb(0xa0) << 8) |
+ ((unsigned long) inb(0x20));
+
+#if 0
+ printk("[0x%08lx]", pld);
+#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 < 16) {
+ isa_device_interrupt(vector, regs);
+ } else {
+ device_interrupt(i, i, regs);
+ }
+ }
+ restore_flags(flags);
+}
+
#endif /* CONFIG_PCI */
+#if defined(CONFIG_ALPHA_RUFFIAN)
+static inline void ruffian_device_interrupt(unsigned long vector,
+ struct pt_regs * regs)
+
+{
+ unsigned long pld, tmp;
+ unsigned int i;
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+
+ /* read the interrupt summary register of PYXIS */
+ pld = (*(volatile unsigned long *)PYXIS_INT_REQ);
+
+ /* for now, AND off any bits we are not interested in:
+ * HALT (2), timer (6), ISA Bridge (7), 21142 (8)
+ * then all the PCI slots/INTXs (12-31)
+ * flash(5) :DWH:
+ */
+ pld &= 0x00000000ffffff9fUL;/* was ffff7f */
+
+ /*
+ * 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 == 7) {
+ isa_device_interrupt(vector, regs);
+ } else { /* if not timer int */
+ device_interrupt(16 + i,16 + i,regs);
+ }
+ *(unsigned long *)PYXIS_INT_REQ = 1UL << i; mb();
+ tmp = *(volatile unsigned long *)PYXIS_INT_REQ;
+ }
+ restore_flags(flags);
+}
+#endif /* RUFFIAN */
+
+static inline void takara_device_interrupt(unsigned long vector,
+ struct pt_regs * regs)
+{
+ unsigned long flags;
+ unsigned intstatus;
+
+ save_flags(flags);
+ cli();
+
+ /*
+ * The PALcode will have passed us vectors 0x800 or 0x810,
+ * which are fairly arbitrary values and serve only to tell
+ * us whether an interrupt has come in on IRQ0 or IRQ1. If
+ * it's IRQ1 it's a PCI interrupt; if it's IRQ0, it's
+ * probably ISA, but PCI interrupts can come through IRQ0
+ * as well if the interrupt controller isn't in accelerated
+ * mode.
+ *
+ * OTOH, the accelerator thing doesn't seem to be working
+ * overly well, so what we'll do instead is try directly
+ * examining the Master Interrupt Register to see if it's a
+ * PCI interrupt, and if _not_ then we'll pass it on to the
+ * ISA handler.
+ */
+
+ intstatus = inw(0x500) & 15;
+ if (intstatus) {
+ /*
+ * This is a PCI interrupt. Check each bit and
+ * despatch an interrupt if it's set.
+ */
+ if (intstatus & 8) device_interrupt(16+3, 16+3, regs);
+ if (intstatus & 4) device_interrupt(16+2, 16+2, regs);
+ if (intstatus & 2) device_interrupt(16+1, 16+1, regs);
+ if (intstatus & 1) device_interrupt(16+0, 16+0, regs);
+ } else
+ isa_device_interrupt (vector, regs);
+
+ restore_flags(flags);
+}
+
/*
* Jensen is special: the vector is 0x8X0 for EISA interrupt X, and
* 0x9X0 for the local motherboard interrupts..
@@ -587,6 +928,9 @@
save_flags(flags);
cli();
+#if 0
+printk("srm_device_interrupt: vector 0x%lx\n", vector);
+#endif
ack = irq = (vector - 0x800) >> 4;
@@ -608,11 +952,69 @@
irq = 7;
#endif /* CONFIG_ALPHA_JENSEN */
+#ifdef CONFIG_ALPHA_MIATA
+ /*
+ * I really hate to do this, but the MIATA SRM console ignores the
+ * low 8 bits in the interrupt summary register, and reports the
+ * vector 0x80 *lower* than I expected from the bit numbering in
+ * the documentation.
+ * This was done because the low 8 summary bits really aren't used
+ * for reporting any interrupts (the PCI-ISA bridge, bit 7, isn't
+ * used for this purpose, as PIC interrupts are delivered as the
+ * vectors 0x800-0x8f0).
+ * But I really don't want to change the fixup code for allocation
+ * of IRQs, nor the irq_mask maintenance stuff, both of which look
+ * nice and clean now.
+ * So, here's this grotty hack... :-(
+ */
+ if (irq >= 16)
+ ack = irq = irq + 8;
+#endif /* CONFIG_ALPHA_MIATA */
+
+#ifdef CONFIG_ALPHA_NORITAKE
+ /*
+ * I really hate to do this, but the NORITAKE SRM console reports
+ * PCI vectors *lower* than I expected from the bit numbering in
+ * the documentation.
+ * But I really don't want to change the fixup code for allocation
+ * of IRQs, nor the irq_mask maintenance stuff, both of which look
+ * nice and clean now.
+ * So, here's this grotty hack... :-(
+ */
+ if (irq >= 16)
+ ack = irq = irq + 1;
+#endif /* CONFIG_ALPHA_NORITAKE */
+
+#ifdef CONFIG_ALPHA_SABLE
+ irq = sable_mask_to_irq[(ack)];
+#if 0
+ if (irq == 5 || irq == 9 || irq == 10 || irq == 11 ||
+ irq == 14 || irq == 15)
+ printk("srm_device_interrupt: vector=0x%lx ack=0x%x irq=0x%x\n",
+ vector, ack, irq);
+#endif
+#endif /* CONFIG_ALPHA_SABLE */
+
device_interrupt(irq, ack, regs);
restore_flags(flags) ;
}
+/* PROBE_MASK is the bitset of irqs that we consider for autoprobing: */
+#if defined(CONFIG_ALPHA_P2K)
+ /* always mask out unused timer irq 0 and RTC irq 8 */
+# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~0x101UL)
+#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
+ /* always mask out unused timer irq 0, "irqs" 20-30, and the EISA cascade: */
+# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~0xfff000000001UL)
+#elif defined(CONFIG_ALPHA_RUFFIAN)
+ /* must leave timer irq 0 in the mask */
+# define PROBE_MASK ((1UL << NR_IRQS) - 1)
+#else
+ /* always mask out unused timer irq 0: */
+# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~1UL)
+#endif
+
/*
* Start listening for interrupts..
*/
@@ -624,10 +1026,13 @@
unsigned int i;
for (i = NR_IRQS - 1; i > 0; i--) {
+ if (!(PROBE_MASK & (1UL << i))) {
+ continue;
+ }
action = irq_action[i];
if (!action) {
enable_irq(i);
- irqs |= (1 << i);
+ irqs |= (1UL << i);
}
}
/*
@@ -650,10 +1055,7 @@
{
int i;
- irqs &= irq_mask & ~1; /* always mask out irq 0---it's the unused timer */
-#ifdef CONFIG_ALPHA_P2K
- irqs &= ~(1 << 8); /* mask out irq 8 since that's the unused RTC input to PIC */
-#endif
+ irqs &= irq_mask;
if (!irqs)
return 0;
i = ffz(~irqs);
@@ -676,6 +1078,14 @@
extern void cia_machine_check(unsigned long vector, unsigned long la,
struct pt_regs * regs);
cia_machine_check(vector, la, regs);
+#elif defined(CONFIG_ALPHA_PYXIS)
+ extern void pyxis_machine_check(unsigned long vector, unsigned long la,
+ struct pt_regs * regs);
+ pyxis_machine_check(vector, la, regs);
+#elif defined(CONFIG_ALPHA_T2)
+ extern void t2_machine_check(unsigned long vector, unsigned long la,
+ struct pt_regs * regs);
+ t2_machine_check(vector, la, regs);
#else
printk("Machine check\n");
#endif
@@ -685,6 +1095,9 @@
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs regs)
{
+#if 0
+printk("do_entInt: type 0x%lx\n", type);
+#endif
switch (type) {
case 0:
printk("Interprocessor interrupt? You must be kidding\n");
@@ -699,17 +1112,30 @@
#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
+#else /* everyone else */
+
+#if defined(CONFIG_ALPHA_MIATA) || defined(CONFIG_ALPHA_SX164)
+ miata_device_interrupt(vector, ®s);
+#elif defined(CONFIG_ALPHA_NORITAKE)
+ noritake_device_interrupt(vector, ®s);
+#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
alcor_and_xlt_device_interrupt(vector, ®s);
-#elif NR_IRQS == 33
+#elif defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P) || \
+ defined(CONFIG_ALPHA_EB164) || defined(CONFIG_ALPHA_PC164) || \
+ defined(CONFIG_ALPHA_LX164)
cabriolet_and_eb66p_device_interrupt(vector, ®s);
#elif defined(CONFIG_ALPHA_MIKASA)
mikasa_device_interrupt(vector, ®s);
-#elif NR_IRQS == 32
+#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
eb66_and_eb64p_device_interrupt(vector, ®s);
+#elif defined(CONFIG_ALPHA_RUFFIAN)
+ ruffian_device_interrupt(vector, ®s);
+#elif defined(CONFIG_ALPHA_TAKARA)
+ takara_device_interrupt(vector, ®s);
#elif NR_IRQS == 16
isa_device_interrupt(vector, ®s);
#endif
+#endif /* everyone else */
return;
case 4:
printk("Performance counter interrupt\n");
@@ -724,23 +1150,141 @@
void init_IRQ(void)
{
+ unsigned int temp;
+
wrent(entInt, 0);
- dma_outb(0, DMA1_RESET_REG);
- dma_outb(0, DMA2_RESET_REG);
- dma_outb(0, DMA1_CLR_MASK_REG);
- dma_outb(0, DMA2_CLR_MASK_REG);
-#if NR_IRQS == 48
+
+ outb(0, DMA1_RESET_REG);
+ outb(0, DMA2_RESET_REG);
+
+/* FIXME FIXME FIXME FIXME FIXME */
+#if !defined(CONFIG_ALPHA_SX164)
+ outb(0, DMA1_CLR_MASK_REG);
+ /* we need to figure out why this fails on the SX164 */
+ outb(0, DMA2_CLR_MASK_REG);
+#endif /* !SX164 */
+/* end FIXMEs */
+
+#if defined(CONFIG_ALPHA_SABLE)
+ outb(irq_mask , 0x537); /* slave 0 */
+ outb(irq_mask >> 8, 0x53b); /* slave 1 */
+ outb(irq_mask >> 16, 0x53d); /* slave 2 */
+ outb(0x44, 0x535); /* enable cascades in master */
+#else /* everybody but SABLE */
+
+#if defined(CONFIG_ALPHA_MIATA)
+ /* note invert on MASK bits */
+ *(unsigned long *)PYXIS_INT_MASK =
+ ~((long)irq_mask >> 16) & ~0x400000000000063bUL; mb();
+#if 0
+ /* these break on MiataGL so we'll try not to do it at all */
+ *(unsigned long *)PYXIS_INT_HILO = 0x000000B2UL; mb();/* ISA/NMI HI */
+ *(unsigned long *)PYXIS_RT_COUNT = 0UL; mb();/* clear count */
+#endif
+ /* clear upper timer */
+ *(unsigned long *)PYXIS_INT_REQ = 0x4000000000000180UL; mb();
+
+ /* Send -INTA pulses to clear any pending interrupts ...*/
+ temp = *(volatile unsigned int *) IACK_SC;
+
+ enable_irq(16 + 2); /* enable HALT switch - SRM only? */
+ enable_irq(16 + 6); /* enable timer */
+ enable_irq(16 + 7); /* enable ISA PIC cascade */
+#endif /* MIATA */
+
+#if defined(CONFIG_ALPHA_SX164)
+#if !defined(CONFIG_ALPHA_SRM)
+ /* note invert on MASK bits */
+ *(unsigned long *)PYXIS_INT_MASK = ~((long)irq_mask >> 16); mb();
+#if 0
+ *(unsigned long *)PYXIS_INT_HILO = 0x000000B2UL; mb();/* ISA/NMI HI */
+ *(unsigned long *)PYXIS_RT_COUNT = 0UL; mb();/* clear count */
+#endif
+#endif /* !SRM */
+ enable_irq(16 + 6); /* enable timer */
+ enable_irq(16 + 7); /* enable ISA PIC cascade */
+#endif /* SX164 */
+
+#if defined(CONFIG_ALPHA_NORITAKE)
+ outw(~(irq_mask >> 16), 0x54a); /* note invert */
+ outw(~(irq_mask >> 32), 0x54c); /* note invert */
+#endif /* NORITAKE */
+
+#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
*(unsigned int *)GRU_INT_MASK = ~(irq_mask >> 16); mb();/* invert */
+ *(unsigned int *)GRU_INT_EDGE = 0UL; mb();/* all are level */
+ *(unsigned int *)GRU_INT_HILO = 0x80000000UL; mb();/* ISA only HI */
+ *(unsigned int *)GRU_INT_CLEAR = 0UL; mb();/* all clear */
enable_irq(16 + 31); /* enable (E)ISA PIC cascade */
-#elif NR_IRQS == 33
+#endif /* ALCOR || XLT */
+
+#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P) || \
+ defined(CONFIG_ALPHA_PC164) || defined(CONFIG_ALPHA_LX164) || \
+ defined(CONFIG_ALPHA_EB164)
+#if !defined(CONFIG_ALPHA_SRM)
outl(irq_mask >> 16, 0x804);
+#endif /* !SRM */
+ /* Send -INTA pulses to clear any pending interrupts ...*/
+ temp = *(volatile unsigned int *) IACK_SC;
enable_irq(16 + 4); /* enable SIO cascade */
-#elif defined(CONFIG_ALPHA_MIKASA)
+#endif /* CABRIO || EB66P || PC164 || LX164 || EB164 */
+
+#if defined(CONFIG_ALPHA_MIKASA)
outw(~(irq_mask >> 16), 0x536); /* note invert */
-#elif NR_IRQS == 32
+#endif /* MIKASA */
+
+#if defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
outb(irq_mask >> 16, 0x26);
outb(irq_mask >> 24, 0x27);
enable_irq(16 + 5); /* enable SIO cascade */
-#endif
- enable_irq(2); /* enable cascade */
+#endif /* EB66 || EB64P */
+
+#if defined(CONFIG_ALPHA_RUFFIAN)
+ /* invert 6&7 for i82371 */
+ *(unsigned long *)PYXIS_INT_HILO = 0x000000c0UL;mb();
+ *(unsigned long *)PYXIS_INT_CNFG = 0x00002064UL;mb(); /* all clear */
+ *(unsigned long *)PYXIS_INT_MASK = ((long)0x00000000UL);mb();
+ *(unsigned long *)PYXIS_INT_REQ = 0xffffffffUL;mb();
+
+ outb(0x11,0xA0);
+ outb(0x08,0xA1);
+ outb(0x02,0xA1);
+ outb(0x01,0xA1);
+ outb(0xFF,0xA1);
+
+ outb(0x11,0x20);
+ outb(0x00,0x21);
+ outb(0x04,0x21);
+ outb(0x01,0x21);
+ outb(0xFF,0x21);
+
+ /* Send -INTA pulses to clear any pending interrupts ...*/
+ temp = *(volatile unsigned int *) IACK_SC;
+
+ /* Finish writing the 82C59A PIC Operation Control Words */
+ outb(0x20,0xA0);
+ outb(0x20,0x20);
+
+ /* Turn on the interrupt controller, the timer interrupt */
+ enable_irq(16 + 7); /* enable ISA PIC cascade */
+ enable_irq(0); /* enable timer */
+#endif /* RUFFIAN */
+
+#ifdef CONFIG_ALPHA_TAKARA
+ {
+ unsigned int ctlreg = inl(0x500);
+ ctlreg &= ~0x8000; /* return to non-accelerated mode */
+ outw(ctlreg >> 16, 0x502);
+ outw(ctlreg & 0xFFFF, 0x500);
+ ctlreg = 0x05107c00; /* enable the PCI interrupt register */
+ printk("Setting to 0x%08x\n", ctlreg);
+ outw(ctlreg >> 16, 0x502);
+ outw(ctlreg & 0xFFFF, 0x500);
+ }
+#endif /* TAKARA */
+
+ /* and finally, everyone but SABLE does this */
+ enable_irq(2); /* enable 2nd PIC cascade */
+
+#endif /* SABLE */
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov