summaryrefslogtreecommitdiffstats
path: root/include/asm-arm/arch-rpc/irq.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-arm/arch-rpc/irq.h')
-rw-r--r--include/asm-arm/arch-rpc/irq.h138
1 files changed, 138 insertions, 0 deletions
diff --git a/include/asm-arm/arch-rpc/irq.h b/include/asm-arm/arch-rpc/irq.h
new file mode 100644
index 000000000..750f5c905
--- /dev/null
+++ b/include/asm-arm/arch-rpc/irq.h
@@ -0,0 +1,138 @@
+/*
+ * include/asm-arm/arch-rpc/irq.h
+ *
+ * Copyright (C) 1996 Russell King
+ *
+ * Changelog:
+ * 10-10-1996 RMK Brought up to date with arch-sa110eval
+ */
+
+#define BUILD_IRQ(s,n,m) \
+ void IRQ##n##_interrupt(void); \
+ void fast_IRQ##n##_interrupt(void); \
+ void bad_IRQ##n##_interrupt(void); \
+ void probe_IRQ##n##_interrupt(void);
+
+/*
+ * The timer is a special interrupt
+ */
+#define IRQ5_interrupt timer_IRQ_interrupt
+
+#define IRQ_INTERRUPT(n) IRQ##n##_interrupt
+#define FAST_INTERRUPT(n) fast_IRQ##n##_interrupt
+#define BAD_INTERRUPT(n) bad_IRQ##n##_interrupt
+#define PROBE_INTERRUPT(n) probe_IRQ##n##_interrupt
+
+#define X(x) (x)|0x01, (x)|0x02, (x)|0x04, (x)|0x08, (x)|0x10, (x)|0x20, (x)|0x40, (x)|0x80
+#define Z(x) (x), (x), (x), (x), (x), (x), (x), (x)
+
+static __inline__ void mask_and_ack_irq(unsigned int irq)
+{
+ static const int addrmasks[] = {
+ X((IOMD_IRQMASKA - IOMD_BASE)<<18 | (1 << 15)),
+ X((IOMD_IRQMASKB - IOMD_BASE)<<18),
+ X((IOMD_DMAMASK - IOMD_BASE)<<18),
+ Z(0),
+ Z(0),
+ Z(0),
+ Z(0),
+ Z(0),
+ X((IOMD_FIQMASK - IOMD_BASE)<<18),
+ Z(0),
+ Z(0),
+ Z(0),
+ Z(0),
+ Z(0),
+ Z(0),
+ Z(0)
+ };
+ unsigned int temp1, temp2;
+
+ __asm__ __volatile__(
+" ldr %1, [%5, %3, lsl #2]\n"
+" teq %1, #0\n"
+" beq 2f\n"
+" ldrb %0, [%2, %1, lsr #16]\n"
+" bic %0, %0, %1\n"
+" strb %0, [%2, %1, lsr #16]\n"
+" tst %1, #0x8000\n" /* do we need an IRQ clear? */
+" strneb %1, [%2, %4]\n"
+"2:"
+ : "=&r" (temp1), "=&r" (temp2)
+ : "r" (ioaddr(IOMD_BASE)), "r" (irq),
+ "I" ((IOMD_IRQCLRA - IOMD_BASE) << 2), "r" (addrmasks));
+}
+
+#undef X
+#undef Z
+
+static __inline__ void mask_irq(unsigned int irq)
+{
+ extern void ecard_disableirq (unsigned int);
+ extern void ecard_disablefiq (unsigned int);
+ unsigned char mask = 1 << (irq & 7);
+
+ switch (irq >> 3) {
+ case 0:
+ outb(inb(IOMD_IRQMASKA) & ~mask, IOMD_IRQMASKA);
+ break;
+ case 1:
+ outb(inb(IOMD_IRQMASKB) & ~mask, IOMD_IRQMASKB);
+ break;
+ case 2:
+ outb(inb(IOMD_DMAMASK) & ~mask, IOMD_DMAMASK);
+ break;
+ case 4:
+ ecard_disableirq (irq & 7);
+ break;
+ case 8:
+ outb(inb(IOMD_FIQMASK) & ~mask, IOMD_FIQMASK);
+ break;
+ case 12:
+ ecard_disablefiq (irq & 7);
+ }
+}
+
+static __inline__ void unmask_irq(unsigned int irq)
+{
+ extern void ecard_enableirq (unsigned int);
+ extern void ecard_enablefiq (unsigned int);
+ unsigned char mask = 1 << (irq & 7);
+
+ switch (irq >> 3) {
+ case 0:
+ outb(inb(IOMD_IRQMASKA) | mask, IOMD_IRQMASKA);
+ break;
+ case 1:
+ outb(inb(IOMD_IRQMASKB) | mask, IOMD_IRQMASKB);
+ break;
+ case 2:
+ outb(inb(IOMD_DMAMASK) | mask, IOMD_DMAMASK);
+ break;
+ case 4:
+ ecard_enableirq (irq & 7);
+ break;
+ case 8:
+ outb(inb(IOMD_FIQMASK) | mask, IOMD_FIQMASK);
+ break;
+ case 12:
+ ecard_enablefiq (irq & 7);
+ }
+}
+
+static __inline__ unsigned long get_enabled_irqs(void)
+{
+ return inb(IOMD_IRQMASKA) | inb(IOMD_IRQMASKB) << 8 | inb(IOMD_DMAMASK) << 16;
+}
+
+static __inline__ void irq_init_irq(void)
+{
+ outb(0, IOMD_IRQMASKA);
+ outb(0, IOMD_IRQMASKB);
+ outb(0, IOMD_FIQMASK);
+ outb(0, IOMD_DMAMASK);
+ outb(0, IOMD_IO0CR);
+ outb(0, IOMD_IO1CR);
+ outb(0, IOMD_IO2CR);
+ outb(0, IOMD_IO3CR);
+}