static int __init of_tb10x_init_irq(struct device_node *ictl, struct device_node *parent) { int i, ret, nrirqs = of_irq_count(ictl); struct resource mem; struct irq_chip_generic *gc; struct irq_domain *domain; void __iomem *reg_base; if (of_address_to_resource(ictl, 0, &mem)) { pr_err("%s: No registers declared in DeviceTree.\n", ictl->name); return -EINVAL; } if (!request_mem_region(mem.start, resource_size(&mem), ictl->name)) { pr_err("%s: Request mem region failed.\n", ictl->name); return -EBUSY; } reg_base = ioremap(mem.start, resource_size(&mem)); if (!reg_base) { ret = -EBUSY; pr_err("%s: ioremap failed.\n", ictl->name); goto ioremap_fail; } domain = irq_domain_add_linear(ictl, AB_IRQCTL_MAXIRQ, &irq_generic_chip_ops, NULL); if (!domain) { ret = -ENOMEM; pr_err("%s: Could not register interrupt domain.\n", ictl->name); goto irq_domain_add_fail; } ret = irq_alloc_domain_generic_chips(domain, AB_IRQCTL_MAXIRQ, 2, ictl->name, handle_level_irq, IRQ_NOREQUEST, IRQ_NOPROBE, IRQ_GC_INIT_MASK_CACHE); if (ret) { pr_err("%s: Could not allocate generic interrupt chip.\n", ictl->name); goto gc_alloc_fail; } gc = domain->gc->gc[0]; gc->reg_base = reg_base; gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK; gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; gc->chip_types[0].chip.irq_set_type = tb10x_irq_set_type; gc->chip_types[0].regs.mask = AB_IRQCTL_INT_ENABLE; gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH; gc->chip_types[1].chip.name = gc->chip_types[0].chip.name; gc->chip_types[1].chip.irq_ack = irq_gc_ack_set_bit; gc->chip_types[1].chip.irq_mask = irq_gc_mask_clr_bit; gc->chip_types[1].chip.irq_unmask = irq_gc_mask_set_bit; gc->chip_types[1].chip.irq_set_type = tb10x_irq_set_type; gc->chip_types[1].regs.ack = AB_IRQCTL_INT_STATUS; gc->chip_types[1].regs.mask = AB_IRQCTL_INT_ENABLE; gc->chip_types[1].handler = handle_edge_irq; for (i = 0; i < nrirqs; i++) { unsigned int irq = irq_of_parse_and_map(ictl, i); irq_set_handler_data(irq, domain); irq_set_chained_handler(irq, tb10x_irq_cascade); } ab_irqctl_writereg(gc, AB_IRQCTL_INT_ENABLE, 0); ab_irqctl_writereg(gc, AB_IRQCTL_INT_MODE, 0); ab_irqctl_writereg(gc, AB_IRQCTL_INT_POLARITY, 0); ab_irqctl_writereg(gc, AB_IRQCTL_INT_STATUS, ~0UL); return 0; gc_alloc_fail: irq_domain_remove(domain); irq_domain_add_fail: iounmap(reg_base); ioremap_fail: release_mem_region(mem.start, resource_size(&mem)); return ret; }
static int pdc_intc_probe(struct platform_device *pdev) { struct pdc_intc_priv *priv; struct device_node *node = pdev->dev.of_node; struct resource *res_regs; struct irq_chip_generic *gc; unsigned int i; int irq, ret; u32 val; if (!node) return -ENOENT; /* Get registers */ res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_regs == NULL) { dev_err(&pdev->dev, "cannot find registers resource\n"); return -ENOENT; } /* Allocate driver data */ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(&pdev->dev, "cannot allocate device data\n"); return -ENOMEM; } raw_spin_lock_init(&priv->lock); platform_set_drvdata(pdev, priv); /* Ioremap the registers */ priv->pdc_base = devm_ioremap(&pdev->dev, res_regs->start, res_regs->end - res_regs->start); if (!priv->pdc_base) return -EIO; /* Get number of peripherals */ ret = of_property_read_u32(node, "num-perips", &val); if (ret) { dev_err(&pdev->dev, "No num-perips node property found\n"); return -EINVAL; } if (val > SYS0_HWIRQ) { dev_err(&pdev->dev, "num-perips (%u) out of range\n", val); return -EINVAL; } priv->nr_perips = val; /* Get number of syswakes */ ret = of_property_read_u32(node, "num-syswakes", &val); if (ret) { dev_err(&pdev->dev, "No num-syswakes node property found\n"); return -EINVAL; } if (val > SYS0_HWIRQ) { dev_err(&pdev->dev, "num-syswakes (%u) out of range\n", val); return -EINVAL; } priv->nr_syswakes = val; /* Get peripheral IRQ numbers */ priv->perip_irqs = devm_kzalloc(&pdev->dev, 4 * priv->nr_perips, GFP_KERNEL); if (!priv->perip_irqs) { dev_err(&pdev->dev, "cannot allocate perip IRQ list\n"); return -ENOMEM; } for (i = 0; i < priv->nr_perips; ++i) { irq = platform_get_irq(pdev, 1 + i); if (irq < 0) { dev_err(&pdev->dev, "cannot find perip IRQ #%u\n", i); return irq; } priv->perip_irqs[i] = irq; } /* check if too many were provided */ if (platform_get_irq(pdev, 1 + i) >= 0) { dev_err(&pdev->dev, "surplus perip IRQs detected\n"); return -EINVAL; } /* Get syswake IRQ number */ irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "cannot find syswake IRQ\n"); return irq; } priv->syswake_irq = irq; /* Set up an IRQ domain */ priv->domain = irq_domain_add_linear(node, 16, &irq_generic_chip_ops, priv); if (unlikely(!priv->domain)) { dev_err(&pdev->dev, "cannot add IRQ domain\n"); return -ENOMEM; } /* * Set up 2 generic irq chips with 2 chip types. * The first one for peripheral irqs (only 1 chip type used) * The second one for syswake irqs (edge and level chip types) */ ret = irq_alloc_domain_generic_chips(priv->domain, 8, 2, "pdc", handle_level_irq, 0, 0, IRQ_GC_INIT_NESTED_LOCK); if (ret) goto err_generic; /* peripheral interrupt chip */ gc = irq_get_domain_generic_chip(priv->domain, 0); gc->unused = ~(BIT(priv->nr_perips) - 1); gc->reg_base = priv->pdc_base; /* * IRQ_ROUTE contains wake bits, so we can't use the generic versions as * they cache the mask */ gc->chip_types[0].regs.mask = PDC_IRQ_ROUTE; gc->chip_types[0].chip.irq_mask = perip_irq_mask; gc->chip_types[0].chip.irq_unmask = perip_irq_unmask; gc->chip_types[0].chip.irq_set_wake = pdc_irq_set_wake; /* syswake interrupt chip */ gc = irq_get_domain_generic_chip(priv->domain, 8); gc->unused = ~(BIT(priv->nr_syswakes) - 1); gc->reg_base = priv->pdc_base; /* edge interrupts */ gc->chip_types[0].type = IRQ_TYPE_EDGE_BOTH; gc->chip_types[0].handler = handle_edge_irq; gc->chip_types[0].regs.ack = PDC_IRQ_CLEAR; gc->chip_types[0].regs.mask = PDC_IRQ_ENABLE; gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; gc->chip_types[0].chip.irq_set_type = syswake_irq_set_type; gc->chip_types[0].chip.irq_set_wake = pdc_irq_set_wake; /* for standby we pass on to the shared syswake IRQ */ gc->chip_types[0].chip.flags = IRQCHIP_MASK_ON_SUSPEND; /* level interrupts */ gc->chip_types[1].type = IRQ_TYPE_LEVEL_MASK; gc->chip_types[1].handler = handle_level_irq; gc->chip_types[1].regs.ack = PDC_IRQ_CLEAR; gc->chip_types[1].regs.mask = PDC_IRQ_ENABLE; gc->chip_types[1].chip.irq_ack = irq_gc_ack_set_bit; gc->chip_types[1].chip.irq_mask = irq_gc_mask_clr_bit; gc->chip_types[1].chip.irq_unmask = irq_gc_mask_set_bit; gc->chip_types[1].chip.irq_set_type = syswake_irq_set_type; gc->chip_types[1].chip.irq_set_wake = pdc_irq_set_wake; /* for standby we pass on to the shared syswake IRQ */ gc->chip_types[1].chip.flags = IRQCHIP_MASK_ON_SUSPEND; /* Set up the hardware to enable interrupt routing */ pdc_intc_setup(priv); /* Setup chained handlers for the peripheral IRQs */ for (i = 0; i < priv->nr_perips; ++i) { irq = priv->perip_irqs[i]; irq_set_handler_data(irq, priv); irq_set_chained_handler(irq, pdc_intc_perip_isr); } /* Setup chained handler for the syswake IRQ */ irq_set_handler_data(priv->syswake_irq, priv); irq_set_chained_handler(priv->syswake_irq, pdc_intc_syswake_isr); dev_info(&pdev->dev, "PDC IRQ controller initialised (%u perip IRQs, %u syswake IRQs)\n", priv->nr_perips, priv->nr_syswakes); return 0; err_generic: irq_domain_remove(priv->domain); return ret; }
static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct s3c_irq_intc *intc = h->host_data; struct s3c_irq_data *irq_data = &intc->irqs[hw]; struct s3c_irq_intc *parent_intc; struct s3c_irq_data *parent_irq_data; unsigned int irqno; /* attach controller pointer to irq_data */ irq_data->intc = intc; irq_data->offset = hw; parent_intc = intc->parent; /* set handler and flags */ switch (irq_data->type) { case S3C_IRQTYPE_NONE: return 0; case S3C_IRQTYPE_EINT: /* On the S3C2412, the EINT0to3 have a parent irq * but need the s3c_irq_eint0t4 chip */ if (parent_intc && (!soc_is_s3c2412() || hw >= 4)) irq_set_chip_and_handler(virq, &s3c_irqext_chip, handle_edge_irq); else irq_set_chip_and_handler(virq, &s3c_irq_eint0t4, handle_edge_irq); break; case S3C_IRQTYPE_EDGE: if (parent_intc || intc->reg_pending == S3C2416_SRCPND2) irq_set_chip_and_handler(virq, &s3c_irq_level_chip, handle_edge_irq); else irq_set_chip_and_handler(virq, &s3c_irq_chip, handle_edge_irq); break; case S3C_IRQTYPE_LEVEL: if (parent_intc) irq_set_chip_and_handler(virq, &s3c_irq_level_chip, handle_level_irq); else irq_set_chip_and_handler(virq, &s3c_irq_chip, handle_level_irq); break; default: pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type); return -EINVAL; } irq_set_chip_data(virq, irq_data); set_irq_flags(virq, IRQF_VALID); if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) { if (irq_data->parent_irq > 31) { pr_err("irq-s3c24xx: parent irq %lu is out of range\n", irq_data->parent_irq); goto err; } parent_irq_data = &parent_intc->irqs[irq_data->parent_irq]; parent_irq_data->sub_intc = intc; parent_irq_data->sub_bits |= (1UL << hw); /* attach the demuxer to the parent irq */ irqno = irq_find_mapping(parent_intc->domain, irq_data->parent_irq); if (!irqno) { pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n", irq_data->parent_irq); goto err; } irq_set_chained_handler(irqno, s3c_irq_demux); } return 0; err: set_irq_flags(virq, 0); /* the only error can result from bad mapping data*/ return -EINVAL; }
/** * zynq_gpio_probe - Initialization method for a zynq_gpio device * @pdev: platform device instance * * This function allocates memory resources for the gpio device and registers * all the banks of the device. It will also set up interrupts for the gpio * pins. * Note: Interrupts are disabled for all the banks during initialization. * * Return: 0 on success, negative error otherwise. */ static int zynq_gpio_probe(struct platform_device *pdev) { int ret, pin_num, bank_num, gpio_irq; unsigned int irq_num; struct zynq_gpio *gpio; struct gpio_chip *chip; struct resource *res; gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); if (!gpio) return -ENOMEM; platform_set_drvdata(pdev, gpio); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); gpio->base_addr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(gpio->base_addr)) return PTR_ERR(gpio->base_addr); irq_num = platform_get_irq(pdev, 0); gpio->irq = irq_num; /* configure the gpio chip */ chip = &gpio->chip; chip->label = "zynq_gpio"; chip->owner = THIS_MODULE; chip->dev = &pdev->dev; chip->get = zynq_gpio_get_value; chip->set = zynq_gpio_set_value; chip->request = zynq_gpio_request; chip->free = zynq_gpio_free; chip->direction_input = zynq_gpio_dir_in; chip->direction_output = zynq_gpio_dir_out; chip->to_irq = zynq_gpio_to_irq; chip->dbg_show = NULL; chip->base = 0; /* default pin base */ chip->ngpio = ZYNQ_GPIO_NR_GPIOS; chip->can_sleep = 0; gpio->irq_base = irq_alloc_descs(-1, 0, chip->ngpio, 0); if (gpio->irq_base < 0) { dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n"); return -ENODEV; } irq_domain = irq_domain_add_legacy(pdev->dev.of_node, chip->ngpio, gpio->irq_base, 0, &irq_domain_simple_ops, NULL); /* report a bug if gpio chip registration fails */ ret = gpiochip_add(chip); if (ret < 0) return ret; /* Enable GPIO clock */ gpio->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(gpio->clk)) { dev_err(&pdev->dev, "input clock not found.\n"); if (gpiochip_remove(chip)) dev_err(&pdev->dev, "Failed to remove gpio chip\n"); return PTR_ERR(gpio->clk); } ret = clk_prepare_enable(gpio->clk); if (ret) { dev_err(&pdev->dev, "Unable to enable clock.\n"); if (gpiochip_remove(chip)) dev_err(&pdev->dev, "Failed to remove gpio chip\n"); return ret; } /* disable interrupts for all banks */ for (bank_num = 0; bank_num < ZYNQ_GPIO_MAX_BANK; bank_num++) { zynq_gpio_writereg(gpio->base_addr + ZYNQ_GPIO_INTDIS_OFFSET(bank_num), ZYNQ_GPIO_IXR_DISABLE_ALL); } /* * set the irq chip, handler and irq chip data for callbacks for * each pin */ for (pin_num = 0; pin_num < min_t(int, ZYNQ_GPIO_NR_GPIOS, (int)chip->ngpio); pin_num++) { gpio_irq = irq_find_mapping(irq_domain, pin_num); irq_set_chip_and_handler(gpio_irq, &zynq_gpio_irqchip, handle_simple_irq); irq_set_chip_data(gpio_irq, (void *)gpio); set_irq_flags(gpio_irq, IRQF_VALID); } irq_set_handler_data(irq_num, (void *)gpio); irq_set_chained_handler(irq_num, zynq_gpio_irqhandler); pm_runtime_enable(&pdev->dev); device_set_wakeup_capable(&pdev->dev, 1); return 0; }
int __init pq2ads_pci_init_irq(void) { struct pq2ads_pci_pic *priv; struct irq_host *host; struct device_node *np; int ret = -ENODEV; int irq; np = of_find_compatible_node(NULL, NULL, "fsl,pq2ads-pci-pic"); if (!np) { printk(KERN_ERR "No pci pic node in device tree.\n"); of_node_put(np); goto out; } irq = irq_of_parse_and_map(np, 0); if (irq == NO_IRQ) { printk(KERN_ERR "No interrupt in pci pic node.\n"); of_node_put(np); goto out; } priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { of_node_put(np); ret = -ENOMEM; goto out_unmap_irq; } /* PCI interrupt controller registers: status and mask */ priv->regs = of_iomap(np, 0); if (!priv->regs) { printk(KERN_ERR "Cannot map PCI PIC registers.\n"); goto out_free_bootmem; } /* mask all PCI interrupts */ out_be32(&priv->regs->mask, ~0); mb(); host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, NUM_IRQS, &pci_pic_host_ops, NUM_IRQS); if (!host) { ret = -ENOMEM; goto out_unmap_regs; } host->host_data = priv; priv->host = host; host->host_data = priv; irq_set_handler_data(irq, priv); irq_set_chained_handler(irq, pq2ads_pci_irq_demux); of_node_put(np); return 0; out_unmap_regs: iounmap(priv->regs); out_free_bootmem: free_bootmem((unsigned long)priv, sizeof(struct pq2ads_pci_pic)); of_node_put(np); out_unmap_irq: irq_dispose_mapping(irq); out: return ret; }
static int pl061_probe(struct amba_device *adev, const struct amba_id *id) { struct device *dev = &adev->dev; struct pl061_platform_data *pdata = dev->platform_data; struct pl061_gpio *chip; int ret, irq, i, irq_base; struct device_node *np = dev->of_node; chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; if (pdata) { chip->gc.base = pdata->gpio_base; irq_base = pdata->irq_base; if (irq_base <= 0) return -ENODEV; } else { chip->gc.base = pl061_parse_gpio_base(dev); irq_base = 0; } if (!devm_request_mem_region(dev, adev->res.start, resource_size(&adev->res), "pl061")) return -EBUSY; chip->base = devm_ioremap(dev, adev->res.start, resource_size(&adev->res)); if (!chip->base) return -ENOMEM; spin_lock_init(&chip->lock); if (of_get_property(np, "gpio,hwspinlock", NULL)) { gpio_hwlock = hwspin_lock_request_specific(GPIO_HWLOCK_ID); if (gpio_hwlock == NULL) return -EBUSY; } /* Hook the request()/free() for pinctrl operation */ if (of_get_property(dev->of_node, "gpio-ranges", NULL)) { chip->gc.request = pl061_gpio_request; chip->gc.free = pl061_gpio_free; } chip->gc.direction_input = pl061_direction_input; chip->gc.direction_output = pl061_direction_output; chip->gc.get = pl061_get_value; chip->gc.set = pl061_set_value; chip->gc.to_irq = pl061_to_irq; chip->gc.ngpio = PL061_GPIO_NR; chip->gc.label = dev_name(dev); chip->gc.dev = dev; chip->gc.owner = THIS_MODULE; ret = gpiochip_add(&chip->gc); if (ret) return ret; /* * irq_chip support */ writeb(0, chip->base + GPIOIE); /* disable irqs */ irq = adev->irq[0]; if (irq < 0) return -ENODEV; irq_set_chained_handler(irq, pl061_irq_handler); irq_set_handler_data(irq, chip); chip->domain = irq_domain_add_simple(adev->dev.of_node, PL061_GPIO_NR, irq_base, &pl061_domain_ops, chip); if (!chip->domain) return -ENODEV; for (i = 0; i < PL061_GPIO_NR; i++) { if (pdata) { if (pdata->directions & (1 << i)) pl061_direction_output(&chip->gc, i, pdata->values & (1 << i)); else pl061_direction_input(&chip->gc, i); } } amba_set_drvdata(adev, chip); return 0; }
/* MMP2 (ARMv7) */ void __init mmp2_init_icu(void) { int irq; max_icu_nr = 8; mmp_icu_base = ioremap(0xd4282000, 0x1000); icu_data[0].conf_enable = mmp2_conf.conf_enable; icu_data[0].conf_disable = mmp2_conf.conf_disable; icu_data[0].conf_mask = mmp2_conf.conf_mask; icu_data[0].nr_irqs = 64; icu_data[0].virq_base = 0; icu_data[0].domain = irq_domain_add_legacy(NULL, 64, 0, 0, &irq_domain_simple_ops, &icu_data[0]); icu_data[1].reg_status = mmp_icu_base + 0x150; icu_data[1].reg_mask = mmp_icu_base + 0x168; icu_data[1].clr_mfp_irq_base = IRQ_MMP2_PMIC_BASE; icu_data[1].clr_mfp_hwirq = IRQ_MMP2_PMIC - IRQ_MMP2_PMIC_BASE; icu_data[1].nr_irqs = 2; icu_data[1].cascade_irq = 4; icu_data[1].virq_base = IRQ_MMP2_PMIC_BASE; icu_data[1].domain = irq_domain_add_legacy(NULL, icu_data[1].nr_irqs, icu_data[1].virq_base, 0, &irq_domain_simple_ops, &icu_data[1]); icu_data[2].reg_status = mmp_icu_base + 0x154; icu_data[2].reg_mask = mmp_icu_base + 0x16c; icu_data[2].nr_irqs = 2; icu_data[2].cascade_irq = 5; icu_data[2].virq_base = IRQ_MMP2_RTC_BASE; icu_data[2].domain = irq_domain_add_legacy(NULL, icu_data[2].nr_irqs, icu_data[2].virq_base, 0, &irq_domain_simple_ops, &icu_data[2]); icu_data[3].reg_status = mmp_icu_base + 0x180; icu_data[3].reg_mask = mmp_icu_base + 0x17c; icu_data[3].nr_irqs = 3; icu_data[3].cascade_irq = 9; icu_data[3].virq_base = IRQ_MMP2_KEYPAD_BASE; icu_data[3].domain = irq_domain_add_legacy(NULL, icu_data[3].nr_irqs, icu_data[3].virq_base, 0, &irq_domain_simple_ops, &icu_data[3]); icu_data[4].reg_status = mmp_icu_base + 0x158; icu_data[4].reg_mask = mmp_icu_base + 0x170; icu_data[4].nr_irqs = 5; icu_data[4].cascade_irq = 17; icu_data[4].virq_base = IRQ_MMP2_TWSI_BASE; icu_data[4].domain = irq_domain_add_legacy(NULL, icu_data[4].nr_irqs, icu_data[4].virq_base, 0, &irq_domain_simple_ops, &icu_data[4]); icu_data[5].reg_status = mmp_icu_base + 0x15c; icu_data[5].reg_mask = mmp_icu_base + 0x174; icu_data[5].nr_irqs = 15; icu_data[5].cascade_irq = 35; icu_data[5].virq_base = IRQ_MMP2_MISC_BASE; icu_data[5].domain = irq_domain_add_legacy(NULL, icu_data[5].nr_irqs, icu_data[5].virq_base, 0, &irq_domain_simple_ops, &icu_data[5]); icu_data[6].reg_status = mmp_icu_base + 0x160; icu_data[6].reg_mask = mmp_icu_base + 0x178; icu_data[6].nr_irqs = 2; icu_data[6].cascade_irq = 51; icu_data[6].virq_base = IRQ_MMP2_MIPI_HSI1_BASE; icu_data[6].domain = irq_domain_add_legacy(NULL, icu_data[6].nr_irqs, icu_data[6].virq_base, 0, &irq_domain_simple_ops, &icu_data[6]); icu_data[7].reg_status = mmp_icu_base + 0x188; icu_data[7].reg_mask = mmp_icu_base + 0x184; icu_data[7].nr_irqs = 2; icu_data[7].cascade_irq = 55; icu_data[7].virq_base = IRQ_MMP2_MIPI_HSI0_BASE; icu_data[7].domain = irq_domain_add_legacy(NULL, icu_data[7].nr_irqs, icu_data[7].virq_base, 0, &irq_domain_simple_ops, &icu_data[7]); for (irq = 0; irq < IRQ_MMP2_MUX_END; irq++) { icu_mask_irq(irq_get_irq_data(irq)); switch (irq) { case IRQ_MMP2_PMIC_MUX: case IRQ_MMP2_RTC_MUX: case IRQ_MMP2_KEYPAD_MUX: case IRQ_MMP2_TWSI_MUX: case IRQ_MMP2_MISC_MUX: case IRQ_MMP2_MIPI_HSI1_MUX: case IRQ_MMP2_MIPI_HSI0_MUX: irq_set_chip(irq, &icu_irq_chip); irq_set_chained_handler(irq, icu_mux_irq_demux); break; default: irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq); break; } set_irq_flags(irq, IRQF_VALID); } irq_set_default_host(icu_data[0].domain); #ifdef CONFIG_CPU_MMP2 icu_irq_chip.irq_set_wake = mmp2_set_wake; #endif }
static int tz1090_gpio_bank_probe(struct tz1090_gpio_bank_info *info) { struct device_node *np = info->node; struct device *dev = info->priv->dev; struct tz1090_gpio_bank *bank; struct irq_chip_generic *gc; int err; bank = devm_kzalloc(dev, sizeof(*bank), GFP_KERNEL); if (!bank) { dev_err(dev, "unable to allocate driver data\n"); return -ENOMEM; } /* Offset the main registers to the first register in this bank */ bank->reg = info->priv->reg + info->index * 4; /* Set up GPIO chip */ snprintf(bank->label, sizeof(bank->label), "tz1090-gpio-%u", info->index); bank->chip.label = bank->label; bank->chip.dev = dev; bank->chip.direction_input = tz1090_gpio_direction_input; bank->chip.direction_output = tz1090_gpio_direction_output; bank->chip.get = tz1090_gpio_get; bank->chip.set = tz1090_gpio_set; bank->chip.free = tz1090_gpio_free; bank->chip.request = tz1090_gpio_request; bank->chip.to_irq = tz1090_gpio_to_irq; bank->chip.of_node = np; /* GPIO numbering from 0 */ bank->chip.base = info->index * 30; bank->chip.ngpio = 30; /* Add the GPIO bank */ gpiochip_add(&bank->chip); /* Get the GPIO bank IRQ if provided */ bank->irq = irq_of_parse_and_map(np, 0); /* The interrupt is optional (it may be used by another core on chip) */ if (bank->irq < 0) { dev_info(dev, "IRQ not provided for bank %u, IRQs disabled\n", info->index); return 0; } dev_info(dev, "Setting up IRQs for GPIO bank %u\n", info->index); /* * Initialise all interrupts to disabled so we don't get * spurious ones on a dirty boot and hit the BUG_ON in the * handler. */ tz1090_gpio_write(bank, REG_GPIO_IRQ_EN, 0); /* Add a virtual IRQ for each GPIO */ bank->domain = irq_domain_add_linear(np, bank->chip.ngpio, &irq_generic_chip_ops, bank); /* Set up a generic irq chip with 2 chip types (level and edge) */ err = irq_alloc_domain_generic_chips(bank->domain, bank->chip.ngpio, 2, bank->label, handle_bad_irq, 0, 0, IRQ_GC_INIT_NESTED_LOCK); if (err) { dev_info(dev, "irq_alloc_domain_generic_chips failed for bank %u, IRQs disabled\n", info->index); irq_domain_remove(bank->domain); return 0; } gc = irq_get_domain_generic_chip(bank->domain, 0); gc->reg_base = bank->reg; /* level chip type */ gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK; gc->chip_types[0].handler = handle_level_irq; gc->chip_types[0].regs.ack = REG_GPIO_IRQ_STS; gc->chip_types[0].regs.mask = REG_GPIO_IRQ_EN; gc->chip_types[0].chip.irq_startup = gpio_startup_irq; gc->chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit; gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; gc->chip_types[0].chip.irq_set_type = gpio_set_irq_type; gc->chip_types[0].chip.irq_set_wake = gpio_set_irq_wake; gc->chip_types[0].chip.flags = IRQCHIP_MASK_ON_SUSPEND; /* edge chip type */ gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH; gc->chip_types[1].handler = handle_edge_irq; gc->chip_types[1].regs.ack = REG_GPIO_IRQ_STS; gc->chip_types[1].regs.mask = REG_GPIO_IRQ_EN; gc->chip_types[1].chip.irq_startup = gpio_startup_irq; gc->chip_types[1].chip.irq_ack = irq_gc_ack_clr_bit; gc->chip_types[1].chip.irq_mask = irq_gc_mask_clr_bit; gc->chip_types[1].chip.irq_unmask = irq_gc_mask_set_bit; gc->chip_types[1].chip.irq_set_type = gpio_set_irq_type; gc->chip_types[1].chip.irq_set_wake = gpio_set_irq_wake; gc->chip_types[1].chip.flags = IRQCHIP_MASK_ON_SUSPEND; /* Setup chained handler for this GPIO bank */ irq_set_handler_data(bank->irq, bank); irq_set_chained_handler(bank->irq, tz1090_gpio_irq_handler); return 0; }
static int __devinit jz_adc_probe(struct platform_device *pdev) { int ret; struct jz_adc *adc; struct resource *mem_base; int irq; int i; unsigned char clkdiv, clkdiv_us; unsigned short clkdiv_ms; struct jz_battery_info *battery_info; struct jz_adc_platform_data *adc_platform_data = pdev->dev.platform_data; if(!adc_platform_data) { dev_err(&pdev->dev,"no platform data,can't attach\n"); return -EINVAL; } battery_info = &adc_platform_data->battery_info; adc = kmalloc(sizeof(*adc), GFP_KERNEL); if (!adc) { dev_err(&pdev->dev, "Failed to allocate driver structre\n"); return -ENOMEM; } adc->irq = platform_get_irq(pdev, 0); if (adc->irq < 0) { ret = adc->irq; dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret); goto err_free; } adc->irq_base = platform_get_irq(pdev, 1); if (adc->irq_base < 0) { ret = adc->irq_base; dev_err(&pdev->dev, "Failed to get irq base: %d\n", ret); goto err_free; } mem_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_base) { ret = -ENOENT; dev_err(&pdev->dev, "Failed to get platform mmio resource"); goto err_free; } adc->mem = request_mem_region(mem_base->start, JZ_REG_ADC_STATUS, pdev->name); if (!adc->mem) { ret = -EBUSY; dev_err(&pdev->dev, "Failed to request mmio memory region\n"); goto err_free; } adc->base = ioremap_nocache(adc->mem->start, resource_size(adc->mem)); if (!adc->base) { ret = -EBUSY; dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); goto err_release_mem_region; } adc->clk = clk_get(&pdev->dev, "sadc"); if (IS_ERR(adc->clk)) { ret = PTR_ERR(adc->clk); dev_err(&pdev->dev, "Failed to get clock: %d\n", ret); goto err_iounmap; } spin_lock_init(&adc->lock); atomic_set(&adc->clk_ref, 0); platform_set_drvdata(pdev, adc); for (irq = adc->irq_base; irq < adc->irq_base + SADC_NR_IRQS; ++irq) { irq_set_chip_data(irq, adc); irq_set_chip_and_handler(irq, &jz_adc_irq_chip, handle_level_irq); } irq_set_handler_data(adc->irq, adc); irq_set_chained_handler(adc->irq, jz_adc_irq_demux); clk_enable(adc->clk); writeb(0x80, adc->base + JZ_REG_ADC_ENABLE); writeb(0xff, adc->base + JZ_REG_ADC_CTRL); clkdiv = CLKDIV - 1; clkdiv_us = CLKDIV_US - 1; clkdiv_ms = CLKDIV_MS - 1; jz_adc_clk_div(adc, clkdiv, clkdiv_us, clkdiv_ms); for(i = 0;i < ARRAY_SIZE(jz_adc_cells);i++) { switch(jz_adc_cells[i].id) { case 1: jz_adc_cells[i].platform_data = battery_info; break; default: break; } } ret = mfd_add_devices(&pdev->dev, 0, jz_adc_cells, ARRAY_SIZE(jz_adc_cells), mem_base, adc->irq_base); if (ret < 0) { goto err_clk_put; } printk("jz4775 SADC driver registeres over!\n"); return 0; err_clk_put: clk_put(adc->clk); err_iounmap: platform_set_drvdata(pdev, NULL); iounmap(adc->base); err_release_mem_region: release_mem_region(adc->mem->start, resource_size(adc->mem)); err_free: kfree(adc); return ret; }
static int byt_gpio_probe(struct platform_device *pdev) { struct byt_gpio *vg; struct gpio_chip *gc; struct resource *mem_rc, *irq_rc; struct device *dev = &pdev->dev; struct acpi_device *acpi_dev; struct pinctrl_gpio_range *range; acpi_handle handle = ACPI_HANDLE(dev); unsigned hwirq; int ret; if (acpi_bus_get_device(handle, &acpi_dev)) return -ENODEV; vg = devm_kzalloc(dev, sizeof(struct byt_gpio), GFP_KERNEL); if (!vg) { dev_err(&pdev->dev, "can't allocate byt_gpio chip data\n"); return -ENOMEM; } for (range = byt_ranges; range->name; range++) { if (!strcmp(acpi_dev->pnp.unique_id, range->name)) { vg->chip.ngpio = range->npins; vg->range = range; break; } } if (!vg->chip.ngpio || !vg->range) return -ENODEV; vg->pdev = pdev; platform_set_drvdata(pdev, vg); mem_rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); vg->reg_base = devm_ioremap_resource(dev, mem_rc); if (IS_ERR(vg->reg_base)) return PTR_ERR(vg->reg_base); spin_lock_init(&vg->lock); gc = &vg->chip; gc->label = dev_name(&pdev->dev); gc->owner = THIS_MODULE; gc->request = byt_gpio_request; gc->free = byt_gpio_free; gc->direction_input = byt_gpio_direction_input; gc->direction_output = byt_gpio_direction_output; gc->get = byt_gpio_get; gc->set = byt_gpio_set; gc->dbg_show = byt_gpio_dbg_show; gc->base = -1; gc->can_sleep = false; gc->dev = dev; ret = gpiochip_add(gc); if (ret) { dev_err(&pdev->dev, "failed adding byt-gpio chip\n"); return ret; } /* set up interrupts */ irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (irq_rc && irq_rc->start) { hwirq = irq_rc->start; gc->to_irq = byt_gpio_to_irq; vg->domain = irq_domain_add_linear(NULL, gc->ngpio, &byt_gpio_irq_ops, vg); if (!vg->domain) return -ENXIO; byt_gpio_irq_init_hw(vg); irq_set_handler_data(hwirq, vg); irq_set_chained_handler(hwirq, byt_gpio_irq_handler); } pm_runtime_enable(dev); return 0; }
static struct megamod_pic * __init init_megamod_pic(struct device_node *np) { struct megamod_pic *pic; int i, irq; int mapping[NR_MUX_OUTPUTS]; pr_info("Initializing C64x+ Megamodule PIC\n"); pic = kzalloc(sizeof(struct megamod_pic), GFP_KERNEL); if (!pic) { pr_err("%s: Could not alloc PIC structure.\n", np->full_name); return NULL; } pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, NR_COMBINERS * 32, &megamod_host_ops, IRQ_UNMAPPED); if (!pic->irqhost) { pr_err("%s: Could not alloc host.\n", np->full_name); goto error_free; } pic->irqhost->host_data = pic; raw_spin_lock_init(&pic->lock); pic->regs = of_iomap(np, 0); if (!pic->regs) { pr_err("%s: Could not map registers.\n", np->full_name); goto error_free; } /* Initialize MUX map */ for (i = 0; i < ARRAY_SIZE(mapping); i++) mapping[i] = IRQ_UNMAPPED; parse_priority_map(pic, mapping, ARRAY_SIZE(mapping)); /* * We can have up to 12 interrupts cascading to the core controller. * These cascades can be from the combined interrupt sources or for * individual interrupt sources. The "interrupts" property only * deals with the cascaded combined interrupts. The individual * interrupts muxed to the core controller use the core controller * as their interrupt parent. */ for (i = 0; i < NR_COMBINERS; i++) { irq = irq_of_parse_and_map(np, i); if (irq == NO_IRQ) continue; /* * We count on the core priority interrupts (4 - 15) being * direct mapped. Check that device tree provided something * in that range. */ if (irq < 4 || irq >= NR_PRIORITY_IRQS) { pr_err("%s: combiner-%d virq %d out of range!\n", np->full_name, i, irq); continue; } /* record the mapping */ mapping[irq - 4] = i; pr_debug("%s: combiner-%d cascading to virq %d\n", np->full_name, i, irq); cascade_data[i].pic = pic; cascade_data[i].index = i; /* mask and clear all events in combiner */ soc_writel(~0, &pic->regs->evtmask[i]); soc_writel(~0, &pic->regs->evtclr[i]); irq_set_handler_data(irq, &cascade_data[i]); irq_set_chained_handler(irq, megamod_irq_cascade); } /* Finally, set up the MUX registers */ for (i = 0; i < NR_MUX_OUTPUTS; i++) { if (mapping[i] != IRQ_UNMAPPED) { pr_debug("%s: setting mux %d to priority %d\n", np->full_name, mapping[i], i + 4); set_megamod_mux(pic, mapping[i], i); } } return pic; error_free: kfree(pic); return NULL; }
static int __init exynos_init_irq_eint(void) { int irq; #ifdef CONFIG_PINCTRL_SAMSUNG /* * The Samsung pinctrl driver provides an integrated gpio/pinmux/pinconf * functionality along with support for external gpio and wakeup * interrupts. If the samsung pinctrl driver is enabled and includes * the wakeup interrupt support, then the setting up external wakeup * interrupts here can be skipped. This check here is temporary to * allow exynos4 platforms that do not use Samsung pinctrl driver to * co-exist with platforms that do. When all of the Samsung Exynos4 * platforms switch over to using the pinctrl driver, the wakeup * interrupt support code here can be completely removed. */ struct device_node *pctrl_np, *wkup_np; const char *pctrl_compat = "samsung,pinctrl-exynos4210"; const char *wkup_compat = "samsung,exynos4210-wakeup-eint"; for_each_compatible_node(pctrl_np, NULL, pctrl_compat) { if (of_device_is_available(pctrl_np)) { wkup_np = of_find_compatible_node(pctrl_np, NULL, wkup_compat); if (wkup_np) return -ENODEV; } } #endif if (soc_is_exynos5250()) exynos_eint_base = ioremap(EXYNOS5_PA_GPIO1, SZ_4K); else exynos_eint_base = ioremap(EXYNOS4_PA_GPIO2, SZ_4K); if (exynos_eint_base == NULL) { pr_err("unable to ioremap for EINT base address\n"); return -ENOMEM; } for (irq = 0 ; irq <= 31 ; irq++) { irq_set_chip_and_handler(IRQ_EINT(irq), &exynos_irq_eint, handle_level_irq); set_irq_flags(IRQ_EINT(irq), IRQF_VALID); } irq_set_chained_handler(EXYNOS_IRQ_EINT16_31, exynos_irq_demux_eint16_31); for (irq = 0 ; irq <= 15 ; irq++) { eint0_15_data[irq] = IRQ_EINT(irq); if (soc_is_exynos5250()) { irq_set_handler_data(exynos5_eint0_15_src_int[irq], &eint0_15_data[irq]); irq_set_chained_handler(exynos5_eint0_15_src_int[irq], exynos_irq_eint0_15); } else { irq_set_handler_data(exynos4_eint0_15_src_int[irq], &eint0_15_data[irq]); irq_set_chained_handler(exynos4_eint0_15_src_int[irq], exynos_irq_eint0_15); } } return 0; }
static int lnw_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) { void *base; resource_size_t start, len; struct lnw_gpio *lnw; u32 gpio_base; u32 irq_base; int retval; int ngpio = id->driver_data; retval = pci_enable_device(pdev); if (retval) return retval; retval = pci_request_regions(pdev, "langwell_gpio"); if (retval) { dev_err(&pdev->dev, "error requesting resources\n"); goto err_pci_req_region; } /* get the gpio_base from bar1 */ start = pci_resource_start(pdev, 1); len = pci_resource_len(pdev, 1); base = ioremap_nocache(start, len); if (!base) { dev_err(&pdev->dev, "error mapping bar1\n"); retval = -EFAULT; goto err_ioremap; } irq_base = *(u32 *)base; gpio_base = *((u32 *)base + 1); /* release the IO mapping, since we already get the info from bar1 */ iounmap(base); /* get the register base from bar0 */ start = pci_resource_start(pdev, 0); len = pci_resource_len(pdev, 0); base = devm_ioremap_nocache(&pdev->dev, start, len); if (!base) { dev_err(&pdev->dev, "error mapping bar0\n"); retval = -EFAULT; goto err_ioremap; } lnw = devm_kzalloc(&pdev->dev, sizeof(*lnw), GFP_KERNEL); if (!lnw) { dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n"); retval = -ENOMEM; goto err_ioremap; } lnw->reg_base = base; lnw->chip.label = dev_name(&pdev->dev); lnw->chip.request = lnw_gpio_request; lnw->chip.direction_input = lnw_gpio_direction_input; lnw->chip.direction_output = lnw_gpio_direction_output; lnw->chip.get = lnw_gpio_get; lnw->chip.set = lnw_gpio_set; lnw->chip.to_irq = lnw_gpio_to_irq; lnw->chip.base = gpio_base; lnw->chip.ngpio = ngpio; lnw->chip.can_sleep = 0; lnw->pdev = pdev; lnw->domain = irq_domain_add_simple(pdev->dev.of_node, ngpio, irq_base, &lnw_gpio_irq_ops, lnw); if (!lnw->domain) { retval = -ENOMEM; goto err_ioremap; } pci_set_drvdata(pdev, lnw); retval = gpiochip_add(&lnw->chip); if (retval) { dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval); goto err_ioremap; } lnw_irq_init_hw(lnw); irq_set_handler_data(pdev->irq, lnw); irq_set_chained_handler(pdev->irq, lnw_irq_handler); spin_lock_init(&lnw->lock); pm_runtime_put_noidle(&pdev->dev); pm_runtime_allow(&pdev->dev); return 0; err_ioremap: pci_release_regions(pdev); err_pci_req_region: pci_disable_device(pdev); return retval; }
static int jz4740_adc_probe(struct platform_device *pdev) { struct irq_chip_generic *gc; struct irq_chip_type *ct; struct jz4740_adc *adc; struct resource *mem_base; int ret; int irq_base; adc = devm_kzalloc(&pdev->dev, sizeof(*adc), GFP_KERNEL); if (!adc) { dev_err(&pdev->dev, "Failed to allocate driver structure\n"); return -ENOMEM; } adc->irq = platform_get_irq(pdev, 0); if (adc->irq < 0) { ret = adc->irq; dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret); return ret; } irq_base = platform_get_irq(pdev, 1); if (irq_base < 0) { dev_err(&pdev->dev, "Failed to get irq base: %d\n", irq_base); return irq_base; } mem_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_base) { dev_err(&pdev->dev, "Failed to get platform mmio resource\n"); return -ENOENT; } /* Only request the shared registers for the MFD driver */ adc->mem = request_mem_region(mem_base->start, JZ_REG_ADC_STATUS, pdev->name); if (!adc->mem) { dev_err(&pdev->dev, "Failed to request mmio memory region\n"); return -EBUSY; } adc->base = ioremap_nocache(adc->mem->start, resource_size(adc->mem)); if (!adc->base) { ret = -EBUSY; dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); goto err_release_mem_region; } adc->clk = clk_get(&pdev->dev, "adc"); if (IS_ERR(adc->clk)) { ret = PTR_ERR(adc->clk); dev_err(&pdev->dev, "Failed to get clock: %d\n", ret); goto err_iounmap; } spin_lock_init(&adc->lock); atomic_set(&adc->clk_ref, 0); platform_set_drvdata(pdev, adc); gc = irq_alloc_generic_chip("INTC", 1, irq_base, adc->base, handle_level_irq); ct = gc->chip_types; ct->regs.mask = JZ_REG_ADC_CTRL; ct->regs.ack = JZ_REG_ADC_STATUS; ct->chip.irq_mask = irq_gc_mask_set_bit; ct->chip.irq_unmask = irq_gc_mask_clr_bit; ct->chip.irq_ack = irq_gc_ack_set_bit; irq_setup_generic_chip(gc, IRQ_MSK(5), 0, 0, IRQ_NOPROBE | IRQ_LEVEL); adc->gc = gc; irq_set_handler_data(adc->irq, gc); irq_set_chained_handler(adc->irq, jz4740_adc_irq_demux); writeb(0x00, adc->base + JZ_REG_ADC_ENABLE); writeb(0xff, adc->base + JZ_REG_ADC_CTRL); ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells, ARRAY_SIZE(jz4740_adc_cells), mem_base, irq_base, NULL); if (ret < 0) goto err_clk_put; return 0; err_clk_put: clk_put(adc->clk); err_iounmap: iounmap(adc->base); err_release_mem_region: release_mem_region(adc->mem->start, resource_size(adc->mem)); return ret; }
int __init mmp2_mux_init(struct device_node *parent) { struct device_node *node; const struct of_device_id *of_id; struct resource res; int i, irq_base, ret, irq; u32 nr_irqs, mfp_irq; node = parent; max_icu_nr = 1; for (i = 1; i < MAX_ICU_NR; i++) { node = of_find_matching_node(node, mmp_mux_irq_match); if (!node) break; of_id = of_match_node(&mmp_mux_irq_match[0], node); ret = of_property_read_u32(node, "mrvl,intc-nr-irqs", &nr_irqs); if (ret) { pr_err("Not found mrvl,intc-nr-irqs property\n"); ret = -EINVAL; goto err; } ret = of_address_to_resource(node, 0, &res); if (ret < 0) { pr_err("Not found reg property\n"); ret = -EINVAL; goto err; } icu_data[i].reg_status = mmp_icu_base + res.start; ret = of_address_to_resource(node, 1, &res); if (ret < 0) { pr_err("Not found reg property\n"); ret = -EINVAL; goto err; } icu_data[i].reg_mask = mmp_icu_base + res.start; icu_data[i].cascade_irq = irq_of_parse_and_map(node, 0); if (!icu_data[i].cascade_irq) { ret = -EINVAL; goto err; } irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); if (irq_base < 0) { pr_err("Failed to allocate IRQ numbers for mux intc\n"); ret = irq_base; goto err; } if (!of_property_read_u32(node, "mrvl,clr-mfp-irq", &mfp_irq)) { icu_data[i].clr_mfp_irq_base = irq_base; icu_data[i].clr_mfp_hwirq = mfp_irq; } irq_set_chained_handler(icu_data[i].cascade_irq, icu_mux_irq_demux); icu_data[i].nr_irqs = nr_irqs; icu_data[i].virq_base = irq_base; icu_data[i].domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 0, &mmp_irq_domain_ops, &icu_data[i]); for (irq = irq_base; irq < irq_base + nr_irqs; irq++) icu_mask_irq(irq_get_irq_data(irq)); } max_icu_nr = i; return 0; err: of_node_put(node); max_icu_nr = i; return ret; }
static void __init mpc8xxx_add_controller(struct device_node *np) { struct mpc8xxx_gpio_chip *mpc8xxx_gc; struct of_mm_gpio_chip *mm_gc; struct gpio_chip *gc; const struct of_device_id *id; unsigned hwirq; int ret; mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL); if (!mpc8xxx_gc) { ret = -ENOMEM; goto err; } spin_lock_init(&mpc8xxx_gc->lock); mm_gc = &mpc8xxx_gc->mm_gc; gc = &mm_gc->gc; mm_gc->save_regs = mpc8xxx_gpio_save_regs; gc->ngpio = MPC8XXX_GPIO_PINS; gc->direction_input = mpc8xxx_gpio_dir_in; gc->direction_output = of_device_is_compatible(np, "fsl,mpc5121-gpio") ? mpc5121_gpio_dir_out : mpc8xxx_gpio_dir_out; gc->get = of_device_is_compatible(np, "fsl,mpc8572-gpio") ? mpc8572_gpio_get : mpc8xxx_gpio_get; gc->set = mpc8xxx_gpio_set; gc->to_irq = mpc8xxx_gpio_to_irq; ret = of_mm_gpiochip_add(np, mm_gc); if (ret) goto err; hwirq = irq_of_parse_and_map(np, 0); if (hwirq == NO_IRQ) goto skip_irq; mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS, &mpc8xxx_gpio_irq_ops, mpc8xxx_gc); if (!mpc8xxx_gc->irq) goto skip_irq; id = of_match_node(mpc8xxx_gpio_ids, np); if (id) mpc8xxx_gc->of_dev_id_data = id->data; /* ack and mask all irqs */ out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); out_be32(mm_gc->regs + GPIO_IMR, 0); irq_set_handler_data(hwirq, mpc8xxx_gc); irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade); skip_irq: return; err: pr_err("%s: registration failed with status %d\n", np->full_name, ret); kfree(mpc8xxx_gc); return; }
static int intel_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) { void __iomem *base; struct intel_mid_gpio *priv; u32 gpio_base; u32 irq_base; int retval; struct intel_mid_gpio_ddata *ddata = (struct intel_mid_gpio_ddata *)id->driver_data; retval = pcim_enable_device(pdev); if (retval) return retval; retval = pcim_iomap_regions(pdev, 1 << 0 | 1 << 1, pci_name(pdev)); if (retval) { dev_err(&pdev->dev, "I/O memory mapping error\n"); return retval; } base = pcim_iomap_table(pdev)[1]; irq_base = readl(base); gpio_base = readl(sizeof(u32) + base); /* release the IO mapping, since we already get the info from bar1 */ pcim_iounmap_regions(pdev, 1 << 1); priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(&pdev->dev, "can't allocate chip data\n"); return -ENOMEM; } priv->reg_base = pcim_iomap_table(pdev)[0]; priv->chip.label = dev_name(&pdev->dev); priv->chip.dev = &pdev->dev; priv->chip.request = intel_gpio_request; priv->chip.direction_input = intel_gpio_direction_input; priv->chip.direction_output = intel_gpio_direction_output; priv->chip.get = intel_gpio_get; priv->chip.set = intel_gpio_set; priv->chip.to_irq = intel_gpio_to_irq; priv->chip.base = gpio_base; priv->chip.ngpio = ddata->ngpio; priv->chip.can_sleep = false; priv->pdev = pdev; spin_lock_init(&priv->lock); priv->domain = irq_domain_add_simple(pdev->dev.of_node, ddata->ngpio, irq_base, &intel_gpio_irq_ops, priv); if (!priv->domain) return -ENOMEM; pci_set_drvdata(pdev, priv); retval = gpiochip_add(&priv->chip); if (retval) { dev_err(&pdev->dev, "gpiochip_add error %d\n", retval); return retval; } intel_mid_irq_init_hw(priv); irq_set_handler_data(pdev->irq, priv); irq_set_chained_handler(pdev->irq, intel_mid_irq_handler); pm_runtime_put_noidle(&pdev->dev); pm_runtime_allow(&pdev->dev); return 0; }
/** * xgpiops_probe - Initialization method for a xgpiops device * @pdev: platform device instance * * This function allocates memory resources for the gpio device and registers * all the banks of the device. It will also set up interrupts for the gpio * pins. * Note: Interrupts are disabled for all the banks during initialization. * Returns 0 on success, negative error otherwise. */ static int __devinit xgpiops_probe(struct platform_device *pdev) { int ret; unsigned int irq_num; struct xgpiops *gpio; struct gpio_chip *chip; resource_size_t remap_size; struct resource *mem_res = NULL; int pin_num, bank_num, gpio_irq; gpio = kzalloc(sizeof(struct xgpiops), GFP_KERNEL); if (!gpio) { dev_err(&pdev->dev, "couldn't allocate memory for gpio private data\n"); return -ENOMEM; } spin_lock_init(&gpio->gpio_lock); platform_set_drvdata(pdev, gpio); mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_res) { dev_err(&pdev->dev, "No memory resource\n"); ret = -ENODEV; goto err_free_gpio; } remap_size = mem_res->end - mem_res->start + 1; if (!request_mem_region(mem_res->start, remap_size, pdev->name)) { dev_err(&pdev->dev, "Cannot request IO\n"); ret = -ENXIO; goto err_free_gpio; } gpio->base_addr = ioremap(mem_res->start, remap_size); if (gpio->base_addr == NULL) { dev_err(&pdev->dev, "Couldn't ioremap memory at 0x%08lx\n", (unsigned long)mem_res->start); ret = -ENOMEM; goto err_release_region; } irq_num = platform_get_irq(pdev, 0); gpio->irq = irq_num; /* configure the gpio chip */ chip = &gpio->chip; chip->label = "xgpiops"; chip->owner = THIS_MODULE; chip->dev = &pdev->dev; chip->get = xgpiops_get_value; chip->set = xgpiops_set_value; chip->request = xgpiops_request; chip->free = xgpiops_free; chip->direction_input = xgpiops_dir_in; chip->direction_output = xgpiops_dir_out; chip->to_irq = xgpiops_to_irq; chip->dbg_show = NULL; chip->base = 0; /* default pin base */ chip->ngpio = XGPIOPS_NR_GPIOS; chip->can_sleep = 0; /* report a bug if gpio chip registration fails */ ret = gpiochip_add(chip); if (ret < 0) { dev_err(&pdev->dev, "gpio chip registration failed\n"); goto err_iounmap; } else { dev_info(&pdev->dev, "gpio at 0x%08lx mapped to 0x%08lx\n", (unsigned long)mem_res->start, (unsigned long)gpio->base_addr); } /* Enable GPIO clock */ gpio->clk = clk_get_sys("GPIO_APER", NULL); if (IS_ERR(gpio->clk)) { dev_err(&pdev->dev, "Clock not found.\n"); ret = PTR_ERR(gpio->clk); goto err_chip_remove; } ret = clk_prepare_enable(gpio->clk); if (ret) { dev_err(&pdev->dev, "Unable to enable clock.\n"); goto err_clk_put; } /* disable interrupts for all banks */ for (bank_num = 0; bank_num < 4; bank_num++) { xgpiops_writereg(0xffffffff, gpio->base_addr + XGPIOPS_INTDIS_OFFSET(bank_num)); } /* * set the irq chip, handler and irq chip data for callbacks for * each pin */ gpio_irq = XGPIOPS_IRQBASE; for (pin_num = 0; pin_num < XGPIOPS_NR_GPIOS; pin_num++, gpio_irq++) { irq_set_chip(gpio_irq, &xgpiops_irqchip); irq_set_chip_data(gpio_irq, (void *)gpio); irq_set_handler(gpio_irq, handle_simple_irq); irq_set_status_flags(gpio_irq, IRQF_VALID); irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST); } irq_set_handler_data(irq_num, (void *)(XGPIOPS_IRQBASE)); irq_set_chained_handler(irq_num, xgpiops_irqhandler); xgpiops_pm_runtime_init(pdev); device_set_wakeup_capable(&pdev->dev, 1); return 0; err_clk_put: clk_put(gpio->clk); err_chip_remove: gpiochip_remove(chip); err_iounmap: iounmap(gpio->base_addr); err_release_region: release_mem_region(mem_res->start, remap_size); err_free_gpio: platform_set_drvdata(pdev, NULL); kfree(gpio); return ret; }
static int __init orion_bridge_irq_init(struct device_node *np, struct device_node *parent) { unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; struct resource r; struct irq_domain *domain; struct irq_chip_generic *gc; int ret, irq, nrirqs = 32; /* get optional number of interrupts provided */ of_property_read_u32(np, "marvell,#interrupts", &nrirqs); domain = irq_domain_add_linear(np, nrirqs, &irq_generic_chip_ops, NULL); if (!domain) { pr_err("%s: unable to add irq domain\n", np->name); return -ENOMEM; } ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name, handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); if (ret) { pr_err("%s: unable to alloc irq domain gc\n", np->name); return ret; } ret = of_address_to_resource(np, 0, &r); if (ret) { pr_err("%s: unable to get resource\n", np->name); return ret; } if (!request_mem_region(r.start, resource_size(&r), np->name)) { pr_err("%s: unable to request mem region\n", np->name); return -ENOMEM; } /* Map the parent interrupt for the chained handler */ irq = irq_of_parse_and_map(np, 0); if (irq <= 0) { pr_err("%s: unable to parse irq\n", np->name); return -EINVAL; } gc = irq_get_domain_generic_chip(domain, 0); gc->reg_base = ioremap(r.start, resource_size(&r)); if (!gc->reg_base) { pr_err("%s: unable to map resource\n", np->name); return -ENOMEM; } gc->chip_types[0].regs.ack = ORION_BRIDGE_IRQ_CAUSE; gc->chip_types[0].regs.mask = ORION_BRIDGE_IRQ_MASK; gc->chip_types[0].chip.irq_startup = orion_bridge_irq_startup; gc->chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit; gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; /* mask and clear all interrupts */ writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK); writel(0, gc->reg_base + ORION_BRIDGE_IRQ_CAUSE); irq_set_handler_data(irq, domain); irq_set_chained_handler(irq, orion_bridge_irq_handler); return 0; }
static int cs75xx_gpio_probe(struct platform_device *pdev) { int i, j; char tmp_str[16]; struct resource *res_mem; gpio_dbgmsg("Function: %s, pdev->name = %s\n", __func__, pdev->name); memset(cs75xx_gpio_base, 0, sizeof(cs75xx_gpio_base)); /* get the module base address and irq number */ sprintf(tmp_str, "global"); res_mem = platform_get_resource_byname(pdev, IORESOURCE_IO, tmp_str); if (!res_mem) { gpio_dbgmsg("Func: %s - can't get resource %s\n", __func__, tmp_str); goto fail; } cs75xx_global_base = ioremap(res_mem->start, res_mem->end - res_mem->start + 1); if (!cs75xx_global_base) { gpio_dbgmsg("Func: %s - unable to remap %s %d memory \n", __func__, tmp_str, res_mem->end - res_mem->start + 1); goto fail; } gpio_dbgmsg("\tcs75xx_global_base = %p\n", cs75xx_global_base); for (i = 0; i < GPIO_BANK_NUM; i++) { sprintf(tmp_str, "gpio%d", i); res_mem = platform_get_resource_byname(pdev, IORESOURCE_IO, tmp_str); if (!res_mem) { gpio_dbgmsg("Func: %s - can't get resource %s\n", __func__, tmp_str); goto fail; } cs75xx_gpio_base[i] = ioremap(res_mem->start, res_mem->end - res_mem->start + 1); if (!cs75xx_gpio_base[i]) { gpio_dbgmsg("Func: %s - unable to remap %s %d memory \n", __func__, tmp_str, res_mem->end - res_mem->start + 1); goto fail; } gpio_dbgmsg("\tcs75xx_gpio_base[%d] = %p\n", i, cs75xx_gpio_base[i]); } for (i = 0; i < GPIO_BANK_NUM; i++) { sprintf(tmp_str, "irq_gpio%d", i); cs75xx_irq_gpio[i] = platform_get_irq_byname(pdev, tmp_str); if (cs75xx_irq_gpio[i] == -ENXIO) { gpio_dbgmsg("Func: %s - can't get resource %s\n", __func__, tmp_str); goto fail; } gpio_dbgmsg("\tcs75xx_irq_gpio[%d] = %08x\n", i, cs75xx_irq_gpio[i]); } /* disable irq and register to gpiolib */ for (i = 0; i < GPIO_BANK_NUM; i++) { /* disable, unmask and clear all interrupts */ __raw_writel(0x0, cs75xx_gpio_base[i] + CS75XX_GPIO_IE); for (j = GPIO_IRQ_BASE + i * GPIO_BANK_SIZE; j < GPIO_IRQ_BASE + (i + 1) * GPIO_BANK_SIZE; j++) { irq_set_chip(j, &cs75xx_gpio_irq_chip); irq_set_handler(j, handle_edge_irq); set_irq_flags(j, IRQF_VALID); } irq_set_chained_handler(cs75xx_irq_gpio[i], cs75xx_gpio_irq_handler); irq_set_handler_data(cs75xx_irq_gpio[i], (void *)i); } BUG_ON(gpiochip_add(&cs75xx_gpio_chip)); return 0; fail: for (i = 0; i < GPIO_BANK_NUM; i++) if (cs75xx_gpio_base[i]) iounmap(cs75xx_gpio_base[i]); return -ENODEV; }
void __init baboon_register_interrupts(void) { irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq); }
static int __init eic_probe(struct platform_device *pdev) { struct eic *eic; struct resource *regs; unsigned int i; unsigned int nr_of_irqs; unsigned int int_irq; int ret; u32 pattern; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); int_irq = platform_get_irq(pdev, 0); if (!regs || (int)int_irq <= 0) { dev_dbg(&pdev->dev, "missing regs and/or irq resource\n"); return -ENXIO; } ret = -ENOMEM; eic = kzalloc(sizeof(struct eic), GFP_KERNEL); if (!eic) { dev_dbg(&pdev->dev, "no memory for eic structure\n"); goto err_kzalloc; } eic->first_irq = EIM_IRQ_BASE + 32 * pdev->id; eic->regs = ioremap(regs->start, resource_size(regs)); if (!eic->regs) { dev_dbg(&pdev->dev, "failed to map regs\n"); goto err_ioremap; } /* */ eic_writel(eic, IDR, ~0UL); eic_writel(eic, MODE, ~0UL); pattern = eic_readl(eic, MODE); nr_of_irqs = fls(pattern); /* */ eic_writel(eic, EDGE, 0UL); eic_writel(eic, LEVEL, 0UL); eic->chip = &eic_chip; for (i = 0; i < nr_of_irqs; i++) { irq_set_chip_and_handler(eic->first_irq + i, &eic_chip, handle_level_irq); irq_set_chip_data(eic->first_irq + i, eic); } irq_set_chained_handler(int_irq, demux_eic_irq); irq_set_handler_data(int_irq, eic); if (pdev->id == 0) { nmi_eic = eic; if (nmi_enabled) /* */ nmi_enable(); } dev_info(&pdev->dev, "External Interrupt Controller at 0x%p, IRQ %u\n", eic->regs, int_irq); dev_info(&pdev->dev, "Handling %u external IRQs, starting with IRQ %u\n", nr_of_irqs, eic->first_irq); return 0; err_ioremap: kfree(eic); err_kzalloc: return ret; }
static int __devinit ezx_pcap_probe(struct spi_device *spi) { struct pcap_platform_data *pdata = spi->dev.platform_data; struct pcap_chip *pcap; int i, adc_irq; int ret = -ENODEV; /* platform data is required */ if (!pdata) goto ret; pcap = kzalloc(sizeof(*pcap), GFP_KERNEL); if (!pcap) { ret = -ENOMEM; goto ret; } mutex_init(&pcap->io_mutex); mutex_init(&pcap->adc_mutex); INIT_WORK(&pcap->isr_work, pcap_isr_work); INIT_WORK(&pcap->msr_work, pcap_msr_work); dev_set_drvdata(&spi->dev, pcap); /* setup spi */ spi->bits_per_word = 32; spi->mode = SPI_MODE_0 | (pdata->config & PCAP_CS_AH ? SPI_CS_HIGH : 0); ret = spi_setup(spi); if (ret) goto free_pcap; pcap->spi = spi; /* setup irq */ pcap->irq_base = pdata->irq_base; pcap->workqueue = create_singlethread_workqueue("pcapd"); if (!pcap->workqueue) { ret = -ENOMEM; dev_err(&spi->dev, "can't create pcap thread\n"); goto free_pcap; } /* redirect interrupts to AP, except adcdone2 */ if (!(pdata->config & PCAP_SECOND_PORT)) ezx_pcap_write(pcap, PCAP_REG_INT_SEL, (1 << PCAP_IRQ_ADCDONE2)); /* setup irq chip */ for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) { irq_set_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq); irq_set_chip_data(i, pcap); #ifdef CONFIG_ARM set_irq_flags(i, IRQF_VALID); #else irq_set_noprobe(i); #endif } /* mask/ack all PCAP interrupts */ ezx_pcap_write(pcap, PCAP_REG_MSR, PCAP_MASK_ALL_INTERRUPT); ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER); pcap->msr = PCAP_MASK_ALL_INTERRUPT; irq_set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING); irq_set_handler_data(spi->irq, pcap); irq_set_chained_handler(spi->irq, pcap_irq_handler); irq_set_irq_wake(spi->irq, 1); /* ADC */ adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ? PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE); ret = request_irq(adc_irq, pcap_adc_irq, 0, "ADC", pcap); if (ret) goto free_irqchip; /* setup subdevs */ for (i = 0; i < pdata->num_subdevs; i++) { ret = pcap_add_subdev(pcap, &pdata->subdevs[i]); if (ret) goto remove_subdevs; } /* board specific quirks */ if (pdata->init) pdata->init(pcap); return 0; remove_subdevs: device_for_each_child(&spi->dev, NULL, pcap_remove_subdev); /* free_adc: */ free_irq(adc_irq, pcap); free_irqchip: for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) irq_set_chip_and_handler(i, NULL, NULL); /* destroy_workqueue: */ destroy_workqueue(pcap->workqueue); free_pcap: kfree(pcap); ret: return ret; }
int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip) { irq_set_chained_handler(chip->devirq, NULL); kfree(chip); return 0; }
int __devinit altera_gpio_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; int id, reg, ret; struct altera_gpio_chip *altera_gc = devm_kzalloc(&pdev->dev, sizeof(*altera_gc), GFP_KERNEL); if (altera_gc == NULL) { ret = -ENOMEM; pr_err("%s: registration failed with status %d\n", node->full_name, ret); return ret; } altera_gc->irq = 0; spin_lock_init(&altera_gc->gpio_lock); id = pdev->id; if (of_property_read_u32(node, "width", ®)) /*By default assume full GPIO controller*/ altera_gc->mmchip.gc.ngpio = 32; else altera_gc->mmchip.gc.ngpio = reg; if (altera_gc->mmchip.gc.ngpio > 32) { pr_warn("%s: ngpio is greater than 32, defaulting to 32\n", node->full_name); altera_gc->mmchip.gc.ngpio = 32; } altera_gc->mmchip.gc.direction_input = altera_gpio_direction_input; altera_gc->mmchip.gc.direction_output = altera_gpio_direction_output; altera_gc->mmchip.gc.get = altera_gpio_get; altera_gc->mmchip.gc.set = altera_gpio_set; altera_gc->mmchip.gc.to_irq = altera_gpio_to_irq; altera_gc->mmchip.gc.owner = THIS_MODULE; ret = of_mm_gpiochip_add(node, &altera_gc->mmchip); if (ret) goto err; platform_set_drvdata(pdev, altera_gc); if (of_get_property(node, "interrupts", ®) == NULL) goto skip_irq; altera_gc->hwirq = irq_of_parse_and_map(node, 0); if (altera_gc->hwirq == NO_IRQ) goto skip_irq; altera_gc->irq = irq_domain_add_linear(node, altera_gc->mmchip.gc.ngpio, &altera_gpio_irq_ops, altera_gc); if (!altera_gc->irq) { ret = -ENODEV; goto dispose_irq; } if (of_property_read_u32(node, "level_trigger", ®)) { ret = -EINVAL; pr_err("%s: level_trigger value not set in device tree\n", node->full_name); goto teardown; } altera_gc->level_trigger = reg; irq_set_handler_data(altera_gc->hwirq, altera_gc); irq_set_chained_handler(altera_gc->hwirq, altera_gpio_irq_handler); return 0; teardown: irq_domain_remove(altera_gc->irq); dispose_irq: irq_dispose_mapping(altera_gc->hwirq); WARN_ON(gpiochip_remove(&altera_gc->mmchip.gc) < 0); err: pr_err("%s: registration failed with status %d\n", node->full_name, ret); devm_kfree(&pdev->dev, altera_gc); return ret; skip_irq: return 0; }