OSDN Git Service

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 4561cb3..71cd685 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 937c40f..02698c0 100644 (file)
@@ -103,13 +103,6 @@ struct gpio_irq_chip {
        unsigned int num_parents;
 
        /**
-        * @parent_irq:
-        *
-        * For use by gpiochip_set_cascaded_irqchip()
-        */
-       unsigned int parent_irq;
-
-       /**
         * @parents:
         *
         * A list of interrupt parents of a GPIO chip. This is owned by the