Commit 4e6b8238 authored by Hans Verkuil's avatar Hans Verkuil Committed by Linus Walleij
Browse files

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: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent f6d9af47
Loading
Loading
Loading
Loading
+33 −22
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -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);