Merge branches 'pm-cpufreq-sched' and 'pm-opp'
* pm-cpufreq-sched:
cpufreq: schedutil: Reset cached_raw_freq when not in sync with next_freq
* pm-opp:
PM / OPP: Add dev_pm_opp_{un}register_get_pstate_helper()
PM / OPP: Support updating performance state of device's power domain
PM / OPP: add missing of_node_put() for of_get_cpu_node()
PM / OPP: Rename dev_pm_opp_register_put_opp_helper()
PM / OPP: Add missing of_node_put(np)
PM / OPP: Move error message to debug level
PM / OPP: Use snprintf() to avoid kasprintf() and kfree()
PM / OPP: Move the OPP directory out of power/
This commit is contained in:
@@ -10049,7 +10049,7 @@ M: Stephen Boyd <sboyd@codeaurora.org>
|
|||||||
L: linux-pm@vger.kernel.org
|
L: linux-pm@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git
|
||||||
F: drivers/base/power/opp/
|
F: drivers/opp/
|
||||||
F: include/linux/pm_opp.h
|
F: include/linux/pm_opp.h
|
||||||
F: Documentation/power/opp.txt
|
F: Documentation/power/opp.txt
|
||||||
F: Documentation/devicetree/bindings/opp/
|
F: Documentation/devicetree/bindings/opp/
|
||||||
|
|||||||
@@ -209,4 +209,6 @@ source "drivers/tee/Kconfig"
|
|||||||
|
|
||||||
source "drivers/mux/Kconfig"
|
source "drivers/mux/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/opp/Kconfig"
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ obj-$(CONFIG_ACCESSIBILITY) += accessibility/
|
|||||||
obj-$(CONFIG_ISDN) += isdn/
|
obj-$(CONFIG_ISDN) += isdn/
|
||||||
obj-$(CONFIG_EDAC) += edac/
|
obj-$(CONFIG_EDAC) += edac/
|
||||||
obj-$(CONFIG_EISA) += eisa/
|
obj-$(CONFIG_EISA) += eisa/
|
||||||
|
obj-$(CONFIG_PM_OPP) += opp/
|
||||||
obj-$(CONFIG_CPU_FREQ) += cpufreq/
|
obj-$(CONFIG_CPU_FREQ) += cpufreq/
|
||||||
obj-$(CONFIG_CPU_IDLE) += cpuidle/
|
obj-$(CONFIG_CPU_IDLE) += cpuidle/
|
||||||
obj-y += mmc/
|
obj-y += mmc/
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
obj-$(CONFIG_PM) += sysfs.o generic_ops.o common.o qos.o runtime.o wakeirq.o
|
obj-$(CONFIG_PM) += sysfs.o generic_ops.o common.o qos.o runtime.o wakeirq.o
|
||||||
obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o
|
obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o
|
||||||
obj-$(CONFIG_PM_TRACE_RTC) += trace.o
|
obj-$(CONFIG_PM_TRACE_RTC) += trace.o
|
||||||
obj-$(CONFIG_PM_OPP) += opp/
|
|
||||||
obj-$(CONFIG_PM_GENERIC_DOMAINS) += domain.o domain_governor.o
|
obj-$(CONFIG_PM_GENERIC_DOMAINS) += domain.o domain_governor.o
|
||||||
obj-$(CONFIG_HAVE_CLK) += clock_ops.o
|
obj-$(CONFIG_HAVE_CLK) += clock_ops.o
|
||||||
|
|
||||||
|
|||||||
13
drivers/opp/Kconfig
Normal file
13
drivers/opp/Kconfig
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
config PM_OPP
|
||||||
|
bool
|
||||||
|
select SRCU
|
||||||
|
---help---
|
||||||
|
SOCs have a standard set of tuples consisting of frequency and
|
||||||
|
voltage pairs that the device will support per voltage domain. This
|
||||||
|
is called Operating Performance Point or OPP. The actual definitions
|
||||||
|
of OPP varies over silicon within the same family of devices.
|
||||||
|
|
||||||
|
OPP layer organizes the data internally using device pointers
|
||||||
|
representing individual voltage domains and provides SOC
|
||||||
|
implementations a ready to use framework to manage OPPs.
|
||||||
|
For more information, read <file:Documentation/power/opp.txt>
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
#include <linux/pm_domain.h>
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
|
|
||||||
#include "opp.h"
|
#include "opp.h"
|
||||||
@@ -296,7 +297,7 @@ int dev_pm_opp_get_opp_count(struct device *dev)
|
|||||||
opp_table = _find_opp_table(dev);
|
opp_table = _find_opp_table(dev);
|
||||||
if (IS_ERR(opp_table)) {
|
if (IS_ERR(opp_table)) {
|
||||||
count = PTR_ERR(opp_table);
|
count = PTR_ERR(opp_table);
|
||||||
dev_err(dev, "%s: OPP table not found (%d)\n",
|
dev_dbg(dev, "%s: OPP table not found (%d)\n",
|
||||||
__func__, count);
|
__func__, count);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@@ -535,6 +536,44 @@ _generic_set_opp_clk_only(struct device *dev, struct clk *clk,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
_generic_set_opp_domain(struct device *dev, struct clk *clk,
|
||||||
|
unsigned long old_freq, unsigned long freq,
|
||||||
|
unsigned int old_pstate, unsigned int new_pstate)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Scaling up? Scale domain performance state before frequency */
|
||||||
|
if (freq > old_freq) {
|
||||||
|
ret = dev_pm_genpd_set_performance_state(dev, new_pstate);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq);
|
||||||
|
if (ret)
|
||||||
|
goto restore_domain_state;
|
||||||
|
|
||||||
|
/* Scaling down? Scale domain performance state after frequency */
|
||||||
|
if (freq < old_freq) {
|
||||||
|
ret = dev_pm_genpd_set_performance_state(dev, new_pstate);
|
||||||
|
if (ret)
|
||||||
|
goto restore_freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
restore_freq:
|
||||||
|
if (_generic_set_opp_clk_only(dev, clk, freq, old_freq))
|
||||||
|
dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n",
|
||||||
|
__func__, old_freq);
|
||||||
|
restore_domain_state:
|
||||||
|
if (freq > old_freq)
|
||||||
|
dev_pm_genpd_set_performance_state(dev, old_pstate);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int _generic_set_opp_regulator(const struct opp_table *opp_table,
|
static int _generic_set_opp_regulator(const struct opp_table *opp_table,
|
||||||
struct device *dev,
|
struct device *dev,
|
||||||
unsigned long old_freq,
|
unsigned long old_freq,
|
||||||
@@ -653,7 +692,16 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
|
|||||||
|
|
||||||
/* Only frequency scaling */
|
/* Only frequency scaling */
|
||||||
if (!opp_table->regulators) {
|
if (!opp_table->regulators) {
|
||||||
ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq);
|
/*
|
||||||
|
* We don't support devices with both regulator and
|
||||||
|
* domain performance-state for now.
|
||||||
|
*/
|
||||||
|
if (opp_table->genpd_performance_state)
|
||||||
|
ret = _generic_set_opp_domain(dev, clk, old_freq, freq,
|
||||||
|
IS_ERR(old_opp) ? 0 : old_opp->pstate,
|
||||||
|
opp->pstate);
|
||||||
|
else
|
||||||
|
ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq);
|
||||||
} else if (!opp_table->set_opp) {
|
} else if (!opp_table->set_opp) {
|
||||||
ret = _generic_set_opp_regulator(opp_table, dev, old_freq, freq,
|
ret = _generic_set_opp_regulator(opp_table, dev, old_freq, freq,
|
||||||
IS_ERR(old_opp) ? NULL : old_opp->supplies,
|
IS_ERR(old_opp) ? NULL : old_opp->supplies,
|
||||||
@@ -988,6 +1036,9 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opp_table->get_pstate)
|
||||||
|
new_opp->pstate = opp_table->get_pstate(dev, new_opp->rate);
|
||||||
|
|
||||||
list_add(&new_opp->node, head);
|
list_add(&new_opp->node, head);
|
||||||
mutex_unlock(&opp_table->lock);
|
mutex_unlock(&opp_table->lock);
|
||||||
|
|
||||||
@@ -1476,13 +1527,13 @@ struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev,
|
|||||||
EXPORT_SYMBOL_GPL(dev_pm_opp_register_set_opp_helper);
|
EXPORT_SYMBOL_GPL(dev_pm_opp_register_set_opp_helper);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dev_pm_opp_register_put_opp_helper() - Releases resources blocked for
|
* dev_pm_opp_unregister_set_opp_helper() - Releases resources blocked for
|
||||||
* set_opp helper
|
* set_opp helper
|
||||||
* @opp_table: OPP table returned from dev_pm_opp_register_set_opp_helper().
|
* @opp_table: OPP table returned from dev_pm_opp_register_set_opp_helper().
|
||||||
*
|
*
|
||||||
* Release resources blocked for platform specific set_opp helper.
|
* Release resources blocked for platform specific set_opp helper.
|
||||||
*/
|
*/
|
||||||
void dev_pm_opp_register_put_opp_helper(struct opp_table *opp_table)
|
void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table)
|
||||||
{
|
{
|
||||||
if (!opp_table->set_opp) {
|
if (!opp_table->set_opp) {
|
||||||
pr_err("%s: Doesn't have custom set_opp helper set\n",
|
pr_err("%s: Doesn't have custom set_opp helper set\n",
|
||||||
@@ -1497,7 +1548,82 @@ void dev_pm_opp_register_put_opp_helper(struct opp_table *opp_table)
|
|||||||
|
|
||||||
dev_pm_opp_put_opp_table(opp_table);
|
dev_pm_opp_put_opp_table(opp_table);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dev_pm_opp_register_put_opp_helper);
|
EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dev_pm_opp_register_get_pstate_helper() - Register get_pstate() helper.
|
||||||
|
* @dev: Device for which the helper is getting registered.
|
||||||
|
* @get_pstate: Helper.
|
||||||
|
*
|
||||||
|
* TODO: Remove this callback after the same information is available via Device
|
||||||
|
* Tree.
|
||||||
|
*
|
||||||
|
* This allows a platform to initialize the performance states of individual
|
||||||
|
* OPPs for its devices, until we get similar information directly from DT.
|
||||||
|
*
|
||||||
|
* This must be called before the OPPs are initialized for the device.
|
||||||
|
*/
|
||||||
|
struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev,
|
||||||
|
int (*get_pstate)(struct device *dev, unsigned long rate))
|
||||||
|
{
|
||||||
|
struct opp_table *opp_table;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!get_pstate)
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
opp_table = dev_pm_opp_get_opp_table(dev);
|
||||||
|
if (!opp_table)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
/* This should be called before OPPs are initialized */
|
||||||
|
if (WARN_ON(!list_empty(&opp_table->opp_list))) {
|
||||||
|
ret = -EBUSY;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Already have genpd_performance_state set */
|
||||||
|
if (WARN_ON(opp_table->genpd_performance_state)) {
|
||||||
|
ret = -EBUSY;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
opp_table->genpd_performance_state = true;
|
||||||
|
opp_table->get_pstate = get_pstate;
|
||||||
|
|
||||||
|
return opp_table;
|
||||||
|
|
||||||
|
err:
|
||||||
|
dev_pm_opp_put_opp_table(opp_table);
|
||||||
|
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(dev_pm_opp_register_get_pstate_helper);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dev_pm_opp_unregister_get_pstate_helper() - Releases resources blocked for
|
||||||
|
* get_pstate() helper
|
||||||
|
* @opp_table: OPP table returned from dev_pm_opp_register_get_pstate_helper().
|
||||||
|
*
|
||||||
|
* Release resources blocked for platform specific get_pstate() helper.
|
||||||
|
*/
|
||||||
|
void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table)
|
||||||
|
{
|
||||||
|
if (!opp_table->genpd_performance_state) {
|
||||||
|
pr_err("%s: Doesn't have performance states set\n",
|
||||||
|
__func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure there are no concurrent readers while updating opp_table */
|
||||||
|
WARN_ON(!list_empty(&opp_table->opp_list));
|
||||||
|
|
||||||
|
opp_table->genpd_performance_state = false;
|
||||||
|
opp_table->get_pstate = NULL;
|
||||||
|
|
||||||
|
dev_pm_opp_put_opp_table(opp_table);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_get_pstate_helper);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dev_pm_opp_add() - Add an OPP table from a table definitions
|
* dev_pm_opp_add() - Add an OPP table from a table definitions
|
||||||
@@ -1706,6 +1832,13 @@ void _dev_pm_opp_remove_table(struct opp_table *opp_table, struct device *dev,
|
|||||||
if (remove_all || !opp->dynamic)
|
if (remove_all || !opp->dynamic)
|
||||||
dev_pm_opp_put(opp);
|
dev_pm_opp_put(opp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The OPP table is getting removed, drop the performance state
|
||||||
|
* constraints.
|
||||||
|
*/
|
||||||
|
if (opp_table->genpd_performance_state)
|
||||||
|
dev_pm_genpd_set_performance_state(dev, 0);
|
||||||
} else {
|
} else {
|
||||||
_remove_opp_dev(_find_opp_dev(dev, opp_table), opp_table);
|
_remove_opp_dev(_find_opp_dev(dev, opp_table), opp_table);
|
||||||
}
|
}
|
||||||
@@ -41,16 +41,15 @@ static bool opp_debug_create_supplies(struct dev_pm_opp *opp,
|
|||||||
{
|
{
|
||||||
struct dentry *d;
|
struct dentry *d;
|
||||||
int i;
|
int i;
|
||||||
char *name;
|
|
||||||
|
|
||||||
for (i = 0; i < opp_table->regulator_count; i++) {
|
for (i = 0; i < opp_table->regulator_count; i++) {
|
||||||
name = kasprintf(GFP_KERNEL, "supply-%d", i);
|
char name[15];
|
||||||
|
|
||||||
|
snprintf(name, sizeof(name), "supply-%d", i);
|
||||||
|
|
||||||
/* Create per-opp directory */
|
/* Create per-opp directory */
|
||||||
d = debugfs_create_dir(name, pdentry);
|
d = debugfs_create_dir(name, pdentry);
|
||||||
|
|
||||||
kfree(name);
|
|
||||||
|
|
||||||
if (!d)
|
if (!d)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -100,6 +99,9 @@ int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table)
|
|||||||
if (!debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend))
|
if (!debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (!debugfs_create_u32("performance_state", S_IRUGO, d, &opp->pstate))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
if (!debugfs_create_ulong("rate_hz", S_IRUGO, d, &opp->rate))
|
if (!debugfs_create_ulong("rate_hz", S_IRUGO, d, &opp->rate))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
|
||||||
@@ -397,6 +397,7 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np)
|
|||||||
dev_err(dev, "%s: Failed to add OPP, %d\n", __func__,
|
dev_err(dev, "%s: Failed to add OPP, %d\n", __func__,
|
||||||
ret);
|
ret);
|
||||||
_dev_pm_opp_remove_table(opp_table, dev, false);
|
_dev_pm_opp_remove_table(opp_table, dev, false);
|
||||||
|
of_node_put(np);
|
||||||
goto put_opp_table;
|
goto put_opp_table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -603,7 +604,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev,
|
|||||||
if (cpu == cpu_dev->id)
|
if (cpu == cpu_dev->id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cpu_np = of_get_cpu_node(cpu, NULL);
|
cpu_np = of_cpu_device_node_get(cpu);
|
||||||
if (!cpu_np) {
|
if (!cpu_np) {
|
||||||
dev_err(cpu_dev, "%s: failed to get cpu%d node\n",
|
dev_err(cpu_dev, "%s: failed to get cpu%d node\n",
|
||||||
__func__, cpu);
|
__func__, cpu);
|
||||||
@@ -613,6 +614,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev,
|
|||||||
|
|
||||||
/* Get OPP descriptor node */
|
/* Get OPP descriptor node */
|
||||||
tmp_np = _opp_of_get_opp_desc_node(cpu_np);
|
tmp_np = _opp_of_get_opp_desc_node(cpu_np);
|
||||||
|
of_node_put(cpu_np);
|
||||||
if (!tmp_np) {
|
if (!tmp_np) {
|
||||||
pr_err("%pOF: Couldn't find opp node\n", cpu_np);
|
pr_err("%pOF: Couldn't find opp node\n", cpu_np);
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
@@ -58,6 +58,7 @@ extern struct list_head opp_tables;
|
|||||||
* @dynamic: not-created from static DT entries.
|
* @dynamic: not-created from static DT entries.
|
||||||
* @turbo: true if turbo (boost) OPP
|
* @turbo: true if turbo (boost) OPP
|
||||||
* @suspend: true if suspend OPP
|
* @suspend: true if suspend OPP
|
||||||
|
* @pstate: Device's power domain's performance state.
|
||||||
* @rate: Frequency in hertz
|
* @rate: Frequency in hertz
|
||||||
* @supplies: Power supplies voltage/current values
|
* @supplies: Power supplies voltage/current values
|
||||||
* @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's
|
* @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's
|
||||||
@@ -76,6 +77,7 @@ struct dev_pm_opp {
|
|||||||
bool dynamic;
|
bool dynamic;
|
||||||
bool turbo;
|
bool turbo;
|
||||||
bool suspend;
|
bool suspend;
|
||||||
|
unsigned int pstate;
|
||||||
unsigned long rate;
|
unsigned long rate;
|
||||||
|
|
||||||
struct dev_pm_opp_supply *supplies;
|
struct dev_pm_opp_supply *supplies;
|
||||||
@@ -135,8 +137,10 @@ enum opp_table_access {
|
|||||||
* @clk: Device's clock handle
|
* @clk: Device's clock handle
|
||||||
* @regulators: Supply regulators
|
* @regulators: Supply regulators
|
||||||
* @regulator_count: Number of power supply regulators
|
* @regulator_count: Number of power supply regulators
|
||||||
|
* @genpd_performance_state: Device's power domain support performance state.
|
||||||
* @set_opp: Platform specific set_opp callback
|
* @set_opp: Platform specific set_opp callback
|
||||||
* @set_opp_data: Data to be passed to set_opp callback
|
* @set_opp_data: Data to be passed to set_opp callback
|
||||||
|
* @get_pstate: Platform specific get_pstate callback
|
||||||
* @dentry: debugfs dentry pointer of the real device directory (not links).
|
* @dentry: debugfs dentry pointer of the real device directory (not links).
|
||||||
* @dentry_name: Name of the real dentry.
|
* @dentry_name: Name of the real dentry.
|
||||||
*
|
*
|
||||||
@@ -170,9 +174,11 @@ struct opp_table {
|
|||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
struct regulator **regulators;
|
struct regulator **regulators;
|
||||||
unsigned int regulator_count;
|
unsigned int regulator_count;
|
||||||
|
bool genpd_performance_state;
|
||||||
|
|
||||||
int (*set_opp)(struct dev_pm_set_opp_data *data);
|
int (*set_opp)(struct dev_pm_set_opp_data *data);
|
||||||
struct dev_pm_set_opp_data *set_opp_data;
|
struct dev_pm_set_opp_data *set_opp_data;
|
||||||
|
int (*get_pstate)(struct device *dev, unsigned long rate);
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
@@ -124,7 +124,9 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table);
|
|||||||
struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name);
|
struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name);
|
||||||
void dev_pm_opp_put_clkname(struct opp_table *opp_table);
|
void dev_pm_opp_put_clkname(struct opp_table *opp_table);
|
||||||
struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
|
struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
|
||||||
void dev_pm_opp_register_put_opp_helper(struct opp_table *opp_table);
|
void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table);
|
||||||
|
struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev, int (*get_pstate)(struct device *dev, unsigned long rate));
|
||||||
|
void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table);
|
||||||
int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
|
int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
|
||||||
int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
|
int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
|
||||||
int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
|
int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
|
||||||
@@ -243,7 +245,15 @@ static inline struct opp_table *dev_pm_opp_register_set_opp_helper(struct device
|
|||||||
return ERR_PTR(-ENOTSUPP);
|
return ERR_PTR(-ENOTSUPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dev_pm_opp_register_put_opp_helper(struct opp_table *opp_table) {}
|
static inline void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) {}
|
||||||
|
|
||||||
|
static inline struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev,
|
||||||
|
int (*get_pstate)(struct device *dev, unsigned long rate))
|
||||||
|
{
|
||||||
|
return ERR_PTR(-ENOTSUPP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table) {}
|
||||||
|
|
||||||
static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
|
static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -259,20 +259,6 @@ config APM_EMULATION
|
|||||||
anything, try disabling/enabling this option (or disabling/enabling
|
anything, try disabling/enabling this option (or disabling/enabling
|
||||||
APM in your BIOS).
|
APM in your BIOS).
|
||||||
|
|
||||||
config PM_OPP
|
|
||||||
bool
|
|
||||||
select SRCU
|
|
||||||
---help---
|
|
||||||
SOCs have a standard set of tuples consisting of frequency and
|
|
||||||
voltage pairs that the device will support per voltage domain. This
|
|
||||||
is called Operating Performance Point or OPP. The actual definitions
|
|
||||||
of OPP varies over silicon within the same family of devices.
|
|
||||||
|
|
||||||
OPP layer organizes the data internally using device pointers
|
|
||||||
representing individual voltage domains and provides SOC
|
|
||||||
implementations a ready to use framework to manage OPPs.
|
|
||||||
For more information, read <file:Documentation/power/opp.txt>
|
|
||||||
|
|
||||||
config PM_CLK
|
config PM_CLK
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on PM && HAVE_CLK
|
depends on PM && HAVE_CLK
|
||||||
|
|||||||
@@ -282,8 +282,12 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
|
|||||||
* Do not reduce the frequency if the CPU has not been idle
|
* Do not reduce the frequency if the CPU has not been idle
|
||||||
* recently, as the reduction is likely to be premature then.
|
* recently, as the reduction is likely to be premature then.
|
||||||
*/
|
*/
|
||||||
if (busy && next_f < sg_policy->next_freq)
|
if (busy && next_f < sg_policy->next_freq) {
|
||||||
next_f = sg_policy->next_freq;
|
next_f = sg_policy->next_freq;
|
||||||
|
|
||||||
|
/* Reset cached freq as next_freq has changed */
|
||||||
|
sg_policy->cached_raw_freq = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sugov_update_commit(sg_policy, time, next_f);
|
sugov_update_commit(sg_policy, time, next_f);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user