* [PATCH] gpio: rockchip: Reset int_bothedge when changing trigger
@ 2022-02-12 20:50 Samuel Holland
2022-02-16 14:55 ` Bartosz Golaszewski
0 siblings, 1 reply; 2+ messages in thread
From: Samuel Holland @ 2022-02-12 20:50 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Heiko Stuebner, Jianqun Xu
Cc: linux-gpio, linux-arm-kernel, linux-rockchip, linux-kernel,
Samuel Holland, Guillaume Savaton
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: 3bcbd1a85b68 ("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>
---
drivers/gpio/gpio-rockchip.c | 56 +++++++++++++++++++-----------------
1 file changed, 29 insertions(+), 27 deletions(-)
diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
index a4c4e4584f5b..099e358d2491 100644
--- a/drivers/gpio/gpio-rockchip.c
+++ b/drivers/gpio/gpio-rockchip.c
@@ -403,65 +403,67 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
if (type & IRQ_TYPE_EDGE_BOTH)
irq_set_handler_locked(d, handle_edge_irq);
else
irq_set_handler_locked(d, handle_level_irq);
raw_spin_lock_irqsave(&bank->slock, flags);
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;
} else {
bank->toggle_edge_mode |= mask;
level |= mask;
/*
* Determine gpio state. If 1 next interrupt should be
* falling otherwise rising.
*/
data = readl(bank->reg_base + bank->gpio_regs->ext_port);
if (data & mask)
polarity &= ~mask;
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);
rockchip_gpio_writel(bank, polarity, bank->gpio_regs->int_polarity);
out:
raw_spin_unlock_irqrestore(&bank->slock, flags);
return ret;
}
--
2.33.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] gpio: rockchip: Reset int_bothedge when changing trigger
2022-02-12 20:50 [PATCH] gpio: rockchip: Reset int_bothedge when changing trigger Samuel Holland
@ 2022-02-16 14:55 ` Bartosz Golaszewski
0 siblings, 0 replies; 2+ messages in thread
From: Bartosz Golaszewski @ 2022-02-16 14:55 UTC (permalink / raw)
To: Samuel Holland
Cc: Linus Walleij, Heiko Stuebner, Jianqun Xu,
open list:GPIO SUBSYSTEM, Linux ARM,
open list:ARM/Rockchip SoC..., Linux Kernel Mailing List,
Guillaume Savaton
On Sat, Feb 12, 2022 at 9:50 PM Samuel Holland <samuel@sholland.org> wrote:
>
> 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: 3bcbd1a85b68 ("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>
> ---
Queued for fixes, thanks!
Bart
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-02-16 14:55 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-12 20:50 [PATCH] gpio: rockchip: Reset int_bothedge when changing trigger Samuel Holland
2022-02-16 14:55 ` Bartosz Golaszewski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).