X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Fddb5xxx%2Fddb5477%2Firq.c;h=a8bd2e66705ce3fda7885426903ee4a4da98d2e6;hb=refs%2Fheads%2Fvserver;hp=0ae83365fe756e8833f4fc9c6eed44263eedc0b2;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/mips/ddb5xxx/ddb5477/irq.c b/arch/mips/ddb5xxx/ddb5477/irq.c index 0ae83365f..a8bd2e667 100644 --- a/arch/mips/ddb5xxx/ddb5477/irq.c +++ b/arch/mips/ddb5xxx/ddb5477/irq.c @@ -10,7 +10,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ -#include #include #include #include @@ -75,15 +74,10 @@ set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger) extern void vrc5477_irq_init(u32 base); extern void mips_cpu_irq_init(u32 base); -extern asmlinkage void ddb5477_handle_int(void); -extern int setup_irq(unsigned int irq, struct irqaction *irqaction); -static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; +static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; -void -ddb5477_irq_setup(void) +void __init arch_init_irq(void) { - db_run(printk("ddb5477_irq_setup invoked.\n")); - /* by default, we disable all interrupts and route all vrc5477 * interrupts to pin 0 (irq 2) */ ddb_out32(DDB_INTCTRL0, 0); @@ -97,7 +91,7 @@ ddb5477_irq_setup(void) /* setup PCI interrupt attributes */ set_pci_int_attr(PCI0, INTA, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI0, INTB, ACTIVE_LOW, LEVEL_SENSE); - if (mips_machtype == MACH_NEC_ROCKHOPPERII) + if (mips_machtype == MACH_NEC_ROCKHOPPERII) set_pci_int_attr(PCI0, INTC, ACTIVE_HIGH, LEVEL_SENSE); else set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE); @@ -137,10 +131,7 @@ ddb5477_irq_setup(void) /* setup cascade interrupts */ setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade); - setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); - - /* hook up the first-level interrupt handler */ - set_except_vector(0, ddb5477_handle_int); + setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); } u8 i8259_interrupt_ack(void) @@ -162,8 +153,7 @@ u8 i8259_interrupt_ack(void) * the first level int-handler will jump here if it is a vrc5477 irq */ #define NUM_5477_IRQS 32 -asmlinkage void -vrc5477_irq_dispatch(struct pt_regs *regs) +static void vrc5477_irq_dispatch(void) { u32 intStatus; u32 bitmask; @@ -187,7 +177,7 @@ vrc5477_irq_dispatch(struct pt_regs *regs) /* check for i8259 interrupts */ if (intStatus & (1 << VRC5477_I8259_CASCADE)) { int i8259_irq = i8259_interrupt_ack(); - do_IRQ(I8259_IRQ_BASE + i8259_irq, regs); + do_IRQ(I8259_IRQ_BASE + i8259_irq); return; } } @@ -195,8 +185,26 @@ vrc5477_irq_dispatch(struct pt_regs *regs) for (i=0, bitmask=1; i<= NUM_5477_IRQS; bitmask <<=1, i++) { /* do we need to "and" with the int mask? */ if (intStatus & bitmask) { - do_IRQ(VRC5477_IRQ_BASE + i, regs); + do_IRQ(VRC5477_IRQ_BASE + i); return; } } } + +#define VR5477INTS (STATUSF_IP2|STATUSF_IP3|STATUSF_IP4|STATUSF_IP5|STATUSF_IP6) + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_cause() & read_c0_status(); + + if (pending & STATUSF_IP7) + do_IRQ(CPU_IRQ_BASE + 7); + else if (pending & VR5477INTS) + vrc5477_irq_dispatch(); + else if (pending & STATUSF_IP0) + do_IRQ(CPU_IRQ_BASE); + else if (pending & STATUSF_IP1) + do_IRQ(CPU_IRQ_BASE + 1); + else + spurious_interrupt(); +}