@@ -79,7 +79,7 @@ void pci_configure_aspm_l1ss(struct pci_dev *pdev)
ERR_PTR(rc));
}
-void pci_save_aspm_l1ss_state(struct pci_dev *pdev)
+static void __pci_save_aspm_l1ss_state(struct pci_dev *pdev)
{
struct pci_cap_saved_state *save_state;
u16 l1ss = pdev->l1ss;
@@ -101,6 +101,22 @@ void pci_save_aspm_l1ss_state(struct pci_dev *pdev)
pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, cap++);
}
+void pci_save_aspm_l1ss_state(struct pci_dev *pdev)
+{
+ struct pci_dev *parent = pdev->bus->self;
+
+ __pci_save_aspm_l1ss_state(pdev);
+
+ /*
+ * Save parent's L1 substate configuration, if the parent has not saved
+ * state. It avoids pci_restore_aspm_l1ss_state() restore wrong value to
+ * parent's L1 substate configuration. However, the parent might be
+ * nothing, if pdev is a PCI bridge.
+ */
+ if (parent && !parent->state_saved)
+ __pci_save_aspm_l1ss_state(parent);
+}
+
void pci_restore_aspm_l1ss_state(struct pci_dev *pdev)
{
struct pci_cap_saved_state *pl_save_state, *cl_save_state;