Skip to content

Commit 239981b

Browse files
committed
Merge branch 'pci/aspm'
- Collect ASPM-related code into aspm.c (David E. Box) - Save and restore ASPM L1 PM Substates configuration so these states continue working after suspend/resume (David E. Box) - Move the ASPM L1.2-related LTR save/restore next to the ASPM save/restore (David E. Box) - Move the required L1 disable before L1 Substate configuration into pci_restore_aspm_l1ss_state() (Bjorn Helgaas) - Update save_save when ASPM config is changed, so a .slot_reset() during error recovery restores the changed config, not the .probe()-time config (Vidya Sagar) * pci/aspm: PCI/ASPM: Update save_state when configuration changes PCI/ASPM: Disable L1 before configuring L1 Substates PCI/ASPM: Call pci_save_ltr_state() from pci_save_pcie_state() PCI/ASPM: Save L1 PM Substates Capability for suspend/resume PCI/ASPM: Move pci_save_ltr_state() to aspm.c PCI/ASPM: Always build aspm.c PCI/ASPM: Move pci_configure_ltr() to aspm.c
2 parents 5aff0f3 + 6d42666 commit 239981b

File tree

6 files changed

+292
-130
lines changed

6 files changed

+292
-130
lines changed

drivers/pci/pci.c

Lines changed: 10 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,25 +1651,10 @@ static int pci_save_pcie_state(struct pci_dev *dev)
16511651
pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &cap[i++]);
16521652
pcie_capability_read_word(dev, PCI_EXP_SLTCTL2, &cap[i++]);
16531653

1654-
return 0;
1655-
}
1656-
1657-
void pci_bridge_reconfigure_ltr(struct pci_dev *dev)
1658-
{
1659-
#ifdef CONFIG_PCIEASPM
1660-
struct pci_dev *bridge;
1661-
u32 ctl;
1654+
pci_save_aspm_l1ss_state(dev);
1655+
pci_save_ltr_state(dev);
16621656

1663-
bridge = pci_upstream_bridge(dev);
1664-
if (bridge && bridge->ltr_path) {
1665-
pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, &ctl);
1666-
if (!(ctl & PCI_EXP_DEVCTL2_LTR_EN)) {
1667-
pci_dbg(bridge, "re-enabling LTR\n");
1668-
pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2,
1669-
PCI_EXP_DEVCTL2_LTR_EN);
1670-
}
1671-
}
1672-
#endif
1657+
return 0;
16731658
}
16741659

16751660
static void pci_restore_pcie_state(struct pci_dev *dev)
@@ -1678,6 +1663,13 @@ static void pci_restore_pcie_state(struct pci_dev *dev)
16781663
struct pci_cap_saved_state *save_state;
16791664
u16 *cap;
16801665

1666+
/*
1667+
* Restore max latencies (in the LTR capability) before enabling
1668+
* LTR itself in PCI_EXP_DEVCTL2.
1669+
*/
1670+
pci_restore_ltr_state(dev);
1671+
pci_restore_aspm_l1ss_state(dev);
1672+
16811673
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
16821674
if (!save_state)
16831675
return;
@@ -1735,46 +1727,6 @@ static void pci_restore_pcix_state(struct pci_dev *dev)
17351727
pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]);
17361728
}
17371729

