mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-04 10:09:06 +00:00
gpio: flush direction status in gpiochip_lock_as_irq()
As irqchip and gpiochip functions are orthogonal, the IRQ set-up or something else can have changed the direction of the GPIO line from what the GPIO descriptor knows when we get into gpiochip_lock_as_irq(). Make sure to re-read the direction setting if we have the .get_direction() callback enabled for the chip. Else we get problems like this: iio iio:device2: interrupts on the rising edge gpio gpiochip2: (8012e080.gpio): gpiochip_lock_as_irq: tried to flag a GPIO set as output for IRQ gpio gpiochip2: (8012e080.gpio): unable to lock HW IRQ 0 for IRQ genirq: Failed to request resources for l3g4200d-trigger (irq 111) on irqchip nmk1-32-63 iio iio:device2: failed to request trigger IRQ. st-gyro-i2c: probe of 2-0068 failed with error -22 Fixes: 72d320006177 ("gpio: set up initial state from .get_direction()") Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
320a6480ef
commit
9c10280d85
@ -2066,17 +2066,30 @@ EXPORT_SYMBOL_GPL(gpiod_to_irq);
|
||||
*/
|
||||
int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
if (offset >= chip->ngpio)
|
||||
return -EINVAL;
|
||||
struct gpio_desc *desc;
|
||||
|
||||
if (test_bit(FLAG_IS_OUT, &chip->gpiodev->descs[offset].flags)) {
|
||||
desc = gpiochip_get_desc(chip, offset);
|
||||
if (IS_ERR(desc))
|
||||
return PTR_ERR(desc);
|
||||
|
||||
/* Flush direction if something changed behind our back */
|
||||
if (chip->get_direction) {
|
||||
int dir = chip->get_direction(chip, offset);
|
||||
|
||||
if (dir)
|
||||
clear_bit(FLAG_IS_OUT, &desc->flags);
|
||||
else
|
||||
set_bit(FLAG_IS_OUT, &desc->flags);
|
||||
}
|
||||
|
||||
if (test_bit(FLAG_IS_OUT, &desc->flags)) {
|
||||
chip_err(chip,
|
||||
"%s: tried to flag a GPIO set as output for IRQ\n",
|
||||
__func__);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
set_bit(FLAG_USED_AS_IRQ, &chip->gpiodev->descs[offset].flags);
|
||||
set_bit(FLAG_USED_AS_IRQ, &desc->flags);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpiochip_lock_as_irq);
|
||||
|
Loading…
x
Reference in New Issue
Block a user