diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2018-09-08 12:23:14 +0300 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2018-09-10 09:54:57 +0300 |
commit | 4e6b823867e2b8afc2b33740ba930e50b1f92421 (patch) | |
tree | 777adeba299de592e1d34355fa362a206fb164da /drivers/gpio/gpiolib.c | |
parent | f6d9af4770995d1f58be57139bce7974868231e8 (diff) | |
download | linux-4e6b823867e2b8afc2b33740ba930e50b1f92421.tar.xz |
gpiolib: export gpiochip_irq_reqres/relres()
GPIO drivers that do not use GPIOLIB_IRQCHIP 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@cisco.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e8f8a1999393..cbab0e744de0 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1804,39 +1804,26 @@ static const struct irq_domain_ops gpiochip_domain_ops = { .xlate = irq_domain_xlate_twocell, }; -static int gpiochip_irq_reqres(struct irq_data *d) +static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) { - struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - int ret; - - if (!try_module_get(chip->gpiodev->owner)) - return -ENODEV; + if (!gpiochip_irqchip_irq_valid(chip, offset)) + return -ENXIO; - 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; + return irq_create_mapping(chip->irq.domain, offset); } -static void gpiochip_irq_relres(struct irq_data *d) +static int gpiochip_irq_reqres(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); + return gpiochip_reqres_irq(chip, d->hwirq); } -static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) +static void gpiochip_irq_relres(struct irq_data *d) { - if (!gpiochip_irqchip_irq_valid(chip, offset)) - return -ENXIO; + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - return irq_create_mapping(chip->irq.domain, offset); + gpiochip_relres_irq(chip, d->hwirq); } /** @@ -3338,6 +3325,30 @@ 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); + bool gpiochip_line_is_open_drain(struct gpio_chip *chip, unsigned int offset) { if (offset >= chip->ngpio) |