From: Hans Verkuil <hans.verkuil@xxxxxxxxx> GPIO drivers can hook these into the irq_request_resource and irq_release_resource callbacks of the irq_chip so they correctly 'get' the module and lock the gpio line for IRQ use. This will simplify driver code. Signed-off-by: Hans Verkuil <hans.verkuil@xxxxxxxxx> --- drivers/gpio/gpiolib.c | 67 ++++++++++++++++++++++--------------- include/linux/gpio/driver.h | 2 ++ 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 8b6086fd4406..2ad58e63ce70 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -86,6 +86,8 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip); static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip); +static int gpiochip_irq_reqres(struct irq_data *d); +static void gpiochip_irq_relres(struct irq_data *d); static bool gpiolib_initialized; @@ -1804,33 +1806,6 @@ static const struct irq_domain_ops gpiochip_domain_ops = { .xlate = irq_domain_xlate_twocell, }; -static int gpiochip_irq_reqres(struct irq_data *d) -{ - struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - int ret; - - if (!try_module_get(chip->gpiodev->owner)) - return -ENODEV; - - ret = gpiochip_lock_as_irq(chip, d->hwirq); - if (ret) { - chip_err(chip, - "unable to lock HW IRQ %lu for IRQ\n", - d->hwirq); - module_put(chip->gpiodev->owner); - return ret; - } - return 0; -} - -static void gpiochip_irq_relres(struct irq_data *d) -{ - struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - - gpiochip_unlock_as_irq(chip, d->hwirq); - module_put(chip->gpiodev->owner); -} - static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) { if (!gpiochip_irqchip_irq_valid(chip, offset)) @@ -3363,6 +3338,44 @@ bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset) } EXPORT_SYMBOL_GPL(gpiochip_line_is_irq); +int gpiochip_reqres_irq(struct gpio_chip *chip, unsigned int offset) +{ + int ret; + + if (!try_module_get(chip->gpiodev->owner)) + return -ENODEV; + + ret = gpiochip_lock_as_irq(chip, offset); + if (ret) { + chip_err(chip, "unable to lock HW IRQ %u for IRQ\n", offset); + module_put(chip->gpiodev->owner); + return ret; + } + return 0; +} +EXPORT_SYMBOL_GPL(gpiochip_reqres_irq); + +void gpiochip_relres_irq(struct gpio_chip *chip, unsigned int offset) +{ + gpiochip_unlock_as_irq(chip, offset); + module_put(chip->gpiodev->owner); +} +EXPORT_SYMBOL_GPL(gpiochip_relres_irq); + +static int gpiochip_irq_reqres(struct irq_data *d) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + + return gpiochip_reqres_irq(chip, d->hwirq); +} + +static void gpiochip_irq_relres(struct irq_data *d) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + + gpiochip_relres_irq(chip, d->hwirq); +} + bool gpiochip_line_is_open_drain(struct gpio_chip *chip, unsigned int offset) { if (offset >= chip->ngpio) diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 91108ac4fffd..84449e95587a 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -397,6 +397,8 @@ void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset); bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset); void gpiochip_disable_irq(struct gpio_chip *chip, unsigned int offset); void gpiochip_enable_irq(struct gpio_chip *chip, unsigned int offset); +int gpiochip_reqres_irq(struct gpio_chip *chip, unsigned int offset); +void gpiochip_relres_irq(struct gpio_chip *chip, unsigned int offset); /* Line status inquiry for drivers */ bool gpiochip_line_is_open_drain(struct gpio_chip *chip, unsigned int offset); -- 2.18.0