-
-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;
-}
-
-extern void bcm1480_timer_interrupt(struct pt_regs *regs);
-extern void bcm1480_mailbox_interrupt(struct pt_regs *regs);
-extern void bcm1480_kgdb_interrupt(struct pt_regs *regs);
-
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
-{
- unsigned int pending;
-
-#ifdef CONFIG_SIBYTE_BCM1480_PROF
- /* Set compare to count to silence count/compare timer interrupts */
- write_c0_compare(read_c0_count());
-#endif
-
- pending = read_c0_cause();
-
-#ifdef CONFIG_SIBYTE_BCM1480_PROF
- if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */
- sbprof_cpu_intr(exception_epc(regs));
- else
-#endif
-
- if (pending & CAUSEF_IP4)
- bcm1480_timer_interrupt(regs);
-
-#ifdef CONFIG_SMP
- else if (pending & CAUSEF_IP3)
- bcm1480_mailbox_interrupt(regs);
-#endif
-
-#ifdef CONFIG_KGDB
- else if (pending & CAUSEF_IP6)
- bcm1480_kgdb_interrupt(regs); /* KGDB (uart 1) */
-#endif
-
- else if (pending & CAUSEF_IP2) {
- unsigned long long mask_h, mask_l;
- unsigned long base;
-
- /*
- * Default...we've hit an IP[2] interrupt, which means we've
- * got to check the 1480 interrupt registers to figure out what
- * to do. Need to detect which CPU we're on, now that
- * smp_affinity is supported.
- */
- base = A_BCM1480_IMR_MAPPER(smp_processor_id());
- mask_h = __raw_readq(
- IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
- mask_l = __raw_readq(
- IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
-
- if (mask_h) {
- if (mask_h ^ 1)
- do_IRQ(63 - dclz(mask_h), regs);
- else
- do_IRQ(127 - dclz(mask_l), regs);
- }
- }
-}