forked from Minki/linux
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: 3bcbd1a85b
("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>
This commit is contained in:
parent
754e0b0e35
commit
7920af5c82
@ -410,10 +410,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type);
|
||||
polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity);
|
||||
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
if (type == IRQ_TYPE_EDGE_BOTH) {
|
||||
if (bank->gpio_type == GPIO_TYPE_V2) {
|
||||
bank->toggle_edge_mode &= ~mask;
|
||||
rockchip_gpio_writel_bit(bank, d->hwirq, 1,
|
||||
bank->gpio_regs->int_bothedge);
|
||||
goto out;
|
||||
@ -431,30 +429,34 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
else
|
||||
polarity |= mask;
|
||||
}
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
bank->toggle_edge_mode &= ~mask;
|
||||
level |= mask;
|
||||
polarity |= mask;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
bank->toggle_edge_mode &= ~mask;
|
||||
level |= mask;
|
||||
polarity &= ~mask;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
bank->toggle_edge_mode &= ~mask;
|
||||
level &= ~mask;
|
||||
polarity |= mask;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
bank->toggle_edge_mode &= ~mask;
|
||||
level &= ~mask;
|
||||
polarity &= ~mask;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
} else {
|
||||
if (bank->gpio_type == GPIO_TYPE_V2) {
|
||||
rockchip_gpio_writel_bit(bank, d->hwirq, 0,
|
||||
bank->gpio_regs->int_bothedge);
|
||||
} else {
|
||||
bank->toggle_edge_mode &= ~mask;
|
||||
}
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
level |= mask;
|
||||
polarity |= mask;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
level |= mask;
|
||||
polarity &= ~mask;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
level &= ~mask;
|
||||
polarity |= mask;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
level &= ~mask;
|
||||
polarity &= ~mask;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type);
|
||||
|
Loading…
Reference in New Issue
Block a user