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>
This commit is contained in:
parent
f6d9af4770
commit
4e6b823867
|
@ -1804,33 +1804,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))
|
||||
|
@ -1839,6 +1812,20 @@ static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset)
|
|||
return irq_create_mapping(chip->irq.domain, offset);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* gpiochip_add_irqchip() - adds an IRQ chip to a GPIO chip
|
||||
* @gpiochip: the GPIO chip to add the IRQ chip to
|
||||
|
@ -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)
|
||||
|
|
|
@ -401,6 +401,8 @@ extern struct gpio_chip *gpiochip_find(void *data,
|
|||
int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset);
|
||||
void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset);
|
||||
bool gpiochip_line_is_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);
|
||||
|
|
Loading…
Reference in New Issue