patch-2.1.132 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/ide.h
Back to the patch index
Back to the overall index
- Lines: 135
- Date:
Thu Dec 17 09:05:43 1998
- Orig file:
v2.1.131/linux/include/asm-arm/arch-ebsa285/irq.h
- Orig date:
Wed Sep 9 14:51:12 1998
diff -u --recursive --new-file v2.1.131/linux/include/asm-arm/arch-ebsa285/irq.h linux/include/asm-arm/arch-ebsa285/irq.h
@@ -5,8 +5,11 @@
*
* Changelog:
* 22-08-1998 RMK Restructured IRQ routines
+ * 03-09-1998 PJB Merged CATS support
*/
+#include <linux/config.h>
+
static void ebsa285_mask_irq(unsigned int irq)
{
*CSR_IRQ_DISABLE = 1 << irq;
@@ -16,7 +19,73 @@
{
*CSR_IRQ_ENABLE = 1 << irq;
}
+
+#ifdef CONFIG_CATS
+
+/*
+ * This contains the irq mask for both 8259A irq controllers,
+ */
+static unsigned int isa_irq_mask = 0xffff;
+
+#define cached_21 (isa_irq_mask & 0xff)
+#define cached_A1 ((isa_irq_mask >> 8) & 0xff)
+
+#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++;
+ }
+}
+
+static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+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 cats_mask_isa_irq(unsigned int irq)
+{
+ isa_irq_mask |= (1 << (irq - 32));
+ update_8259(irq);
+}
+
+static void cats_unmask_isa_irq(unsigned int irq)
+{
+ isa_irq_mask &= ~(1 << (irq - 32));
+ update_8259(irq);
+}
+#endif
+
static __inline__ void irq_init_irq(void)
{
int irq;
@@ -27,8 +96,45 @@
for (irq = 0; irq < NR_IRQS; irq++) {
irq_desc[irq].valid = 1;
irq_desc[irq].probe_ok = 1;
- irq_desc[irq].mask_ack = ebsa285_mask_irq;
- irq_desc[irq].mask = ebsa285_mask_irq;
- irq_desc[irq].unmask = ebsa285_unmask_irq;
+#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;
+ } else
+#endif
+ {
+ irq_desc[irq].mask_ack = ebsa285_mask_irq;
+ irq_desc[irq].mask = ebsa285_mask_irq;
+ irq_desc[irq].unmask = ebsa285_unmask_irq;
+ }
+ }
+
+#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);
+
+ setup_arm_irq(IRQ_ISA_PIC, &irq_isa);
+ setup_arm_irq(IRQ_ISA_CASCADE, &irq_cascade);
}
+#endif
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov