diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-20 17:41:31 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-20 17:41:31 -0800 |
commit | 02c3de1105228e367320e7fdeffbf511904f398c (patch) | |
tree | d0861ed0752806c6c85e72749734dad9914a8cd9 /Documentation/power | |
parent | 7aa7d608112baf63a0b1278955f9619427373807 (diff) | |
parent | eee77a8a0d268b936b1641fd7d55efaa17c351d6 (diff) | |
download | linux-02c3de1105228e367320e7fdeffbf511904f398c.tar.bz2 |
Merge tag 'pm-4.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki:
"The majority of changes go into the Operating Performance Points (OPP)
framework and cpufreq this time, followed by devfreq and some
scattered updates all over.
The OPP changes are mostly related to switching over from RCU-based
synchronization, that turned out to be overly complicated and
problematic, to reference counting using krefs.
In the cpufreq land there are core cleanups, documentation updates, a
new driver for Broadcom BMIPS SoCs, a new cpufreq-dt sub-driver for TI
SoCs that require special handling, ARM64 SoCs support for the qoriq
driver, intel_pstate updates, powernv driver update and assorted
fixes.
The devfreq changes are mostly fixes related to the sysfs interface
and some Exynos drivers updates.
Apart from that, the cpuidle menu governor will support per-CPU PM QoS
constraints for the wakeup latency now, some bugs in the wakeup IRQs
framework are fixed, the generic power domains framework should handle
asynchronous invocations of *noirq suspend/resume callbacks from now
on, the analyze_suspend.py script is updated and there is a new tool
for intel_pstate diagnostics.
Specifics:
- Operating Performance Points (OPP) framework fixes, cleanups and
switch over from RCU-based synchronization to reference counting
using krefs (Viresh Kumar, Wei Yongjun, Dave Gerlach)
- cpufreq core cleanups and documentation updates (Viresh Kumar,
Rafael Wysocki)
- New cpufreq driver for Broadcom BMIPS SoCs (Markus Mayer)
- New cpufreq-dt sub-driver for TI SoCs requiring special handling,
like in the AM335x, AM437x, DRA7x, and AM57x families, along with
new DT bindings for it (Dave Gerlach, Paul Gortmaker)
- ARM64 SoCs support for the qoriq cpufreq driver (Tang Yuantian)
- intel_pstate driver updates including a new sysfs knob to control
the driver's operation mode and fixes related to the no_turbo sysfs
knob and the hardware-managed P-states feature support (Rafael
Wysocki, Srinivas Pandruvada)
- New interface to export ultra-turbo frequencies for the powernv
cpufreq driver (Shilpasri Bhat)
- Assorted fixes for cpufreq drivers (Arnd Bergmann, Dan Carpenter,
Wei Yongjun)
- devfreq core fixes, mostly related to the sysfs interface exported
by it (Chanwoo Choi, Chris Diamand)
- Updates of the exynos-bus and exynos-ppmu devfreq drivers (Chanwoo
Choi)
- Device PM QoS extension to support CPUs and support for per-CPU
wakeup (device resume) latency constraints in the cpuidle menu
governor (Alex Shi)
- Wakeup IRQs framework fixes (Grygorii Strashko)
- Generic power domains framework update including a fix to make it
handle asynchronous invocations of *noirq suspend/resume callbacks
correctly (Ulf Hansson, Geert Uytterhoeven)
- Assorted fixes and cleanups in the core suspend/hibernate code, PM
QoS framework and x86 ACPI idle support code (Corentin Labbe, Geert
Uytterhoeven, Geliang Tang, John Keeping, Nick Desaulniers)
- Update of the analyze_suspend.py script is updated to version 4.5
offering multiple improvements (Todd Brandt)
- New tool for intel_pstate diagnostics using the pstate_sample
tracepoint (Doug Smythies)"
* tag 'pm-4.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (85 commits)
MAINTAINERS: cpufreq: add bmips-cpufreq.c
PM / QoS: Fix memory leak on resume_latency.notifiers
PM / Documentation: Spelling s/wrtie/write/
PM / sleep: Fix test_suspend after sleep state rework
cpufreq: CPPC: add ACPI_PROCESSOR dependency
cpufreq: make ti-cpufreq explicitly non-modular
cpufreq: Do not clear real_cpus mask on policy init
tools/power/x86: Debug utility for intel_pstate driver
AnalyzeSuspend: fix drag and zoom bug in javascript
PM / wakeirq: report a wakeup_event on dedicated wekup irq
PM / wakeirq: Fix spurious wake-up events for dedicated wakeirqs
PM / wakeirq: Enable dedicated wakeirq for suspend
cpufreq: dt: Don't use generic platdev driver for ti-cpufreq platforms
cpufreq: ti: Add cpufreq driver to determine available OPPs at runtime
Documentation: dt: add bindings for ti-cpufreq
PM / OPP: Expose _of_get_opp_desc_node as dev_pm_opp API
cpufreq: qoriq: Don't look at clock implementation details
cpufreq: qoriq: add ARM64 SoCs support
PM / Domains: Provide dummy governors if CONFIG_PM_GENERIC_DOMAINS=n
cpufreq: brcmstb-avs-cpufreq: remove unnecessary platform_set_drvdata()
...
Diffstat (limited to 'Documentation/power')
-rw-r--r-- | Documentation/power/opp.txt | 52 | ||||
-rw-r--r-- | Documentation/power/states.txt | 2 |
2 files changed, 17 insertions, 37 deletions
diff --git a/Documentation/power/opp.txt b/Documentation/power/opp.txt index c6279c2be47c..0c007e250cd1 100644 --- a/Documentation/power/opp.txt +++ b/Documentation/power/opp.txt @@ -79,22 +79,6 @@ dependent subsystems such as cpufreq are left to the discretion of the SoC specific framework which uses the OPP library. Similar care needs to be taken care to refresh the cpufreq table in cases of these operations. -WARNING on OPP List locking mechanism: -------------------------------------------------- -OPP library uses RCU for exclusivity. RCU allows the query functions to operate -in multiple contexts and this synchronization mechanism is optimal for a read -intensive operations on data structure as the OPP library caters to. - -To ensure that the data retrieved are sane, the users such as SoC framework -should ensure that the section of code operating on OPP queries are locked -using RCU read locks. The opp_find_freq_{exact,ceil,floor}, -opp_get_{voltage, freq, opp_count} fall into this category. - -opp_{add,enable,disable} are updaters which use mutex and implement it's own -RCU locking mechanisms. These functions should *NOT* be called under RCU locks -and other contexts that prevent blocking functions in RCU or mutex operations -from working. - 2. Initial OPP List Registration ================================ The SoC implementation calls dev_pm_opp_add function iteratively to add OPPs per @@ -137,15 +121,18 @@ functions return the matching pointer representing the opp if a match is found, else returns error. These errors are expected to be handled by standard error checks such as IS_ERR() and appropriate actions taken by the caller. +Callers of these functions shall call dev_pm_opp_put() after they have used the +OPP. Otherwise the memory for the OPP will never get freed and result in +memleak. + dev_pm_opp_find_freq_exact - Search for an OPP based on an *exact* frequency and availability. This function is especially useful to enable an OPP which is not available by default. Example: In a case when SoC framework detects a situation where a higher frequency could be made available, it can use this function to find the OPP prior to call the dev_pm_opp_enable to actually make it available. - rcu_read_lock(); opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); - rcu_read_unlock(); + dev_pm_opp_put(opp); /* dont operate on the pointer.. just do a sanity check.. */ if (IS_ERR(opp)) { pr_err("frequency not disabled!\n"); @@ -163,9 +150,8 @@ dev_pm_opp_find_freq_floor - Search for an available OPP which is *at most* the frequency. Example: To find the highest opp for a device: freq = ULONG_MAX; - rcu_read_lock(); - dev_pm_opp_find_freq_floor(dev, &freq); - rcu_read_unlock(); + opp = dev_pm_opp_find_freq_floor(dev, &freq); + dev_pm_opp_put(opp); dev_pm_opp_find_freq_ceil - Search for an available OPP which is *at least* the provided frequency. This function is useful while searching for a @@ -173,17 +159,15 @@ dev_pm_opp_find_freq_ceil - Search for an available OPP which is *at least* the frequency. Example 1: To find the lowest opp for a device: freq = 0; - rcu_read_lock(); - dev_pm_opp_find_freq_ceil(dev, &freq); - rcu_read_unlock(); + opp = dev_pm_opp_find_freq_ceil(dev, &freq); + dev_pm_opp_put(opp); Example 2: A simplified implementation of a SoC cpufreq_driver->target: soc_cpufreq_target(..) { /* Do stuff like policy checks etc. */ /* Find the best frequency match for the req */ - rcu_read_lock(); opp = dev_pm_opp_find_freq_ceil(dev, &freq); - rcu_read_unlock(); + dev_pm_opp_put(opp); if (!IS_ERR(opp)) soc_switch_to_freq_voltage(freq); else @@ -208,9 +192,8 @@ dev_pm_opp_enable - Make a OPP available for operation. implementation might choose to do something as follows: if (cur_temp < temp_low_thresh) { /* Enable 1GHz if it was disabled */ - rcu_read_lock(); opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); - rcu_read_unlock(); + dev_pm_opp_put(opp); /* just error check */ if (!IS_ERR(opp)) ret = dev_pm_opp_enable(dev, 1000000000); @@ -224,9 +207,8 @@ dev_pm_opp_disable - Make an OPP to be not available for operation choose to do something as follows: if (cur_temp > temp_high_thresh) { /* Disable 1GHz if it was enabled */ - rcu_read_lock(); opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true); - rcu_read_unlock(); + dev_pm_opp_put(opp); /* just error check */ if (!IS_ERR(opp)) ret = dev_pm_opp_disable(dev, 1000000000); @@ -249,10 +231,9 @@ dev_pm_opp_get_voltage - Retrieve the voltage represented by the opp pointer. soc_switch_to_freq_voltage(freq) { /* do things */ - rcu_read_lock(); opp = dev_pm_opp_find_freq_ceil(dev, &freq); v = dev_pm_opp_get_voltage(opp); - rcu_read_unlock(); + dev_pm_opp_put(opp); if (v) regulator_set_voltage(.., v); /* do other things */ @@ -266,12 +247,12 @@ dev_pm_opp_get_freq - Retrieve the freq represented by the opp pointer. { /* do things.. */ max_freq = ULONG_MAX; - rcu_read_lock(); max_opp = dev_pm_opp_find_freq_floor(dev,&max_freq); requested_opp = dev_pm_opp_find_freq_ceil(dev,&freq); if (!IS_ERR(max_opp) && !IS_ERR(requested_opp)) r = soc_test_validity(max_opp, requested_opp); - rcu_read_unlock(); + dev_pm_opp_put(max_opp); + dev_pm_opp_put(requested_opp); /* do other things */ } soc_test_validity(..) @@ -289,7 +270,6 @@ dev_pm_opp_get_opp_count - Retrieve the number of available opps for a device soc_notify_coproc_available_frequencies() { /* Do things */ - rcu_read_lock(); num_available = dev_pm_opp_get_opp_count(dev); speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL); /* populate the table in increasing order */ @@ -298,8 +278,8 @@ dev_pm_opp_get_opp_count - Retrieve the number of available opps for a device speeds[i] = freq; freq++; i++; + dev_pm_opp_put(opp); } - rcu_read_unlock(); soc_notify_coproc(AVAILABLE_FREQs, speeds, num_available); /* Do other things */ diff --git a/Documentation/power/states.txt b/Documentation/power/states.txt index 008ecb588317..bc4548245a24 100644 --- a/Documentation/power/states.txt +++ b/Documentation/power/states.txt @@ -25,7 +25,7 @@ to be used subsequently to change to the one represented by that string. Consequently, there are two ways to cause the system to go into the Suspend-To-Idle sleep state. The first one is to write "freeze" directly to /sys/power/state. The second one is to write "s2idle" to /sys/power/mem_sleep -and then to wrtie "mem" to /sys/power/state. Similarly, there are two ways +and then to write "mem" to /sys/power/state. Similarly, there are two ways to cause the system to go into the Power-On Suspend sleep state (the strings to write to the control files in that case are "standby" or "shallow" and "mem", respectively) if that state is supported by the platform. In turn, there is |