[PATCH 06/15] PCI/ASPM: Save LTR state in the saved capability store
From: David Matlack
Date: Thu Sep 24 2026 - 14:45:36 EST
Save and restore the LTR maximum latency registers through the per-device
saved capability store instead of a private pci_cap_saved_state buffer.
Reserve the DWORD by its configuration space offset during device setup,
and keep accessing the registers a DWORD at a time because some devices
only support DWORD access to them.
No functional change intended.
Assisted-by: LLM
Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx>
---
drivers/pci/pci.c | 12 ++++++++----
drivers/pci/pcie/aspm.c | 19 +++----------------
2 files changed, 11 insertions(+), 20 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 9e49806c6891..e53bca1cb50f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3580,10 +3580,14 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
pci_err(dev, "unable to reserve PCI-X save state\n");
}
- error = pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_LTR,
- 2 * sizeof(u16));
- if (error)
- pci_err(dev, "unable to allocate suspend buffer for LTR\n");
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR);
+ if (pos) {
+ unsigned int off = pos + PCI_LTR_MAX_SNOOP_LAT;
+
+ error = pci_reserve_saved_cap(dev, off, sizeof(u32));
+ if (error)
+ pci_err(dev, "unable to reserve LTR save state\n");
+ }
pci_allocate_vc_save_buffers(dev);
}
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 02922b887ec6..16f22af98686 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -30,8 +30,6 @@
void pci_save_ltr_state(struct pci_dev *dev)
{
int ltr;
- struct pci_cap_saved_state *save_state;
- u32 *cap;
if (!pci_is_pcie(dev))
return;
@@ -40,31 +38,20 @@ void pci_save_ltr_state(struct pci_dev *dev)
if (!ltr)
return;
- save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_LTR);
- if (!save_state) {
- pci_err(dev, "no suspend buffer for LTR; ASPM issues possible after resume\n");
- return;
- }
-
/* Some broken devices only support dword access to LTR */
- cap = &save_state->cap.data[0];
- pci_read_config_dword(dev, ltr + PCI_LTR_MAX_SNOOP_LAT, cap);
+ pci_save_cap_dword(dev, ltr + PCI_LTR_MAX_SNOOP_LAT);
}
void pci_restore_ltr_state(struct pci_dev *dev)
{
- struct pci_cap_saved_state *save_state;
int ltr;
- u32 *cap;
- save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_LTR);
ltr = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR);
- if (!save_state || !ltr)
+ if (!ltr)
return;
/* Some broken devices only support dword access to LTR */
- cap = &save_state->cap.data[0];
- pci_write_config_dword(dev, ltr + PCI_LTR_MAX_SNOOP_LAT, *cap);
+ pci_restore_cap_dword(dev, ltr + PCI_LTR_MAX_SNOOP_LAT);
}
void pci_configure_aspm_l1ss(struct pci_dev *pdev)
--
2.56.0.rc1.315.gc6ed9934b7-goog