[PATCH 4/4] PCI: Do not mistake an absent device for an active link

From: Francisco Beltrán Millalén

Date: Thu Sep 24 2026 - 08:56:27 EST


pci_bridge_wait_for_secondary_bus() reads PCI_EXP_LNKSTA and treats
PCI_EXP_LNKSTA_DLLLA as "the link is up". When the device is gone the
read returns 0xffff, which has that bit set, so an absent device looks
like an active link and the code waits PCIE_RESET_READY_POLL_MS -- 60
seconds -- before giving up.

Treat an all-ones read as "no link", which is what it means. On a
MacBookPro14,3 whose Thunderbolt controller does not come back from S3
this takes the resume from 65 seconds down to one.

Signed-off-by: Francisco Beltrán Millalén <fbeltranmillalen@xxxxxxxxx>
---
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4773,8 +4773,16 @@
if (!dev->link_active_reporting)
return -ENOTTY;

+ /*
+ * A device that is gone answers config reads with all ones,
+ * and all ones has DLLLA set, so an unchecked read here is
+ * indistinguishable from an active link. That makes the
+ * code below wait the full PCIE_RESET_READY_POLL_MS for a
+ * device that is not there. Treat it as absent instead.
+ */
pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &status);
- if (!(status & PCI_EXP_LNKSTA_DLLLA))
+ if (PCI_POSSIBLE_ERROR(status) ||
+ !(status & PCI_EXP_LNKSTA_DLLLA))
return -ENOTTY;

return pci_dev_wait(child, reset_type,