All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] pinctrl/amd: poll InterruptEnable bits in enable_irq
@ 2018-03-12 16:45 ` Daniel Kurtz
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Kurtz @ 2018-03-12 16:45 UTC (permalink / raw)
  Cc: adurbin, Daniel Kurtz, Linus Walleij,
	open list:PIN CONTROL SUBSYSTEM, open list

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>
---
 drivers/pinctrl/pinctrl-amd.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index dae184c4b962..af8ef485fbe7 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -348,12 +348,21 @@ static void amd_gpio_irq_enable(struct irq_data *d)
 	unsigned long flags;
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+	u32 mask = BIT(INTERRUPT_ENABLE_OFF) | BIT(INTERRUPT_MASK_OFF);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
 	pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
 	pin_reg |= BIT(INTERRUPT_ENABLE_OFF);
 	pin_reg |= BIT(INTERRUPT_MASK_OFF);
 	writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
+	/*
+	 * When debounce logic is enabled it takes ~900 us before interrupts
+	 * can be enabled.  During this "debounce warm up" period the
+	 * "INTERRUPT_ENABLE" bit will read as 0. Poll the bit here until it
+	 * reads back as 1, signaling that interrupts are now enabled.
+	 */
+	while ((readl(gpio_dev->base + (d->hwirq)*4) & mask) != mask)
+		continue;
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 }
 
-- 
2.16.2.660.g709887971b-goog

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH] pinctrl/amd: poll InterruptEnable bits in enable_irq
@ 2018-03-12 16:45 ` Daniel Kurtz
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Kurtz @ 2018-03-12 16:45 UTC (permalink / raw)
  Cc: adurbin, Daniel Kurtz, Linus Walleij,
	open list:PIN CONTROL SUBSYSTEM, open list

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>
---
 drivers/pinctrl/pinctrl-amd.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index dae184c4b962..af8ef485fbe7 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -348,12 +348,21 @@ static void amd_gpio_irq_enable(struct irq_data *d)
 	unsigned long flags;
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+	u32 mask = BIT(INTERRUPT_ENABLE_OFF) | BIT(INTERRUPT_MASK_OFF);
 
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
 	pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
 	pin_reg |= BIT(INTERRUPT_ENABLE_OFF);
 	pin_reg |= BIT(INTERRUPT_MASK_OFF);
 	writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
+	/*
+	 * When debounce logic is enabled it takes ~900 us before interrupts
+	 * can be enabled.  During this "debounce warm up" period the
+	 * "INTERRUPT_ENABLE" bit will read as 0. Poll the bit here until it
+	 * reads back as 1, signaling that interrupts are now enabled.
+	 */
+	while ((readl(gpio_dev->base + (d->hwirq)*4) & mask) != mask)
+		continue;
 	raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
 }
 
-- 
2.16.2.660.g709887971b-goog

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] pinctrl/amd: poll InterruptEnable bits in enable_irq
  2018-03-12 16:45 ` Daniel Kurtz
  (?)
@ 2018-03-26  9:12 ` Linus Walleij
  2018-03-28  5:19   ` Shah, Nehal-bakulchandra
  -1 siblings, 1 reply; 4+ messages in thread
From: Linus Walleij @ 2018-03-26  9:12 UTC (permalink / raw)
  To: Daniel Kurtz, Shyam Sundar S K, Nehal Shah, Ken Xue
  Cc: adurbin, open list:PIN CONTROL SUBSYSTEM, open list

On Mon, Mar 12, 2018 at 5:45 PM, Daniel Kurtz <djkurtz@chromium.org> wrote:

> 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>

Patch applied.

I see the AMD people were not on CC so adding them here so they can
say if there is any problem with the approach.

Daniel: maybe you should consider listing yourself as comaintainer of this
driver?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] pinctrl/amd: poll InterruptEnable bits in enable_irq
  2018-03-26  9:12 ` Linus Walleij
@ 2018-03-28  5:19   ` Shah, Nehal-bakulchandra
  0 siblings, 0 replies; 4+ messages in thread
From: Shah, Nehal-bakulchandra @ 2018-03-28  5:19 UTC (permalink / raw)
  To: Linus Walleij, Daniel Kurtz, Shyam Sundar S K, Ken Xue
  Cc: adurbin, open list:PIN CONTROL SUBSYSTEM, open list

Hi

On 3/26/2018 2:42 PM, Linus Walleij wrote:
> On Mon, Mar 12, 2018 at 5:45 PM, Daniel Kurtz <djkurtz@chromium.org> wrote:
> 
>> 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>
> 
> Patch applied.
> 
> I see the AMD people were not on CC so adding them here so they can
> say if there is any problem with the approach.
> 
> Daniel: maybe you should consider listing yourself as comaintainer of this
> driver?
> 
> Yours,
> Linus Walleij
> 

Looks good. 

Regards
Nehal Shah

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-03-28  5:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-12 16:45 [PATCH] pinctrl/amd: poll InterruptEnable bits in enable_irq Daniel Kurtz
2018-03-12 16:45 ` Daniel Kurtz
2018-03-26  9:12 ` Linus Walleij
2018-03-28  5:19   ` Shah, Nehal-bakulchandra

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.