From: sashiko-bot@kernel.org
To: "Yaohan Li" <shunsheng1218@gmail.com>
Cc: linux-usb@vger.kernel.org
Subject: Re: [PATCH v3] usb: typec: tcpci: filter masked alerts and quiesce the IRQ
Date: Thu, 12 Nov 2026 08:56:34 +0000 [thread overview]
Message-ID: <sashiko-outbox-210802@kernel.org> (raw)
In-Reply-To: <20261112084014.2564834-1-shunsheng1218@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [High] usb: typec: tcpci: masking status before clearing TCPC_ALERT
causes IRQ storm
- [Medium] usb: typec: tcpci: zeroing alert_mask before hardware mask
write causes IRQ storm
--
commit 3b5f8c5cf280be1359b54eb345cc21c55eeb3247
Author: Yaohan Li <shunsheng1218@gmail.com>
usb: typec: tcpci: filter masked alerts and quiesce the IRQ
This commit filters TCPC_ALERT status bits with tcpci->alert_mask in
tcpci_irq() and adds an alerts_quiesced state and synchronize_irq() calls
to quiesce interrupts before unregistering the TCPM port on removal and
probe failure.
> diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
> index c6165466c54b6..d413ebca75da2 100644
> --- a/drivers/usb/typec/tcpm/tcpci.c
> +++ b/drivers/usb/typec/tcpm/tcpci.c
[ ... ]
> @@ -722,8 +738,12 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
> int irq_ret;
> unsigned int raw;
>
> + if (!READ_ONCE(tcpci->alert_mask))
> + return IRQ_NONE;
> +
> tcpci_read16(tcpci, TCPC_ALERT, &status);
> - irq_ret = status & tcpci->alert_mask;
> + status &= READ_ONCE(tcpci->alert_mask);
> + irq_ret = status;
>
> process_status:
> /*
[Severity: High]
Can masking status with tcpci->alert_mask before writing TCPC_ALERT leave
hardware-enabled alerts latched and cause a level-triggered IRQ storm?
tcpci_init() never sets TCPC_ALERT_RX_BUF_OVF, TCPC_ALERT_FAULT or
TCPC_ALERT_VBUS_DISCNCT in tcpci->alert_mask, but vendor drivers that
delegate interrupt handling to tcpci_irq() unmask those bits in hardware:
drivers/usb/typec/tcpm/tcpci_rt1711h.c:rt1711h_probe() {
...
const u16 alert_mask = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_DISCARDED |
TCPC_ALERT_TX_FAILED | TCPC_ALERT_RX_HARD_RST |
TCPC_ALERT_RX_STATUS | TCPC_ALERT_POWER_STATUS |
TCPC_ALERT_CC_STATUS | TCPC_ALERT_RX_BUF_OVF |
TCPC_ALERT_FAULT;
...
ret = rt1711h_write16(chip, TCPC_ALERT_MASK, alert_mask);
}
Previously, tcpci_write16(tcpci, TCPC_ALERT, status & ~TCPC_ALERT_RX_STATUS)
cleared any latched bit read from TCPC_ALERT. With status masked by
tcpci->alert_mask first (and again after the re-read at the bottom of
tcpci_irq()), TCPC_ALERT_FAULT or TCPC_ALERT_RX_BUF_OVF is never written
back to TCPC_ALERT, so the active-low Alert# line stays asserted while
tcpci_irq() repeatedly returns IRQ_NONE until the spurious IRQ detector
disables the interrupt line.
[ ... ]
> @@ -988,10 +1013,19 @@ static void tcpci_remove(struct i2c_client *client)
> struct tcpci_chip *chip = i2c_get_clientdata(client);
> int err;
>
> - /* Disable chip interrupts before unregistering port */
> + /*
> + * The port's kthread worker is destroyed by tcpci_unregister_port()
> + * below, while the threaded IRQ handler can still queue work on it.
> + * Publish a zero software mask first: tcpci_irq() then ignores any
> + * alert that is still latched, or asserted again on a shared IRQ,
> + * even if the hardware mask write fails. synchronize_irq() waits
> + * for handlers that already read the old mask.
> + */
> + tcpci_quiesce_alerts(chip->tcpci);
> err = tcpci_write16(chip->tcpci, TCPC_ALERT_MASK, 0);
> if (err < 0)
> dev_warn(&client->dev, "Failed to disable irqs (%pe)\n", ERR_PTR(err));
> + synchronize_irq(client->irq);
>
> tcpci_unregister_port(chip->tcpci);
> }
[Severity: Medium]
Can zeroing tcpci->alert_mask before masking TCPC_ALERT_MASK in hardware
trigger an unhandled IRQ storm if an alert fires during the I2C write?
CPU0 irq/client->irq (SCHED_FIFO)
tcpci_remove()
tcpci_quiesce_alerts()
tcpci->alert_mask = 0
tcpci_write16(..., TCPC_ALERT_MASK, 0)
<blocks on I2C transfer>
<Alert# asserted low>
_tcpci_irq()
tcpci_irq()
if (!READ_ONCE(tcpci->alert_mask))
return IRQ_NONE;
irq_finalize_oneshot()
<unmasks level-low IRQ line>
<Alert# re-fires immediately> <-- IRQ storm
While tcpci_write16() sleeps waiting for the I2C transfer, hardware
interrupts are still enabled in TCPC_ALERT_MASK. Because tcpci_irq() now
returns IRQ_NONE immediately without sleeping on I2C or clearing
TCPC_ALERT, irq_finalize_oneshot() unmasks the level-triggered line with
Alert# still asserted low, spinning in the real-time IRQ thread until the
I2C write finishes or the spurious IRQ detector disables the shared IRQ.
Should TCPC_ALERT_MASK be cleared in hardware before calling
tcpci_quiesce_alerts()?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112084014.2564834-1-shunsheng1218@gmail.com?part=1
prev parent reply other threads:[~2026-11-12 8:56 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 8:40 [PATCH v3] usb: typec: tcpci: filter masked alerts and quiesce the IRQ Yaohan Li
2026-11-12 8:56 ` sashiko-bot [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-210802@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=shunsheng1218@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.