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
This commit is contained in:
Bjorn Helgaas
2022-10-05 17:32:53 -05:00
5 changed files with 250 additions and 225 deletions

View File

@@ -66,13 +66,15 @@ struct pci_pme_device {
static void pci_dev_d3_sleep(struct pci_dev *dev)
{
unsigned int delay = dev->d3hot_delay;
unsigned int delay_ms = max(dev->d3hot_delay, pci_pm_d3hot_delay);
unsigned int upper;
if (delay < pci_pm_d3hot_delay)
delay = pci_pm_d3hot_delay;
if (delay)
msleep(delay);
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;
}