Skip to content

Fix USB IRQ storm on R4 Pro when the CN15 M.2 slot is empty - #204

Merged
frank-w merged 1 commit into
frank-w:7.1-mainfrom
meehien:bpi/clk-mt7988-usb-pipe
Jul 30, 2026
Merged

Fix USB IRQ storm on R4 Pro when the CN15 M.2 slot is empty#204
frank-w merged 1 commit into
frank-w:7.1-mainfrom
meehien:bpi/clk-mt7988-usb-pipe

Conversation

@meehien

Copy link
Copy Markdown

On the BPI-R4 Pro, ssusb0's SuperSpeed lane and pcie2 share one serdes.
pcie2 is the only consumer holding CLK_INFRA_USB_PIPE, so when the M.2 slot
is empty and pcie2 fails link training, its error path gates the clock out
from under a SuperSpeed root hub that is still registered and polling.
The result is an unacknowledgeable interrupt, nobody cared, a disabled
IRQ line, and then a hang in xhci_disable_slot() at the next USB teardown
or reboot.

Marking the gate CLK_IS_CRITICAL keeps the lane's reference clock alive.
Only port 0 is affected; ssusb1 uses a separate gate.

Tested on BPI-R4 Pro 8X with CN15 empty. Also see the companion
xhci-mtk fix (PR 5), which addresses the other half of the same symptom.

CLK_INFRA_USB_PIPE is the reference clock of xphyu3port0, the U3/PCIe
combo serdes. On MT7988 that lane is shared between ssusb0's SuperSpeed
side and pcie2, but only the consumer that claims the PHY holds the gate.
On the BPI-R4 Pro, ssusb0 is configured USB2-only (u3p-dis-msk=1) and
pcie2 claims the lane for the CN13/CN15 M.2 slot, so pcie2 is the sole
holder. u3p-dis-msk does not remove ssusb0's SuperSpeed root hub: that is
decided by xhci_has_one_roothub(), which keys off usb3_rhub.num_ports
from the xHCI capability registers, so bus 2 is registered and live
regardless. When the M.2 slot is empty, pcie2 fails link training (-110)
and its error path calls phy_power_off()/phy_exit(), which gates this
clock - and sspxtp_sel with it, as nothing else consumes it. The still
registered SuperSpeed root hub is then left polling a serdes whose PHY
reference clock has just stopped, and asserts the shared SSUSB interrupt
outside the xHCI event ring; xhci_irq() reads USBSTS with EINT clear and
returns IRQ_NONE, so the core disables the line ("nobody cared") and the
next USB teardown blocks forever in xhci_disable_slot().
Boot logs show the storm threshold being crossed 86-107 ms after the
pcie2 probe failure, while the earlier combo-mux switch to PCIe mode
(~550 ms before) causes no trouble, pointing at the clock gating rather
than the mux as the trigger.
Mark the gate CLK_IS_CRITICAL so the combo lane keeps its reference clock.
Only port 0's gate is affected; ssusb1 uses CLK_INFRA_USB_PIPE_CK_P1.
Signed-off-by: Mihai Ordean <research@mihaiordean.com>
@frank-w
frank-w merged commit 3e4b73b into frank-w:7.1-mainJul 30, 2026
@frank-w

Copy link
Copy Markdown
Owner

Which PR does fix xhci one? PR5 is mali support,so unrelated

@meehien

Copy link
Copy Markdown
Author

sorry it's #200 (comment)

@frank-w

Copy link
Copy Markdown
Owner

both merged :) thanks for this fix, will try soon if the irq-trace is gone...not sure if it is a upstreamable way as clocks should not be made critical for this

@meehien
meehien deleted the bpi/clk-mt7988-usb-pipe branch August 1, 2026 11:48
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@meehien@frank-w