Merge branch 'pm-cpufreq'

* pm-cpufreq: (167 commits)
  cpufreq: create per policy rwsem instead of per CPU cpu_policy_rwsem
  intel_pstate: Add Baytrail support
  intel_pstate: Refactor driver to support CPUs with different MSR layouts
  cpufreq: Implement light weight ->target_index() routine
  PM / OPP: rename header to linux/pm_opp.h
  PM / OPP: rename data structures to dev_pm equivalents
  PM / OPP: rename functions to dev_pm_opp*
  cpufreq / governor: Remove fossil comment
  cpufreq: exynos4210: Use the common clock framework to set APLL clock rate
  cpufreq: exynos4x12: Use the common clock framework to set APLL clock rate
  cpufreq: Detect spurious invocations of update_policy_cpu()
  cpufreq: pmac64: enable cpufreq on iMac G5 (iSight) model
  cpufreq: pmac64: provide cpufreq transition latency for older G5 models
  cpufreq: pmac64: speed up frequency switch
  cpufreq: highbank-cpufreq: Enable Midway/ECX-2000
  exynos-cpufreq: fix false return check from "regulator_set_voltage"
  speedstep-centrino: Remove unnecessary braces
  acpi-cpufreq: Add comment under ACPI_ADR_SPACE_SYSTEM_IO case
  cpufreq: arm-big-little: use clk_get instead of clk_get_sys
  cpufreq: exynos: Show a list of available frequencies
  ...

Conflicts:
	drivers/devfreq/exynos/exynos5_bus.c
This commit is contained in:
Rafael J. Wysocki
2013-10-28 01:29:34 +01:00
90 changed files with 1227 additions and 2729 deletions

View File

@@ -42,7 +42,7 @@ We can represent these as three OPPs as the following {Hz, uV} tuples:
OPP library provides a set of helper functions to organize and query the OPP
information. The library is located in drivers/base/power/opp.c and the header
is located in include/linux/opp.h. OPP library can be enabled by enabling
is located in include/linux/pm_opp.h. OPP library can be enabled by enabling
CONFIG_PM_OPP from power management menuconfig menu. OPP library depends on
CONFIG_PM as certain SoCs such as Texas Instrument's OMAP framework allows to
optionally boot at a certain OPP without needing cpufreq.
@@ -71,14 +71,14 @@ operations until that OPP could be re-enabled if possible.
OPP library facilitates this concept in it's implementation. The following
operational functions operate only on available opps:
opp_find_freq_{ceil, floor}, opp_get_voltage, opp_get_freq, opp_get_opp_count
and opp_init_cpufreq_table
opp_find_freq_{ceil, floor}, dev_pm_opp_get_voltage, dev_pm_opp_get_freq, dev_pm_opp_get_opp_count
and dev_pm_opp_init_cpufreq_table
opp_find_freq_exact is meant to be used to find the opp pointer which can then
be used for opp_enable/disable functions to make an opp available as required.
dev_pm_opp_find_freq_exact is meant to be used to find the opp pointer which can then
be used for dev_pm_opp_enable/disable functions to make an opp available as required.
WARNING: Users of OPP library should refresh their availability count using
get_opp_count if opp_enable/disable functions are invoked for a device, the
get_opp_count if dev_pm_opp_enable/disable functions are invoked for a device, the
exact mechanism to trigger these or the notification mechanism to other
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
@@ -96,24 +96,24 @@ 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. opp_init_cpufreq_table acts as an updater and uses
RCU locking mechanisms. dev_pm_opp_init_cpufreq_table acts as an updater and uses
mutex to implment RCU updater strategy. 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 opp_add function iteratively to add OPPs per
The SoC implementation calls dev_pm_opp_add function iteratively to add OPPs per
device. It is expected that the SoC framework will register the OPP entries
optimally- typical numbers range to be less than 5. The list generated by
registering the OPPs is maintained by OPP library throughout the device
operation. The SoC framework can subsequently control the availability of the
OPPs dynamically using the opp_enable / disable functions.
OPPs dynamically using the dev_pm_opp_enable / disable functions.
opp_add - Add a new OPP for a specific domain represented by the device pointer.
dev_pm_opp_add - Add a new OPP for a specific domain represented by the device pointer.
The OPP is defined using the frequency and voltage. Once added, the OPP
is assumed to be available and control of it's availability can be done
with the opp_enable/disable functions. OPP library internally stores
with the dev_pm_opp_enable/disable functions. OPP library internally stores
and manages this information in the opp struct. This function may be
used by SoC framework to define a optimal list as per the demands of
SoC usage environment.
@@ -124,7 +124,7 @@ opp_add - Add a new OPP for a specific domain represented by the device pointer.
soc_pm_init()
{
/* Do things */
r = opp_add(mpu_dev, 1000000, 900000);
r = dev_pm_opp_add(mpu_dev, 1000000, 900000);
if (!r) {
pr_err("%s: unable to register mpu opp(%d)\n", r);
goto no_cpufreq;
@@ -143,44 +143,44 @@ 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.
opp_find_freq_exact - Search for an OPP based on an *exact* frequency and
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 opp_enable to actually make it available.
find the OPP prior to call the dev_pm_opp_enable to actually make it available.
rcu_read_lock();
opp = opp_find_freq_exact(dev, 1000000000, false);
opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false);
rcu_read_unlock();
/* dont operate on the pointer.. just do a sanity check.. */
if (IS_ERR(opp)) {
pr_err("frequency not disabled!\n");
/* trigger appropriate actions.. */
} else {
opp_enable(dev,1000000000);
dev_pm_opp_enable(dev,1000000000);
}
NOTE: This is the only search function that operates on OPPs which are
not available.
opp_find_freq_floor - Search for an available OPP which is *at most* the
dev_pm_opp_find_freq_floor - Search for an available OPP which is *at most* the
provided frequency. This function is useful while searching for a lesser
match OR operating on OPP information in the order of decreasing
frequency.
Example: To find the highest opp for a device:
freq = ULONG_MAX;
rcu_read_lock();
opp_find_freq_floor(dev, &freq);
dev_pm_opp_find_freq_floor(dev, &freq);
rcu_read_unlock();
opp_find_freq_ceil - Search for an available OPP which is *at least* the
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
higher match OR operating on OPP information in the order of increasing
frequency.
Example 1: To find the lowest opp for a device:
freq = 0;
rcu_read_lock();
opp_find_freq_ceil(dev, &freq);
dev_pm_opp_find_freq_ceil(dev, &freq);
rcu_read_unlock();
Example 2: A simplified implementation of a SoC cpufreq_driver->target:
soc_cpufreq_target(..)
@@ -188,7 +188,7 @@ opp_find_freq_ceil - Search for an available OPP which is *at least* the
/* Do stuff like policy checks etc. */
/* Find the best frequency match for the req */
rcu_read_lock();
opp = opp_find_freq_ceil(dev, &freq);
opp = dev_pm_opp_find_freq_ceil(dev, &freq);
rcu_read_unlock();
if (!IS_ERR(opp))
soc_switch_to_freq_voltage(freq);
@@ -208,34 +208,34 @@ as thermal considerations (e.g. don't use OPPx until the temperature drops).
WARNING: Do not use these functions in interrupt context.
opp_enable - Make a OPP available for operation.
dev_pm_opp_enable - Make a OPP available for operation.
Example: Lets say that 1GHz OPP is to be made available only if the
SoC temperature is lower than a certain threshold. The SoC framework
implementation might choose to do something as follows:
if (cur_temp < temp_low_thresh) {
/* Enable 1GHz if it was disabled */
rcu_read_lock();
opp = opp_find_freq_exact(dev, 1000000000, false);
opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false);
rcu_read_unlock();
/* just error check */
if (!IS_ERR(opp))
ret = opp_enable(dev, 1000000000);
ret = dev_pm_opp_enable(dev, 1000000000);
else
goto try_something_else;
}
opp_disable - Make an OPP to be not available for operation
dev_pm_opp_disable - Make an OPP to be not available for operation
Example: Lets say that 1GHz OPP is to be disabled if the temperature
exceeds a threshold value. The SoC framework implementation might
choose to do something as follows:
if (cur_temp > temp_high_thresh) {
/* Disable 1GHz if it was enabled */
rcu_read_lock();
opp = opp_find_freq_exact(dev, 1000000000, true);
opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true);
rcu_read_unlock();
/* just error check */
if (!IS_ERR(opp))
ret = opp_disable(dev, 1000000000);
ret = dev_pm_opp_disable(dev, 1000000000);
else
goto try_something_else;
}
@@ -247,7 +247,7 @@ information from the OPP structure is necessary. Once an OPP pointer is
retrieved using the search functions, the following functions can be used by SoC
framework to retrieve the information represented inside the OPP layer.
opp_get_voltage - Retrieve the voltage represented by the opp pointer.
dev_pm_opp_get_voltage - Retrieve the voltage represented by the opp pointer.
Example: At a cpufreq transition to a different frequency, SoC
framework requires to set the voltage represented by the OPP using
the regulator framework to the Power Management chip providing the
@@ -256,15 +256,15 @@ opp_get_voltage - Retrieve the voltage represented by the opp pointer.
{
/* do things */
rcu_read_lock();
opp = opp_find_freq_ceil(dev, &freq);
v = opp_get_voltage(opp);
opp = dev_pm_opp_find_freq_ceil(dev, &freq);
v = dev_pm_opp_get_voltage(opp);
rcu_read_unlock();
if (v)
regulator_set_voltage(.., v);
/* do other things */
}
opp_get_freq - Retrieve the freq represented by the opp pointer.
dev_pm_opp_get_freq - Retrieve the freq represented by the opp pointer.
Example: Lets say the SoC framework uses a couple of helper functions
we could pass opp pointers instead of doing additional parameters to
handle quiet a bit of data parameters.
@@ -273,8 +273,8 @@ opp_get_freq - Retrieve the freq represented by the opp pointer.
/* do things.. */
max_freq = ULONG_MAX;
rcu_read_lock();
max_opp = opp_find_freq_floor(dev,&max_freq);
requested_opp = opp_find_freq_ceil(dev,&freq);
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();
@@ -282,25 +282,25 @@ opp_get_freq - Retrieve the freq represented by the opp pointer.
}
soc_test_validity(..)
{
if(opp_get_voltage(max_opp) < opp_get_voltage(requested_opp))
if(dev_pm_opp_get_voltage(max_opp) < dev_pm_opp_get_voltage(requested_opp))
return -EINVAL;
if(opp_get_freq(max_opp) < opp_get_freq(requested_opp))
if(dev_pm_opp_get_freq(max_opp) < dev_pm_opp_get_freq(requested_opp))
return -EINVAL;
/* do things.. */
}
opp_get_opp_count - Retrieve the number of available opps for a device
dev_pm_opp_get_opp_count - Retrieve the number of available opps for a device
Example: Lets say a co-processor in the SoC needs to know the available
frequencies in a table, the main processor can notify as following:
soc_notify_coproc_available_frequencies()
{
/* Do things */
rcu_read_lock();
num_available = opp_get_opp_count(dev);
num_available = dev_pm_opp_get_opp_count(dev);
speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL);
/* populate the table in increasing order */
freq = 0;
while (!IS_ERR(opp = opp_find_freq_ceil(dev, &freq))) {
while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) {
speeds[i] = freq;
freq++;
i++;
@@ -313,7 +313,7 @@ opp_get_opp_count - Retrieve the number of available opps for a device
6. Cpufreq Table Generation
===========================
opp_init_cpufreq_table - cpufreq framework typically is initialized with
dev_pm_opp_init_cpufreq_table - cpufreq framework typically is initialized with
cpufreq_frequency_table_cpuinfo which is provided with the list of
frequencies that are available for operation. This function provides
a ready to use conversion routine to translate the OPP layer's internal
@@ -326,7 +326,7 @@ opp_init_cpufreq_table - cpufreq framework typically is initialized with
soc_pm_init()
{
/* Do things */
r = opp_init_cpufreq_table(dev, &freq_table);
r = dev_pm_opp_init_cpufreq_table(dev, &freq_table);
if (!r)
cpufreq_frequency_table_cpuinfo(policy, freq_table);
/* Do other things */
@@ -336,7 +336,7 @@ opp_init_cpufreq_table - cpufreq framework typically is initialized with
addition to CONFIG_PM as power management feature is required to
dynamically scale voltage and frequency in a system.
opp_free_cpufreq_table - Free up the table allocated by opp_init_cpufreq_table
dev_pm_opp_free_cpufreq_table - Free up the table allocated by dev_pm_opp_init_cpufreq_table
7. Data Structures
==================
@@ -358,16 +358,16 @@ accessed by various functions as described above. However, the structures
representing the actual OPPs and domains are internal to the OPP library itself
to allow for suitable abstraction reusable across systems.
struct opp - The internal data structure of OPP library which is used to
struct dev_pm_opp - The internal data structure of OPP library which is used to
represent an OPP. In addition to the freq, voltage, availability
information, it also contains internal book keeping information required
for the OPP library to operate on. Pointer to this structure is
provided back to the users such as SoC framework to be used as a
identifier for OPP in the interactions with OPP layer.
WARNING: The struct opp pointer should not be parsed or modified by the
users. The defaults of for an instance is populated by opp_add, but the
availability of the OPP can be modified by opp_enable/disable functions.
WARNING: The struct dev_pm_opp pointer should not be parsed or modified by the
users. The defaults of for an instance is populated by dev_pm_opp_add, but the
availability of the OPP can be modified by dev_pm_opp_enable/disable functions.
struct device - This is used to identify a domain to the OPP layer. The
nature of the device and it's implementation is left to the user of
@@ -377,19 +377,19 @@ Overall, in a simplistic view, the data structure operations is represented as
following:
Initialization / modification:
+-----+ /- opp_enable
opp_add --> | opp | <-------
| +-----+ \- opp_disable
+-----+ /- dev_pm_opp_enable
dev_pm_opp_add --> | opp | <-------
| +-----+ \- dev_pm_opp_disable
\-------> domain_info(device)
Search functions:
/-- opp_find_freq_ceil ---\ +-----+
domain_info<---- opp_find_freq_exact -----> | opp |
\-- opp_find_freq_floor ---/ +-----+
/-- dev_pm_opp_find_freq_ceil ---\ +-----+
domain_info<---- dev_pm_opp_find_freq_exact -----> | opp |
\-- dev_pm_opp_find_freq_floor ---/ +-----+
Retrieval functions:
+-----+ /- opp_get_voltage
+-----+ /- dev_pm_opp_get_voltage
| opp | <---
+-----+ \- opp_get_freq
+-----+ \- dev_pm_opp_get_freq
domain_info <- opp_get_opp_count
domain_info <- dev_pm_opp_get_opp_count