static void intcs_demux(unsigned int irq, struct irq_desc *desc) { void __iomem *reg = (void *)get_irq_data(irq); unsigned int evtcodeas = ioread32(reg); generic_handle_irq(intcs_evt2irq(evtcodeas)); }
static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) { struct gic_chip_data *chip_data = get_irq_data(irq); struct irq_chip *chip = get_irq_chip(irq); unsigned int cascade_irq, gic_irq; unsigned long status; /* primary controller ack'ing */ chip->ack(irq); spin_lock(&irq_controller_lock); status = readl(chip_data->cpu_base + GIC_CPU_INTACK); 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: /* primary controller unmasking */ chip->unmask(irq); }
int native_setup_irq_handler(unsigned int irq) { struct irq_data *data = get_irq_data(irq); if(data->handle == NULL) { return -E_NULL_PTR; } else { setup_irq_handler(irq); } /* now we check if we might have to reset some values.. */ if(data->base_handle == NULL || data->base_handle == &do_irq) { data->base_handle = &do_irq; return -E_SUCCESS; } else { /* * A different base handler has to be used. */ writel((void*)data->irq_base+DYNAMIC_IRQ_HANDLER_VALUE, (uint32_t)data-> base_handle); } return 0; }
/* * The interrupt demux function. Check if this was an ILC interrupt, and * if so which device generated the interrupt. */ void ilc_irq_demux(unsigned int irq, struct irq_desc *desc) { struct ilc *ilc = get_irq_data(irq); #if defined(CONFIG_CPU_SUBTYPE_STX5206) || \ defined(CONFIG_CPU_SUBTYPE_STX7108) || \ defined(CONFIG_CPU_SUBTYPE_STX7111) || \ defined(CONFIG_CPU_SUBTYPE_STX7141) unsigned int priority = 7; #elif defined(CONFIG_CPU_SUBTYPE_FLI7510) || \ defined(CONFIG_CPU_SUBTYPE_STX5197) || \ defined(CONFIG_CPU_SUBTYPE_STX7105) || \ defined(CONFIG_CPU_SUBTYPE_STX7200) unsigned int priority = 14 - irq; #endif int handled = 0; int idx; DPRINTK2("%s: irq %d\n", __func__, irq); for (idx = 0; idx < DIV_ROUND_UP(ilc->inputs_num, 32); ++idx) { unsigned long status; unsigned int input; struct irq_desc *desc; status = readl(ilc->base + ILC_BASE_STATUS + (idx << 2)) & readl(ilc->base + ILC_BASE_ENABLE + (idx << 2)) & ilc->priority[priority][idx]; if (!status) continue; input = (idx * 32) + ffs(status) - 1; desc = irq_desc + input + ilc->first_irq; desc->handle_irq(ilc->first_irq + input, desc); handled = 1; ILC_CLR_STATUS(ilc->base, input); } if (likely(handled)) return; atomic_inc(&irq_err_count); printk(KERN_INFO "ILC: spurious interrupt demux %d\n", irq); printk(KERN_DEBUG "ILC: inputs status enabled used\n"); for (idx = 0; idx < DIV_ROUND_UP(ilc->inputs_num, 32); ++idx) { unsigned long status, enabled, used; status = readl(ilc->base + ILC_BASE_STATUS + (idx << 2)); enabled = readl(ilc->base + ILC_BASE_ENABLE + (idx << 2)); used = 0; for (priority = 0; priority < ilc->outputs_num; ++priority) used |= ilc->priority[priority][idx]; printk(KERN_DEBUG "ILC: %3d-%3d: %08lx %08lx %08lx" "\n", idx * 32, (idx * 32) + 31, status, enabled, used); } }
/* * From evt2irq to ilc2irq */ int ilc2irq(unsigned int evtcode) { struct ilc *ilc = get_irq_data(evt2irq(evtcode)); #if defined(CONFIG_CPU_SUBTYPE_STX5206) || \ defined(CONFIG_CPU_SUBTYPE_STX7108) || \ defined(CONFIG_CPU_SUBTYPE_STX7111) || \ defined(CONFIG_CPU_SUBTYPE_STX7141) unsigned int priority = 7; #elif defined(CONFIG_CPU_SUBTYPE_FLI7510) || \ defined(CONFIG_CPU_SUBTYPE_STX5197) || \ defined(CONFIG_CPU_SUBTYPE_STX7105) || \ defined(CONFIG_CPU_SUBTYPE_STX7200) unsigned int priority = 14 - evt2irq(evtcode); #endif unsigned long status; int idx; for (idx = 0, status = 0; idx < DIV_ROUND_UP(ilc->inputs_num, 32) && !status; ++idx) status = readl(ilc->base + ILC_BASE_STATUS + (idx << 2)) & readl(ilc->base + ILC_BASE_ENABLE + (idx << 2)) & ilc->priority[priority][idx]; if (!status) return -1; return ilc->first_irq + ((idx-1) * 32) + (ffs(status) - 1); }
static void pm8901_irq_unmask(unsigned int irq) { int master, irq_bit; struct pm8901_chip *chip = get_irq_data(irq); u8 block, config, old_irqs_allowed, old_blocks_allowed; irq -= chip->pdata.irq_base; block = irq / 8; master = block / 8; irq_bit = irq % 8; old_irqs_allowed = chip->irqs_allowed[block]; chip->irqs_allowed[block] |= 1 << irq_bit; if (!old_irqs_allowed) { master = block / 8; old_blocks_allowed = chip->blocks_allowed[master]; chip->blocks_allowed[master] |= 1 << (block % 8); if (!old_blocks_allowed) chip->masters_allowed |= 1 << master; } config = PM8901_IRQF_WRITE | chip->config[irq]; pm8901_config_irq(chip, &block, &config); }
static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) { struct pcap_chip *pcap = get_irq_data(irq); desc->chip->ack(irq); queue_work(pcap->workqueue, &pcap->isr_work); return; }
/* MX3 has one interrupt *per* gpio port */ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) { u32 irq_stat; struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq); irq_stat = __raw_readl(port->base + GPIO_ISR) & __raw_readl(port->base + GPIO_IMR); BUG_ON(!irq_stat); mxc_gpio_irq_handler(port, irq_stat); }
void do_irq(struct general_irq_stack stack) { #ifdef IRQ_DBG debug("Called irq: %x\n", stack.irq); #endif struct irq_data *data = get_irq_data(stack.irq); data->handle(stack.irq, stack.regs); return; }
static void pm8901_irq_ack(unsigned int irq) { struct pm8901_chip *chip = get_irq_data(irq); u8 block, config; irq -= chip->pdata.irq_base; block = irq / 8; config = PM8901_IRQF_WRITE | chip->config[irq] | PM8901_IRQF_CLR; pm8901_config_irq(chip, &block, &config); }
IRQ(timer_irq, irq, stack) { struct irq_data *data = get_irq_data(irq); struct device *dev = (struct device *)(data->irq_data); TIMER *timer = dev->device_data; timer->tick++; timer->tick_handle(timer); return; }
static void pm8058_irq_bus_lock(unsigned int irq) { u8 block; struct pm8058_chip *chip = get_irq_data(irq); irq -= chip->pdata.irq_base; block = irq / 8; chip->bus_unlock_config[irq] = 0; mutex_lock(&chip->pm_lock); }
static void pm8058_irq_bus_sync_unlock(unsigned int irq) { u8 block, config; struct pm8058_chip *chip = get_irq_data(irq); irq -= chip->pdata.irq_base; block = irq / 8; config = chip->bus_unlock_config[irq]; /* dont waste cpu cycles if we dont have data to write */ if (config) pm8058_config_irq(chip, &block, &config); mutex_unlock(&chip->pm_lock); }
static irqreturn_t max_valid_handler(int irq, void *dev_id) { struct max8903_struct *max_chg; struct platform_device *pdev; struct pm8058_chip *chip; int state; pdev = (struct platform_device *)dev_id; max_chg = platform_get_drvdata(pdev); chip = get_irq_data(irq); #if 0 /* Dock insert, think it as AC charger */ if (gpio_get_value_cansleep(max_chg->dock_det) && (BOARD_NUM(hw_ver) != BOARD_NUM_V11)) max_chg->adapter_hw_chg.type = CHG_TYPE_USB; else max_chg->adapter_hw_chg.type = CHG_TYPE_AC; #endif /* reinitialize charger type */ if ((BOARD_NUM(hw_ver) == BOARD_NUM_V11)) max_chg->adapter_hw_chg.type = CHG_TYPE_AC; else max_chg->adapter_hw_chg.type = CHG_TYPE_USB; state = pm8058_irq_get_rt_status(chip, irq); pr_info("%s:charge state=%d, hw_chg_type=%d\n", __func__, state, max_chg->adapter_hw_chg.type); if(state){ /* delay to queue charge insert envent when charger inserted, * need to detect if it is an ac charger */ //msm_charger_notify_event(&max_chg->adapter_hw_chg, // CHG_INSERTED_EVENT); delay_ac_charger_detect = 1; pr_info("%s:delay_ac_charger_detect=%d start ac charger delay work\n", __func__, delay_ac_charger_detect); schedule_delayed_work(&max_chg->ac_charger, AC_CHARGER_DETECT_DELAY); max_chg->present = 1; wake_lock(&max_chg->wl); }else{ delay_ac_charger_detect = 0; pr_info("%s:delay_ac_charger_detect=%d cancel ac charger delay work\n", __func__, delay_ac_charger_detect); cancel_delayed_work(&saved_msm_chg->ac_charger); msm_charger_notify_event(&max_chg->adapter_hw_chg, CHG_REMOVED_EVENT); max_chg->present = 0; wake_unlock(&max_chg->wl); } return IRQ_HANDLED; }
/** * Setup a default irq config. The default irq configration is a low priority, * edge triggered interrupt. The only field which is not set is the hardware pin/ * msi field. */ static struct irq_cfg * setup_irq_cfg(int irq) { struct irq_data *data = get_irq_data(irq); if(data->irq_config == NULL) data->irq_config = kalloc(sizeof(*(data->irq_config))); struct irq_cfg *cfg = data->irq_config; cfg->trigger = 0; cfg->delivery_mode = 1; cfg->vector = alloc_idt_entry(); return data->irq_config; }
static void pmic_irq_handler(unsigned irq, struct irq_desc *desc) { struct pmic_gpio *pg = (struct pmic_gpio *)get_irq_data(irq); u8 intsts = *((u8 *)pg->gpiointr + 4); int gpio; for (gpio = 0; gpio < 8; gpio++) { if (intsts & (1 << gpio)) { pr_debug("pmic pin %d triggered\n", gpio); generic_handle_irq(pg->irq_base + gpio); } } desc->chip->eoi(irq); }
/* Handle the T7L66XB interrupt mux */ static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) { struct t7l66xb *t7l66xb = get_irq_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); }
static void pm8058_irq_ack(unsigned int irq) { struct pm8058_chip *chip = get_irq_data(irq); u8 block, config; irq -= chip->pdata.irq_base; block = irq / 8; config = PM8058_IRQF_WRITE | chip->config[irq] | PM8058_IRQF_CLR; /* Keep the mask */ if (!(chip->irqs_allowed[block] & (1 << (irq % 8)))) config |= PM8058_IRQF_MASK_FE | PM8058_IRQF_MASK_RE; chip->bus_unlock_config[irq] = config; }
static void stmp3xxx_gpio_irq(u32 irq, struct irq_desc *desc) { struct stmp3xxx_pinmux_bank *pm = get_irq_data(irq); int gpio_irq = pm->virq; u32 stat = __raw_readl(pm->irqstat); while (stat) { if (stat & 1) irq_desc[gpio_irq].handle_irq(gpio_irq, &irq_desc[gpio_irq]); gpio_irq++; stat >>= 1; } }
static void stm_gpio_irqmux_handler(unsigned int irq, struct irq_desc *desc) { struct stm_gpio_irqmux *irqmux = get_irq_data(irq); unsigned long status; int bit; status = readl(irqmux->base); while ((bit = ffs(status)) != 0) { struct stm_gpio_port *port; bit--; port = &stm_gpio_ports[irqmux->port_first + bit]; __stm_gpio_irq_handler(port); status &= ~(1 << bit); } }
/* MX2 has one interrupt *for all* gpio ports */ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) { int i; u32 irq_msk, irq_stat; struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq); /* walk through all interrupt status registers */ for (i = 0; i < gpio_table_size; i++) { irq_msk = __raw_readl(port[i].base + GPIO_IMR); if (!irq_msk) continue; irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk; if (irq_stat) mxc_gpio_irq_handler(&port[i], irq_stat); } }
void setup_irq_data(void) { __list_all_irqs(); int i = 1; uint16_t vector; for(; i < 16; i++) { vector = i + IDT_VECTOR_OFFSET; struct irq_data *data = get_irq_data(i); data->irq_base = get_isa_irq_vector(i); data->irq = i; data->irq_config = kalloc(sizeof(struct irq_cfg)); data->irq_config->vector = (uint16_t)vector; install_irq_vector(data); } }
static void setup_irq_handler(unsigned int irq) { struct irq_data *idata = get_irq_data(irq); unsigned int stub_size = get_general_irqstub_size(); void *stub = kalloc(stub_size); memcpy(stub, gen_irq_stub, stub_size); /* * Now we will change the content of the IRQ handler data: * * The irq_handler first, then the irq number */ writel(stub+DYNAMIC_IRQ_HANDLER_VALUE, (unsigned int)&do_irq); writel(stub+DYNAMIC_IRQ_VALUE, idata->irq); idata->irq_base = (unsigned int)stub; }
/* MXS has one interrupt *per* gpio port */ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc) { u32 irq_stat; struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq); u32 gpio_irq_no_base = port->virtual_irq_start; desc->irq_data.chip->irq_ack(&desc->irq_data); irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) & __raw_readl(port->base + PINCTRL_IRQEN(port->id)); while (irq_stat != 0) { int irqoffset = fls(irq_stat) - 1; generic_handle_irq(gpio_irq_no_base + irqoffset); irq_stat &= ~(1 << irqoffset); } }
static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc) { struct mxs_gpio_port *port = get_irq_data(irq); int gpio_irq = port->child_irq; u32 irq_stat = port->chip->get_irq_stat(port); desc->chip->mask(irq); while (irq_stat) { if (irq_stat & 1) generic_handle_irq(gpio_irq); gpio_irq++; irq_stat >>= 1; } desc->chip->ack(irq); desc->chip->unmask(irq); }
static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned int gpio_irq_no, irq_stat; unsigned int port = (unsigned int)get_irq_data(irq); irq_stat = __raw_readl(GPIO_BASE(port) + GPIO_INT_STAT); gpio_irq_no = GPIO_IRQ_BASE + port * 32; 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 pmic_irq_handler(unsigned irq, struct irq_desc *desc) { struct pmic_gpio *pg = (struct pmic_gpio *)get_irq_data(irq); u8 intsts = *((u8 *)pg->gpiointr + 4); int gpio; for (gpio = 0; gpio < 8; gpio++) { if (intsts & (1 << gpio)) { pr_debug("pmic pin %d triggered\n", gpio); generic_handle_irq(pg->irq_base + gpio); } } if (desc->chip->irq_eoi) desc->chip->irq_eoi(irq_get_irq_data(irq)); else dev_warn(pg->chip.dev, "missing EOI handler for irq %d\n", irq); }
static void egpio_handler(unsigned int irq, struct irq_desc *desc) { struct egpio_info *ei = get_irq_data(irq); int irqpin; /* Read current pins. */ u16 readval = readw(&ei->addrBase[ei->ackRegister << ei->bus_shift]); /* Ack/unmask interrupts. */ ackirqs(ei); /* Process all set pins. */ for (irqpin=0; irqpin<MAX_EGPIO_IRQS; irqpin++) { if (!(readval & ei->irqsEnabled & (1<<irqpin))) continue; /* Run irq handler */ irq = ei->irqStart + irqpin; desc = &irq_desc[irq]; desc->handle_irq(irq, desc); } }
static int pm8901_irq_set_wake(unsigned int irq, unsigned int on) { struct pm8901_chip *chip = get_irq_data(irq); irq -= chip->pdata.irq_base; if (on) { if (!chip->wake_enable[irq]) { chip->wake_enable[irq] = 1; chip->count_wakeable++; } } else { if (chip->wake_enable[irq]) { chip->wake_enable[irq] = 0; chip->count_wakeable--; } } return 0; }
static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { struct nmk_gpio_chip *nmk_chip; struct irq_chip *host_chip; unsigned int gpio_irq; u32 pending; unsigned int first_irq; nmk_chip = get_irq_data(irq); first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) { gpio_irq = first_irq + __ffs(pending); generic_handle_irq(gpio_irq); } if (0) {/* don't ack parent irq, as ack == disable */ host_chip = get_irq_chip(irq); host_chip->ack(irq); } }