static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc, struct pt_regs *regs, int intc_offset) { int pnd; int offset; pnd = __raw_readl(intc->reg_intpnd); if (!pnd) return false; /* non-dt machines use individual domains */ if (!irq_domain_get_of_node(intc->domain)) intc_offset = 0; /* We have a problem that the INTOFFSET register does not always * show one interrupt. Occasionally we get two interrupts through * the prioritiser, and this causes the INTOFFSET register to show * what looks like the logical-or of the two interrupt numbers. * * Thanks to Klaus, Shannon, et al for helping to debug this problem */ offset = __raw_readl(intc->reg_intpnd + 4); /* Find the bit manually, when the offset is wrong. * The pending register only ever contains the one bit of the next * interrupt to handle. */ if (!(pnd & (1 << offset))) offset = __ffs(pnd); handle_domain_irq(intc->domain, intc_offset + offset, regs); return true; }
static void or1k_pic_handle_irq(struct pt_regs *regs) { int irq = -1; while ((irq = pic_get_irq(irq + 1)) != NO_IRQ) handle_domain_irq(root_domain, irq, regs); }
static asmlinkage void __exception_irq_entry omap_intc_handle_irq(struct pt_regs *regs) { u32 irqnr = 0; int handled_irq = 0; int i; do { for (i = 0; i < omap_nr_pending; i++) { irqnr = intc_readl(INTC_PENDING_IRQ0 + (0x20 * i)); if (irqnr) goto out; } out: if (!irqnr) break; irqnr = intc_readl(INTC_SIR); irqnr &= ACTIVEIRQ_MASK; if (irqnr) { handle_domain_irq(domain, irqnr, regs); handled_irq = 1; } } while (irqnr); /* * If an irq is masked or deasserted while active, we will * keep ending up here with no irq handled. So remove it from * the INTC with an ack. */ if (!handled_irq) omap_ack_irq(NULL); }
asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs) { u32 irqnr; irqnr = __raw_readl(icoll_priv.stat); __raw_writel(irqnr, icoll_priv.vector); handle_domain_irq(icoll_domain, irqnr, regs); }
static void __exception_irq_entry bcm2835_handle_irq( struct pt_regs *regs) { u32 hwirq; while ((hwirq = get_next_armctrl_hwirq()) != ~0) handle_domain_irq(intc.domain, hwirq, regs); }
/* * Main handler for inter-processor interrupts */ void handle_IPI(int ipinr, struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); struct pt_regs *old_regs = set_irq_regs(regs); if ((unsigned)ipinr < NR_IPI) { trace_ipi_entry_rcuidle(ipi_types[ipinr]); __inc_irq_stat(cpu, ipi_irqs[ipinr]); } switch (ipinr) { case IPI_RESCHEDULE: scheduler_ipi(); break; case IPI_CALL_FUNC: irq_enter(); generic_smp_call_function_interrupt(); irq_exit(); break; case IPI_CPU_STOP: irq_enter(); ipi_cpu_stop(cpu); irq_exit(); break; #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST case IPI_TIMER: irq_enter(); tick_receive_broadcast(); irq_exit(); break; #endif #ifdef CONFIG_IRQ_WORK case IPI_IRQ_WORK: irq_enter(); irq_work_run(); irq_exit(); break; #endif default: if (ipi_custom_irq_domain && ipinr >= IPI_CUSTOM_FIRST && ipinr <= IPI_CUSTOM_LAST) handle_domain_irq(ipi_custom_irq_domain, ipinr, regs); else pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break; } if ((unsigned)ipinr < NR_IPI) trace_ipi_exit_rcuidle(ipi_types[ipinr]); set_irq_regs(old_regs); }
static asmlinkage void __exception_irq_entry omap_intc_handle_irq(struct pt_regs *regs) { u32 irqnr; irqnr = intc_readl(INTC_SIR); irqnr &= ACTIVEIRQ_MASK; WARN_ONCE(!irqnr, "Spurious IRQ ?\n"); handle_domain_irq(domain, irqnr, regs); }
asmlinkage void __exception_irq_entry ft010_irqchip_handle_irq(struct pt_regs *regs) { struct ft010_irq_data *f = &firq; int irq; u32 status; while ((status = readl(FT010_IRQ_STATUS(f->base)))) { irq = ffs(status) - 1; handle_domain_irq(f->domain, irq, regs); } }
static asmlinkage void __exception_irq_entry aic5_handle(struct pt_regs *regs) { struct irq_chip_generic *bgc = irq_get_domain_generic_chip(aic5_domain, 0); u32 irqnr; u32 irqstat; irqnr = irq_reg_readl(bgc, AT91_AIC5_IVR); irqstat = irq_reg_readl(bgc, AT91_AIC5_ISR); if (!irqstat) irq_reg_writel(bgc, 0, AT91_AIC5_EOICR); else handle_domain_irq(aic5_domain, irqnr, regs); }
static asmlinkage void __exception_irq_entry aic_handle(struct pt_regs *regs) { struct irq_domain_chip_generic *dgc = aic_domain->gc; struct irq_chip_generic *gc = dgc->gc[0]; u32 irqnr; u32 irqstat; irqnr = irq_reg_readl(gc, AT91_AIC_IVR); irqstat = irq_reg_readl(gc, AT91_AIC_ISR); if (!irqstat) irq_reg_writel(gc, 0, AT91_AIC_EOICR); else handle_domain_irq(aic_domain, irqnr, regs); }
static void __exception_irq_entry orion_handle_irq(struct pt_regs *regs) { struct irq_domain_chip_generic *dgc = orion_irq_domain->gc; int n, base = 0; for (n = 0; n < dgc->num_chips; n++, base += ORION_IRQS_PER_CHIP) { struct irq_chip_generic *gc = irq_get_domain_generic_chip(orion_irq_domain, base); u32 stat = readl_relaxed(gc->reg_base + ORION_IRQ_CAUSE) & gc->mask_cache; while (stat) { u32 hwirq = __fls(stat); handle_domain_irq(orion_irq_domain, gc->irq_base + hwirq, regs); stat &= ~(1 << hwirq); } } }
static void __exception_irq_entry digicolor_handle_irq(struct pt_regs *regs) { struct irq_domain_chip_generic *dgc = digicolor_irq_domain->gc; struct irq_chip_generic *gc = dgc->gc[0]; u32 status, hwirq; do { status = irq_reg_readl(gc, IC_INT0STATUS_LO); if (status) { hwirq = ffs(status) - 1; } else { status = irq_reg_readl(gc, IC_INT0STATUS_XLO); if (status) hwirq = ffs(status) - 1 + 32; else return; } handle_domain_irq(digicolor_irq_domain, hwirq, regs); } while (1); }
static void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs) { u32 stat, i; int irqnr; void __iomem *base; /* Loop through each active controller */ for (i=0; i<active_cnt; i++) { base = intc[i].base; irqnr = readl_relaxed(base) & 0x3F; /* Highest Priority register default = 63, so check that this is a real interrupt by checking the status register */ if (irqnr == 63) { stat = readl_relaxed(base + VT8500_ICIS + 4); if (!(stat & BIT(31))) continue; } handle_domain_irq(intc[i].domain, irqnr, regs); } }
static void __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs) { int cpu = smp_processor_id(); u32 stat; stat = readl_relaxed(intc.base + LOCAL_IRQ_PENDING0 + 4 * cpu); if (stat & BIT(LOCAL_IRQ_MAILBOX0)) { #ifdef CONFIG_SMP void __iomem *mailbox0 = (intc.base + LOCAL_MAILBOX0_CLR0 + 16 * cpu); u32 mbox_val = readl(mailbox0); u32 ipi = ffs(mbox_val) - 1; writel(1 << ipi, mailbox0); handle_IPI(ipi, regs); #endif } else if (stat) { u32 hwirq = ffs(stat) - 1; handle_domain_irq(intc.domain, hwirq, regs); } }