1738-
static void pci_save_ltr_state(struct pci_dev *dev)
1739-
{
1740-
int ltr;
1741-
struct pci_cap_saved_state *save_state;
1742-
u32 *cap;
1743-
1744-
if (!pci_is_pcie(dev))
1745-
return;
1746-
1747-
ltr = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR);
1748-
if (!ltr)
1749-
return;
1750-
1751-
save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_LTR);
1752-
if (!save_state) {
1753-
pci_err(dev, "no suspend buffer for LTR; ASPM issues possible after resume\n");
1754-
return;
1755-
}
1756-
1757-
/* Some broken devices only support dword access to LTR */
1758-
cap = &save_state->cap.data[0];
1759-
pci_read_config_dword(dev, ltr + PCI_LTR_MAX_SNOOP_LAT, cap);
1760-
}
1761-
1762-
static void pci_restore_ltr_state(struct pci_dev *dev)
1763-
{
1764-
struct pci_cap_saved_state *save_state;
1765-
int ltr;
1766-
u32 *cap;
1767-
1768-
save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_LTR);
1769-
ltr = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR);
1770-
if (!save_state || !ltr)
1771-
return;
1772-
1773-
/* Some broken devices only support dword access to LTR */
1774-
cap = &save_state->cap.data[0];
1775-
pci_write_config_dword(dev, ltr + PCI_LTR_MAX_SNOOP_LAT, *cap);
1776-
}
1777-
17781730
/**
17791731
* pci_save_state - save the PCI configuration space of a device before
17801732
* suspending
@@ -1799,7 +1751,6 @@ int pci_save_state(struct pci_dev *dev)
17991751
if (i != 0)
18001752
return i;
18011753

1802-
pci_save_ltr_state(dev);
18031754
pci_save_dpc_state(dev);
18041755
pci_save_aer_state(dev);
18051756
pci_save_ptm_state(dev);
@@ -1900,12 +1851,6 @@ void pci_restore_state(struct pci_dev *dev)
19001851
if (!dev->state_saved)
19011852
return;
19021853

1903-
/*
1904-
* Restore max latencies (in the LTR capability) before enabling
1905-
* LTR itself (in the PCIe capability).
1906-
*/
1907-
pci_restore_ltr_state(dev);
1908-
19091854
pci_restore_pcie_state(dev);
19101855
pci_restore_pasid_state(dev);
19111856
pci_restore_pri_state(dev);

drivers/pci/pci.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ void pci_msi_init(struct pci_dev *dev);
9797
void pci_msix_init(struct pci_dev *dev);
9898
bool pci_bridge_d3_possible(struct pci_dev *dev);
9999
void pci_bridge_d3_update(struct pci_dev *dev);
100-
void pci_bridge_reconfigure_ltr(struct pci_dev *dev);
101100
int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type);
102101

103102
static inline void pci_wakeup_event(struct pci_dev *dev)
@@ -568,16 +567,28 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
568567

569568
bool pcie_wait_for_link(struct pci_dev *pdev, bool active);
570569
int pcie_retrain_link(struct pci_dev *pdev, bool use_lt);
570+
571+
/* ASPM-related functionality we need even without CONFIG_PCIEASPM */
572+
void pci_save_ltr_state(struct pci_dev *dev);
573+
void pci_restore_ltr_state(struct pci_dev *dev);
574+
void pci_configure_aspm_l1ss(struct pci_dev *dev);
575+
void pci_save_aspm_l1ss_state(struct pci_dev *dev);
576+
void pci_restore_aspm_l1ss_state(struct pci_dev *dev);
577+
571578
#ifdef CONFIG_PCIEASPM
572579
void pcie_aspm_init_link_state(struct pci_dev *pdev);
573580
void pcie_aspm_exit_link_state(struct pci_dev *pdev);
574581
void pcie_aspm_pm_state_change(struct pci_dev *pdev);
575582
void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
583+
void pci_configure_ltr(struct pci_dev *pdev);
584+
void pci_bridge_reconfigure_ltr(struct pci_dev *pdev);
576585
#else
577586
static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { }
578587
static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { }
579588
static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { }
580589
static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { }
590+
static inline void pci_configure_ltr(struct pci_dev *pdev) { }
591+
static inline void pci_bridge_reconfigure_ltr(struct pci_dev *pdev) { }
581592
#endif
582593

583594
#ifdef CONFIG_PCIE_ECRC

drivers/pci/pcie/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pcieportdrv-y := portdrv.o rcec.o
66

77
obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o
88

9-
obj-$(CONFIG_PCIEASPM) += aspm.o
9+
obj-y += aspm.o
1010
obj-$(CONFIG_PCIEAER) += aer.o err.o
1111
obj-$(CONFIG_PCIEAER_INJECT) += aer_inject.o
1212
obj-$(CONFIG_PCIE_PME) += pme.o

0 commit comments

Comments
 (0)