Linux-GPIO Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH] pinctrl/amd: disable spurious-firing GPIO IRQs
@ 2019-08-14  9:05 Daniel Drake
  2019-08-23  7:56 ` Linus Walleij
  0 siblings, 1 reply; 2+ messages in thread
From: Daniel Drake @ 2019-08-14  9:05 UTC (permalink / raw)
  To: linus.walleij
  Cc: linux-gpio, linux, sandeep.singh, Shyam-sundar.S-k,
	Nehal-Bakulchandra.shah

When cold-booting Asus X434DA, GPIO 7 is found to be already configured
as an interrupt, and the GPIO level is found to be in a state that
causes the interrupt to fire.

As soon as pinctrl-amd probes, this interrupt fires and invokes
amd_gpio_irq_handler(). The IRQ is acked, but no GPIO-IRQ handler was
invoked, so the GPIO level being unchanged just causes another interrupt
to fire again immediately after.

This results in an interrupt storm causing this platform to hang
during boot, right after pinctrl-amd is probed.

Detect this situation and disable the GPIO interrupt when this happens.
This enables the affected platform to boot as normal. GPIO 7 actually is
the I2C touchpad interrupt line, and later on, i2c-multitouch loads and
re-enables this interrupt when it is ready to handle it.

Instead of this approach, I considered disabling all GPIO interrupts at
probe time, however that seems a little risky, and I also confirmed that
Windows does not seem to have this behaviour: the same 41 GPIO IRQs are
enabled under both Linux and Windows, which is a far larger collection
than the GPIOs referenced by the DSDT on this platform.

Signed-off-by: Daniel Drake <drake@endlessm.com>
---
 drivers/pinctrl/pinctrl-amd.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index 9b9c61e3f065..977792654e01 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -565,15 +565,25 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
 			    !(regval & BIT(INTERRUPT_MASK_OFF)))
 				continue;
 			irq = irq_find_mapping(gc->irq.domain, irqnr + i);
-			generic_handle_irq(irq);
+			if (irq != 0)
+				generic_handle_irq(irq);
 
 			/* Clear interrupt.
 			 * We must read the pin register again, in case the
 			 * value was changed while executing
 			 * generic_handle_irq() above.
+			 * If we didn't find a mapping for the interrupt,
+			 * disable it in order to avoid a system hang caused
+			 * by an interrupt storm.
 			 */
 			raw_spin_lock_irqsave(&gpio_dev->lock, flags);
 			regval = readl(regs + i);
+			if (irq == 0) {
+				regval &= ~BIT(INTERRUPT_ENABLE_OFF);
+				dev_dbg(&gpio_dev->pdev->dev,
+					"Disabling spurious GPIO IRQ %d\n",
+					irqnr + i);
+			}
 			writel(regval, regs + i);
 			raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 			ret = IRQ_HANDLED;
-- 
2.20.1


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

* Re: [PATCH] pinctrl/amd: disable spurious-firing GPIO IRQs
  2019-08-14  9:05 [PATCH] pinctrl/amd: disable spurious-firing GPIO IRQs Daniel Drake
@ 2019-08-23  7:56 ` Linus Walleij
  0 siblings, 0 replies; 2+ messages in thread
From: Linus Walleij @ 2019-08-23  7:56 UTC (permalink / raw)
  To: Daniel Drake
  Cc: open list:GPIO SUBSYSTEM, linux, Singh, Sandeep, S-k,
	Shyam-sundar, Shah, Nehal-bakulchandra

On Wed, Aug 14, 2019 at 11:05 AM Daniel Drake <drake@endlessm.com> wrote:

> When cold-booting Asus X434DA, GPIO 7 is found to be already configured
> as an interrupt, and the GPIO level is found to be in a state that
> causes the interrupt to fire.
>
> As soon as pinctrl-amd probes, this interrupt fires and invokes
> amd_gpio_irq_handler(). The IRQ is acked, but no GPIO-IRQ handler was
> invoked, so the GPIO level being unchanged just causes another interrupt
> to fire again immediately after.
>
> This results in an interrupt storm causing this platform to hang
> during boot, right after pinctrl-amd is probed.
>
> Detect this situation and disable the GPIO interrupt when this happens.
> This enables the affected platform to boot as normal. GPIO 7 actually is
> the I2C touchpad interrupt line, and later on, i2c-multitouch loads and
> re-enables this interrupt when it is ready to handle it.
>
> Instead of this approach, I considered disabling all GPIO interrupts at
> probe time, however that seems a little risky, and I also confirmed that
> Windows does not seem to have this behaviour: the same 41 GPIO IRQs are
> enabled under both Linux and Windows, which is a far larger collection
> than the GPIOs referenced by the DSDT on this platform.
>
> Signed-off-by: Daniel Drake <drake@endlessm.com>

Patch applied!

Yours,
Linus Walleij

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

end of thread, back to index

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-14  9:05 [PATCH] pinctrl/amd: disable spurious-firing GPIO IRQs Daniel Drake
2019-08-23  7:56 ` Linus Walleij

Linux-GPIO Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-gpio/0 linux-gpio/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-gpio linux-gpio/ https://lore.kernel.org/linux-gpio \
		linux-gpio@vger.kernel.org linux-gpio@archiver.kernel.org
	public-inbox-index linux-gpio


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-gpio


AGPL code for this site: git clone https://public-inbox.org/ public-inbox