static int ftgpio_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct resource *res; struct ftgpio_gpio *g; int irq; int ret; g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL); if (!g) return -ENOMEM; g->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); g->base = devm_ioremap_resource(dev, res); if (IS_ERR(g->base)) return PTR_ERR(g->base); irq = platform_get_irq(pdev, 0); if (irq <= 0) return irq ? irq : -EINVAL; ret = bgpio_init(&g->gc, dev, 4, g->base + GPIO_DATA_IN, g->base + GPIO_DATA_SET, g->base + GPIO_DATA_CLR, g->base + GPIO_DIR, NULL, 0); if (ret) { dev_err(dev, "unable to init generic GPIO\n"); return ret; } g->gc.label = "FTGPIO010"; g->gc.base = -1; g->gc.parent = dev; g->gc.owner = THIS_MODULE; /* ngpio is set by bgpio_init() */ ret = devm_gpiochip_add_data(dev, &g->gc, g); if (ret) return ret; /* Disable, unmask and clear all interrupts */ writel(0x0, g->base + GPIO_INT_EN); writel(0x0, g->base + GPIO_INT_MASK); writel(~0x0, g->base + GPIO_INT_CLR); ret = gpiochip_irqchip_add(&g->gc, &ftgpio_gpio_irqchip, 0, handle_bad_irq, IRQ_TYPE_NONE); if (ret) { dev_info(dev, "could not add irqchip\n"); return ret; } gpiochip_set_chained_irqchip(&g->gc, &ftgpio_gpio_irqchip, irq, ftgpio_gpio_irq_handler); dev_info(dev, "FTGPIO010 @%p registered\n", g->base); return 0; }
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.parent = &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.base = gpio_base; priv->chip.ngpio = ddata->ngpio; priv->chip.can_sleep = false; priv->pdev = pdev; spin_lock_init(&priv->lock); pci_set_drvdata(pdev, priv); retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv); if (retval) { dev_err(&pdev->dev, "gpiochip_add error %d\n", retval); return retval; } retval = gpiochip_irqchip_add(&priv->chip, &intel_mid_irqchip, irq_base, handle_simple_irq, IRQ_TYPE_NONE); if (retval) { dev_err(&pdev->dev, "could not connect irqchip to gpiochip\n"); return retval; } intel_mid_irq_init_hw(priv); gpiochip_set_chained_irqchip(&priv->chip, &intel_mid_irqchip, pdev->irq, intel_mid_irq_handler); pm_runtime_put_noidle(&pdev->dev); pm_runtime_allow(&pdev->dev); return 0; }
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); 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) { byt_gpio_irq_init_hw(vg); ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0, handle_simple_irq, IRQ_TYPE_NONE); if (ret) { dev_err(dev, "failed to add irqchip\n"); gpiochip_remove(gc); return ret; } gpiochip_set_chained_irqchip(gc, &byt_irqchip, (unsigned)irq_rc->start, byt_gpio_irq_handler); } pm_runtime_enable(dev); return 0; }
static int int0002_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const struct x86_cpu_id *cpu_id; struct gpio_chip *chip; int irq, ret; /* Menlow has a different INT0002 device? <sigh> */ cpu_id = x86_match_cpu(int0002_cpu_ids); if (!cpu_id) return -ENODEV; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "Error getting IRQ: %d\n", irq); return irq; } chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; chip->label = DRV_NAME; chip->parent = dev; chip->owner = THIS_MODULE; chip->get = int0002_gpio_get; chip->set = int0002_gpio_set; chip->direction_input = int0002_gpio_get; chip->direction_output = int0002_gpio_direction_output; chip->base = -1; chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1; chip->irq.need_valid_mask = true; ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL); if (ret) { dev_err(dev, "Error adding gpio chip: %d\n", ret); return ret; } bitmap_clear(chip->irq.valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN); /* * We manually request the irq here instead of passing a flow-handler * to gpiochip_set_chained_irqchip, because the irq is shared. */ ret = devm_request_irq(dev, irq, int0002_irq, IRQF_SHARED | IRQF_NO_THREAD, "INT0002", chip); if (ret) { dev_err(dev, "Error requesting IRQ %d: %d\n", irq, ret); return ret; } ret = gpiochip_irqchip_add(chip, &int0002_irqchip, 0, handle_edge_irq, IRQ_TYPE_NONE); if (ret) { dev_err(dev, "Error adding irqchip: %d\n", ret); return ret; } gpiochip_set_chained_irqchip(chip, &int0002_irqchip, irq, NULL); return 0; }
static int oxnas_gpio_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct of_phandle_args pinspec; struct oxnas_gpio_bank *bank; unsigned int id, ngpios; int irq, ret; struct resource *res; if (of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &pinspec)) { dev_err(&pdev->dev, "gpio-ranges property not found\n"); return -EINVAL; } id = pinspec.args[1] / PINS_PER_BANK; ngpios = pinspec.args[2]; if (id >= ARRAY_SIZE(oxnas_gpio_banks)) { dev_err(&pdev->dev, "invalid gpio-ranges base arg\n"); return -EINVAL; } if (ngpios > PINS_PER_BANK) { dev_err(&pdev->dev, "invalid gpio-ranges count arg\n"); return -EINVAL; } bank = &oxnas_gpio_banks[id]; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bank->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(bank->reg_base)) return PTR_ERR(bank->reg_base); irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "irq get failed\n"); return irq; } bank->id = id; bank->gpio_chip.parent = &pdev->dev; bank->gpio_chip.of_node = np; bank->gpio_chip.ngpio = ngpios; ret = gpiochip_add_data(&bank->gpio_chip, bank); if (ret < 0) { dev_err(&pdev->dev, "Failed to add GPIO chip %u: %d\n", id, ret); return ret; } ret = gpiochip_irqchip_add(&bank->gpio_chip, &bank->irq_chip, 0, handle_level_irq, IRQ_TYPE_NONE); if (ret < 0) { dev_err(&pdev->dev, "Failed to add IRQ chip %u: %d\n", id, ret); gpiochip_remove(&bank->gpio_chip); return ret; } gpiochip_set_chained_irqchip(&bank->gpio_chip, &bank->irq_chip, irq, oxnas_gpio_irq_handler); return 0; }