pinctrl: amd: Detect and mask spurious interrupts
commit 0cf9e48ff22e15f3f0882991f33d23ccc5ae1d01 upstream.
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: stable@vger.kernel.org
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217315
Signed-off-by: Kornel Dulęba <korneld@chromium.org>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://lore.kernel.org/r/20230421120625.3366-4-mario.limonciello@amd.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
1516518794
commit
1cd1a0151f
1 changed files with 6 additions and 6 deletions
|
|
@ -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
|
* We must read the pin register again, in case the
|
||||||
* value was changed while executing
|
* value was changed while executing
|
||||||
* generic_handle_domain_irq() above.
|
* generic_handle_domain_irq() above.
|
||||||
* If we didn't find a mapping for the interrupt,
|
* If the line is not an irq, disable it in order to
|
||||||
* disable it in order to avoid a system hang caused
|
* avoid a system hang caused by an interrupt storm.
|
||||||
* by an interrupt storm.
|
|
||||||
*/
|
*/
|
||||||
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
|
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
|
||||||
regval = readl(regs + i);
|
regval = readl(regs + i);
|
||||||
if (irq == 0) {
|
if (!gpiochip_line_is_irq(gc, irqnr + i)) {
|
||||||
regval &= ~BIT(INTERRUPT_ENABLE_OFF);
|
regval &= ~BIT(INTERRUPT_MASK_OFF);
|
||||||
dev_dbg(&gpio_dev->pdev->dev,
|
dev_dbg(&gpio_dev->pdev->dev,
|
||||||
"Disabling spurious GPIO IRQ %d\n",
|
"Disabling spurious GPIO IRQ %d\n",
|
||||||
irqnr + i);
|
irqnr + i);
|
||||||
|
} else {
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
writel(regval, regs + i);
|
writel(regval, regs + i);
|
||||||
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
|
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
|
||||||
ret = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* did not cause wake on resume context for shared IRQ */
|
/* did not cause wake on resume context for shared IRQ */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue