linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] pinctrl: ocelot: Fix incorrect trigger of the interrupt.
@ 2022-10-18  7:09 Horatiu Vultur
  2022-10-18  7:30 ` Michael Walle
  2022-10-18  8:42 ` Linus Walleij
  0 siblings, 2 replies; 3+ messages in thread
From: Horatiu Vultur @ 2022-10-18  7:09 UTC (permalink / raw)
  To: linux-gpio, linux-kernel
  Cc: linus.walleij, andy.shevchenko, michael, UNGLinuxDriver, Horatiu Vultur

The interrupt controller can detect only link changes. So in case an
external device generated a level based interrupt, then the interrupt
controller detected correctly the first edge. But the problem was that
the interrupt controller was detecting also the edge when the interrupt
was cleared. So it would generate another interrupt.
The fix for this is to clear the second interrupt but still check the
interrupt line status.

Fixes: c297561bc98a ("pinctrl: ocelot: Fix interrupt controller")
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
 drivers/pinctrl/pinctrl-ocelot.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
index 266fbc9572736..3d5995cbcb782 100644
--- a/drivers/pinctrl/pinctrl-ocelot.c
+++ b/drivers/pinctrl/pinctrl-ocelot.c
@@ -1864,19 +1864,28 @@ static void ocelot_irq_unmask_level(struct irq_data *data)
 	if (val & bit)
 		ack = true;
 
+	/* Try to clear any rising edges */
+	if (!active && ack)
+		regmap_write_bits(info->map, REG(OCELOT_GPIO_INTR, info, gpio),
+				  bit, bit);
+
 	/* Enable the interrupt now */
 	gpiochip_enable_irq(chip, gpio);
 	regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio),
 			   bit, bit);
 
 	/*
-	 * In case the interrupt line is still active and the interrupt
-	 * controller has not seen any changes in the interrupt line, then it
-	 * means that there happen another interrupt while the line was active.
+	 * In case the interrupt line is still active then it means that
+	 * there happen another interrupt while the line was active.
 	 * So we missed that one, so we need to kick the interrupt again
 	 * handler.
 	 */
-	if (active && !ack) {
+	regmap_read(info->map, REG(OCELOT_GPIO_IN, info, gpio), &val);
+	if ((!(val & bit) && trigger_level == IRQ_TYPE_LEVEL_LOW) ||
+	      (val & bit && trigger_level == IRQ_TYPE_LEVEL_HIGH))
+		active = true;
+
+	if (active) {
 		struct ocelot_irq_work *work;
 
 		work = kmalloc(sizeof(*work), GFP_ATOMIC);
-- 
2.38.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] pinctrl: ocelot: Fix incorrect trigger of the interrupt.
  2022-10-18  7:09 [PATCH] pinctrl: ocelot: Fix incorrect trigger of the interrupt Horatiu Vultur
@ 2022-10-18  7:30 ` Michael Walle
  2022-10-18  8:42 ` Linus Walleij
  1 sibling, 0 replies; 3+ messages in thread
From: Michael Walle @ 2022-10-18  7:30 UTC (permalink / raw)
  To: Horatiu Vultur
  Cc: linux-gpio, linux-kernel, linus.walleij, andy.shevchenko, UNGLinuxDriver

Am 2022-10-18 09:09, schrieb Horatiu Vultur:
> The interrupt controller can detect only link changes. So in case an
> external device generated a level based interrupt, then the interrupt
> controller detected correctly the first edge. But the problem was that
> the interrupt controller was detecting also the edge when the interrupt
> was cleared. So it would generate another interrupt.
> The fix for this is to clear the second interrupt but still check the
> interrupt line status.
> 
> Fixes: c297561bc98a ("pinctrl: ocelot: Fix interrupt controller")
> Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>

Tested-by: Michael Walle <michael@walle.cc>

-michael

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] pinctrl: ocelot: Fix incorrect trigger of the interrupt.
  2022-10-18  7:09 [PATCH] pinctrl: ocelot: Fix incorrect trigger of the interrupt Horatiu Vultur
  2022-10-18  7:30 ` Michael Walle
@ 2022-10-18  8:42 ` Linus Walleij
  1 sibling, 0 replies; 3+ messages in thread
From: Linus Walleij @ 2022-10-18  8:42 UTC (permalink / raw)
  To: Horatiu Vultur
  Cc: linux-gpio, linux-kernel, andy.shevchenko, michael, UNGLinuxDriver

On Tue, Oct 18, 2022 at 9:05 AM Horatiu Vultur
<horatiu.vultur@microchip.com> wrote:

> The interrupt controller can detect only link changes. So in case an
> external device generated a level based interrupt, then the interrupt
> controller detected correctly the first edge. But the problem was that
> the interrupt controller was detecting also the edge when the interrupt
> was cleared. So it would generate another interrupt.
> The fix for this is to clear the second interrupt but still check the
> interrupt line status.
>
> Fixes: c297561bc98a ("pinctrl: ocelot: Fix interrupt controller")
> Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>

Patch applied for fixes!

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-10-18  8:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-18  7:09 [PATCH] pinctrl: ocelot: Fix incorrect trigger of the interrupt Horatiu Vultur
2022-10-18  7:30 ` Michael Walle
2022-10-18  8:42 ` Linus Walleij

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).