Messages in this thread Patch in this message |  | | From | Konrad Dybcio <> | | Date | Tue, 05 May 2026 10:55:04 +0200 | | Subject | [PATCH 1/2] usb: host: xhci: Allow non-Intel usb_link_tunnel_mode reporting |
| |
From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
The Thunderbolt framework relies on the USB core to create device links for tunneled ports, so that the USB3 controller is only kept runtime-resumed for the duration of the tunneling.
Currently, retrieving that information is only possibe on Intel XHCI hosts, through a vendor-specific capability. Extend xhci-plat to allow plumbing a custom one.
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> --- drivers/usb/host/xhci-hub.c | 4 ++-- drivers/usb/host/xhci-plat.c | 2 ++ drivers/usb/host/xhci-plat.h | 1 + drivers/usb/host/xhci.c | 6 +++++- drivers/usb/host/xhci.h | 5 ++++- 5 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index bacd0ddd0d09..09e5da912066 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -750,7 +750,7 @@ static int xhci_exit_test_mode(struct xhci_hcd *xhci) } /** - * xhci_port_is_tunneled() - Check if USB3 connection is tunneled over USB4 + * xhci_port_tunnel_mode() - Check if USB3 connection is tunneled over USB4 * @xhci: xhci host controller * @port: USB3 port to be checked. * @@ -764,7 +764,7 @@ static int xhci_exit_test_mode(struct xhci_hcd *xhci) * detecting USB3 over USB4 tunnels. USB_LINK_NATIVE or USB_LINK_TUNNELED * otherwise. */ -enum usb_link_tunnel_mode xhci_port_is_tunneled(struct xhci_hcd *xhci, +enum usb_link_tunnel_mode xhci_port_tunnel_mode(struct xhci_hcd *xhci, struct xhci_port *port) { struct usb_hcd *hcd; diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 074d9c731639..dbaca694baa2 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -244,6 +244,8 @@ int xhci_plat_probe(struct platform_device *pdev, struct device *sysdev, const s priv = hcd_to_xhci_priv(hcd); /* Just copy data for now */ *priv = *priv_match; + + xhci->tunnel_mode = priv->tunnel_mode; } device_set_wakeup_capable(&pdev->dev, true); diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h index 00751d851831..c5042766a486 100644 --- a/drivers/usb/host/xhci-plat.h +++ b/drivers/usb/host/xhci-plat.h @@ -22,6 +22,7 @@ struct xhci_plat_priv { int (*suspend_quirk)(struct usb_hcd *); int (*resume_quirk)(struct usb_hcd *); int (*post_resume_quirk)(struct usb_hcd *); + enum usb_link_tunnel_mode (*tunnel_mode)(struct usb_hcd *hcd, int portnum); }; #define hcd_to_xhci_priv(h) ((struct xhci_plat_priv *)hcd_to_xhci(h)->priv) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index a54f5b57f205..90a6751b5c69 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4754,7 +4754,11 @@ static int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) if (hcd->speed >= HCD_USB3 && !udev->parent->parent) { port = xhci->usb3_rhub.ports[udev->portnum - 1]; - udev->tunnel_mode = xhci_port_is_tunneled(xhci, port); + if (xhci->tunnel_mode) + udev->tunnel_mode = xhci->tunnel_mode(hcd, port->hcd_portnum); + else + udev->tunnel_mode = xhci_port_tunnel_mode(xhci, port); + if (udev->tunnel_mode == USB_LINK_UNKNOWN) dev_dbg(&udev->dev, "link tunnel state unknown\n"); else if (udev->tunnel_mode == USB_LINK_TUNNELED) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index aeecd301f207..59cc5797d5d2 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1672,6 +1672,9 @@ struct xhci_hcd { struct list_head regset_list; void *dbc; + + enum usb_link_tunnel_mode (*tunnel_mode)(struct usb_hcd *hcd, int portnum); + /* platform-specific data -- must come last */ unsigned long priv[] __aligned(sizeof(s64)); }; @@ -1977,7 +1980,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1); struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd); -enum usb_link_tunnel_mode xhci_port_is_tunneled(struct xhci_hcd *xhci, +enum usb_link_tunnel_mode xhci_port_tunnel_mode(struct xhci_hcd *xhci, struct xhci_port *port); void xhci_hc_died(struct xhci_hcd *xhci); -- 2.54.0
|  |