summaryrefslogtreecommitdiff
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2022-10-06 01:32:53 +0300
committerBjorn Helgaas <bhelgaas@google.com>2022-10-06 01:32:53 +0300
commit034f93fcb12f579c0108c7e2ca2d17ec4e5170aa (patch)
tree4267fa002912ec4e90ac7fb7549f875bc47385dd /drivers/pci/pci.c
parent519e512110e45c818ea8bd5c657b246d87c5ccd8 (diff)
parent3e347969a5776947a115649dae740a9ed47473f5 (diff)
downloadlinux-034f93fcb12f579c0108c7e2ca2d17ec4e5170aa.tar.xz
Merge branch 'pci/pm'
- Cache the PTM capability offset instead of searching for it every time (Bjorn Helgaas) - Separate PTM configuration from PTM enable (Bjorn Helgaas) - Add pci_suspend_ptm() and pci_resume_ptm() to disable and re-enable PTM on suspend/resume so some Root Ports can safely enter a lower-power PM state (Bjorn Helgaas) - Disable PTM for all devices during suspend; previously we only did this for Root Ports and even then only in certain cases (Bjorn Helgaas) - Simplify pci_pm_suspend_noirq() (Rajvi Jingar) - Reduce the delay after transitions to/from D3hot by using usleep_range() instead of msleep(), which reduces the typical delay from 19ms to 10ms (Sajid Dalvi, Will McVicker) * pci/pm: PCI/PM: Reduce D3hot delay with usleep_range() PCI/PM: Simplify pci_pm_suspend_noirq() PCI/PM: Always disable PTM for all devices during suspend PCI/PTM: Consolidate PTM interface declarations PCI/PTM: Reorder functions in logical order PCI/PTM: Preserve RsvdP bits in PTM Control register PCI/PTM: Move pci_ptm_info() body into its only caller PCI/PTM: Add pci_suspend_ptm() and pci_resume_ptm() PCI/PTM: Separate configuration and enable PCI/PTM: Add pci_upstream_ptm() helper PCI/PTM: Cache PTM Capability offset
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c44
1 files changed, 11 insertions, 33 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 68a49fbaabde..2127aba3550b 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -66,13 +66,15 @@ struct pci_pme_device {
static void pci_dev_d3_sleep(struct pci_dev *dev)
{
- unsigned int delay = dev->d3hot_delay;
-
- if (delay < pci_pm_d3hot_delay)
- delay = pci_pm_d3hot_delay;
-
- if (delay)
- msleep(delay);
+ unsigned int delay_ms = max(dev->d3hot_delay, pci_pm_d3hot_delay);
+ unsigned int upper;
+
+ if (delay_ms) {
+ /* Use a 20% upper bound, 1ms minimum */
+ upper = max(DIV_ROUND_CLOSEST(delay_ms, 5), 1U);
+ usleep_range(delay_ms * USEC_PER_MSEC,
+ (delay_ms + upper) * USEC_PER_MSEC);
+ }
}
bool pci_reset_supported(struct pci_dev *dev)
@@ -2708,24 +2710,12 @@ int pci_prepare_to_sleep(struct pci_dev *dev)
if (target_state == PCI_POWER_ERROR)
return -EIO;
- /*
- * There are systems (for example, Intel mobile chips since Coffee
- * Lake) where the power drawn while suspended can be significantly
- * reduced by disabling PTM on PCIe root ports as this allows the
- * port to enter a lower-power PM state and the SoC to reach a
- * lower-power idle state as a whole.
- */
- if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
- pci_disable_ptm(dev);
-
pci_enable_wake(dev, target_state, wakeup);
error = pci_set_power_state(dev, target_state);
- if (error) {
+ if (error)
pci_enable_wake(dev, target_state, false);
- pci_restore_ptm_state(dev);
- }
return error;
}
@@ -2766,24 +2756,12 @@ int pci_finish_runtime_suspend(struct pci_dev *dev)
if (target_state == PCI_POWER_ERROR)
return -EIO;
- /*
- * There are systems (for example, Intel mobile chips since Coffee
- * Lake) where the power drawn while suspended can be significantly
- * reduced by disabling PTM on PCIe root ports as this allows the
- * port to enter a lower-power PM state and the SoC to reach a
- * lower-power idle state as a whole.
- */
- if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
- pci_disable_ptm(dev);
-
__pci_enable_wake(dev, target_state, pci_dev_run_wake(dev));
error = pci_set_power_state(dev, target_state);
- if (error) {
+ if (error)
pci_enable_wake(dev, target_state, false);
- pci_restore_ptm_state(dev);
- }
return error;
}