[PATCH] usb: typec: port-mapper: Only match USB4 port if host interface is available

From: Marek Maslanka

Date: Fri Sep 25 2026 - 09:21:12 EST


typec_port_match() adds a component match for the USB4 port whenever a
USB 3.x port that shares the _PLD with the Type-C connector has the
"usb4-host-interface" property, regardless of whether a USB4 port can
ever be registered for it. The component framework binds the aggregate
device only once every match has found its component, so if the USB4
port never shows up, the USB 2.0 and USB 3.x ports are not linked to the
connector either: the "connector" symlinks are never created and USB
devices enumerated on those ports are never linked with the Type-C
partner.

This happens in at least two cases:

1. CONFIG_USB4 is not reachable from the Type-C core, i.e. CONFIG_USB4=n,
or CONFIG_USB4=m with CONFIG_TYPEC=y as in the x86_64 gki_defconfig.
usb4_usb3_port_match() is then a stub that always returns false.

2. The firmware references a USB4 host interface that is disabled. For
example, on Intel Alder Lake-N (ChromeOS Nissa) the TCSS xHCI USB3
ports (SS01-SS04) reference TDM0/TDM1, whose _STA returns 0 because
the SoC has no integrated Thunderbolt/USB4 and the DMA controllers
are disabled in TCSS DEVEN. No PCI device is enumerated for them.

Only add the USB4 component match if CONFIG_USB4 is reachable and the
referenced host interface is available and has been enumerated as a
device. The latter mirrors the check in usb_acpi_add_usb4_devlink(), see
commit 623dae3e7084 ("usb: acpi: fix boot hang due to early incorrect
'tunneled' USB3 device links").

Fixes: 4fd7a1f0f7f2 ("usb: typec: Connect Type-C port with associated USB4 port")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Marek Maslanka <mmaslanka@xxxxxxxxxx>
---
drivers/usb/typec/port-mapper.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/typec/port-mapper.c b/drivers/usb/typec/port-mapper.c
index cdbb7c11d714..3a97b084c3bd 100644
--- a/drivers/usb/typec/port-mapper.c
+++ b/drivers/usb/typec/port-mapper.c
@@ -42,6 +42,23 @@ static int usb4_port_compare(struct device *dev, void *fwnode)
return usb4_usb3_port_match(dev, fwnode);
}

+static bool typec_has_usb4_host_interface(const struct fwnode_handle *fwnode)
+{
+ if (!IS_REACHABLE(CONFIG_USB4))
+ return false;
+
+ struct fwnode_handle *nhi_fwnode __free(fwnode_handle) =
+ fwnode_find_reference(fwnode, "usb4-host-interface", 0);
+
+ /*
+ * The USB4 port can only appear if the host interface is enabled in
+ * the firmware and has been enumerated as a device. The latter is
+ * the same check as in usb_acpi_add_usb4_devlink().
+ */
+ return !IS_ERR(nhi_fwnode) && fwnode_device_is_available(nhi_fwnode) &&
+ nhi_fwnode->dev;
+}
+
static int typec_port_compare(struct device *dev, void *fwnode)
{
return device_match_fwnode(dev, fwnode);
@@ -64,11 +81,11 @@ static int typec_port_match(struct device *dev, void *data)
adev_fwnode);

/*
- * If dev is USB 3.x port, it may have reference to the
+ * If dev is USB 3.x port, it may have reference to an available
* USB4 host interface in which case we can also link the
* Type-C port with the USB4 port.
*/
- if (fwnode_property_present(adev_fwnode, "usb4-host-interface"))
+ if (typec_has_usb4_host_interface(adev_fwnode))
component_match_add(&arg->port->dev, &arg->match,
usb4_port_compare, adev_fwnode);
}
--
2.56.0.rc1.315.gc6ed9934b7-goog