linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] pinctrl/amd: only handle irq if it is pending and unmasked
@ 2018-07-17  0:57 Daniel Kurtz
  2018-07-17  0:57 ` [PATCH 2/2] pinctrl/amd: use byte access to clear irq/wake status bits Daniel Kurtz
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Daniel Kurtz @ 2018-07-17  0:57 UTC (permalink / raw)
  Cc: Shyam Sundar S K, Nehal Shah, Ken Xue, Daniel Drake,
	Thomas Gleixner, Daniel Kurtz, Linus Walleij,
	open list:PIN CONTROL SUBSYSTEM, open list

The AMD pinctrl driver demultiplexes GPIO interrupts and fires off their
individual handlers.

If one of these GPIO irqs is configured as a level interrupt, and its
downstream handler is a threaded ONESHOT interrupt, the GPIO interrupt
source is masked by handle_level_irq() until the eventual return of the
threaded irq handler.  During this time the level GPIO interrupt status
will still report as high until the actual gpio source is cleared - both
in the individual GPIO interrupt status bit (INTERRUPT_STS_OFF) and in
its corresponding "WAKE_INT_STATUS_REG" bit.

Thus, if another GPIO interrupt occurs during this time,
amd_gpio_irq_handler() will see that the (masked-and-not-yet-cleared)
level irq is still pending and incorrectly call its handler again.

To fix this, have amd_gpio_irq_handler() check for both interrupts status
and mask before calling generic_handle_irq().

Note: Is it possible that this bug was the source of the interrupt storm
on Ryzen when using chained interrupts before commit ba714a9c1dea85
("pinctrl/amd: Use regular interrupt instead of chained")?

Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
---
 drivers/pinctrl/pinctrl-amd.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index 04ae139671c8a8..b91db89eb9247c 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -552,7 +552,8 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
 		/* Each status bit covers four pins */
 		for (i = 0; i < 4; i++) {
 			regval = readl(regs + i);
-			if (!(regval & PIN_IRQ_PENDING))
+			if (!(regval & PIN_IRQ_PENDING) ||
+			    !(regval & BIT(INTERRUPT_MASK_OFF)))
 				continue;
 			irq = irq_find_mapping(gc->irq.domain, irqnr + i);
 			generic_handle_irq(irq);
-- 
2.18.0.203.gfac676dfb9-goog

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

end of thread, other threads:[~2018-07-29 20:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-17  0:57 [PATCH 1/2] pinctrl/amd: only handle irq if it is pending and unmasked Daniel Kurtz
2018-07-17  0:57 ` [PATCH 2/2] pinctrl/amd: use byte access to clear irq/wake status bits Daniel Kurtz
2018-07-17 12:30   ` Daniel Drake
2018-07-20 23:38     ` Daniel Kurtz
2018-07-24 12:29       ` Daniel Drake
2018-07-19 14:54 ` [PATCH 1/2] pinctrl/amd: only handle irq if it is pending and unmasked Thomas Gleixner
2018-07-29 20:44 ` 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).