Commit 7920af5c authored by Samuel Holland's avatar Samuel Holland Committed by Bartosz Golaszewski

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: 3bcbd1a8 ("gpio/rockchip: support next version gpio controller")
Reported-by: default avatarGuillaume Savaton <guillaume@baierouge.fr>
Tested-by: default avatarGuillaume Savaton <guillaume@baierouge.fr>
Signed-off-by: default avatarSamuel Holland <samuel@sholland.org>
Signed-off-by: default avatarBartosz Golaszewski <brgl@bgdev.pl>
parent 754e0b0e
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment