gpio: hlwd: Pass irqchip when adding gpiochip
authorLinus Walleij <linus.walleij@linaro.org>
Fri, 9 Aug 2019 14:00:05 +0000 (16:00 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Thu, 15 Aug 2019 07:57:29 +0000 (09:57 +0200)
We need to convert all old gpio irqchips to pass the irqchip
setup along when adding the gpio_chip. For more info see
drivers/gpio/TODO.

For chained irqchips this is a pretty straight-forward
conversion.

Cc: Thierry Reding <treding@nvidia.com>
Link: https://lore.kernel.org/r/20190809140005.11654-1-linus.walleij@linaro.org
Reviewed-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Tested-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpio-hlwd.c

index e5fa00f8145f3e41eba8f48f851d832b42d88ac8..4a17599f6d44d23db22eb18d6ef9c5a409c10706 100644 (file)
@@ -244,43 +244,45 @@ static int hlwd_gpio_probe(struct platform_device *pdev)
                ngpios = 32;
        hlwd->gpioc.ngpio = ngpios;
 
-       res = devm_gpiochip_add_data(&pdev->dev, &hlwd->gpioc, hlwd);
-       if (res)
-               return res;
-
        /* Mask and ack all interrupts */
        iowrite32be(0, hlwd->regs + HW_GPIOB_INTMASK);
        iowrite32be(0xffffffff, hlwd->regs + HW_GPIOB_INTFLAG);
 
        /*
         * If this GPIO controller is not marked as an interrupt controller in
-        * the DT, return.
+        * the DT, skip interrupt support.
         */
-       if (!of_property_read_bool(pdev->dev.of_node, "interrupt-controller"))
-               return 0;
-
-       hlwd->irq = platform_get_irq(pdev, 0);
-       if (hlwd->irq < 0) {
-               dev_info(&pdev->dev, "platform_get_irq returned %d\n",
-                        hlwd->irq);
-               return hlwd->irq;
+       if (of_property_read_bool(pdev->dev.of_node, "interrupt-controller")) {
+               struct gpio_irq_chip *girq;
+
+               hlwd->irq = platform_get_irq(pdev, 0);
+               if (hlwd->irq < 0) {
+                       dev_info(&pdev->dev, "platform_get_irq returned %d\n",
+                                hlwd->irq);
+                       return hlwd->irq;
+               }
+
+               hlwd->irqc.name = dev_name(&pdev->dev);
+               hlwd->irqc.irq_mask = hlwd_gpio_irq_mask;
+               hlwd->irqc.irq_unmask = hlwd_gpio_irq_unmask;
+               hlwd->irqc.irq_enable = hlwd_gpio_irq_enable;
+               hlwd->irqc.irq_set_type = hlwd_gpio_irq_set_type;
+
+               girq = &hlwd->gpioc.irq;
+               girq->chip = &hlwd->irqc;
+               girq->parent_handler = hlwd_gpio_irqhandler;
+               girq->num_parents = 1;
+               girq->parents = devm_kcalloc(&pdev->dev, 1,
+                                            sizeof(*girq->parents),
+                                            GFP_KERNEL);
+               if (!girq->parents)
+                       return -ENOMEM;
+               girq->parents[0] = hlwd->irq;
+               girq->default_type = IRQ_TYPE_NONE;
+               girq->handler = handle_level_irq;
        }
 
-       hlwd->irqc.name = dev_name(&pdev->dev);
-       hlwd->irqc.irq_mask = hlwd_gpio_irq_mask;
-       hlwd->irqc.irq_unmask = hlwd_gpio_irq_unmask;
-       hlwd->irqc.irq_enable = hlwd_gpio_irq_enable;
-       hlwd->irqc.irq_set_type = hlwd_gpio_irq_set_type;
-
-       res = gpiochip_irqchip_add(&hlwd->gpioc, &hlwd->irqc, 0,
-                                  handle_level_irq, IRQ_TYPE_NONE);
-       if (res)
-               return res;
-
-       gpiochip_set_chained_irqchip(&hlwd->gpioc, &hlwd->irqc,
-                                    hlwd->irq, hlwd_gpio_irqhandler);
-
-       return 0;
+       return devm_gpiochip_add_data(&pdev->dev, &hlwd->gpioc, hlwd);
 }
 
 static const struct of_device_id hlwd_gpio_match[] = {