X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Fmips-boards%2Fatlas%2Fatlas_int.c;h=bc0ebc69bfb3f4b9a2078bbb31c71a437f1558f0;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=db53950b7cfbae7bd9e8936ede6fd6f6f5c64882;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c index db53950b7..bc0ebc69b 100644 --- a/arch/mips/mips-boards/atlas/atlas_int.c +++ b/arch/mips/mips-boards/atlas/atlas_int.c @@ -39,6 +39,8 @@ static struct atlas_ictrl_regs *atlas_hw0_icregs; +extern asmlinkage void mipsIRQ(void); + #if 0 #define DEBUG_INT(x...) printk(x) #else @@ -96,7 +98,7 @@ static inline int ls1bit32(unsigned int x) return b; } -static inline void atlas_hw0_irqdispatch(struct pt_regs *regs) +void atlas_hw0_irqdispatch(struct pt_regs *regs) { unsigned long int_status; int irq; @@ -114,91 +116,6 @@ static inline void atlas_hw0_irqdispatch(struct pt_regs *regs) do_IRQ(irq, regs); } -static inline int clz(unsigned long x) -{ - __asm__ ( - " .set push \n" - " .set mips32 \n" - " clz %0, %1 \n" - " .set pop \n" - : "=r" (x) - : "r" (x)); - - return x; -} - -/* - * Version of ffs that only looks at bits 12..15. - */ -static inline unsigned int irq_ffs(unsigned int pending) -{ -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - return -clz(pending) + 31 - CAUSEB_IP; -#else - unsigned int a0 = 7; - unsigned int t0; - - t0 = s0 & 0xf000; - t0 = t0 < 1; - t0 = t0 << 2; - a0 = a0 - t0; - s0 = s0 << t0; - - t0 = s0 & 0xc000; - t0 = t0 < 1; - t0 = t0 << 1; - a0 = a0 - t0; - s0 = s0 << t0; - - t0 = s0 & 0x8000; - t0 = t0 < 1; - //t0 = t0 << 2; - a0 = a0 - t0; - //s0 = s0 << t0; - - return a0; -#endif -} - -/* - * IRQs on the Atlas board look basically (barring software IRQs which we - * don't use at all and all external interrupt sources are combined together - * on hardware interrupt 0 (MIPS IRQ 2)) like: - * - * MIPS IRQ Source - * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 Combined hardware interrupt (hw0) - * 3 Hardware (ignored) - * 4 Hardware (ignored) - * 5 Hardware (ignored) - * 6 Hardware (ignored) - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Lowest ---- Combined hardware interrupt - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. - */ -asmlinkage void plat_irq_dispatch(struct pt_regs *regs) -{ - unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; - int irq; - - irq = irq_ffs(pending); - - if (irq == MIPSCPU_INT_ATLAS) - atlas_hw0_irqdispatch(regs); - else if (irq > 0) - do_IRQ(MIPSCPU_INT_BASE + irq, regs); - else - spurious_interrupt(regs); -} - void __init arch_init_irq(void) { int i; @@ -211,6 +128,9 @@ void __init arch_init_irq(void) */ atlas_hw0_icregs->intrsten = 0xffffffff; + /* Now safe to set the exception vector. */ + set_except_vector(0, mipsIRQ); + for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0;