Skip to content

Commit 9c10280

Browse files
committed
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: 72d3200 ("gpio: set up initial state from .get_direction()") Signed-off-by: Linus Walleij <[email protected]>
1 parent 320a648 commit 9c10280

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

drivers/gpio/gpiolib.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,17 +2066,30 @@ EXPORT_SYMBOL_GPL(gpiod_to_irq);
20662066
*/
20672067
int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
20682068
{
2069-
if (offset >= chip->ngpio)
2070-
return -EINVAL;
2069+
struct gpio_desc *desc;
2070+
2071+
desc = gpiochip_get_desc(chip, offset);
2072+
if (IS_ERR(desc))
2073+
return PTR_ERR(desc);
2074+
2075+
/* Flush direction if something changed behind our back */
2076+
if (chip->get_direction) {
2077+
int dir = chip->get_direction(chip, offset);
2078+
2079+
if (dir)
2080+
clear_bit(FLAG_IS_OUT, &desc->flags);
2081+
else
2082+
set_bit(FLAG_IS_OUT, &desc->flags);
2083+
}
20712084

2072-
if (test_bit(FLAG_IS_OUT, &chip->gpiodev->descs[offset].flags)) {
2085+
if (test_bit(FLAG_IS_OUT, &desc->flags)) {
20732086
chip_err(chip,
20742087
"%s: tried to flag a GPIO set as output for IRQ\n",
20752088
__func__);
20762089
return -EIO;
20772090
}
20782091

2079-
set_bit(FLAG_USED_AS_IRQ, &chip->gpiodev->descs[offset].flags);
2092+
set_bit(FLAG_USED_AS_IRQ, &desc->flags);
20802093
return 0;
20812094
}
20822095
EXPORT_SYMBOL_GPL(gpiochip_lock_as_irq);

0 commit comments

Comments
 (0)