Skip to content

Commit ba714a9

Browse files
KAGA-KOKOlinusw
authored andcommitted
pinctrl/amd: Use regular interrupt instead of chained
The AMD pinctrl driver uses a chained interrupt to demultiplex the GPIO interrupts. Kevin Vandeventer reported, that his new AMD Ryzen locks up hard on boot when the AMD pinctrl driver is initialized. The reason is an interrupt storm. It's not clear whether that's caused by hardware or firmware or both. Using chained interrupts on X86 is a dangerous endavour. If a system is misconfigured or the hardware buggy there is no safety net to catch an interrupt storm. Convert the driver to use a regular interrupt for the demultiplex handler. This allows the interrupt storm detector to catch the malfunction and lets the system boot up. This should be backported to stable because it's likely that more users run into this problem as the AMD Ryzen machines are spreading. Reported-by: Kevin Vandeventer Link: https://bugzilla.suse.com/show_bug.cgi?id=1034261 Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 3c2993b commit ba714a9

File tree

1 file changed

+41
-50
lines changed

1 file changed

+41
-50
lines changed

drivers/pinctrl/pinctrl-amd.c

Lines changed: 41 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -495,64 +495,54 @@ static struct irq_chip amd_gpio_irqchip = {
495495
.flags = IRQCHIP_SKIP_SET_WAKE,
496496
};
497497

498-
static void amd_gpio_irq_handler(struct irq_desc *desc)
498+
#define PIN_IRQ_PENDING (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
499+
500+
static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
499501
{
500-
u32 i;
501-
u32 off;
502-
u32 reg;
503-
u32 pin_reg;
504-
u64 reg64;
505-
int handled = 0;
506-
unsigned int irq;
502+
struct amd_gpio *gpio_dev = dev_id;
503+
struct gpio_chip *gc = &gpio_dev->gc;
504+
irqreturn_t ret = IRQ_NONE;
505+
unsigned int i, irqnr;
507506
unsigned long flags;
508-
struct irq_chip *chip = irq_desc_get_chip(desc);
509-
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
510-
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
507+
u32 *regs, regval;
508+
u64 status, mask;
511509

512-
chained_irq_enter(chip, desc);
513-
/*enable GPIO interrupt again*/
510+
/* Read the wake status */
514511
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
515-
reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
516-
reg64 = reg;
517-
reg64 = reg64 << 32;
518-
519-
reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
520-
reg64 |= reg;
512+
status = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
513+
status <<= 32;
514+
status |= readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
521515
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
522516

523-
/*
524-
* first 46 bits indicates interrupt status.
525-
* one bit represents four interrupt sources.
526-
*/
527-
for (off = 0; off < 46 ; off++) {
528-
if (reg64 & BIT(off)) {
529-
for (i = 0; i < 4; i++) {
530-
pin_reg = readl(gpio_dev->base +
531-
(off * 4 + i) * 4);
532-
if ((pin_reg & BIT(INTERRUPT_STS_OFF)) ||
533-
(pin_reg & BIT(WAKE_STS_OFF))) {
534-
irq = irq_find_mapping(gc->irqdomain,
535-
off * 4 + i);
536-
generic_handle_irq(irq);
537-
writel(pin_reg,
538-
gpio_dev->base
539-
+ (off * 4 + i) * 4);
540-
handled++;
541-
}
542-
}
517+
/* Bit 0-45 contain the relevant status bits */
518+
status &= (1ULL << 46) - 1;
519+
regs = gpio_dev->base;
520+
for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) {
521+
if (!(status & mask))
522+
continue;
523+
status &= ~mask;
524+
525+
/* Each status bit covers four pins */
526+
for (i = 0; i < 4; i++) {
527+
regval = readl(regs + i);
528+
if (!(regval & PIN_IRQ_PENDING))
529+
continue;
530+
irq = irq_find_mapping(gc->irqdomain, irqnr + i);
531+
generic_handle_irq(irq);
532+
/* Clear interrupt */
533+
writel(regval, regs + i);
534+
ret = IRQ_HANDLED;
543535
}
544536
}
545537

546-
if (handled == 0)
547-
handle_bad_irq(desc);
548-
538+
/* Signal EOI to the GPIO unit */
549539
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
550-
reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
551-
reg |= EOI_MASK;
552-
writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
540+
regval = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
541+
regval |= EOI_MASK;
542+
writel(regval, gpio_dev->base + WAKE_INT_MASTER_REG);
553543
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
554544

555-
chained_irq_exit(chip, desc);
545+
return ret;
556546
}
557547

558548
static int amd_get_groups_count(struct pinctrl_dev *pctldev)
@@ -821,10 +811,11 @@ static int amd_gpio_probe(struct platform_device *pdev)
821811
goto out2;
822812
}
823813

824-
gpiochip_set_chained_irqchip(&gpio_dev->gc,
825-
&amd_gpio_irqchip,
826-
irq_base,
827-
amd_gpio_irq_handler);
814+
ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, 0,
815+
KBUILD_MODNAME, gpio_dev);
816+
if (ret)
817+
goto out2;
818+
828819
platform_set_drvdata(pdev, gpio_dev);
829820

830821
dev_dbg(&pdev->dev, "amd gpio driver loaded\n");

0 commit comments

Comments
 (0)