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() & ST0_IM; #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(); }
static void rt288x_intc_irq_dispatch(void) { u32 pending; pending = ramips_intc_get_status(); if (pending & RT2880_INTC_INT_TIMER0) do_IRQ(RT2880_INTC_IRQ_TIMER0); else if (pending & RT2880_INTC_INT_TIMER1) do_IRQ(RT2880_INTC_IRQ_TIMER1); else if (pending & RT2880_INTC_INT_UART0) do_IRQ(RT2880_INTC_IRQ_UART0); else if (pending & RT2880_INTC_INT_PCM) do_IRQ(RT2880_INTC_IRQ_PCM); else if (pending & RT2880_INTC_INT_UART1) do_IRQ(RT2880_INTC_IRQ_UART1); else if (pending & RT2880_INTC_INT_PIO) do_IRQ(RT2880_INTC_IRQ_PIO); else spurious_interrupt(); }
static void rt3883_intc_irq_dispatch(void) { u32 pending; pending = ramips_intc_get_status(); if (pending & RT3883_INTC_INT_TIMER0) do_IRQ(RT3883_INTC_IRQ_TIMER0); else if (pending & RT3883_INTC_INT_TIMER1) do_IRQ(RT3883_INTC_IRQ_TIMER1); else if (pending & RT3883_INTC_INT_UART0) do_IRQ(RT3883_INTC_IRQ_UART0); else if (pending & RT3883_INTC_INT_UART1) do_IRQ(RT3883_INTC_IRQ_UART1); else if (pending & RT3883_INTC_INT_PERFC) do_IRQ(RT3883_INTC_IRQ_PERFC); else if (pending & RT3883_INTC_INT_UHST) do_IRQ(RT3883_INTC_IRQ_UHST); /* TODO: handle PIO interrupts as well */ else spurious_interrupt(); }
static void qca955x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc) { u32 status; disable_irq_nosync(irq); status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); status &= QCA955X_EXT_INT_PCIE_RC2_ALL | QCA955X_EXT_INT_USB1 | QCA955X_EXT_INT_USB2; if (status == 0) { spurious_interrupt(); goto enable; } if (status & QCA955X_EXT_INT_USB1) { /* TODO: flush DDR? */ generic_handle_irq(ATH79_IP3_IRQ(0)); } if (status & QCA955X_EXT_INT_USB2) { /* TODO: flush DDR? */ generic_handle_irq(ATH79_IP3_IRQ(1)); } if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) { /* TODO: flush DDR? */ generic_handle_irq(ATH79_IP3_IRQ(2)); } enable: enable_irq(irq); }
asmlinkage void plat_irq_dispatch(void) { unsigned int cpu = smp_processor_id(); unsigned int pending; /* * 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() & ST0_IM; if (pending & CAUSEF_IP7) /* CPU performance counter interrupt */ do_IRQ(MIPS_CPU_IRQ_BASE + 7); else if (pending & CAUSEF_IP4) do_IRQ(K_INT_TIMER_0 + cpu); /* sb1250_timer_interrupt() */ #ifdef CONFIG_SMP else if (pending & CAUSEF_IP3) sb1250_mailbox_interrupt(); #endif else if (pending & CAUSEF_IP2) dispatch_ip2(); else spurious_interrupt(); }
static void ar7_cascade(void) { u32 status; int i, irq; /* Primary IRQ's */ irq = readl(REG(PIR_OFFSET)) & 0x3f; if (irq) { do_IRQ(ar7_irq_base + irq); return; } /* Secondary IRQ's are cascaded through primary '0' */ writel(1, REG(CR_OFFSET(irq))); status = readl(REG(SEC_SR_OFFSET)); for (i = 0; i < 32; i++) { if (status & 1) { do_IRQ(ar7_irq_base + i + 40); return; } status >>= 1; } spurious_interrupt(); }
/*! @brief the interrupt exception service function. * @details The \cplat_irq_dispatch() function is the interrupt exception * service function called. When an exception is set and the exception * code indicates an interrupt (0x00). */ asmlinkage void plat_irq_dispatch( struct pt_regs *regs /*!< registers of the interrupted task */ ) { /* Get the current pending interrupt status */ unsigned long pending = read_c0_cause() & read_c0_status(); /*! @note Clear all pending interrupts before dispatching. The interrupt information structure will call the "end" function from the do_IRQ function that should re-enable the specific interrupt while completing the interrupt handling (see irq_chip structure). */ /* Disable all MIPS active pending interrupts */ clear_c0_status(pending); /* These are the interrupts that are to be dispatched */ if( pending & (STATUSF_IP7|STATUSF_IP2) ) { /* Dispatch timer interrupt (HW INT#5/IP7) */ if (pending & STATUSF_IP7) brcm_mips_int7_dispatch(regs); /* Dispatch shared interrupt (HW INT#0/IP2) */ if (pending & STATUSF_IP2) brcm_mips_int2_dispatch(regs); /* Return following the successful interrupt exception handling */ return; } /* Other interrupts are unhandled and treated as spurious interrupts */ spurious_interrupt(regs); }
asmlinkage void plat_irq_dispatch(void) { unsigned long pending; pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP7) do_IRQ(AR71XX_CPU_IRQ_TIMER); #ifdef CONFIG_PCI else if (pending & STATUSF_IP2) ar71xx_pci_irq_dispatch(); #endif else if (pending & STATUSF_IP4) do_IRQ(AR71XX_CPU_IRQ_GE0); else if (pending & STATUSF_IP5) do_IRQ(AR71XX_CPU_IRQ_GE1); else if (pending & STATUSF_IP3) do_IRQ(AR71XX_CPU_IRQ_USB); else if (pending & STATUSF_IP6) ar71xx_misc_irq_dispatch(); else spurious_interrupt(); }
asmlinkage void plat_irq_dispatch(void) { unsigned long pending; pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP7) do_IRQ(ATH79_CPU_IRQ(7)); else if (pending & STATUSF_IP2) ath79_ip2_handler(); else if (pending & STATUSF_IP4) do_IRQ(ATH79_CPU_IRQ(4)); else if (pending & STATUSF_IP5) do_IRQ(ATH79_CPU_IRQ(5)); else if (pending & STATUSF_IP3) ath79_ip3_handler(); else if (pending & STATUSF_IP6) do_IRQ(ATH79_CPU_IRQ(6)); else spurious_interrupt(); }
asmlinkage void vrc5476_irq_dispatch(struct pt_regs *regs) { extern unsigned int do_IRQ(int irq, struct pt_regs *regs); extern void spurious_interrupt(void); u32 mask; int nile4_irq; mask = nile4_get_irq_stat(0); /* quick check for possible time interrupt */ if (mask & (1 << VRC5476_IRQ_GPT)) { do_IRQ(VRC5476_IRQ_BASE + VRC5476_IRQ_GPT, regs); return; } /* check for i8259 interrupts */ if (mask & (1 << VRC5476_I8259_CASCADE)) { int i8259_irq = nile4_i8259_iack(); do_IRQ(I8259_IRQ_BASE + i8259_irq, regs); return; } /* regular nile4 interrupts (we should not really have any */ for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) { if (mask & 1) { do_IRQ(VRC5476_IRQ_BASE + nile4_irq, regs); return; } } spurious_interrupt(); }
asmlinkage void plat_irq_dispatch(void) { unsigned long pending; pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP7) do_IRQ(ATH79_CPU_IRQ_TIMER); else if (pending & STATUSF_IP2) { ath79_ddr_wb_flush(ath79_ip2_flush_reg); do_IRQ(ATH79_CPU_IRQ_IP2); } else if (pending & STATUSF_IP4) do_IRQ(ATH79_CPU_IRQ_GE0); else if (pending & STATUSF_IP5) do_IRQ(ATH79_CPU_IRQ_GE1); else if (pending & STATUSF_IP3) { ath79_ddr_wb_flush(ath79_ip3_flush_reg); do_IRQ(ATH79_CPU_IRQ_USB); } else if (pending & STATUSF_IP6) do_IRQ(ATH79_CPU_IRQ_MISC); else spurious_interrupt(); }
asmlinkage void plat_irq_dispatch(void) { unsigned long pending; pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP7) do_IRQ(AR71XX_CPU_IRQ_TIMER); else if (pending & STATUSF_IP2) ip2_handler(); else if (pending & STATUSF_IP4) do_IRQ(AR71XX_CPU_IRQ_GE0); else if (pending & STATUSF_IP5) do_IRQ(AR71XX_CPU_IRQ_GE1); else if (pending & STATUSF_IP3) ip3_handler(); else if (pending & STATUSF_IP6) ar71xx_misc_irq_dispatch(); else spurious_interrupt(); }
asmlinkage void plat_irq_dispatch(void) { unsigned int pending = read_c0_status() & read_c0_cause(); if (pending & CAUSEF_IP7) { do_IRQ(M36_IRQ_TIMER); } else if ((pending & CAUSEF_IP3) || (pending & CAUSEF_IP2)) { sys_irqdispatch(); } else { #ifdef CONFIG_ENABLE_RPC { unsigned long rpc_status; rpc_status = *(volatile unsigned char *)(sys_rpc_addr); rpc_status &= sys_rpc_mask; if(rpc_status & sys_rpc_irq1_mask) do_IRQ(71); if(rpc_status & sys_rpc_irq2_mask) do_IRQ(70); } #endif spurious_interrupt(); } }
static void rt305x_intc_irq_dispatch(void) { u32 pending; pending = ramips_intc_get_status(); if (pending & RT305X_INTC_INT_TIMER0) do_IRQ(RT305X_INTC_IRQ_TIMER0); else if (pending & RT305X_INTC_INT_TIMER1) do_IRQ(RT305X_INTC_IRQ_TIMER1); else if (pending & RT305X_INTC_INT_UART0) do_IRQ(RT305X_INTC_IRQ_UART0); else if (pending & RT305X_INTC_INT_UART1) do_IRQ(RT305X_INTC_IRQ_UART1); else if (pending & RT305X_INTC_INT_PERFC) do_IRQ(RT305X_INTC_IRQ_PERFC); else if (pending & RT305X_INTC_INT_OTG) do_IRQ(RT305X_INTC_IRQ_OTG); else if (pending & RT305X_INTC_INT_PIO) do_IRQ(RT305X_INTC_IRQ_PIO); else spurious_interrupt(); }
static void ar71xx_misc_irq_dispatch(void) { u32 pending; pending = ar71xx_reset_rr(RESET_REG_MISC_INT_STATUS) & ar71xx_reset_rr(RESET_REG_MISC_INT_ENABLE); if (pending & MISC_INT_UART) do_IRQ(AR71XX_MISC_IRQ_UART); else if (pending & MISC_INT_DMA) do_IRQ(AR71XX_MISC_IRQ_DMA); else if (pending & MISC_INT_PERFC) do_IRQ(AR71XX_MISC_IRQ_PERFC); else if (pending & MISC_INT_TIMER) do_IRQ(AR71XX_MISC_IRQ_TIMER); else if (pending & MISC_INT_OHCI) do_IRQ(AR71XX_MISC_IRQ_OHCI); else if (pending & MISC_INT_ERROR) do_IRQ(AR71XX_MISC_IRQ_ERROR); else if (pending & MISC_INT_GPIO) ar71xx_gpio_irq_dispatch(); else if (pending & MISC_INT_WDOG) do_IRQ(AR71XX_MISC_IRQ_WDOG); else spurious_interrupt(); }
static void i8259_irqdispatch(void) { int irq; irq = mach_i8259_irq(); if (irq >= 0) do_IRQ(irq); else spurious_interrupt(); }
asmlinkage void plat_irq_dispatch(void) { unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP2) do_IRQ(2); else if (pending & STATUSF_IP3) do_IRQ(3); else spurious_interrupt(); }
asmlinkage void plat_irq_dispatch(void) { unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP7) /* cpu timer */ do_IRQ(7); else if (pending & STATUSF_IP2) /* int0 hardware line */ ar7_cascade(); else spurious_interrupt(); }
static void ralink_intc_irq_handler(unsigned int irq, struct irq_desc *desc) { u32 pending = rt_intc_r32(INTC_REG_STATUS0); if (pending) { struct irq_domain *domain = irq_desc_get_handler_data(desc); generic_handle_irq(irq_find_mapping(domain, __ffs(pending))); } else { spurious_interrupt(); } }
asmlinkage void plat_irq_dispatch(void) { unsigned int pending; #if defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_MT7620) || \ defined (CONFIG_RALINK_MT7628) unsigned int pci_status; #endif pending = read_c0_status() & read_c0_cause() & ST0_IM; if (!pending) { spurious_interrupt(); return; } if (pending & CAUSEF_IP7) { do_IRQ(SURFBOARDINT_MIPS_TIMER); // CPU Timer return; } if (pending & CAUSEF_IP5) do_IRQ(SURFBOARDINT_FE); // Frame Engine if (pending & CAUSEF_IP6) do_IRQ(SURFBOARDINT_WLAN); // Wireless if (pending & CAUSEF_IP4) { #if defined (CONFIG_RALINK_RT3883) pci_status = RALINK_PCI_PCIINT_ADDR; if (pci_status & 0x100000) do_IRQ(SURFBOARDINT_PCIE0); #if defined (CONFIG_PCI_ONLY) || defined (CONFIG_PCIE_PCI_CONCURRENT) else if (pci_status & 0x040000) do_IRQ(SURFBOARDINT_PCI0); else do_IRQ(SURFBOARDINT_PCI1); #endif #elif defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7628) pci_status = RALINK_PCI_PCIINT_ADDR; if (pci_status & 0x100000) do_IRQ(SURFBOARDINT_PCIE0); #endif } if (pending & CAUSEF_IP3) ralink_hw0_irqdispatch(1); else if (pending & CAUSEF_IP2) ralink_hw0_irqdispatch(0); #if 0 /* clear new potentially pending IP6..IP2 */ set_c0_status( STATUSF_IP6 | STATUSF_IP5 | STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 ); #endif }
asmlinkage void plat_irq_dispatch(void) { unsigned int pending = read_c0_status() & read_c0_cause(); if (pending & STATUSF_IP4) pic_dispatch(); else if (pending & STATUSF_IP7) do_IRQ(PNX833X_TIMER_IRQ); else spurious_interrupt(); }
asmlinkage void plat_irq_dispatch(void) { const unsigned long core_id = cvmx_get_core_num(); const uint64_t ciu_sum0_address = CVMX_CIU_INTX_SUM0(core_id * 2); const uint64_t ciu_en0_address = CVMX_CIU_INTX_EN0(core_id * 2); const uint64_t ciu_sum1_address = CVMX_CIU_INT_SUM1; const uint64_t ciu_en1_address = CVMX_CIU_INTX_EN1(core_id * 2 + 1); unsigned long cop0_cause; unsigned long cop0_status; uint64_t ciu_en; uint64_t ciu_sum; while (1) { cop0_cause = read_c0_cause(); cop0_status = read_c0_status(); cop0_cause &= cop0_status; cop0_cause &= ST0_IM; if (unlikely(cop0_cause & STATUSF_IP2)) { ciu_sum = cvmx_read_csr(ciu_sum0_address); ciu_en = cvmx_read_csr(ciu_en0_address); ciu_sum &= ciu_en; if (likely(ciu_sum)) do_IRQ(fls64(ciu_sum) + OCTEON_IRQ_WORKQ0 - 1); else spurious_interrupt(); } else if (unlikely(cop0_cause & STATUSF_IP3)) { ciu_sum = cvmx_read_csr(ciu_sum1_address); ciu_en = cvmx_read_csr(ciu_en1_address); ciu_sum &= ciu_en; if (likely(ciu_sum)) do_IRQ(fls64(ciu_sum) + OCTEON_IRQ_WDOG0 - 1); else spurious_interrupt(); } else if (likely(cop0_cause)) { do_IRQ(fls(cop0_cause) - 9 + MIPS_CPU_IRQ_BASE); } else { break; } } }
asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status(); if (pending & STATUSF_IP7) brcm_mips_int7_dispatch(regs); else if (pending & STATUSF_IP2) brcm_mips_int2_dispatch(regs); else spurious_interrupt(regs); }
static void adm8668_irq_cascade(void) { int irq; u32 intsrc; intsrc = intc_read_reg(IRQ_STATUS_REG) & IRQ_MASK; if (intsrc) { irq = fls(intsrc) - 1; do_IRQ(irq); } else spurious_interrupt(); }
/* * IRQs on the SEAD board look basically are combined together on hardware * interrupt 0 (MIPS IRQ 2)) like: * * MIPS IRQ Source * -------- ------ * 0 Software (ignored) * 1 Software (ignored) * 2 UART0 (hw0) * 3 UART1 (hw1) * 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(void) { unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; int irq; irq = irq_ffs(pending); if (irq >= 0) do_IRQ(MIPSCPU_INT_BASE + irq); else spurious_interrupt(regs); }
asmlinkage void plat_irq_dispatch(void) { unsigned int pending = read_c0_status() & read_c0_cause(); if (pending & STATUSF_IP7) /* cpu timer */ do_IRQ(TX4927_IRQ_CPU_TIMER); else if (pending & STATUSF_IP2) { /* tx4927 pic */ unsigned int irq = tx4927_irq_nested(); if (unlikely(irq == 0)) { spurious_interrupt(); return; } do_IRQ(irq); } else if (pending & STATUSF_IP0) /* user line 0 */ do_IRQ(TX4927_IRQ_USER0); else if (pending & STATUSF_IP1) /* user line 1 */ do_IRQ(TX4927_IRQ_USER1); else spurious_interrupt(); }
static void adm5120_intc_irq_dispatch(void) { unsigned long status; int irq; status = intc_read_reg(INTC_REG_IRQ_STATUS) & INTC_INT_ALL; if (status) { irq = ADM5120_INTC_IRQ_BASE + fls(status) - 1; do_IRQ(irq); } else spurious_interrupt(); }
static void ar71xx_gpio_irq_dispatch(void) { u32 pending; pending = ar71xx_gpio_rr(GPIO_REG_INT_PENDING) & ar71xx_gpio_rr(GPIO_REG_INT_ENABLE); if (pending) do_IRQ(AR71XX_GPIO_IRQ_BASE + fls(pending) - 1); else spurious_interrupt(); }
asmlinkage void plat_irq_dispatch(void) { unsigned long pending; pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP7) do_IRQ(ADM5120_IRQ_COUNTER); else if (pending & STATUSF_IP2) adm5120_intc_irq_dispatch(); else spurious_interrupt(); }
asmlinkage void plat_irq_dispatch(void) { unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP7) do_IRQ(WRPPMC_MIPS_TIMER_IRQ); /* CPU Compare/Count internal timer */ else if (pending & STATUSF_IP6) do_IRQ(WRPPMC_UART16550_IRQ); /* UART 16550 port */ else if (pending & STATUSF_IP3) do_IRQ(WRPPMC_PCI_INTA_IRQ); /* PCI INT_A */ else spurious_interrupt(); }