[PATCH v2] PCI/ASPM: Clear L1SS capability when L1 latency is unacceptable
From: Aniket
Date: Fri Aug 21 2026 - 09:52:47 EST
pcie_aspm_cap_init() initializes link->aspm_capable from
link->aspm_support, which includes PCIE_LINK_STATE_L1SS (L1.1, L1.2,
etc.) if supported by both ends of the link.
pcie_aspm_check_latency() then evaluates whether the exit latency of
the link exceeds the acceptable L1 latency advertised by downstream
endpoints. If the latency is unacceptable, it clears
PCIE_LINK_STATE_L1 from link->aspm_capable. However, it does not clear
PCIE_LINK_STATE_L1SS.
L1 PM Substates are substates of L1 and require L1 to be supported
and enabled. If L1 is not capable due to unacceptable exit latency,
L1 PM Substates cannot be supported either. Leaving
PCIE_LINK_STATE_L1SS set in link->aspm_capable causes
aspm_ctrl_attrs_are_visible() to expose L1SS sysfs control files (e.g.,
l1_1_aspm, l1_2_aspm) even though the link cannot use L1/L1SS.
Clear PCIE_LINK_STATE_L1SS along with PCIE_LINK_STATE_L1 from
link->aspm_capable when L1 exit latency is unacceptable.
In addition, update pcie_config_aspm_link() to check link->aspm_support
instead of link->aspm_capable before invoking pcie_config_aspm_l1ss().
This ensures that pcie_config_aspm_l1ss() is called to properly clear L1
PM Substates in the hardware configuration registers if the BIOS left
them enabled, even when link->aspm_capable no longer contains
PCIE_LINK_STATE_L1SS.
Signed-off-by: Aniket <aniketmaurya@xxxxxxxxxx>
---
drivers/pci/pcie/aspm.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 172783e7f519..b2660892972a 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -666,7 +666,8 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
latency = max_t(u32, latency_up_l1, latency_dw_l1);
if ((link->aspm_capable & PCIE_LINK_STATE_L1) &&
(latency + l1_switch_latency > acceptable_l1))
- link->aspm_capable &= ~PCIE_LINK_STATE_L1;
+ link->aspm_capable &= ~(PCIE_LINK_STATE_L1 |
+ PCIE_LINK_STATE_L1SS);
l1_switch_latency += NSEC_PER_USEC;
link = link->parent;
@@ -1041,7 +1042,7 @@ static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
pcie_config_aspm_dev(child, 0);
pcie_config_aspm_dev(parent, 0);
- if (link->aspm_capable & PCIE_LINK_STATE_L1SS)
+ if (link->aspm_support & PCIE_LINK_STATE_L1SS)
pcie_config_aspm_l1ss(link, state);
pcie_config_aspm_dev(parent, upstream);
--
2.55.0.766.g2966f0265a-goog