Skip to content

Commit 74622f0

Browse files
matnymangregkh
authored andcommitted
xhci: Detect lpm incapable xHC USB3 roothub ports from ACPI tables
USB3 ports on xHC hosts may have retimers that cause too long exit latency to work with native USB3 U1/U2 link power management states. For now only use usb_acpi_port_lpm_incapable() to evaluate if port lpm should be disabled while setting up the USB3 roothub. Other ways to identify lpm incapable ports can be added here later if ACPI _DSM does not exist. Limit this to Intel hosts for now, this is to my knowledge only an Intel issue. Cc: [email protected] Signed-off-by: Mathias Nyman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent cd702d1 commit 74622f0

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

drivers/usb/host/xhci-pci.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,38 @@ static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev)
355355
NULL);
356356
ACPI_FREE(obj);
357357
}
358+
359+
static void xhci_find_lpm_incapable_ports(struct usb_hcd *hcd, struct usb_device *hdev)
360+
{
361+
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
362+
struct xhci_hub *rhub = &xhci->usb3_rhub;
363+
int ret;
364+
int i;
365+
366+
/* This is not the usb3 roothub we are looking for */
367+
if (hcd != rhub->hcd)
368+
return;
369+
370+
if (hdev->maxchild > rhub->num_ports) {
371+
dev_err(&hdev->dev, "USB3 roothub port number mismatch\n");
372+
return;
373+
}
374+
375+
for (i = 0; i < hdev->maxchild; i++) {
376+
ret = usb_acpi_port_lpm_incapable(hdev, i);
377+
378+
dev_dbg(&hdev->dev, "port-%d disable U1/U2 _DSM: %d\n", i + 1, ret);
379+
380+
if (ret >= 0) {
381+
rhub->ports[i]->lpm_incapable = ret;
382+
continue;
383+
}
384+
}
385+
}
386+
358387
#else
359388
static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev) { }
389+
static void xhci_find_lpm_incapable_ports(struct usb_hcd *hcd, struct usb_device *hdev) { }
360390
#endif /* CONFIG_ACPI */
361391

362392
/* called during probe() after chip reset completes */
@@ -392,6 +422,10 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
392422
static int xhci_pci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
393423
struct usb_tt *tt, gfp_t mem_flags)
394424
{
425+
/* Check if acpi claims some USB3 roothub ports are lpm incapable */
426+
if (!hdev->parent)
427+
xhci_find_lpm_incapable_ports(hcd, hdev);
428+
395429
return xhci_update_hub_device(hcd, hdev, tt, mem_flags);
396430
}
397431

0 commit comments

Comments
 (0)