linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / mips / sibyte / sb1250 / irq.c
index 0f6e54d..589537b 100644 (file)
@@ -163,6 +163,10 @@ static void sb1250_set_affinity(unsigned int irq, cpumask_t mask)
 }
 #endif
 
+
+/* Defined in arch/mips/sibyte/sb1250/irq_handler.S */
+extern void sb1250_irq_handler(void);
+
 /*****************************************************************************/
 
 static unsigned int startup_sb1250_irq(unsigned int irq)
@@ -375,6 +379,7 @@ void __init arch_init_irq(void)
 #endif
        /* Enable necessary IPs, disable the rest */
        change_c0_status(ST0_IM, imask);
+       set_except_vector(0, sb1250_irq_handler);
 
 #ifdef CONFIG_KGDB
        if (kgdb_flag) {
@@ -404,7 +409,7 @@ void __init arch_init_irq(void)
 #define duart_out(reg, val)     csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
 #define duart_in(reg)           csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
 
-static void sb1250_kgdb_interrupt(struct pt_regs *regs)
+void sb1250_kgdb_interrupt(struct pt_regs *regs)
 {
        /*
         * Clear break-change status (allow some time for the remote
@@ -419,74 +424,3 @@ static void sb1250_kgdb_interrupt(struct pt_regs *regs)
 }
 
 #endif         /* CONFIG_KGDB */
-
-static inline int dclz(unsigned long long x)
-{
-       int lz;
-
-       __asm__ (
-       "       .set    push                                            \n"
-       "       .set    mips64                                          \n"
-       "       dclz    %0, %1                                          \n"
-       "       .set    pop                                             \n"
-       : "=r" (lz)
-       : "r" (x));
-
-       return lz;
-}
-
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
-{
-       unsigned int pending;
-
-#ifdef CONFIG_SIBYTE_SB1250_PROF
-       /* Set compare to count to silence count/compare timer interrupts */
-       write_c0_count(read_c0_count());
-#endif
-
-       /*
-        * What a pain. We have to be really careful saving the upper 32 bits
-        * of any * register across function calls if we don't want them
-        * trashed--since were running in -o32, the calling routing never saves
-        * the full 64 bits of a register across a function call.  Being the
-        * interrupt handler, we're guaranteed that interrupts are disabled
-        * during this code so we don't have to worry about random interrupts
-        * blasting the high 32 bits.
-        */
-
-       pending = read_c0_cause();
-
-#ifdef CONFIG_SIBYTE_SB1250_PROF
-       if (pending & CAUSEF_IP7) { /* Cpu performance counter interrupt */
-               sbprof_cpu_intr(exception_epc(regs));
-       }
-#endif
-
-       if (pending & CAUSEF_IP4)
-               sb1250_timer_interrupt(regs);
-
-#ifdef CONFIG_SMP
-       if (pending & CAUSEF_IP3)
-               sb1250_mailbox_interrupt(regs);
-#endif
-
-#ifdef CONFIG_KGDB
-       if (pending & CAUSEF_IP6)                       /* KGDB (uart 1) */
-               sb1250_kgdb_interrupt(regs);
-#endif
-
-       if (pending & CAUSEF_IP2) {
-               unsigned long long mask;
-
-               /*
-                * Default...we've hit an IP[2] interrupt, which means we've
-                * got to check the 1250 interrupt registers to figure out what
-                * to do.  Need to detect which CPU we're on, now that
-                ~ smp_affinity is supported.
-                */
-               mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(),
-                                             R_IMR_INTERRUPT_STATUS_BASE)));
-               if (mask)
-                       do_IRQ(63 - dclz(mask), regs);
-       }
-}