Skip to content

Commit 7920af5

Browse files
smaeulbrgl
authored andcommitted
gpio: rockchip: Reset int_bothedge when changing trigger
With v2 hardware, an IRQ can be configured to trigger on both edges via a bit in the int_bothedge register. Currently, the driver sets this bit when changing the trigger type to IRQ_TYPE_EDGE_BOTH, but fails to reset this bit if the trigger type is later changed to something else. This causes spurious IRQs, and when using gpio-keys with wakeup-event-action set to EV_ACT_(DE)ASSERTED, those IRQs translate into spurious wakeups. Fixes: 3bcbd1a ("gpio/rockchip: support next version gpio controller") Reported-by: Guillaume Savaton <guillaume@baierouge.fr> Tested-by: Guillaume Savaton <guillaume@baierouge.fr> Signed-off-by: Samuel Holland <samuel@sholland.org> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
1 parent 754e0b0 commit 7920af5

1 file changed

Lines changed: 29 additions & 27 deletions

File tree

drivers/gpio/gpio-rockchip.c

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
410410
level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type);
411411
polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity);
412412

413-
switch (type) {
414-
case IRQ_TYPE_EDGE_BOTH:
413+
if (type == IRQ_TYPE_EDGE_BOTH) {
415414
if (bank->gpio_type == GPIO_TYPE_V2) {
416-
bank->toggle_edge_mode &= ~mask;
417415
rockchip_gpio_writel_bit(bank, d->hwirq, 1,
418416
bank->gpio_regs->int_bothedge);
419417
goto out;
@@ -431,30 +429,34 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
431429
else
432430
polarity |= mask;
433431
}
434-
break;
435-
case IRQ_TYPE_EDGE_RISING:
436-
bank->toggle_edge_mode &= ~mask;
437-
level |= mask;
438-
polarity |= mask;
439-
break;
440-
case IRQ_TYPE_EDGE_FALLING:
441-
bank->toggle_edge_mode &= ~mask;
442-
level |= mask;
443-
polarity &= ~mask;
444-
break;
445-
case IRQ_TYPE_LEVEL_HIGH:
446-
bank->toggle_edge_mode &= ~mask;
447-
level &= ~mask;
448-
polarity |= mask;
449-
break;
450-
case IRQ_TYPE_LEVEL_LOW:
451-
bank->toggle_edge_mode &= ~mask;
452-
level &= ~mask;
453-
polarity &= ~mask;
454-
break;
455-
default:
456-
ret = -EINVAL;
457-
goto out;
432+
} else {
433+
if (bank->gpio_type == GPIO_TYPE_V2) {
434+
rockchip_gpio_writel_bit(bank, d->hwirq, 0,
435+
bank->gpio_regs->int_bothedge);
436+
} else {
437+
bank->toggle_edge_mode &= ~mask;
438+
}
439+
switch (type) {
440+
case IRQ_TYPE_EDGE_RISING:
441+
level |= mask;
442+
polarity |= mask;
443+
break;
444+
case IRQ_TYPE_EDGE_FALLING:
445+
level |= mask;
446+
polarity &= ~mask;
447+
break;
448+
case IRQ_TYPE_LEVEL_HIGH:
449+
level &= ~mask;
450+
polarity |= mask;
451+
break;
452+
case IRQ_TYPE_LEVEL_LOW:
453+
level &= ~mask;
454+
polarity &= ~mask;
455+
break;
456+
default:
457+
ret = -EINVAL;
458+
goto out;
459+
}
458460
}
459461

460462
rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type);

0 commit comments

Comments
 (0)