diff options
Diffstat (limited to 'drivers/gpio/gpio-grgpio.c')
-rw-r--r-- | drivers/gpio/gpio-grgpio.c | 75 |
1 files changed, 38 insertions, 37 deletions
diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c index 017c7170eb57..169f33c41c59 100644 --- a/drivers/gpio/gpio-grgpio.c +++ b/drivers/gpio/gpio-grgpio.c @@ -16,20 +16,20 @@ * Contributors: Andreas Larsson <andreas@gaisler.com> */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/spinlock.h> -#include <linux/io.h> -#include <linux/of.h> -#include <linux/gpio/driver.h> -#include <linux/slab.h> +#include <linux/bitops.h> #include <linux/err.h> +#include <linux/gpio/driver.h> +#include <linux/init.h> #include <linux/interrupt.h> +#include <linux/io.h> #include <linux/irq.h> #include <linux/irqdomain.h> -#include <linux/bitops.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/spinlock.h> #define GRGPIO_MAX_NGPIO 32 @@ -318,6 +318,13 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq) raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); } +static void grgpio_irq_domain_remove(void *data) +{ + struct irq_domain *domain = data; + + irq_domain_remove(domain); +} + static const struct irq_domain_ops grgpio_irq_domain_ops = { .map = grgpio_irq_map, .unmap = grgpio_irq_unmap, @@ -328,6 +335,7 @@ static const struct irq_domain_ops grgpio_irq_domain_ops = { static int grgpio_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; + struct device *dev = &ofdev->dev; void __iomem *regs; struct gpio_chip *gc; struct grgpio_priv *priv; @@ -337,7 +345,7 @@ static int grgpio_probe(struct platform_device *ofdev) int size; int i; - priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -346,28 +354,31 @@ static int grgpio_probe(struct platform_device *ofdev) return PTR_ERR(regs); gc = &priv->gc; - err = bgpio_init(gc, &ofdev->dev, 4, regs + GRGPIO_DATA, + err = bgpio_init(gc, dev, 4, regs + GRGPIO_DATA, regs + GRGPIO_OUTPUT, NULL, regs + GRGPIO_DIR, NULL, BGPIOF_BIG_ENDIAN_BYTE_ORDER); if (err) { - dev_err(&ofdev->dev, "bgpio_init() failed\n"); + dev_err(dev, "bgpio_init() failed\n"); return err; } priv->regs = regs; priv->imask = gc->read_reg(regs + GRGPIO_IMASK); - priv->dev = &ofdev->dev; + priv->dev = dev; gc->owner = THIS_MODULE; gc->to_irq = grgpio_to_irq; - gc->label = devm_kasprintf(&ofdev->dev, GFP_KERNEL, "%pOF", np); + gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np); + if (!gc->label) + return -ENOMEM; + gc->base = -1; err = of_property_read_u32(np, "nbits", &prop); if (err || prop <= 0 || prop > GRGPIO_MAX_NGPIO) { gc->ngpio = GRGPIO_MAX_NGPIO; - dev_dbg(&ofdev->dev, - "No or invalid nbits property: assume %d\n", gc->ngpio); + dev_dbg(dev, "No or invalid nbits property: assume %d\n", + gc->ngpio); } else { gc->ngpio = prop; } @@ -379,7 +390,7 @@ static int grgpio_probe(struct platform_device *ofdev) irqmap = (s32 *)of_get_property(np, "irqmap", &size); if (irqmap) { if (size < gc->ngpio) { - dev_err(&ofdev->dev, + dev_err(dev, "irqmap shorter than ngpio (%d < %d)\n", size, gc->ngpio); return -EINVAL; @@ -389,10 +400,15 @@ static int grgpio_probe(struct platform_device *ofdev) &grgpio_irq_domain_ops, priv); if (!priv->domain) { - dev_err(&ofdev->dev, "Could not add irq domain\n"); + dev_err(dev, "Could not add irq domain\n"); return -EINVAL; } + err = devm_add_action_or_reset(dev, grgpio_irq_domain_remove, + priv->domain); + if (err) + return err; + for (i = 0; i < gc->ngpio; i++) { struct grgpio_lirq *lirq; int ret; @@ -415,32 +431,18 @@ static int grgpio_probe(struct platform_device *ofdev) } } - platform_set_drvdata(ofdev, priv); - - err = gpiochip_add_data(gc, priv); + err = devm_gpiochip_add_data(dev, gc, priv); if (err) { - dev_err(&ofdev->dev, "Could not add gpiochip\n"); - if (priv->domain) - irq_domain_remove(priv->domain); + dev_err(dev, "Could not add gpiochip\n"); return err; } - dev_info(&ofdev->dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n", + dev_info(dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n", priv->regs, gc->base, gc->ngpio, priv->domain ? "on" : "off"); return 0; } -static void grgpio_remove(struct platform_device *ofdev) -{ - struct grgpio_priv *priv = platform_get_drvdata(ofdev); - - gpiochip_remove(&priv->gc); - - if (priv->domain) - irq_domain_remove(priv->domain); -} - static const struct of_device_id grgpio_match[] = { {.name = "GAISLER_GPIO"}, {.name = "01_01a"}, @@ -455,7 +457,6 @@ static struct platform_driver grgpio_driver = { .of_match_table = grgpio_match, }, .probe = grgpio_probe, - .remove_new = grgpio_remove, }; module_platform_driver(grgpio_driver); |