static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id) { struct nmk_gpio_platform_data *pdata; struct nmk_gpio_chip *nmk_chip; struct gpio_chip *chip; int ret; pdata = dev->dev.platform_data; ret = amba_request_regions(dev, pdata->name); if (ret) return ret; nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); if (!nmk_chip) { ret = -ENOMEM; goto out_amba; } /* * The virt address in nmk_chip->addr is in the nomadik register space, * so we can simply convert the resource address, without remapping */ nmk_chip->addr = io_p2v(dev->res.start); nmk_chip->chip = nmk_gpio_template; nmk_chip->parent_irq = pdata->parent_irq; chip = &nmk_chip->chip; chip->base = pdata->first_gpio; chip->label = pdata->name; chip->dev = &dev->dev; chip->owner = THIS_MODULE; ret = gpiochip_add(&nmk_chip->chip); if (ret) goto out_free; amba_set_drvdata(dev, nmk_chip); nmk_gpio_init_irq(nmk_chip); dev_info(&dev->dev, "Bits %i-%i at address %p\n", nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr); return 0; out_free: kfree(nmk_chip); out_amba: amba_release_regions(dev); dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret, pdata->first_gpio, pdata->first_gpio+31); return ret; }
static int __devinit nmk_gpio_probe(struct platform_device *dev) { struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; struct device_node *np = dev->dev.of_node; struct nmk_gpio_chip *nmk_chip; struct gpio_chip *chip; struct resource *res; struct clk *clk; int secondary_irq; void __iomem *base; int irq; int ret; if (!pdata && !np) { dev_err(&dev->dev, "No platform data or device tree found\n"); return -ENODEV; } if (np) { pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; if (of_get_property(np, "supports-sleepmode", NULL)) pdata->supports_sleepmode = true; if (of_property_read_u32(np, "gpio-bank", &dev->id)) { dev_err(&dev->dev, "gpio-bank property not found\n"); ret = -EINVAL; goto out; } pdata->first_gpio = dev->id * NMK_GPIO_PER_CHIP; pdata->num_gpio = NMK_GPIO_PER_CHIP; } res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) { ret = -ENOENT; goto out; } irq = platform_get_irq(dev, 0); if (irq < 0) { ret = irq; goto out; } secondary_irq = platform_get_irq(dev, 1); if (secondary_irq >= 0 && !pdata->get_secondary_status) { ret = -EINVAL; goto out; } if (request_mem_region(res->start, resource_size(res), dev_name(&dev->dev)) == NULL) { ret = -EBUSY; goto out; } base = ioremap(res->start, resource_size(res)); if (!base) { ret = -ENOMEM; goto out_release; } clk = clk_get(&dev->dev, NULL); if (IS_ERR(clk)) { ret = PTR_ERR(clk); goto out_unmap; } nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); if (!nmk_chip) { ret = -ENOMEM; goto out_clk; } /* * The virt address in nmk_chip->addr is in the nomadik register space, * so we can simply convert the resource address, without remapping */ nmk_chip->bank = dev->id; nmk_chip->clk = clk; nmk_chip->addr = base; nmk_chip->chip = nmk_gpio_template; nmk_chip->parent_irq = irq; nmk_chip->secondary_parent_irq = secondary_irq; nmk_chip->get_secondary_status = pdata->get_secondary_status; nmk_chip->set_ioforce = pdata->set_ioforce; nmk_chip->sleepmode = pdata->supports_sleepmode; spin_lock_init(&nmk_chip->lock); chip = &nmk_chip->chip; chip->base = pdata->first_gpio; chip->ngpio = pdata->num_gpio; chip->label = pdata->name ?: dev_name(&dev->dev); chip->dev = &dev->dev; chip->owner = THIS_MODULE; clk_enable(nmk_chip->clk); nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI); clk_disable(nmk_chip->clk); #ifdef CONFIG_OF_GPIO chip->of_node = np; #endif ret = gpiochip_add(&nmk_chip->chip); if (ret) goto out_free; BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips)); nmk_gpio_chips[nmk_chip->bank] = nmk_chip; platform_set_drvdata(dev, nmk_chip); nmk_chip->domain = irq_domain_add_legacy(np, NMK_GPIO_PER_CHIP, NOMADIK_GPIO_TO_IRQ(pdata->first_gpio), 0, &nmk_gpio_irq_simple_ops, nmk_chip); if (!nmk_chip->domain) { pr_err("%s: Failed to create irqdomain\n", np->full_name); ret = -ENOSYS; goto out_free; } nmk_gpio_init_irq(nmk_chip); dev_info(&dev->dev, "at address %p\n", nmk_chip->addr); return 0; out_free: kfree(nmk_chip); out_clk: clk_disable(clk); clk_put(clk); out_unmap: iounmap(base); out_release: release_mem_region(res->start, resource_size(res)); out: dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret, pdata->first_gpio, pdata->first_gpio+31); if (np) kfree(pdata); return ret; }
static int __devinit nmk_gpio_probe(struct platform_device *dev) { struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; struct nmk_gpio_chip *nmk_chip; struct gpio_chip *chip; struct resource *res; struct clk *clk; int secondary_irq; int irq; int ret; if (!pdata) return -ENODEV; res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) { ret = -ENOENT; goto out; } irq = platform_get_irq(dev, 0); if (irq < 0) { ret = irq; goto out; } secondary_irq = platform_get_irq(dev, 1); if (secondary_irq >= 0 && !pdata->get_secondary_status) { ret = -EINVAL; goto out; } if (request_mem_region(res->start, resource_size(res), dev_name(&dev->dev)) == NULL) { ret = -EBUSY; goto out; } clk = clk_get(&dev->dev, NULL); if (IS_ERR(clk)) { ret = PTR_ERR(clk); goto out_release; } clk_enable(clk); nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); if (!nmk_chip) { ret = -ENOMEM; goto out_clk; } /* * The virt address in nmk_chip->addr is in the nomadik register space, * so we can simply convert the resource address, without remapping */ nmk_chip->bank = dev->id; nmk_chip->clk = clk; nmk_chip->addr = io_p2v(res->start); nmk_chip->chip = nmk_gpio_template; nmk_chip->parent_irq = irq; nmk_chip->secondary_parent_irq = secondary_irq; nmk_chip->get_secondary_status = pdata->get_secondary_status; nmk_chip->set_ioforce = pdata->set_ioforce; nmk_chip->sleepmode = pdata->supports_sleepmode; spin_lock_init(&nmk_chip->lock); chip = &nmk_chip->chip; chip->base = pdata->first_gpio; chip->ngpio = pdata->num_gpio; chip->label = pdata->name ?: dev_name(&dev->dev); chip->dev = &dev->dev; chip->owner = THIS_MODULE; ret = gpiochip_add(&nmk_chip->chip); if (ret) goto out_free; BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips)); nmk_gpio_chips[nmk_chip->bank] = nmk_chip; platform_set_drvdata(dev, nmk_chip); nmk_gpio_init_irq(nmk_chip); dev_info(&dev->dev, "Bits %i-%i at address %p\n", nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr); return 0; out_free: kfree(nmk_chip); out_clk: clk_disable(clk); clk_put(clk); out_release: release_mem_region(res->start, resource_size(res)); out: dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret, pdata->first_gpio, pdata->first_gpio+31); return ret; }