+
+extern void sb1250_timer_interrupt(void);
+extern void sb1250_mailbox_interrupt(void);
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending;
+
+#ifdef CONFIG_SIBYTE_SB1250_PROF
+ /* Set compare to count to silence count/compare timer interrupts */
+ write_c0_compare(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() & read_c0_status();
+
+#ifdef CONFIG_SIBYTE_SB1250_PROF
+ if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */
+ sbprof_cpu_intr();
+ else
+#endif
+
+ if (pending & CAUSEF_IP4)
+ sb1250_timer_interrupt();
+
+#ifdef CONFIG_SMP
+ else if (pending & CAUSEF_IP3)
+ sb1250_mailbox_interrupt();
+#endif
+
+#ifdef CONFIG_KGDB
+ else if (pending & CAUSEF_IP6) /* KGDB (uart 1) */
+ sb1250_kgdb_interrupt();
+#endif
+
+ else 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(fls64(mask) - 1);
+ else
+ spurious_interrupt();
+ } else
+ spurious_interrupt();
+}