aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-04 16:39:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-04 16:39:41 -0400
commit408c9861c6979db974455b9e7a9bcadd60e0934c (patch)
tree9bdb862da2883cd4f74297d01ec8ce3b4619dd66 /drivers/pci/pci.c
parentb39de277b02ffd8e3dccb01e9159bd45cb07b95d (diff)
parent8f8e5c3e2796eaf150d6262115af12707c2616dd (diff)
Merge tag 'pm-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki: "The big ticket items here are the rework of suspend-to-idle in order to add proper support for power button wakeup from it on recent Dell laptops and the rework of interfaces exporting the current CPU frequency on x86. In addition to that, support for a few new pieces of hardware is added, the PCI/ACPI device wakeup infrastructure is simplified significantly and the wakeup IRQ framework is fixed to unbreak the IRQ bus locking infrastructure. Also, there are some functional improvements for intel_pstate, tools updates and small fixes and cleanups all over. Specifics: - Rework suspend-to-idle to allow it to take wakeup events signaled by the EC into account on ACPI-based platforms in order to properly support power button wakeup from suspend-to-idle on recent Dell laptops (Rafael Wysocki). That includes the core suspend-to-idle code rework, support for the Low Power S0 _DSM interface, and support for the ACPI INT0002 Virtual GPIO device from Hans de Goede (required for USB keyboard wakeup from suspend-to-idle to work on some machines). - Stop trying to export the current CPU frequency via /proc/cpuinfo on x86 as that is inaccurate and confusing (Len Brown). - Rework the way in which the current CPU frequency is exported by the kernel (over the cpufreq sysfs interface) on x86 systems with the APERF and MPERF registers by always using values read from these registers, when available, to compute the current frequency regardless of which cpufreq driver is in use (Len Brown). - Rework the PCI/ACPI device wakeup infrastructure to remove the questionable and artificial distinction between "devices that can wake up the system from sleep states" and "devices that can generate wakeup signals in the working state" from it, which allows the code to be simplified quite a bit (Rafael Wysocki). - Fix the wakeup IRQ framework by making it use SRCU instead of RCU which doesn't allow sleeping in the read-side critical sections, but which in turn is expected to be allowed by the IRQ bus locking infrastructure (Thomas Gleixner). - Modify some computations in the intel_pstate driver to avoid rounding errors resulting from them (Srinivas Pandruvada). - Reduce the overhead of the intel_pstate driver in the HWP (hardware-managed P-states) mode and when the "performance" P-state selection algorithm is in use by making it avoid registering scheduler callbacks in those cases (Len Brown). - Rework the energy_performance_preference sysfs knob in intel_pstate by changing the values that correspond to different symbolic hint names used by it (Len Brown). - Make it possible to use more than one cpuidle driver at the same time on ARM (Daniel Lezcano). - Make it possible to prevent the cpuidle menu governor from using the 0 state by disabling it via sysfs (Nicholas Piggin). - Add support for FFH (Fixed Functional Hardware) MWAIT in ACPI C1 on AMD systems (Yazen Ghannam). - Make the CPPC cpufreq driver take the lowest nonlinear performance information into account (Prashanth Prakash). - Add support for hi3660 to the cpufreq-dt driver, fix the imx6q driver and clean up the sfi, exynos5440 and intel_pstate drivers (Colin Ian King, Krzysztof Kozlowski, Octavian Purdila, Rafael Wysocki, Tao Wang). - Fix a few minor issues in the generic power domains (genpd) framework and clean it up somewhat (Krzysztof Kozlowski, Mikko Perttunen, Viresh Kumar). - Fix a couple of minor issues in the operating performance points (OPP) framework and clean it up somewhat (Viresh Kumar). - Fix a CONFIG dependency in the hibernation core and clean it up slightly (Balbir Singh, Arvind Yadav, BaoJun Luo). - Add rk3228 support to the rockchip-io adaptive voltage scaling (AVS) driver (David Wu). - Fix an incorrect bit shift operation in the RAPL power capping driver (Adam Lessnau). - Add support for the EPP field in the HWP (hardware managed P-states) control register, HWP.EPP, to the x86_energy_perf_policy tool and update msr-index.h with HWP.EPP values (Len Brown). - Fix some minor issues in the turbostat tool (Len Brown). - Add support for AMD family 0x17 CPUs to the cpupower tool and fix a minor issue in it (Sherry Hurwitz). - Assorted cleanups, mostly related to the constification of some data structures (Arvind Yadav, Joe Perches, Kees Cook, Krzysztof Kozlowski)" * tag 'pm-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (69 commits) cpufreq: Update scaling_cur_freq documentation cpufreq: intel_pstate: Clean up after performance governor changes PM: hibernate: constify attribute_group structures. cpuidle: menu: allow state 0 to be disabled intel_idle: Use more common logging style PM / Domains: Fix missing default_power_down_ok comment PM / Domains: Fix unsafe iteration over modified list of domains PM / Domains: Fix unsafe iteration over modified list of domain providers PM / Domains: Fix unsafe iteration over modified list of device links PM / Domains: Handle safely genpd_syscore_switch() call on non-genpd device PM / Domains: Call driver's noirq callbacks PM / core: Drop run_wake flag from struct dev_pm_info PCI / PM: Simplify device wakeup settings code PCI / PM: Drop pme_interrupt flag from struct pci_dev ACPI / PM: Consolidate device wakeup settings code ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags PM / QoS: constify *_attribute_group. PM / AVS: rockchip-io: add io selectors and supplies for rk3228 powercap/RAPL: prevent overridding bits outside of the mask PM / sysfs: Constify attribute groups ...
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 563901cd9c06..0b5302a9fdae 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -574,8 +574,7 @@ static const struct pci_platform_pm_ops *pci_platform_pm;
574int pci_set_platform_pm(const struct pci_platform_pm_ops *ops) 574int pci_set_platform_pm(const struct pci_platform_pm_ops *ops)
575{ 575{
576 if (!ops->is_manageable || !ops->set_state || !ops->get_state || 576 if (!ops->is_manageable || !ops->set_state || !ops->get_state ||
577 !ops->choose_state || !ops->sleep_wake || !ops->run_wake || 577 !ops->choose_state || !ops->set_wakeup || !ops->need_resume)
578 !ops->need_resume)
579 return -EINVAL; 578 return -EINVAL;
580 pci_platform_pm = ops; 579 pci_platform_pm = ops;
581 return 0; 580 return 0;
@@ -603,16 +602,10 @@ static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev)
603 pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; 602 pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR;
604} 603}
605 604
606static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) 605static inline int platform_pci_set_wakeup(struct pci_dev *dev, bool enable)
607{ 606{
608 return pci_platform_pm ? 607 return pci_platform_pm ?
609 pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; 608 pci_platform_pm->set_wakeup(dev, enable) : -ENODEV;
610}
611
612static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable)
613{
614 return pci_platform_pm ?
615 pci_platform_pm->run_wake(dev, enable) : -ENODEV;
616} 609}
617 610
618static inline bool platform_pci_need_resume(struct pci_dev *dev) 611static inline bool platform_pci_need_resume(struct pci_dev *dev)
@@ -1805,6 +1798,23 @@ static void __pci_pme_active(struct pci_dev *dev, bool enable)
1805 pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); 1798 pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
1806} 1799}
1807 1800
1801static void pci_pme_restore(struct pci_dev *dev)
1802{
1803 u16 pmcsr;
1804
1805 if (!dev->pme_support)
1806 return;
1807
1808 pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
1809 if (dev->wakeup_prepared) {
1810 pmcsr |= PCI_PM_CTRL_PME_ENABLE;
1811 } else {
1812 pmcsr &= ~PCI_PM_CTRL_PME_ENABLE;
1813 pmcsr |= PCI_PM_CTRL_PME_STATUS;
1814 }
1815 pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
1816}
1817
1808/** 1818/**
1809 * pci_pme_active - enable or disable PCI device's PME# function 1819 * pci_pme_active - enable or disable PCI device's PME# function
1810 * @dev: PCI device to handle. 1820 * @dev: PCI device to handle.
@@ -1872,10 +1882,9 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
1872EXPORT_SYMBOL(pci_pme_active); 1882EXPORT_SYMBOL(pci_pme_active);
1873 1883
1874/** 1884/**
1875 * __pci_enable_wake - enable PCI device as wakeup event source 1885 * pci_enable_wake - enable PCI device as wakeup event source
1876 * @dev: PCI device affected 1886 * @dev: PCI device affected
1877 * @state: PCI state from which device will issue wakeup events 1887 * @state: PCI state from which device will issue wakeup events
1878 * @runtime: True if the events are to be generated at run time
1879 * @enable: True to enable event generation; false to disable 1888 * @enable: True to enable event generation; false to disable
1880 * 1889 *
1881 * This enables the device as a wakeup event source, or disables it. 1890 * This enables the device as a wakeup event source, or disables it.
@@ -1891,17 +1900,18 @@ EXPORT_SYMBOL(pci_pme_active);
1891 * Error code depending on the platform is returned if both the platform and 1900 * Error code depending on the platform is returned if both the platform and
1892 * the native mechanism fail to enable the generation of wake-up events 1901 * the native mechanism fail to enable the generation of wake-up events
1893 */ 1902 */
1894int __pci_enable_wake(struct pci_dev *dev, pci_power_t state, 1903int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable)
1895 bool runtime, bool enable)
1896{ 1904{
1897 int ret = 0; 1905 int ret = 0;
1898 1906
1899 if (enable && !runtime && !device_may_wakeup(&dev->dev)) 1907 /*
1900 return -EINVAL; 1908 * Don't do the same thing twice in a row for one device, but restore
1901 1909 * PME Enable in case it has been updated by config space restoration.
1902 /* Don't do the same thing twice in a row for one device. */ 1910 */
1903 if (!!enable == !!dev->wakeup_prepared) 1911 if (!!enable == !!dev->wakeup_prepared) {
1912 pci_pme_restore(dev);
1904 return 0; 1913 return 0;
1914 }
1905 1915
1906 /* 1916 /*
1907 * According to "PCI System Architecture" 4th ed. by Tom Shanley & Don 1917 * According to "PCI System Architecture" 4th ed. by Tom Shanley & Don
@@ -1916,24 +1926,20 @@ int __pci_enable_wake(struct pci_dev *dev, pci_power_t state,
1916 pci_pme_active(dev, true); 1926 pci_pme_active(dev, true);
1917 else 1927 else
1918 ret = 1; 1928 ret = 1;
1919 error = runtime ? platform_pci_run_wake(dev, true) : 1929 error = platform_pci_set_wakeup(dev, true);
1920 platform_pci_sleep_wake(dev, true);
1921 if (ret) 1930 if (ret)
1922 ret = error; 1931 ret = error;
1923 if (!ret) 1932 if (!ret)
1924 dev->wakeup_prepared = true; 1933 dev->wakeup_prepared = true;
1925 } else { 1934 } else {
1926 if (runtime) 1935 platform_pci_set_wakeup(dev, false);
1927 platform_pci_run_wake(dev, false);
1928 else
1929 platform_pci_sleep_wake(dev, false);
1930 pci_pme_active(dev, false); 1936 pci_pme_active(dev, false);
1931 dev->wakeup_prepared = false; 1937 dev->wakeup_prepared = false;
1932 } 1938 }
1933 1939
1934 return ret; 1940 return ret;
1935} 1941}
1936EXPORT_SYMBOL(__pci_enable_wake); 1942EXPORT_SYMBOL(pci_enable_wake);
1937 1943
1938/** 1944/**
1939 * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold 1945 * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold
@@ -2075,12 +2081,12 @@ int pci_finish_runtime_suspend(struct pci_dev *dev)
2075 2081
2076 dev->runtime_d3cold = target_state == PCI_D3cold; 2082 dev->runtime_d3cold = target_state == PCI_D3cold;
2077 2083
2078 __pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev)); 2084 pci_enable_wake(dev, target_state, pci_dev_run_wake(dev));
2079 2085
2080 error = pci_set_power_state(dev, target_state); 2086 error = pci_set_power_state(dev, target_state);
2081 2087
2082 if (error) { 2088 if (error) {
2083 __pci_enable_wake(dev, target_state, true, false); 2089 pci_enable_wake(dev, target_state, false);
2084 dev->runtime_d3cold = false; 2090 dev->runtime_d3cold = false;
2085 } 2091 }
2086 2092
@@ -2099,7 +2105,7 @@ bool pci_dev_run_wake(struct pci_dev *dev)
2099{ 2105{
2100 struct pci_bus *bus = dev->bus; 2106 struct pci_bus *bus = dev->bus;
2101 2107
2102 if (device_run_wake(&dev->dev)) 2108 if (device_can_wakeup(&dev->dev))
2103 return true; 2109 return true;
2104 2110
2105 if (!dev->pme_support) 2111 if (!dev->pme_support)
@@ -2112,7 +2118,7 @@ bool pci_dev_run_wake(struct pci_dev *dev)
2112 while (bus->parent) { 2118 while (bus->parent) {
2113 struct pci_dev *bridge = bus->self; 2119 struct pci_dev *bridge = bus->self;
2114 2120
2115 if (device_run_wake(&bridge->dev)) 2121 if (device_can_wakeup(&bridge->dev))
2116 return true; 2122 return true;
2117 2123
2118 bus = bus->parent; 2124 bus = bus->parent;
@@ -2120,7 +2126,7 @@ bool pci_dev_run_wake(struct pci_dev *dev)
2120 2126
2121 /* We have reached the root bus. */ 2127 /* We have reached the root bus. */
2122 if (bus->bridge) 2128 if (bus->bridge)
2123 return device_run_wake(bus->bridge); 2129 return device_can_wakeup(bus->bridge);
2124 2130
2125 return false; 2131 return false;
2126} 2132}