gliolib: set hooks in gpiochip_set_irq_hooks()
authorHans Verkuil <hans.verkuil@cisco.com>
Sat, 8 Sep 2018 09:23:15 +0000 (11:23 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Mon, 10 Sep 2018 06:55:38 +0000 (08:55 +0200)
Centralize setting the irq_request/release_resources callbacks
in one function since we'll be adding more callbacks to that.

Also fix the removal of the callback overrides: this should
only be done if we actually installed our own callback there.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpiolib.c

index cbab0e7..b17f114 100644 (file)
@@ -1826,6 +1826,17 @@ static void gpiochip_irq_relres(struct irq_data *d)
        gpiochip_relres_irq(chip, d->hwirq);
 }
 
+static void gpiochip_set_irq_hooks(struct gpio_chip *gpiochip)
+{
+       struct irq_chip *irqchip = gpiochip->irq.chip;
+
+       if (!irqchip->irq_request_resources &&
+           !irqchip->irq_release_resources) {
+               irqchip->irq_request_resources = gpiochip_irq_reqres;
+               irqchip->irq_release_resources = gpiochip_irq_relres;
+       }
+}
+
 /**
  * gpiochip_add_irqchip() - adds an IRQ chip to a GPIO chip
  * @gpiochip: the GPIO chip to add the IRQ chip to
@@ -1884,16 +1895,6 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip,
        if (!gpiochip->irq.domain)
                return -EINVAL;
 
-       /*
-        * It is possible for a driver to override this, but only if the
-        * alternative functions are both implemented.
-        */
-       if (!irqchip->irq_request_resources &&
-           !irqchip->irq_release_resources) {
-               irqchip->irq_request_resources = gpiochip_irq_reqres;
-               irqchip->irq_release_resources = gpiochip_irq_relres;
-       }
-
        if (gpiochip->irq.parent_handler) {
                void *data = gpiochip->irq.parent_handler_data ?: gpiochip;
 
@@ -1909,6 +1910,8 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip,
                }
        }
 
+       gpiochip_set_irq_hooks(gpiochip);
+
        acpi_gpiochip_request_interrupts(gpiochip);
 
        return 0;
@@ -1922,11 +1925,12 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip,
  */
 static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
 {
+       struct irq_chip *irqchip = gpiochip->irq.chip;
        unsigned int offset;
 
        acpi_gpiochip_free_interrupts(gpiochip);
 
-       if (gpiochip->irq.chip && gpiochip->irq.parent_handler) {
+       if (irqchip && gpiochip->irq.parent_handler) {
                struct gpio_irq_chip *irq = &gpiochip->irq;
                unsigned int i;
 
@@ -1950,11 +1954,12 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
                irq_domain_remove(gpiochip->irq.domain);
        }
 
-       if (gpiochip->irq.chip) {
-               gpiochip->irq.chip->irq_request_resources = NULL;
-               gpiochip->irq.chip->irq_release_resources = NULL;
-               gpiochip->irq.chip = NULL;
+       if (irqchip &&
+           irqchip->irq_request_resources == gpiochip_irq_reqres) {
+               irqchip->irq_request_resources = NULL;
+               irqchip->irq_release_resources = NULL;
        }
+       gpiochip->irq.chip = NULL;
 
        gpiochip_irqchip_free_valid_mask(gpiochip);
 }
@@ -2043,15 +2048,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip,
                return -EINVAL;
        }
 
-       /*
-        * It is possible for a driver to override this, but only if the
-        * alternative functions are both implemented.
-        */
-       if (!irqchip->irq_request_resources &&
-           !irqchip->irq_release_resources) {
-               irqchip->irq_request_resources = gpiochip_irq_reqres;
-               irqchip->irq_release_resources = gpiochip_irq_relres;
-       }
+       gpiochip_set_irq_hooks(gpiochip);
 
        acpi_gpiochip_request_interrupts(gpiochip);