PCI/ASPM: Save/restore L1SS Capability for suspend/resume
[linux-2.6-microblaze.git] / drivers / pci / pcie / aspm.c
index ac0557a..a08e7d6 100644 (file)
@@ -734,6 +734,50 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
                                PCI_L1SS_CTL1_L1SS_MASK, val);
 }
 
+void pci_save_aspm_l1ss_state(struct pci_dev *dev)
+{
+       int aspm_l1ss;
+       struct pci_cap_saved_state *save_state;
+       u32 *cap;
+
+       if (!pci_is_pcie(dev))
+               return;
+
+       aspm_l1ss = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_L1SS);
+       if (!aspm_l1ss)
+               return;
+
+       save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_L1SS);
+       if (!save_state)
+               return;
+
+       cap = (u32 *)&save_state->cap.data[0];
+       pci_read_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL1, cap++);
+       pci_read_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL2, cap++);
+}
+
+void pci_restore_aspm_l1ss_state(struct pci_dev *dev)
+{
+       int aspm_l1ss;
+       struct pci_cap_saved_state *save_state;
+       u32 *cap;
+
+       if (!pci_is_pcie(dev))
+               return;
+
+       aspm_l1ss = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_L1SS);
+       if (!aspm_l1ss)
+               return;
+
+       save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_L1SS);
+       if (!save_state)
+               return;
+
+       cap = (u32 *)&save_state->cap.data[0];
+       pci_write_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL1, *cap++);
+       pci_write_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL2, *cap++);
+}
+
 static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val)
 {
        pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL,