patch-2.2.8 linux/include/asm-arm/arch-ebsa285/irq.h
Next file: linux/include/asm-arm/arch-ebsa285/irqs.h
Previous file: linux/include/asm-arm/arch-ebsa285/io.h
Back to the patch index
Back to the overall index
- Lines: 301
- Date:
Mon May 10 10:17:28 1999
- Orig file:
v2.2.7/linux/include/asm-arm/arch-ebsa285/irq.h
- Orig date:
Fri Jan 8 22:36:21 1999
diff -u --recursive --new-file v2.2.7/linux/include/asm-arm/arch-ebsa285/irq.h linux/include/asm-arm/arch-ebsa285/irq.h
@@ -4,136 +4,206 @@
* Copyright (C) 1996-1998 Russell King
*
* Changelog:
- * 22-08-1998 RMK Restructured IRQ routines
- * 03-09-1998 PJB Merged CATS support
+ * 22-Aug-1998 RMK Restructured IRQ routines
+ * 03-Sep-1998 PJB Merged CATS support
+ * 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder
+ * 26-Jan-1999 PJB Don't use IACK on CATS
+ * 16-Mar-1999 RMK Added autodetect of ISA PICs
*/
#include <linux/config.h>
+#include <asm/hardware.h>
+#include <asm/dec21285.h>
+#include <asm/irq.h>
-static void ebsa285_mask_irq(unsigned int irq)
+/*
+ * Footbridge IRQ translation table
+ * Converts from our IRQ numbers into FootBridge masks
+ */
+static int dc21285_irq_mask[] = {
+ IRQ_MASK_UART_RX, /* 0 */
+ IRQ_MASK_UART_TX, /* 1 */
+ IRQ_MASK_TIMER1, /* 2 */
+ IRQ_MASK_TIMER2, /* 3 */
+ IRQ_MASK_TIMER3, /* 4 */
+ IRQ_MASK_IN0, /* 5 */
+ IRQ_MASK_IN1, /* 6 */
+ IRQ_MASK_IN2, /* 7 */
+ IRQ_MASK_IN3, /* 8 */
+ IRQ_MASK_DOORBELLHOST, /* 9 */
+ IRQ_MASK_DMA1, /* 10 */
+ IRQ_MASK_DMA2, /* 11 */
+ IRQ_MASK_PCI, /* 12 */
+ IRQ_MASK_SDRAMPARITY, /* 13 */
+ IRQ_MASK_I2OINPOST, /* 14 */
+ IRQ_MASK_PCI_ERR /* 15 */
+};
+
+static int isa_irq = -1;
+
+static inline int fixup_irq(unsigned int irq)
+{
+#ifdef CONFIG_HOST_FOOTBRIDGE
+ if (irq == isa_irq)
+ irq = *(unsigned char *)PCIIACK_BASE;
+#endif
+
+ return irq;
+}
+
+static void dc21285_mask_irq(unsigned int irq)
{
- *CSR_IRQ_DISABLE = 1 << irq;
+ *CSR_IRQ_DISABLE = dc21285_irq_mask[irq & 15];
}
-static void ebsa285_unmask_irq(unsigned int irq)
+static void dc21285_unmask_irq(unsigned int irq)
{
- *CSR_IRQ_ENABLE = 1 << irq;
+ *CSR_IRQ_ENABLE = dc21285_irq_mask[irq & 15];
}
-#ifdef CONFIG_CATS
+static void isa_mask_pic_lo_irq(unsigned int irq)
+{
+ unsigned int mask = 1 << (irq & 7);
-/*
- * This contains the irq mask for both 8259A irq controllers,
- */
-static unsigned int isa_irq_mask = 0xffff;
+ outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
+}
-#define cached_21 (isa_irq_mask & 0xff)
-#define cached_A1 ((isa_irq_mask >> 8) & 0xff)
+static void isa_mask_ack_pic_lo_irq(unsigned int irq)
+{
+ unsigned int mask = 1 << (irq & 7);
-#define update_8259(_irq) \
- if ((_irq) & 8) \
- outb(cached_A1, 0xa1); \
- else \
- outb(cached_21, 0x21);
-
-static void isa_interrupt(int irq, void *h, struct pt_regs *regs)
-{
- asmlinkage void do_IRQ(int irq, struct pt_regs * regs);
- unsigned int irqbits = inb(0x20) | (inb(0xa0) << 8), irqnr = 0;
- irqbits &= ~(1<<2); /* don't try to service the cascade */
- while (irqbits) {
- if (irqbits & 1)
- do_IRQ(32 + irqnr, regs);
- irqbits >>= 1;
- irqnr++;
- }
+ outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
+ outb(0x20, PIC_LO);
}
-static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+static void isa_unmask_pic_lo_irq(unsigned int irq)
+{
+ unsigned int mask = 1 << (irq & 7);
+
+ outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO);
+}
-static struct irqaction irq_isa =
- { isa_interrupt, SA_INTERRUPT, 0, "ISA PIC", NULL, NULL };
-static struct irqaction irq_cascade =
- { no_action, 0, 0, "cascade", NULL, NULL };
-
-static void cats_mask_and_ack_isa_irq(unsigned int irq)
-{
- isa_irq_mask |= (1 << (irq - 32));
- update_8259(irq);
- if (irq & 8) {
- inb(0xA1); /* DUMMY */
- outb(cached_A1,0xA1);
- outb(0x62,0x20); /* Specific EOI to cascade */
- outb(0x20,0xA0);
- } else {
- inb(0x21); /* DUMMY */
- outb(cached_21,0x21);
- outb(0x20,0x20);
- }
+static void isa_mask_pic_hi_irq(unsigned int irq)
+{
+ unsigned int mask = 1 << (irq & 7);
+
+ outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
}
-static void cats_mask_isa_irq(unsigned int irq)
+static void isa_mask_ack_pic_hi_irq(unsigned int irq)
{
- isa_irq_mask |= (1 << (irq - 32));
- update_8259(irq);
+ unsigned int mask = 1 << (irq & 7);
+
+ outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
+ outb(0x62, PIC_LO);
+ outb(0x20, PIC_HI);
}
-static void cats_unmask_isa_irq(unsigned int irq)
+static void isa_unmask_pic_hi_irq(unsigned int irq)
{
- isa_irq_mask &= ~(1 << (irq - 32));
- update_8259(irq);
+ unsigned int mask = 1 << (irq & 7);
+
+ outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
}
-
-#endif
+
+static void no_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+}
+
+static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL };
static __inline__ void irq_init_irq(void)
{
int irq;
+ /*
+ * setup DC21285 IRQs
+ */
*CSR_IRQ_DISABLE = -1;
*CSR_FIQ_DISABLE = -1;
- for (irq = 0; irq < NR_IRQS; irq++) {
+ for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(16); irq++) {
irq_desc[irq].valid = 1;
irq_desc[irq].probe_ok = 1;
-#ifdef CONFIG_CATS
- if (machine_is_cats() && IRQ_IS_ISA(irq)) {
- irq_desc[irq].mask_ack = cats_mask_and_ack_isa_irq;
- irq_desc[irq].mask = cats_mask_isa_irq;
- irq_desc[irq].unmask = cats_unmask_isa_irq;
+ irq_desc[irq].mask_ack = dc21285_mask_irq;
+ irq_desc[irq].mask = dc21285_mask_irq;
+ irq_desc[irq].unmask = dc21285_unmask_irq;
+ }
+
+ /*
+ * Determine the ISA settings for
+ * the machine we're running on.
+ */
+ switch (machine_arch_type) {
+ default:
+ isa_irq = -1;
+ break;
+
+ case MACH_TYPE_EBSA285:
+ /* The following is dependent on which slot
+ * you plug the Southbridge card into. We
+ * currently assume that you plug it into
+ * the right-hand most slot.
+ */
+ isa_irq = IRQ_PCI;
+ break;
+
+ case MACH_TYPE_CATS:
+ isa_irq = IRQ_IN2;
+ break;
+
+ case MACH_TYPE_NETWINDER:
+ isa_irq = IRQ_IN3;
+ break;
+ }
+
+ if (isa_irq != -1) {
+ /*
+ * Setup, and then probe for an ISA PIC
+ */
+ outb(0x11, PIC_LO);
+ outb(_ISA_IRQ(0), PIC_MASK_LO); /* IRQ number */
+ outb(0x04, PIC_MASK_LO); /* Slave on Ch2 */
+ outb(0x01, PIC_MASK_LO); /* x86 */
+ outb(0xf5, PIC_MASK_LO); /* pattern: 11110101 */
+
+ outb(0x11, PIC_HI);
+ outb(_ISA_IRQ(8), PIC_MASK_HI); /* IRQ number */
+ outb(0x02, PIC_MASK_HI); /* Slave on Ch1 */
+ outb(0x01, PIC_MASK_HI); /* x86 */
+ outb(0xfa, PIC_MASK_HI); /* pattern: 11111010 */
+
+// outb(0x68, PIC_LO); /* enable special mode */
+// outb(0x68, PIC_HI); /* enable special mode */
+ outb(0x0b, PIC_LO);
+ outb(0x0b, PIC_HI);
+
+ if (inb(PIC_MASK_LO) == 0xf5 && inb(PIC_MASK_HI) == 0xfa) {
+ outb(0xff, PIC_MASK_LO);/* mask all IRQs */
+ outb(0xff, PIC_MASK_HI);/* mask all IRQs */
} else
-#endif
- {
- irq_desc[irq].mask_ack = ebsa285_mask_irq;
- irq_desc[irq].mask = ebsa285_mask_irq;
- irq_desc[irq].unmask = ebsa285_unmask_irq;
- }
+ isa_irq = -1;
}
-#ifdef CONFIG_CATS
- if (machine_is_cats()) {
- request_region(0x20, 2, "pic1");
- request_region(0xa0, 2, "pic2");
-
- /* set up master 8259 */
- outb(0x11, 0x20);
- outb(0, 0x21);
- outb(1<<2, 0x21);
- outb(0x1, 0x21);
- outb(0xff, 0x21);
- outb(0x68, 0x20);
- outb(0xa, 0x20);
-
- /* set up slave 8259 */
- outb(0x11, 0xa0);
- outb(0, 0xa1);
- outb(2, 0xa1);
- outb(0x1, 0xa1);
- outb(0xff, 0xa1);
- outb(0x68, 0xa0);
- outb(0xa, 0xa0);
+ if (isa_irq != -1) {
+ for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) {
+ irq_desc[irq].valid = 1;
+ irq_desc[irq].probe_ok = 1;
+ irq_desc[irq].mask_ack = isa_mask_ack_pic_lo_irq;
+ irq_desc[irq].mask = isa_mask_pic_lo_irq;
+ irq_desc[irq].unmask = isa_unmask_pic_lo_irq;
+ }
+
+ for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) {
+ irq_desc[irq].valid = 1;
+ irq_desc[irq].probe_ok = 1;
+ irq_desc[irq].mask_ack = isa_mask_ack_pic_hi_irq;
+ irq_desc[irq].mask = isa_mask_pic_hi_irq;
+ irq_desc[irq].unmask = isa_unmask_pic_hi_irq;
+ }
- setup_arm_irq(IRQ_ISA_PIC, &irq_isa);
+ request_region(PIC_LO, 2, "pic1");
+ request_region(PIC_HI, 2, "pic2");
setup_arm_irq(IRQ_ISA_CASCADE, &irq_cascade);
+ setup_arm_irq(isa_irq, &irq_cascade);
}
-#endif
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)