[PATCH] pinctrl: amd: add timeout to irq-enable readback
Linkai Gong <[email protected]>
| Newsgroups | org.kernel.vger.linux-gpio,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
amd_gpio_irq_set_type() polls INTERRUPT_ENABLE with IRQs off
and no timeout. Use readl_poll_timeout_atomic() and return
-ETIMEDOUT.
Fixes: b85bfa246efd ("pinctrl/amd: poll InterruptEnable bits in amd_gpio_irq_set_type")
Signed-off-by: Linkai Gong <[email protected]>
---
drivers/pinctrl/pinctrl-amd.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index 15a398bb3be2..65728b590999 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -18,6 +18,7 @@
#include <linux/errno.h>
#include <linux/log2.h>
#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/gpio/driver.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
@@ -494,7 +495,7 @@ static void amd_gpio_irq_eoi(struct irq_data *d)
static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
int ret = 0;
- u32 pin_reg, pin_reg_irq_en, mask;
+ u32 pin_reg, pin_reg_irq_en, mask, reg;
unsigned long flags;
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
@@ -568,8 +569,9 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
pin_reg_irq_en |= mask;
pin_reg_irq_en &= ~BIT(INTERRUPT_MASK_OFF);
writel(pin_reg_irq_en, gpio_dev->base + hwirq * 4);
- while ((readl(gpio_dev->base + hwirq * 4) & mask) != mask)
- continue;
+ if (readl_poll_timeout_atomic(gpio_dev->base + hwirq * 4, reg,
+ (reg & mask) == mask, 1, 1000))
+ ret = -ETIMEDOUT;
writel(pin_reg, gpio_dev->base + hwirq * 4);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
--
2.25.1