* [PATCH] extcon: usbc-tusb320: always rewrite REG9 to deassert INT_N
@ 2026-07-28 15:37 Advait Dhamorikar
2026-07-29 7:27 ` Alvin Šipraga
0 siblings, 1 reply; 4+ messages in thread
From: Advait Dhamorikar @ 2026-07-28 15:37 UTC (permalink / raw)
To: myungjoo.ham, cw00.choi, linux-kernel
Cc: alsi, gregkh, marex, heikki.krogerus, Advait Dhamorikar
The IRQ handler currently returns IRQ_NONE without rewriting REG9 when
INTERRUPT_STATUS is clear, skipping the documented interrupt acknowledge
sequence which says that rewrites to this register are needed for the
INT_N to be correctly asserted for all interrupt events.
On some hardware, this can leave INT_N asserted, causing repeated
level-triggered interrupts until the kernel disables the IRQ as
spurious.
Always rewrite REG9 before returning from the IRQ handler, regardless
of the observed INTERRUPT_STATUS bit, and return IRQ_HANDLED once the
acknowledge sequence has been performed. Also report REG9 write
failures to aid debugging.
Fixes: 581c848b610d ("extcon: usbc-tusb320: Update state on probe even if no IRQ pending")
Signed-off-by: Advait Dhamorikar <advaitd@mechasystems.com>
---
drivers/extcon/extcon-usbc-tusb320.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c
index 920b03421850..56c888004f41 100644
--- a/drivers/extcon/extcon-usbc-tusb320.c
+++ b/drivers/extcon/extcon-usbc-tusb320.c
@@ -375,14 +375,25 @@ static irqreturn_t tusb320_state_update_handler(struct tusb320_priv *priv,
bool force_update)
{
unsigned int reg;
+ int ret;
- if (regmap_read(priv->regmap, TUSB320_REG9, ®)) {
- dev_err(priv->dev, "error during i2c read!\n");
+ ret = regmap_read(priv->regmap, TUSB320_REG9, ®);
+ if (ret) {
+ dev_err(priv->dev, "REG9 read failed: %d\n", ret);
return IRQ_NONE;
}
- if (!force_update && !(reg & TUSB320_REG9_INTERRUPT_STATUS))
- return IRQ_NONE;
+ if (!force_update && !(reg & TUSB320_REG9_INTERRUPT_STATUS)) {
+ dev_dbg(priv->dev, "IRQ fired but interrupt status not set\n");
+ /*
+ * Rewrites to this register are needed for the INT_N
+ * to be correctly asserted for all interrupt events.
+ */
+ ret = regmap_write(priv->regmap, TUSB320_REG9, reg);
+ if (ret)
+ dev_err(priv->dev, "REG9 write failed: %d\n", ret);
+ return IRQ_HANDLED;
+ }
tusb320_extcon_irq_handler(priv, reg);
@@ -393,7 +404,9 @@ static irqreturn_t tusb320_state_update_handler(struct tusb320_priv *priv,
if (priv->port)
tusb320_typec_irq_handler(priv, reg);
- regmap_write(priv->regmap, TUSB320_REG9, reg);
+ ret = regmap_write(priv->regmap, TUSB320_REG9, reg);
+ if (ret)
+ dev_err(priv->dev, "REG9 write failed: %d\n", ret);
return IRQ_HANDLED;
}
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] extcon: usbc-tusb320: always rewrite REG9 to deassert INT_N
2026-07-28 15:37 [PATCH] extcon: usbc-tusb320: always rewrite REG9 to deassert INT_N Advait Dhamorikar
@ 2026-07-29 7:27 ` Alvin Šipraga
2026-07-29 11:08 ` Advait Dhamorikar
0 siblings, 1 reply; 4+ messages in thread
From: Alvin Šipraga @ 2026-07-29 7:27 UTC (permalink / raw)
To: Advait Dhamorikar
Cc: myungjoo.ham, cw00.choi, linux-kernel, alsi, gregkh, marex,
heikki.krogerus
On Tue, Jul 28, 2026 at 09:07:44PM +0530, Advait Dhamorikar wrote:
> The IRQ handler currently returns IRQ_NONE without rewriting REG9 when
> INTERRUPT_STATUS is clear, skipping the documented interrupt acknowledge
> sequence which says that rewrites to this register are needed for the
> INT_N to be correctly asserted for all interrupt events.
>
> On some hardware, this can leave INT_N asserted, causing repeated
> level-triggered interrupts until the kernel disables the IRQ as
> spurious.
Can you say a bit more about your hardware? You seem to be saying that
INT_N is sometimes being asserted when INTERRUPT_STATUS=0, but that is
in contradiction with the datasheet, which states that:
| When INT_N is pulled low, this bit [INTERRUPT_STATUS] will be 1.
(check table 7-7 in [1] or table 9 in [2])
[1] https://www.ti.com/lit/ds/symlink/tusb320.pdf?ts=1785241670013
Taking the datasheet at face value, the driver's logic seems sound to me.
I know Marek fought with the interrupt handling of this chip in the past
and has some more experience, so perhaps he knows better what you are
talking about.
> Always rewrite REG9 before returning from the IRQ handler, regardless
> of the observed INTERRUPT_STATUS bit, and return IRQ_HANDLED once the
> acknowledge sequence has been performed. Also report REG9 write
> failures to aid debugging.
This will also break support for shared interrupts, should anybody want
to add it later on.
>
> Fixes: 581c848b610d ("extcon: usbc-tusb320: Update state on probe even if no IRQ pending")
> Signed-off-by: Advait Dhamorikar <advaitd@mechasystems.com>
> ---
> drivers/extcon/extcon-usbc-tusb320.c | 23 ++++++++++++++++++-----
> 1 file changed, 18 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c
> index 920b03421850..56c888004f41 100644
> --- a/drivers/extcon/extcon-usbc-tusb320.c
> +++ b/drivers/extcon/extcon-usbc-tusb320.c
> @@ -375,14 +375,25 @@ static irqreturn_t tusb320_state_update_handler(struct tusb320_priv *priv,
> bool force_update)
> {
> unsigned int reg;
> + int ret;
>
> - if (regmap_read(priv->regmap, TUSB320_REG9, ®)) {
> - dev_err(priv->dev, "error during i2c read!\n");
> + ret = regmap_read(priv->regmap, TUSB320_REG9, ®);
> + if (ret) {
> + dev_err(priv->dev, "REG9 read failed: %d\n", ret);
> return IRQ_NONE;
> }
>
> - if (!force_update && !(reg & TUSB320_REG9_INTERRUPT_STATUS))
> - return IRQ_NONE;
> + if (!force_update && !(reg & TUSB320_REG9_INTERRUPT_STATUS)) {
> + dev_dbg(priv->dev, "IRQ fired but interrupt status not set\n");
Isn't this the equivalent of calling this function with
force_update=true from the interrupt handler? And in that case all
callsites set it to true, so you could just drop it.
> + /*
> + * Rewrites to this register are needed for the INT_N
> + * to be correctly asserted for all interrupt events.
> + */
Even though INTERRUPT_STATUS=0 and you're writing 0 to it here?
> + ret = regmap_write(priv->regmap, TUSB320_REG9, reg);
> + if (ret)
> + dev_err(priv->dev, "REG9 write failed: %d\n", ret);
> + return IRQ_HANDLED;
> + }
>
> tusb320_extcon_irq_handler(priv, reg);
>
> @@ -393,7 +404,9 @@ static irqreturn_t tusb320_state_update_handler(struct tusb320_priv *priv,
> if (priv->port)
> tusb320_typec_irq_handler(priv, reg);
>
> - regmap_write(priv->regmap, TUSB320_REG9, reg);
> + ret = regmap_write(priv->regmap, TUSB320_REG9, reg);
> + if (ret)
> + dev_err(priv->dev, "REG9 write failed: %d\n", ret);
>
> return IRQ_HANDLED;
> }
> --
> 2.43.0
>
Kind regards,
Alvin
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] extcon: usbc-tusb320: always rewrite REG9 to deassert INT_N
2026-07-29 7:27 ` Alvin Šipraga
@ 2026-07-29 11:08 ` Advait Dhamorikar
2026-07-29 11:28 ` Alvin Šipraga
0 siblings, 1 reply; 4+ messages in thread
From: Advait Dhamorikar @ 2026-07-29 11:08 UTC (permalink / raw)
To: Alvin Šipraga
Cc: myungjoo.ham, cw00.choi, linux-kernel, alsi, gregkh, marex,
heikki.krogerus
Hi Alvin,
Thanks for taking a look.
> Can you say a bit more about your hardware?
This is on an NXP i.MX8MP based board using a TUSB320 connected over I²C.
The INT_N signal is connected to a GPIO configured as a level-low interrupt.
I agree that, taken at face value, the datasheet suggests the current
driver logic is correct. However, while debugging this issue I modified
the driver to log both REG9 and the interrupt GPIO level on every interrupt.
On my hardware I consistently observe:
GPIO = 0
REG9 = 0x20
INTERRUPT_STATUS = 0
The handler therefore returns IRQ_NONE, and because the GPIO
interrupt continues to be triggered, the generic IRQ layer eventually reports:
irq 143: nobody cared
Disabling IRQ
This appears inconsistent with my understanding of the datasheet,
which states that INTERRUPT_STATUS should be set whenever
INT_N is asserted. That observation is what initially led me to
investigate rewriting REG9 unconditionally.
> Even though INTERRUPT_STATUS=0 and you're writing 0 to it here?
That motivation came from the datasheet statement that "Rewrites to
this register are needed for the INT_N to be correctly asserted for all
interrupt events." I wanted to determine experimentally whether the
write transaction itself affected the interrupt state, even when
INTERRUPT_STATUS was already clear. This fix, however, appears
to only mask the issue by returning IRQ_HANDLED, preventing the
generic IRQ subsystem from treating the interrupt as unhandled.
The additional logging suggests that returning IRQ_HANDLED in
this path merely masks the issue by preventing the generic IRQ
layer from treating the interrupt as unhandled, rather than addressing
why the interrupt line remains asserted while INTERRUPT_STATUS is clear.
I'm trying to understand why the hardware presents an asserted
INT_N while REG9 reports no pending interrupt.
If there are additional registers or device states useful to inspect
in this situation, I'd be happy to investigate those as well.
Best regards,
Advait
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] extcon: usbc-tusb320: always rewrite REG9 to deassert INT_N
2026-07-29 11:08 ` Advait Dhamorikar
@ 2026-07-29 11:28 ` Alvin Šipraga
0 siblings, 0 replies; 4+ messages in thread
From: Alvin Šipraga @ 2026-07-29 11:28 UTC (permalink / raw)
To: Advait Dhamorikar
Cc: myungjoo.ham, cw00.choi, linux-kernel, alsi, gregkh, marex,
heikki.krogerus
Hi Advait,
On Wed, Jul 29, 2026 at 04:38:52PM +0530, Advait Dhamorikar wrote:
> Hi Alvin,
>
> Thanks for taking a look.
>
> > Can you say a bit more about your hardware?
>
> This is on an NXP i.MX8MP based board using a TUSB320 connected over I²C.
> The INT_N signal is connected to a GPIO configured as a level-low interrupt.
(I think we agree your patch is wrong, so I cut the rest of your reply)
[snip]
> I'm trying to understand why the hardware presents an asserted
> INT_N while REG9 reports no pending interrupt.
The INT_N signal is an open-drain output, so you need an external
pull-up resistor on the line. The TUSB320 will not drive it high when
there is no interrupt. Perhaps that's the problem?
If you have a pull-up resistor, check the behaviour when you hold the
TUSB320 in reset (use EN_N signal or power it off). If it's still low
then it's not the TUSB320 that's the problem.
If you have some kind of measuring tool (oscilloscope/etc.) it will be
more meaningful to probe the physical line than to listen to what Linux
or /proc/interrupts is telling you.
Hope that helps.
Kind regards,
Alvin
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-07-29 11:28 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-28 15:37 [PATCH] extcon: usbc-tusb320: always rewrite REG9 to deassert INT_N Advait Dhamorikar
2026-07-29 7:27 ` Alvin Šipraga
2026-07-29 11:08 ` Advait Dhamorikar
2026-07-29 11:28 ` Alvin Šipraga
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®