X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Fsgi-ip32%2Fip32-irq.c;h=2eb22d692ed9bef6293f5345b68cdd0c6ba6e3c5;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=8ba08047d164222b31bf6315b66fb51603d3a93a;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 8ba08047d..2eb22d692 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -31,12 +31,12 @@ /* issue a PIO read to make sure no PIO writes are pending */ static void inline flush_crime_bus(void) { - crime->control; + volatile unsigned long junk = crime->control; } static void inline flush_mace_bus(void) { - mace->perif.ctrl.misc; + volatile unsigned long junk = mace->perif.ctrl.misc; } #undef DEBUG_IRQ @@ -130,6 +130,8 @@ struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, CPU_MASK_NONE, "CRIME CPU error", NULL, NULL }; +extern void ip32_handle_int(void); + /* * For interrupts wired from a single device to the CPU. Only the clock * uses this it seems, which is IRQ 0 and IP7. @@ -501,67 +503,48 @@ static void ip32_unknown_interrupt(struct pt_regs *regs) /* CRIME 1.1 appears to deliver all interrupts to this one pin. */ /* change this to loop over all edge-triggered irqs, exception masked out ones */ -static void ip32_irq0(struct pt_regs *regs) +void ip32_irq0(struct pt_regs *regs) { uint64_t crime_int; int irq = 0; crime_int = crime->istat & crime_mask; - irq = __ffs(crime_int); - crime_int = 1 << irq; + irq = ffs(crime_int); + crime_int = 1 << (irq - 1); if (crime_int & CRIME_MACEISA_INT_MASK) { unsigned long mace_int = mace->perif.ctrl.istat; - irq = __ffs(mace_int & maceisa_mask) + 32; + irq = ffs(mace_int & maceisa_mask) + 32; } - irq++; DBG("*irq %u*\n", irq); do_IRQ(irq, regs); } -static void ip32_irq1(struct pt_regs *regs) +void ip32_irq1(struct pt_regs *regs) { ip32_unknown_interrupt(regs); } -static void ip32_irq2(struct pt_regs *regs) +void ip32_irq2(struct pt_regs *regs) { ip32_unknown_interrupt(regs); } -static void ip32_irq3(struct pt_regs *regs) +void ip32_irq3(struct pt_regs *regs) { ip32_unknown_interrupt(regs); } -static void ip32_irq4(struct pt_regs *regs) +void ip32_irq4(struct pt_regs *regs) { ip32_unknown_interrupt(regs); } -static void ip32_irq5(struct pt_regs *regs) +void ip32_irq5(struct pt_regs *regs) { ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs); } -asmlinkage void plat_irq_dispatch(struct pt_regs *regs) -{ - unsigned int pending = read_c0_cause(); - - if (likely(pending & IE_IRQ0)) - ip32_irq0(regs); - else if (unlikely(pending & IE_IRQ1)) - ip32_irq1(regs); - else if (unlikely(pending & IE_IRQ2)) - ip32_irq2(regs); - else if (unlikely(pending & IE_IRQ3)) - ip32_irq3(regs); - else if (unlikely(pending & IE_IRQ4)) - ip32_irq4(regs); - else if (likely(pending & IE_IRQ5)) - ip32_irq5(regs); -} - void __init arch_init_irq(void) { unsigned int irq; @@ -573,6 +556,7 @@ void __init arch_init_irq(void) crime->soft_int = 0; mace->perif.ctrl.istat = 0; mace->perif.ctrl.imask = 0; + set_except_vector(0, ip32_handle_int); for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { hw_irq_controller *controller;