static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) { struct combiner_chip_data *chip_data = irq_get_handler_data(irq); struct irq_chip *chip = irq_get_chip(irq); unsigned int cascade_irq, combiner_irq; unsigned long status; chained_irq_enter(chip, desc); spin_lock(&irq_controller_lock); status = __raw_readl(chip_data->base + COMBINER_INT_STATUS); spin_unlock(&irq_controller_lock); status &= chip_data->irq_mask; if (status == 0) goto out; combiner_irq = __ffs(status); cascade_irq = combiner_irq + (chip_data->irq_offset & ~31); if (unlikely(cascade_irq >= NR_IRQS)) do_bad_IRQ(cascade_irq, desc); else generic_handle_irq(cascade_irq); out: chained_irq_exit(chip, desc); }
static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) { struct gic_chip_data *chip_data = irq_get_handler_data(irq); struct irq_chip *chip = irq_get_chip(irq); unsigned int cascade_irq, gic_irq; unsigned long status; chained_irq_enter(chip, desc); raw_spin_lock(&irq_controller_lock); status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK); raw_spin_unlock(&irq_controller_lock); gic_irq = (status & 0x3ff); if (gic_irq == 1023) goto out; cascade_irq = gic_irq + chip_data->irq_offset; if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS)) do_bad_IRQ(cascade_irq, desc); else generic_handle_irq(cascade_irq); out: chained_irq_exit(chip, desc); }
static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, u32 status) { struct nmk_gpio_chip *nmk_chip; struct irq_chip *host_chip = irq_get_chip(irq); unsigned int first_irq; if (host_chip->irq_mask_ack) host_chip->irq_mask_ack(&desc->irq_data); else { host_chip->irq_mask(&desc->irq_data); if (host_chip->irq_ack) host_chip->irq_ack(&desc->irq_data); } nmk_chip = irq_get_handler_data(irq); first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); while (status) { int bit = __ffs(status); generic_handle_irq(first_irq + bit); status &= ~BIT(bit); } host_chip->irq_unmask(&desc->irq_data); }
/* gpio/eic cascaded irq handler */ static void gpio_muxed_handler(unsigned int irq, struct irq_desc *desc) { struct gpio_chip *chip = irq_get_handler_data(irq); struct sci_gpio_chip *sci_gpio = to_sci_gpio(chip); int group, n, addr, value, count = 0; pr_debug("%s %d+%d %d\n", __FUNCTION__, chip->base, chip->ngpio, irq); for (group = 0; group * GPIO_GROUP_NR < chip->ngpio; group++) { addr = sci_gpio->base_addr + sci_gpio->group_offset * group + REG_GPIO_MIS; value = sci_gpio->read_reg(addr) & GPIO_GROUP_MASK; while (value) { n = __ffs(value); value &= ~(1 << n); n = chip->to_irq(chip, group * GPIO_GROUP_NR + n); pr_debug("%s generic_handle_n %d\n", __FUNCTION__, n); count++; generic_handle_irq(n); } } #ifndef CONFIG_ARCH_SC7710 /* handle the shared D-Die EIC */ if (irq == IRQ_GPIO_INT && count == 0) { gpio_muxed_handler(IRQ_EIC_INT, irq_to_desc(IRQ_EIC_INT)); } #endif #ifdef CONFIG_NKERNEL desc->irq_data.chip->irq_unmask(&desc->irq_data); #endif }
static void rk30_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { struct rk30_gpio_bank *bank = irq_get_handler_data(irq); struct irq_chip *chip = irq_desc_get_chip(desc); unsigned gpio_irq; u32 isr, ilr; unsigned pin; unsigned unmasked = 0; chained_irq_enter(chip, desc); isr = __raw_readl(bank->regbase + GPIO_INT_STATUS); ilr = __raw_readl(bank->regbase + GPIO_INTTYPE_LEVEL); gpio_irq = gpio_to_irq(bank->chip.base); while (isr) { pin = fls(isr) - 1; /* if gpio is edge triggered, clear condition * before executing the hander so that we don't * miss edges */ if (ilr & (1 << pin)) { unmasked = 1; chained_irq_exit(chip, desc); } generic_handle_irq(gpio_irq + pin); isr &= ~(1 << pin); } if (!unmasked) chained_irq_exit(chip, desc); }
static void shirq_handler(unsigned irq, struct irq_desc *desc) { u32 i, j, val, mask, tmp; struct irq_chip *chip; struct spear_shirq *shirq = irq_get_handler_data(irq); chip = irq_get_chip(irq); chip->irq_ack(&desc->irq_data); mask = ((0x1 << shirq->irq_nr) - 1) << shirq->irq_bit_off; while ((val = readl(shirq->base + shirq->regs.status_reg) & mask)) { val >>= shirq->irq_bit_off; for (i = 0, j = 1; i < shirq->irq_nr; i++, j <<= 1) { if (!(j & val)) continue; generic_handle_irq(shirq->irq_base + i); /* clear interrupt */ if (shirq->regs.clear_reg == -1) continue; tmp = readl(shirq->base + shirq->regs.clear_reg); if (shirq->regs.reset_to_clear) tmp &= ~(j << shirq->irq_bit_off); else tmp |= (j << shirq->irq_bit_off); writel(tmp, shirq->base + shirq->regs.clear_reg); } } chip->irq_unmask(&desc->irq_data); }
static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) { struct pcap_chip *pcap = irq_get_handler_data(irq); desc->irq_data.chip->irq_ack(&desc->irq_data); queue_work(pcap->workqueue, &pcap->isr_work); }
static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); u32 status = readl(nmk_chip->addr + NMK_GPIO_IS); __nmk_gpio_irq_handler(irq, desc, status); }
static void intcs_demux(unsigned int irq, struct irq_desc *desc) { void __iomem *reg = (void *)irq_get_handler_data(irq); unsigned int evtcodeas = ioread32(reg); generic_handle_irq(intcs_evt2irq(evtcodeas)); }
/* * xgold irq find mapping custom */ static unsigned int xgold_irq_find_mapping_custom(unsigned int irq) { struct xgold_irq_chip_data *data = irq_get_handler_data(irq); if (data && data->find_mapping) return data->find_mapping(irq); else return -2; }
static void nmk_gpio_secondary_irq_handler(unsigned int irq, struct irq_desc *desc) { struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); u32 status = nmk_chip->get_secondary_status(nmk_chip->bank); __nmk_gpio_irq_handler(irq, desc, status); }
static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) { u32 *irq_data = irq_get_handler_data(irq); struct irq_chip *chip = irq_get_chip(irq); chained_irq_enter(chip, desc); generic_handle_irq(*irq_data); chained_irq_exit(chip, desc); }
static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) { u32 *irq_data = irq_get_handler_data(irq); struct irq_chip *chip = irq_get_chip(irq); int eint_irq; chained_irq_enter(chip, desc); eint_irq = irq_find_mapping(irq_domain, *irq_data); generic_handle_irq(eint_irq); chained_irq_exit(chip, desc); }
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_get_handler_data(irq); generic_handle_irq(irq_find_mapping(domain, __ffs(pending))); } else { spurious_interrupt(); } }
/* Handle the T7L66XB interrupt mux */ static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) { struct t7l66xb *t7l66xb = irq_get_handler_data(irq); unsigned int isr; unsigned int i, irq_base; irq_base = t7l66xb->irq_base; while ((isr = tmio_ioread8(t7l66xb->scr + SCR_ISR) & ~tmio_ioread8(t7l66xb->scr + SCR_IMR))) for (i = 0; i < T7L66XB_NR_IRQS; i++) if (isr & (1 << i)) generic_handle_irq(irq_base + i); }
/** * xgpiops_irqhandler - IRQ handler for the gpio banks of a gpio device * @irq: irq number of the gpio bank where interrupt has occurred * @desc: irq descriptor instance of the 'irq' * * This function reads the Interrupt Status Register of each bank to get the * gpio pin number which has triggered an interrupt. It then acks the triggered * interrupt and calls the pin specific handler set by the higher layer * application for that pin. * Note: A bug is reported if no handler is set for the gpio pin. */ void xgpiops_irqhandler(unsigned int irq, struct irq_desc *desc) { int gpio_irq = (int)irq_get_handler_data(irq); struct xgpiops *gpio = (struct xgpiops *)irq_get_chip_data(gpio_irq); unsigned int int_sts, int_enb, bank_num; struct irq_desc *gpio_irq_desc; struct irq_chip *chip = irq_desc_get_chip(desc); chained_irq_enter(chip, desc); for (bank_num = 0; bank_num < 4; bank_num++) { int_sts = xgpiops_readreg(gpio->base_addr + XGPIOPS_INTSTS_OFFSET(bank_num)); int_enb = xgpiops_readreg(gpio->base_addr + XGPIOPS_INTMASK_OFFSET(bank_num)); int_sts &= ~int_enb; for (; int_sts != 0; int_sts >>= 1, gpio_irq++) { if ((int_sts & 1) == 0) continue; gpio_irq_desc = irq_to_desc(gpio_irq); BUG_ON(!gpio_irq_desc); chip = irq_desc_get_chip(gpio_irq_desc); BUG_ON(!chip); chip->irq_ack(&gpio_irq_desc->irq_data); /* call the pin specific handler */ generic_handle_irq(gpio_irq); } /* shift to first virtual irq of next bank */ gpio_irq = (int)irq_get_handler_data(irq) + (xgpiops_pin_table[bank_num] + 1); } chip = irq_desc_get_chip(desc); chained_irq_exit(chip, desc); }
/* * Allocate a MSI vector on a link */ static int xlp_setup_msi(uint64_t lnkbase, int node, int link, struct msi_desc *desc) { struct xlp_msi_data *md; struct msi_msg msg; unsigned long flags; int msivec, irt, lirq, xirq, ret; uint64_t msiaddr; /* Get MSI data for the link */ lirq = PIC_PCIE_LINK_MSI_IRQ(link); xirq = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0)); md = irq_get_handler_data(xirq); msiaddr = MSI_LINK_ADDR(node, link); spin_lock_irqsave(&md->msi_lock, flags); if (md->msi_alloc_mask == 0) { xlp_config_link_msi(lnkbase, lirq, msiaddr); /* switch the link IRQ to MSI range */ if (cpu_is_xlp9xx()) irt = PIC_9XX_IRT_PCIE_LINK_INDEX(link); else irt = PIC_IRT_PCIE_LINK_INDEX(link); nlm_setup_pic_irq(node, lirq, lirq, irt); nlm_pic_init_irt(nlm_get_node(node)->picbase, irt, lirq, node * nlm_threads_per_node(), 1 /*en */); } /* allocate a MSI vec, and tell the bridge about it */ msivec = fls(md->msi_alloc_mask); if (msivec == XLP_MSIVEC_PER_LINK) { spin_unlock_irqrestore(&md->msi_lock, flags); return -ENOMEM; } md->msi_alloc_mask |= (1u << msivec); spin_unlock_irqrestore(&md->msi_lock, flags); msg.address_hi = msiaddr >> 32; msg.address_lo = msiaddr & 0xffffffff; msg.data = 0xc00 | msivec; xirq = xirq + msivec; /* msi mapped to global irq space */ ret = irq_set_msi_desc(xirq, desc); if (ret < 0) return ret; write_msi_msg(xirq, &msg); return 0; }
static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) { struct irq_domain *d = irq_get_handler_data(irq); struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, 0); u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) & gc->mask_cache; while (stat) { u32 hwirq = ffs(stat) - 1; generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq)); stat &= ~(1 << hwirq); } }
/* * xgold irq find mapping from a N to N domain */ static int xgold_irq_find_mapping_n2n(unsigned int irq) { struct xgold_irq_chip_data *data = irq_get_handler_data(irq); auto int i; pr_debug("%s(%d)\n", __func__, irq); if (!data) return -1; for (i = 0; i < data->nr_int; i++) { if (data->table[i] == irq) { pr_debug("%s: mapping found for %d: %d\n", __func__, irq, i); return i; } } pr_debug("%s: mapping not found for %d\n", __func__, irq); return -1; }
static void cs75xx_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned int gpio_irq_no, irq_stat; unsigned int port = (unsigned int)irq_get_handler_data(irq); irq_stat = __raw_readl(cs75xx_gpio_base[port] + CS75XX_GPIO_INT); irq_stat &= __raw_readl(cs75xx_gpio_base[port] + CS75XX_GPIO_IE); gpio_irq_no = GPIO_IRQ_BASE + port * GPIO_BANK_SIZE; for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) { if ((irq_stat & 1) == 0) continue; BUG_ON(!(irq_desc[gpio_irq_no].handle_irq)); irq_desc[gpio_irq_no].handle_irq(gpio_irq_no, &irq_desc[gpio_irq_no]); } }
static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, u32 status) { struct nmk_gpio_chip *nmk_chip; struct irq_chip *host_chip = irq_get_chip(irq); unsigned int first_irq; chained_irq_enter(host_chip, desc); nmk_chip = irq_get_handler_data(irq); first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); while (status) { int bit = __ffs(status); generic_handle_irq(first_irq + bit); status &= ~BIT(bit); } chained_irq_exit(host_chip, desc); }
static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, u32 status) { struct nmk_gpio_chip *nmk_chip; struct irq_chip *host_chip = irq_get_chip(irq); unsigned int first_irq; chained_irq_enter(host_chip, desc); nmk_chip = irq_get_handler_data(irq); first_irq = nmk_chip->domain->revmap_data.legacy.first_irq; while (status) { int bit = __ffs(status); generic_handle_irq(first_irq + bit); status &= ~BIT(bit); } chained_irq_exit(host_chip, desc); }
static void ar5312_misc_irq_handler(unsigned irq, struct irq_desc *desc) { u32 pending = ar5312_rst_reg_read(AR5312_ISR) & ar5312_rst_reg_read(AR5312_IMR); unsigned nr, misc_irq = 0; if (pending) { struct irq_domain *domain = irq_get_handler_data(irq); nr = __ffs(pending); misc_irq = irq_find_mapping(domain, nr); } if (misc_irq) { generic_handle_irq(misc_irq); if (nr == AR5312_MISC_IRQ_TIMER) ar5312_rst_reg_read(AR5312_TIMER); } else { spurious_interrupt(); } }
/* * xgold irq find mapping from a N to 1 domain */ static int xgold_irq_find_mapping_n21(unsigned int irq) { struct xgold_irq_chip_data *data = irq_get_handler_data(irq); auto int i; uint32_t raised = 0, enabled = 0; pr_debug("%s(%d)\n", __func__, irq); if (!data) return -1; for (i = 0; i < data->nr_int; i++) { raised = xgold_irq_read(data, data->status[i]); enabled = xgold_irq_read(data, data->mask[i]); pr_debug("%s: status:%#x - mask:%#x\n", __func__, raised, enabled); if (raised && enabled) { pr_debug("%s: mapping found for %d: %d\n", __func__, irq, i); return i; } } pr_debug("%s: mapping not found for %d\n", __func__, irq); return -1; }
/** * zynq_gpio_irqhandler - IRQ handler for the gpio banks of a gpio device * @irq: irq number of the gpio bank where interrupt has occurred * @desc: irq descriptor instance of the 'irq' * * This function reads the Interrupt Status Register of each bank to get the * gpio pin number which has triggered an interrupt. It then acks the triggered * interrupt and calls the pin specific handler set by the higher layer * application for that pin. * Note: A bug is reported if no handler is set for the gpio pin. */ static void zynq_gpio_irqhandler(unsigned int irq, struct irq_desc *desc) { struct zynq_gpio *gpio = (struct zynq_gpio *)irq_get_handler_data(irq); int gpio_irq = gpio->irq_base; unsigned int int_sts, int_enb, bank_num; struct irq_desc *gpio_irq_desc; struct irq_chip *chip = irq_desc_get_chip(desc); chained_irq_enter(chip, desc); for (bank_num = 0; bank_num < ZYNQ_GPIO_MAX_BANK; bank_num++) { int_sts = zynq_gpio_readreg(gpio->base_addr + ZYNQ_GPIO_INTSTS_OFFSET(bank_num)); int_enb = zynq_gpio_readreg(gpio->base_addr + ZYNQ_GPIO_INTMASK_OFFSET(bank_num)); int_sts &= ~int_enb; for (; int_sts != 0; int_sts >>= 1, gpio_irq++) { if (!(int_sts & 1)) continue; gpio_irq_desc = irq_to_desc(gpio_irq); BUG_ON(!gpio_irq_desc); chip = irq_desc_get_chip(gpio_irq_desc); BUG_ON(!chip); chip->irq_ack(&gpio_irq_desc->irq_data); /* call the pin specific handler */ generic_handle_irq(gpio_irq); } /* shift to first virtual irq of next bank */ gpio_irq = gpio->irq_base + zynq_gpio_pin_table[bank_num] + 1; } chip = irq_desc_get_chip(desc); chained_irq_exit(chip, desc); }
static unsigned int sun4m_build_device_irq(struct platform_device *op, unsigned int real_irq) { struct sun4m_handler_data *handler_data; unsigned int irq; unsigned int pil; if (real_irq >= OBP_INT_LEVEL_VME) { prom_printf("Bogus sun4m IRQ %u\n", real_irq); prom_halt(); } pil = (real_irq & 0xf); irq = irq_alloc(real_irq, pil); if (irq == 0) goto out; handler_data = irq_get_handler_data(irq); if (unlikely(handler_data)) goto out; handler_data = kzalloc(sizeof(struct sun4m_handler_data), GFP_ATOMIC); if (unlikely(!handler_data)) { prom_printf("IRQ: kzalloc(sun4m_handler_data) failed.\n"); prom_halt(); } handler_data->mask = sun4m_imask[real_irq]; handler_data->percpu = real_irq < OBP_INT_LEVEL_ONBOARD; irq_set_chip_and_handler_name(irq, &sun4m_irq, handle_level_irq, "level"); irq_set_handler_data(irq, handler_data); out: return irq; }
/* * xgold cascade handler entry */ void xgold_irq_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) { struct xgold_irq_chip_data *data = NULL; struct irq_domain *domain = NULL; struct irq_chip *chip = irq_get_chip(irq); uint32_t casc_irq = 0; int32_t domain_irq = 0; data = irq_get_handler_data(irq); if (!data || !chip) return; domain = data->domain; chained_irq_enter(chip, desc); domain_irq = xgold_irq_find_mapping(irq, data->type); if (domain_irq >= 0) casc_irq = irq_find_mapping(data->domain, domain_irq); if (data->handle_entry) data->handle_entry(data); if (casc_irq > 0) generic_handle_irq(casc_irq); if (data->handle_exit) data->handle_exit(data); chained_irq_exit(chip, desc); return; }
/* gpio/eic cascaded irq handler */ static void gpio_muxed_flow_handler(unsigned int irq, struct irq_desc *desc) { struct gpio_chip *chip = irq_get_handler_data(irq); gpio_eic_handler(irq, chip); }