Commit 57def856 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'pm-opp'

* pm-opp:
  PM / OPP: Don't WARN on multiple calls to dev_pm_opp_set_regulators()
  PM / OPP: Allow platform specific custom set_opp() callbacks
  PM / OPP: Separate out _generic_set_opp()
  PM / OPP: Add infrastructure to manage multiple regulators
  PM / OPP: Pass struct dev_pm_opp_supply to _set_opp_voltage()
  PM / OPP: Manage supply's voltage/current in a separate structure
  PM / OPP: Don't use OPP structure outside of rcu protected section
  PM / OPP: Reword binding supporting multiple regulators per device
  PM / OPP: Fix incorrect cpu-supply property in binding
  PM / OPP: Pass opp_table to dev_pm_opp_put_regulator()
  PM / OPP: fix debug/error messages in dev_pm_opp_of_get_sharing_cpus()
  PM / OPP: make _of_get_opp_desc_node() a static function
parents 852b7fa2 e231f8d7
...@@ -86,8 +86,14 @@ Optional properties: ...@@ -86,8 +86,14 @@ Optional properties:
Single entry is for target voltage and three entries are for <target min max> Single entry is for target voltage and three entries are for <target min max>
voltages. voltages.
Entries for multiple regulators must be present in the same order as Entries for multiple regulators shall be provided in the same field separated
regulators are specified in device's DT node. by angular brackets <>. The OPP binding doesn't provide any provisions to
relate the values to their power supplies or the order in which the supplies
need to be configured and that is left for the implementation specific
binding.
Entries for all regulators shall be of the same size, i.e. either all use a
single value or triplets.
- opp-microvolt-<name>: Named opp-microvolt property. This is exactly similar to - opp-microvolt-<name>: Named opp-microvolt property. This is exactly similar to
the above opp-microvolt property, but allows multiple voltage ranges to be the above opp-microvolt property, but allows multiple voltage ranges to be
...@@ -104,10 +110,13 @@ Optional properties: ...@@ -104,10 +110,13 @@ Optional properties:
Should only be set if opp-microvolt is set for the OPP. Should only be set if opp-microvolt is set for the OPP.
Entries for multiple regulators must be present in the same order as Entries for multiple regulators shall be provided in the same field separated
regulators are specified in device's DT node. If this property isn't required by angular brackets <>. If current values aren't required for a regulator,
for few regulators, then this should be marked as zero for them. If it isn't then it shall be filled with 0. If current values aren't required for any of
required for any regulator, then this property need not be present. the regulators, then this field is not required. The OPP binding doesn't
provide any provisions to relate the values to their power supplies or the
order in which the supplies need to be configured and that is left for the
implementation specific binding.
- opp-microamp-<name>: Named opp-microamp property. Similar to - opp-microamp-<name>: Named opp-microamp property. Similar to
opp-microvolt-<name> property, but for microamp instead. opp-microvolt-<name> property, but for microamp instead.
...@@ -386,10 +395,12 @@ Example 4: Handling multiple regulators ...@@ -386,10 +395,12 @@ Example 4: Handling multiple regulators
/ { / {
cpus { cpus {
cpu@0 { cpu@0 {
compatible = "arm,cortex-a7"; compatible = "vendor,cpu-type";
... ...
cpu-supply = <&cpu_supply0>, <&cpu_supply1>, <&cpu_supply2>; vcc0-supply = <&cpu_supply0>;
vcc1-supply = <&cpu_supply1>;
vcc2-supply = <&cpu_supply2>;
operating-points-v2 = <&cpu0_opp_table>; operating-points-v2 = <&cpu0_opp_table>;
}; };
}; };
......
This diff is collapsed.
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/limits.h> #include <linux/limits.h>
#include <linux/slab.h>
#include "opp.h" #include "opp.h"
...@@ -34,6 +35,46 @@ void opp_debug_remove_one(struct dev_pm_opp *opp) ...@@ -34,6 +35,46 @@ void opp_debug_remove_one(struct dev_pm_opp *opp)
debugfs_remove_recursive(opp->dentry); debugfs_remove_recursive(opp->dentry);
} }
static bool opp_debug_create_supplies(struct dev_pm_opp *opp,
struct opp_table *opp_table,
struct dentry *pdentry)
{
struct dentry *d;
int i = 0;
char *name;
/* Always create at least supply-0 directory */
do {
name = kasprintf(GFP_KERNEL, "supply-%d", i);
/* Create per-opp directory */
d = debugfs_create_dir(name, pdentry);
kfree(name);
if (!d)
return false;
if (!debugfs_create_ulong("u_volt_target", S_IRUGO, d,
&opp->supplies[i].u_volt))
return false;
if (!debugfs_create_ulong("u_volt_min", S_IRUGO, d,
&opp->supplies[i].u_volt_min))
return false;
if (!debugfs_create_ulong("u_volt_max", S_IRUGO, d,
&opp->supplies[i].u_volt_max))
return false;
if (!debugfs_create_ulong("u_amp", S_IRUGO, d,
&opp->supplies[i].u_amp))
return false;
} while (++i < opp_table->regulator_count);
return true;
}
int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table) int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table)
{ {
struct dentry *pdentry = opp_table->dentry; struct dentry *pdentry = opp_table->dentry;
...@@ -63,16 +104,7 @@ int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table) ...@@ -63,16 +104,7 @@ int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table)
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;
if (!debugfs_create_ulong("u_volt_target", S_IRUGO, d, &opp->u_volt)) if (!opp_debug_create_supplies(opp, opp_table, d))
return -ENOMEM;
if (!debugfs_create_ulong("u_volt_min", S_IRUGO, d, &opp->u_volt_min))
return -ENOMEM;
if (!debugfs_create_ulong("u_volt_max", S_IRUGO, d, &opp->u_volt_max))
return -ENOMEM;
if (!debugfs_create_ulong("u_amp", S_IRUGO, d, &opp->u_amp))
return -ENOMEM; return -ENOMEM;
if (!debugfs_create_ulong("clock_latency_ns", S_IRUGO, d, if (!debugfs_create_ulong("clock_latency_ns", S_IRUGO, d,
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/slab.h>
#include <linux/export.h> #include <linux/export.h>
#include "opp.h" #include "opp.h"
...@@ -101,16 +102,16 @@ static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table, ...@@ -101,16 +102,16 @@ static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,
return true; return true;
} }
/* TODO: Support multiple regulators */
static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
struct opp_table *opp_table) struct opp_table *opp_table)
{ {
u32 microvolt[3] = {0}; u32 *microvolt, *microamp = NULL;
u32 val; int supplies, vcount, icount, ret, i, j;
int count, ret;
struct property *prop = NULL; struct property *prop = NULL;
char name[NAME_MAX]; char name[NAME_MAX];
supplies = opp_table->regulator_count ? opp_table->regulator_count : 1;
/* Search for "opp-microvolt-<name>" */ /* Search for "opp-microvolt-<name>" */
if (opp_table->prop_name) { if (opp_table->prop_name) {
snprintf(name, sizeof(name), "opp-microvolt-%s", snprintf(name, sizeof(name), "opp-microvolt-%s",
...@@ -128,34 +129,29 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, ...@@ -128,34 +129,29 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
return 0; return 0;
} }
count = of_property_count_u32_elems(opp->np, name); vcount = of_property_count_u32_elems(opp->np, name);
if (count < 0) { if (vcount < 0) {
dev_err(dev, "%s: Invalid %s property (%d)\n", dev_err(dev, "%s: Invalid %s property (%d)\n",
__func__, name, count); __func__, name, vcount);
return count; return vcount;
} }
/* There can be one or three elements here */ /* There can be one or three elements per supply */
if (count != 1 && count != 3) { if (vcount != supplies && vcount != supplies * 3) {
dev_err(dev, "%s: Invalid number of elements in %s property (%d)\n", dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n",
__func__, name, count); __func__, name, vcount, supplies);
return -EINVAL; return -EINVAL;
} }
ret = of_property_read_u32_array(opp->np, name, microvolt, count); microvolt = kmalloc_array(vcount, sizeof(*microvolt), GFP_KERNEL);
if (!microvolt)
return -ENOMEM;
ret = of_property_read_u32_array(opp->np, name, microvolt, vcount);
if (ret) { if (ret) {
dev_err(dev, "%s: error parsing %s: %d\n", __func__, name, ret); dev_err(dev, "%s: error parsing %s: %d\n", __func__, name, ret);
return -EINVAL; ret = -EINVAL;
} goto free_microvolt;
opp->u_volt = microvolt[0];
if (count == 1) {
opp->u_volt_min = opp->u_volt;
opp->u_volt_max = opp->u_volt;
} else {
opp->u_volt_min = microvolt[1];
opp->u_volt_max = microvolt[2];
} }
/* Search for "opp-microamp-<name>" */ /* Search for "opp-microamp-<name>" */
...@@ -172,10 +168,59 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, ...@@ -172,10 +168,59 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
prop = of_find_property(opp->np, name, NULL); prop = of_find_property(opp->np, name, NULL);
} }
if (prop && !of_property_read_u32(opp->np, name, &val)) if (prop) {
opp->u_amp = val; icount = of_property_count_u32_elems(opp->np, name);
if (icount < 0) {
dev_err(dev, "%s: Invalid %s property (%d)\n", __func__,
name, icount);
ret = icount;
goto free_microvolt;
}
return 0; if (icount != supplies) {
dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n",
__func__, name, icount, supplies);
ret = -EINVAL;
goto free_microvolt;
}
microamp = kmalloc_array(icount, sizeof(*microamp), GFP_KERNEL);
if (!microamp) {
ret = -EINVAL;
goto free_microvolt;
}
ret = of_property_read_u32_array(opp->np, name, microamp,
icount);
if (ret) {
dev_err(dev, "%s: error parsing %s: %d\n", __func__,
name, ret);
ret = -EINVAL;
goto free_microamp;
}
}
for (i = 0, j = 0; i < supplies; i++) {
opp->supplies[i].u_volt = microvolt[j++];
if (vcount == supplies) {
opp->supplies[i].u_volt_min = opp->supplies[i].u_volt;
opp->supplies[i].u_volt_max = opp->supplies[i].u_volt;
} else {
opp->supplies[i].u_volt_min = microvolt[j++];
opp->supplies[i].u_volt_max = microvolt[j++];
}
if (microamp)
opp->supplies[i].u_amp = microamp[i];
}
free_microamp:
kfree(microamp);
free_microvolt:
kfree(microvolt);
return ret;
} }
/** /**
...@@ -198,7 +243,7 @@ void dev_pm_opp_of_remove_table(struct device *dev) ...@@ -198,7 +243,7 @@ void dev_pm_opp_of_remove_table(struct device *dev)
EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table); EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table);
/* Returns opp descriptor node for a device, caller must do of_node_put() */ /* Returns opp descriptor node for a device, caller must do of_node_put() */
struct device_node *_of_get_opp_desc_node(struct device *dev) static struct device_node *_of_get_opp_desc_node(struct device *dev)
{ {
/* /*
* TODO: Support for multiple OPP tables. * TODO: Support for multiple OPP tables.
...@@ -303,9 +348,9 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np) ...@@ -303,9 +348,9 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np)
mutex_unlock(&opp_table_lock); mutex_unlock(&opp_table_lock);
pr_debug("%s: turbo:%d rate:%lu uv:%lu uvmin:%lu uvmax:%lu latency:%lu\n", pr_debug("%s: turbo:%d rate:%lu uv:%lu uvmin:%lu uvmax:%lu latency:%lu\n",
__func__, new_opp->turbo, new_opp->rate, new_opp->u_volt, __func__, new_opp->turbo, new_opp->rate,
new_opp->u_volt_min, new_opp->u_volt_max, new_opp->supplies[0].u_volt, new_opp->supplies[0].u_volt_min,
new_opp->clock_latency_ns); new_opp->supplies[0].u_volt_max, new_opp->clock_latency_ns);
/* /*
* Notify the changes in the availability of the operable * Notify the changes in the availability of the operable
...@@ -562,7 +607,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, ...@@ -562,7 +607,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev,
/* Get OPP descriptor node */ /* Get OPP descriptor node */
np = _of_get_opp_desc_node(cpu_dev); np = _of_get_opp_desc_node(cpu_dev);
if (!np) { if (!np) {
dev_dbg(cpu_dev, "%s: Couldn't find cpu_dev node.\n", __func__); dev_dbg(cpu_dev, "%s: Couldn't find opp node.\n", __func__);
return -ENOENT; return -ENOENT;
} }
...@@ -587,7 +632,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, ...@@ -587,7 +632,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev,
/* Get OPP descriptor node */ /* Get OPP descriptor node */
tmp_np = _of_get_opp_desc_node(tcpu_dev); tmp_np = _of_get_opp_desc_node(tcpu_dev);
if (!tmp_np) { if (!tmp_np) {
dev_err(tcpu_dev, "%s: Couldn't find tcpu_dev node.\n", dev_err(tcpu_dev, "%s: Couldn't find opp node.\n",
__func__); __func__);
ret = -ENOENT; ret = -ENOENT;
goto put_cpu_node; goto put_cpu_node;
......
...@@ -61,10 +61,7 @@ extern struct list_head opp_tables; ...@@ -61,10 +61,7 @@ extern struct list_head opp_tables;
* @turbo: true if turbo (boost) OPP * @turbo: true if turbo (boost) OPP
* @suspend: true if suspend OPP * @suspend: true if suspend OPP
* @rate: Frequency in hertz * @rate: Frequency in hertz
* @u_volt: Target voltage in microvolts corresponding to this OPP * @supplies: Power supplies voltage/current values
* @u_volt_min: Minimum voltage in microvolts corresponding to this OPP
* @u_volt_max: Maximum voltage in microvolts corresponding to this OPP
* @u_amp: Maximum current drawn by the device in microamperes
* @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's * @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's
* frequency from any other OPP's frequency. * frequency from any other OPP's frequency.
* @opp_table: points back to the opp_table struct this opp belongs to * @opp_table: points back to the opp_table struct this opp belongs to
...@@ -83,10 +80,8 @@ struct dev_pm_opp { ...@@ -83,10 +80,8 @@ struct dev_pm_opp {
bool suspend; bool suspend;
unsigned long rate; unsigned long rate;
unsigned long u_volt; struct dev_pm_opp_supply *supplies;
unsigned long u_volt_min;
unsigned long u_volt_max;
unsigned long u_amp;
unsigned long clock_latency_ns; unsigned long clock_latency_ns;
struct opp_table *opp_table; struct opp_table *opp_table;
...@@ -144,7 +139,10 @@ enum opp_table_access { ...@@ -144,7 +139,10 @@ enum opp_table_access {
* @supported_hw_count: Number of elements in supported_hw array. * @supported_hw_count: Number of elements in supported_hw array.
* @prop_name: A name to postfix to many DT properties, while parsing them. * @prop_name: A name to postfix to many DT properties, while parsing them.
* @clk: Device's clock handle * @clk: Device's clock handle
* @regulator: Supply regulator * @regulators: Supply regulators
* @regulator_count: Number of power supply regulators
* @set_opp: Platform specific set_opp callback
* @set_opp_data: Data to be passed to set_opp 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.
* *
...@@ -179,7 +177,11 @@ struct opp_table { ...@@ -179,7 +177,11 @@ struct opp_table {
unsigned int supported_hw_count; unsigned int supported_hw_count;
const char *prop_name; const char *prop_name;
struct clk *clk; struct clk *clk;
struct regulator *regulator; struct regulator **regulators;
unsigned int regulator_count;
int (*set_opp)(struct dev_pm_set_opp_data *data);
struct dev_pm_set_opp_data *set_opp_data;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *dentry; struct dentry *dentry;
...@@ -190,7 +192,6 @@ struct opp_table { ...@@ -190,7 +192,6 @@ struct opp_table {
/* Routines internal to opp core */ /* Routines internal to opp core */
struct opp_table *_find_opp_table(struct device *dev); struct opp_table *_find_opp_table(struct device *dev);
struct opp_device *_add_opp_dev(const struct device *dev, struct opp_table *opp_table); struct opp_device *_add_opp_dev(const struct device *dev, struct opp_table *opp_table);
struct device_node *_of_get_opp_desc_node(struct device *dev);
void _dev_pm_opp_remove_table(struct device *dev, bool remove_all); void _dev_pm_opp_remove_table(struct device *dev, bool remove_all);
struct dev_pm_opp *_allocate_opp(struct device *dev, struct opp_table **opp_table); struct dev_pm_opp *_allocate_opp(struct device *dev, struct opp_table **opp_table);
int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table); int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "cpufreq-dt.h" #include "cpufreq-dt.h"
struct private_data { struct private_data {
struct opp_table *opp_table;
struct device *cpu_dev; struct device *cpu_dev;
struct thermal_cooling_device *cdev; struct thermal_cooling_device *cdev;
const char *reg_name; const char *reg_name;
...@@ -143,6 +144,7 @@ static int resources_available(void) ...@@ -143,6 +144,7 @@ static int resources_available(void)
static int cpufreq_init(struct cpufreq_policy *policy) static int cpufreq_init(struct cpufreq_policy *policy)
{ {
struct cpufreq_frequency_table *freq_table; struct cpufreq_frequency_table *freq_table;
struct opp_table *opp_table = NULL;
struct private_data *priv; struct private_data *priv;
struct device *cpu_dev; struct device *cpu_dev;
struct clk *cpu_clk; struct clk *cpu_clk;
...@@ -186,8 +188,9 @@ static int cpufreq_init(struct cpufreq_policy *policy) ...@@ -186,8 +188,9 @@ static int cpufreq_init(struct cpufreq_policy *policy)
*/ */
name = find_supply_name(cpu_dev); name = find_supply_name(cpu_dev);
if (name) { if (name) {
ret = dev_pm_opp_set_regulator(cpu_dev, name); opp_table = dev_pm_opp_set_regulators(cpu_dev, &name, 1);
if (ret) { if (IS_ERR(opp_table)) {
ret = PTR_ERR(opp_table);
dev_err(cpu_dev, "Failed to set regulator for cpu%d: %d\n", dev_err(cpu_dev, "Failed to set regulator for cpu%d: %d\n",
policy->cpu, ret); policy->cpu, ret);
goto out_put_clk; goto out_put_clk;
...@@ -237,6 +240,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) ...@@ -237,6 +240,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
} }
priv->reg_name = name; priv->reg_name = name;
priv->opp_table = opp_table;
ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
if (ret) { if (ret) {
...@@ -285,7 +289,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) ...@@ -285,7 +289,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
out_free_opp: out_free_opp:
dev_pm_opp_of_cpumask_remove_table(policy->cpus); dev_pm_opp_of_cpumask_remove_table(policy->cpus);
if (name) if (name)
dev_pm_opp_put_regulator(cpu_dev); dev_pm_opp_put_regulators(opp_table);
out_put_clk: out_put_clk:
clk_put(cpu_clk); clk_put(cpu_clk);
...@@ -300,7 +304,7 @@ static int cpufreq_exit(struct cpufreq_policy *policy) ...@@ -300,7 +304,7 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
dev_pm_opp_of_cpumask_remove_table(policy->related_cpus); dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
if (priv->reg_name) if (priv->reg_name)
dev_pm_opp_put_regulator(priv->cpu_dev); dev_pm_opp_put_regulators(priv->opp_table);
clk_put(policy->clk); clk_put(policy->clk);
kfree(priv); kfree(priv);
......
...@@ -17,13 +17,65 @@ ...@@ -17,13 +17,65 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/notifier.h> #include <linux/notifier.h>
struct clk;
struct regulator;
struct dev_pm_opp; struct dev_pm_opp;
struct device; struct device;
struct opp_table;
enum dev_pm_opp_event { enum dev_pm_opp_event {
OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE, OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
}; };
/**
* struct dev_pm_opp_supply - Power supply voltage/current values
* @u_volt: Target voltage in microvolts corresponding to this OPP
* @u_volt_min: Minimum voltage in microvolts corresponding to this OPP
* @u_volt_max: Maximum voltage in microvolts corresponding to this OPP
* @u_amp: Maximum current drawn by the device in microamperes
*
* This structure stores the voltage/current values for a single power supply.
*/
struct dev_pm_opp_supply {
unsigned long u_volt;
unsigned long u_volt_min;
unsigned long u_volt_max;
unsigned long u_amp;
};
/**
* struct dev_pm_opp_info - OPP freq/voltage/current values
* @rate: Target clk rate in hz
* @supplies: Array of voltage/current values for all power supplies
*
* This structure stores the freq/voltage/current values for a single OPP.
*/
struct dev_pm_opp_info {
unsigned long rate;
struct dev_pm_opp_supply *supplies;
};
/**
* struct dev_pm_set_opp_data - Set OPP data
* @old_opp: Old OPP info
* @new_opp: New OPP info
* @regulators: Array of regulator pointers
* @regulator_count: Number of regulators
* @clk: Pointer to clk
* @dev: Pointer to the struct device
*
* This structure contains all information required for setting an OPP.
*/
struct dev_pm_set_opp_data {
struct dev_pm_opp_info old_opp;
struct dev_pm_opp_info new_opp;
struct regulator **regulators;
unsigned int regulator_count;
struct clk *clk;
struct device *dev;
};
#if defined(CONFIG_PM_OPP) #if defined(CONFIG_PM_OPP)
unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp); unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp);
...@@ -62,8 +114,10 @@ int dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, ...@@ -62,8 +114,10 @@ int dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions,
void dev_pm_opp_put_supported_hw(struct device *dev); void dev_pm_opp_put_supported_hw(struct device *dev);
int dev_pm_opp_set_prop_name(struct device *dev, const char *name); int dev_pm_opp_set_prop_name(struct device *dev, const char *name);
void dev_pm_opp_put_prop_name(struct device *dev); void dev_pm_opp_put_prop_name(struct device *dev);
int dev_pm_opp_set_regulator(struct device *dev, const char *name); struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count);
void dev_pm_opp_put_regulator(struct device *dev); void dev_pm_opp_put_regulators(struct opp_table *opp_table);
int 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 device *dev);
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);
...@@ -163,6 +217,14 @@ static inline int dev_pm_opp_set_supported_hw(struct device *dev, ...@@ -163,6 +217,14 @@ static inline int dev_pm_opp_set_supported_hw(struct device *dev,
static inline void dev_pm_opp_put_supported_hw(struct device *dev) {} static inline void dev_pm_opp_put_supported_hw(struct device *dev) {}
static inline int dev_pm_opp_register_set_opp_helper(struct device *dev,
int (*set_opp)(struct dev_pm_set_opp_data *data))
{
return -ENOTSUPP;
}
static inline void dev_pm_opp_register_put_opp_helper(struct device *dev) {}
static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name) static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name)
{ {
return -ENOTSUPP; return -ENOTSUPP;
...@@ -170,12 +232,12 @@ static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name) ...@@ -170,12 +232,12 @@ static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name)
static inline void dev_pm_opp_put_prop_name(struct device *dev) {} static inline void dev_pm_opp_put_prop_name(struct device *dev) {}
static inline int dev_pm_opp_set_regulator(struct device *dev, const char *name) static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count)
{ {
return -ENOTSUPP; return ERR_PTR(-ENOTSUPP);
} }
static inline void dev_pm_opp_put_regulator(struct device *dev) {} static inline void dev_pm_opp_put_regulators(struct opp_table *opp_table) {}
static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment