Skip to content

Commit c824581

Browse files
westeribjorn-helgaas
authored andcommitted
PCI/PM: Mark devices disconnected if upstream PCIe link is down on resume
Mark Blakeney reported that when suspending system with a Thunderbolt dock connected and then unplugging the dock before resume (which is pretty normal flow with laptops), resuming takes long time. What happens is that the PCIe link from the root port to the PCIe switch inside the Thunderbolt device does not train (as expected, the link is unplugged): pcieport 0000:00:07.2: restoring config space at offset 0x24 (was 0x3bf12001, writing 0x3bf12001) pcieport 0000:00:07.0: waiting 100 ms for downstream link pcieport 0000:01:00.0: not ready 1023ms after resume; giving up However, at this point we still try to resume the devices below that unplugged link: pcieport 0000:01:00.0: Unable to change power state from D3cold to D0, device inaccessible ... pcieport 0000:01:00.0: restoring config space at offset 0x38 (was 0xffffffff, writing 0x0) ... pcieport 0000:02:02.0: waiting 100 ms for downstream link, after activation And this is the link from PCIe switch downstream port to the xHCI on the dock: xhci_hcd 0000:03:00.0: not ready 65535ms after resume; giving up xhci_hcd 0000:03:00.0: Unable to change power state from D3cold to D0, device inaccessible xhci_hcd 0000:03:00.0: restoring config space at offset 0x3c (was 0xffffffff, writing 0x1ff) This ends up slowing down the resume time considerably. For this reason mark these devices as disconnected if the link above them did not train properly. Fixes: e8b9081 ("PCI/PM: Increase wait time after resume") Link: https://lore.kernel.org/r/20230918053041.1018876-1-mika.westerberg@linux.intel.com Reported-by: Mark Blakeney <mark.blakeney@bullet-systems.net> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217915 Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Lukas Wunner <lukas@wunner.de> Cc: stable@vger.kernel.org # v6.4+
1 parent f699774 commit c824581

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

drivers/pci/pci-driver.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,19 @@ static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
572572

573573
static void pci_pm_bridge_power_up_actions(struct pci_dev *pci_dev)
574574
{
575-
pci_bridge_wait_for_secondary_bus(pci_dev, "resume");
575+
int ret;
576+
577+
ret = pci_bridge_wait_for_secondary_bus(pci_dev, "resume");
578+
if (ret) {
579+
/*
580+
* The downstream link failed to come up, so mark the
581+
* devices below as disconnected to make sure we don't
582+
* attempt to resume them.
583+
*/
584+
pci_walk_bus(pci_dev->subordinate, pci_dev_set_disconnected,
585+
NULL);
586+
return;
587+
}
576588

577589
/*
578590
* When powering on a bridge from D3cold, the whole hierarchy may be

0 commit comments

Comments
 (0)