diff options
author | Kornel Dulęba <[email protected]> | 2023-04-21 07:06:23 -0500 |
---|---|---|
committer | Linus Walleij <[email protected]> | 2023-05-08 15:42:24 +0200 |
commit | 0cf9e48ff22e15f3f0882991f33d23ccc5ae1d01 (patch) | |
tree | eecdedcf740812c26270d27dd0c0766ba2b2e8ad | |
parent | a855724dc08b8cb0c13ab1e065a4922f1e5a7552 (diff) |
pinctrl: amd: Detect and mask spurious interrupts
Leverage gpiochip_line_is_irq to check whether a pin has an irq
associated with it. The previous check ("irq == 0") didn't make much
sense. The irq variable refers to the pinctrl irq, and has nothing do to
with an individual pin.
On some systems, during suspend/resume cycle, the firmware leaves
an interrupt enabled on a pin that is not used by the kernel.
Without this patch that caused an interrupt storm.
Cc: [email protected]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217315
Signed-off-by: Kornel Dulęba <[email protected]>
Reviewed-by: Mario Limonciello <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Linus Walleij <[email protected]>
-rw-r--r-- | drivers/pinctrl/pinctrl-amd.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 840f9b885ecf..b4dee32e78ee 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -660,21 +660,21 @@ static bool do_amd_gpio_irq_handler(int irq, void *dev_id) * We must read the pin register again, in case the * value was changed while executing * generic_handle_domain_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. + * If the line is not an irq, 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); + if (!gpiochip_line_is_irq(gc, irqnr + i)) { + regval &= ~BIT(INTERRUPT_MASK_OFF); dev_dbg(&gpio_dev->pdev->dev, "Disabling spurious GPIO IRQ %d\n", irqnr + i); + } else { + ret = true; } writel(regval, regs + i); raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); - ret = true; } } /* did not cause wake on resume context for shared IRQ */ |