Skip to content

Commit 4c1de04

Browse files
djkurtzlinusw
authored andcommitted
pinctrl/amd: poll InterruptEnable bits in enable_irq
In certain cases interrupt enablement will be delayed relative to when the InterruptEnable bits are written. One example of this is when a GPIO's "debounce" logice is first enabled. After enabling debounce, there is a 900 us "warm up" period during which InterruptEnable[0] (bit 11) will read as 0 despite being written 1. During this time InterruptSts will not be updated, nor will interrupts be delivered, even if the GPIO's interrupt configuration has been written to the register. To work around this delay, poll the InterruptEnable bits after setting them to ensure interrupts have truly been enabled in hardware before returning from the irq_enable handler. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 44edff1 commit 4c1de04

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

drivers/pinctrl/pinctrl-amd.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,12 +348,21 @@ static void amd_gpio_irq_enable(struct irq_data *d)
348348
unsigned long flags;
349349
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
350350
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
351+
u32 mask = BIT(INTERRUPT_ENABLE_OFF) | BIT(INTERRUPT_MASK_OFF);
351352

352353
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
353354
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
354355
pin_reg |= BIT(INTERRUPT_ENABLE_OFF);
355356
pin_reg |= BIT(INTERRUPT_MASK_OFF);
356357
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
358+
/*
359+
* When debounce logic is enabled it takes ~900 us before interrupts
360+
* can be enabled. During this "debounce warm up" period the
361+
* "INTERRUPT_ENABLE" bit will read as 0. Poll the bit here until it
362+
* reads back as 1, signaling that interrupts are now enabled.
363+
*/
364+
while ((readl(gpio_dev->base + (d->hwirq)*4) & mask) != mask)
365+
continue;
357366
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
358367
}
359368

0 commit comments

Comments
 (0)