diff options
Diffstat (limited to 'include/asm-arm/arch-rpc/irq.h')
-rw-r--r-- | include/asm-arm/arch-rpc/irq.h | 138 |
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); +} |