Merge branch 'pci/aspm'

- Save parent L1 PM Substates config so when we restore it along with an
  endpoint's config, the parent info isn't junk (Jian-Hong Pan)

* pci/aspm:
  PCI/ASPM: Save parent L1SS config in pci_save_aspm_l1ss_state()
This commit is contained in:
Bjorn Helgaas
2025-01-23 13:04:49 -06:00

View File

@@ -81,24 +81,47 @@ void pci_configure_aspm_l1ss(struct pci_dev *pdev)
void pci_save_aspm_l1ss_state(struct pci_dev *pdev)
{
struct pci_dev *parent = pdev->bus->self;
struct pci_cap_saved_state *save_state;
u16 l1ss = pdev->l1ss;
u32 *cap;
/*
* If this is a Downstream Port, we never restore the L1SS state
* directly; we only restore it when we restore the state of the
* Upstream Port below it.
*/
if (pcie_downstream_port(pdev) || !parent)
return;
if (!pdev->l1ss || !parent->l1ss)
return;
/*
* Save L1 substate configuration. The ASPM L0s/L1 configuration
* in PCI_EXP_LNKCTL_ASPMC is saved by pci_save_pcie_state().
*/
if (!l1ss)
return;
save_state = pci_find_saved_ext_cap(pdev, PCI_EXT_CAP_ID_L1SS);
if (!save_state)
return;
cap = &save_state->cap.data[0];
pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL2, cap++);
pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, cap++);
pci_read_config_dword(pdev, pdev->l1ss + PCI_L1SS_CTL2, cap++);
pci_read_config_dword(pdev, pdev->l1ss + PCI_L1SS_CTL1, cap++);
if (parent->state_saved)
return;
/*
* Save parent's L1 substate configuration so we have it for
* pci_restore_aspm_l1ss_state(pdev) to restore.
*/
save_state = pci_find_saved_ext_cap(parent, PCI_EXT_CAP_ID_L1SS);
if (!save_state)
return;
cap = &save_state->cap.data[0];
pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL2, cap++);
pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1, cap++);
}
void pci_restore_aspm_l1ss_state(struct pci_dev *pdev)