Skip to content

Commit e902f10

Browse files
linuswgregkh
authored andcommitted
gpio: do not double-check direction on sleeping chips
commit 60f8339 upstream. When locking a GPIO line as IRQ, we go to lengths to double-check that the line is really set as input before marking it as used for IRQ. This is not good on GPIO chips that can sleep, because this function is called in IRQ-safe context. Just skip this if it can't be checked quickly. Currently this happens on sleeping expanders such as STMPE or TC3589x: BUG: scheduling while atomic: swapper/1/0x00000002 Modules linked in: CPU: 0 PID: 1 Comm: swapper Not tainted 4.9.0-rc1+ #38 Hardware name: Nomadik STn8815 [<c000f2e0>] (unwind_backtrace) from [<c000d244>] (show_stack+0x10/0x14) [<c000d244>] (show_stack) from [<c0037b78>] (__schedule_bug+0x54/0x80) [<c0037b78>] (__schedule_bug) from [<c042df14>] (__schedule+0x3a0/0x460) [<c042df14>] (__schedule) from [<c042e028>] (schedule+0x54/0xb8) (...) This patch fixes that problem and relies on the direction read from the chip when it was added. Fixes: 9c10280 ("gpio: flush direction status in gpiochip_lock_as_irq()") Cc: Patrice Chotard <[email protected]> Signed-off-by: Linus Walleij <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b21b327 commit e902f10

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

drivers/gpio/gpiolib.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2667,8 +2667,11 @@ int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
26672667
if (IS_ERR(desc))
26682668
return PTR_ERR(desc);
26692669

2670-
/* Flush direction if something changed behind our back */
2671-
if (chip->get_direction) {
2670+
/*
2671+
* If it's fast: flush the direction setting if something changed
2672+
* behind our back
2673+
*/
2674+
if (!chip->can_sleep && chip->get_direction) {
26722675
int dir = chip->get_direction(chip, offset);
26732676

26742677
if (dir)

0 commit comments

Comments
 (0)