gpio: Drop the parent_irq from gpio_irq_chip
authorLinus Walleij <linus.walleij@linaro.org>
Fri, 14 Jun 2019 08:12:26 +0000 (10:12 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Fri, 14 Jun 2019 08:16:16 +0000 (10:16 +0200)
We already have an array named "parents" so instead
of letting one point to the other, simply allocate a
dynamic array to hold the parents, just one if desired
and drop the number of members in gpio_irq_chip by
1. Rename gpiochip to gc in the process.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpiolib.c
include/linux/gpio/driver.h

index 4561cb39bdb45fe34c5a47c31a10bec94e3424fd..71cd685ed6c462b40975c1c0c2f3f1d448dc926e 100644 (file)
@@ -1644,39 +1644,47 @@ EXPORT_SYMBOL_GPL(gpiochip_irqchip_irq_valid);
 
 /**
  * gpiochip_set_cascaded_irqchip() - connects a cascaded irqchip to a gpiochip
- * @gpiochip: the gpiochip to set the irqchip chain to
+ * @gc: the gpiochip to set the irqchip chain to
  * @parent_irq: the irq number corresponding to the parent IRQ for this
  * chained irqchip
  * @parent_handler: the parent interrupt handler for the accumulated IRQ
  * coming out of the gpiochip. If the interrupt is nested rather than
  * cascaded, pass NULL in this handler argument
  */
-static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gpiochip,
+static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gc,
                                          unsigned int parent_irq,
                                          irq_flow_handler_t parent_handler)
 {
-       if (!gpiochip->irq.domain) {
-               chip_err(gpiochip, "called %s before setting up irqchip\n",
+       struct gpio_irq_chip *girq = &gc->irq;
+       struct device *dev = &gc->gpiodev->dev;
+
+       if (!girq->domain) {
+               chip_err(gc, "called %s before setting up irqchip\n",
                         __func__);
                return;
        }
 
        if (parent_handler) {
-               if (gpiochip->can_sleep) {
-                       chip_err(gpiochip,
+               if (gc->can_sleep) {
+                       chip_err(gc,
                                 "you cannot have chained interrupts on a chip that may sleep\n");
                        return;
                }
+               girq->parents = devm_kcalloc(dev, 1,
+                                            sizeof(*girq->parents),
+                                            GFP_KERNEL);
+               if (!girq->parents) {
+                       chip_err(gc, "out of memory allocating parent IRQ\n");
+                       return;
+               }
+               girq->parents[0] = parent_irq;
+               girq->num_parents = 1;
                /*
                 * The parent irqchip is already using the chip_data for this
                 * irqchip, so our callbacks simply use the handler_data.
                 */
                irq_set_chained_handler_and_data(parent_irq, parent_handler,
-                                                gpiochip);
-
-               gpiochip->irq.parent_irq = parent_irq;
-               gpiochip->irq.parents = &gpiochip->irq.parent_irq;
-               gpiochip->irq.num_parents = 1;
+                                                gc);
        }
 }
 
index 937c40fb61f7e727d6c89b219c90bc40823a26d1..02698c0f34eaef16c3ea1082d7a256a44068a91e 100644 (file)
@@ -102,13 +102,6 @@ struct gpio_irq_chip {
         */
        unsigned int num_parents;
 
-       /**
-        * @parent_irq:
-        *
-        * For use by gpiochip_set_cascaded_irqchip()
-        */
-       unsigned int parent_irq;
-
        /**
         * @parents:
         *