mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
OPP: Add dev_pm_opp_add_dynamic() to allow more flexibility
The dev_pm_opp_add() API is limited to add dynamic OPPs with a frequency and a voltage level. To enable more flexibility, let's add a new API, dev_pm_opp_add_dynamic() that's takes a struct dev_pm_opp_data* instead of a list of in-parameters. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
This commit is contained in:
parent
401e09201a
commit
248a38d5cc
@ -2002,8 +2002,7 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
|
|||||||
* _opp_add_v1() - Allocate a OPP based on v1 bindings.
|
* _opp_add_v1() - Allocate a OPP based on v1 bindings.
|
||||||
* @opp_table: OPP table
|
* @opp_table: OPP table
|
||||||
* @dev: device for which we do this operation
|
* @dev: device for which we do this operation
|
||||||
* @freq: Frequency in Hz for this OPP
|
* @data: The OPP data for the OPP to add
|
||||||
* @u_volt: Voltage in uVolts for this OPP
|
|
||||||
* @dynamic: Dynamically added OPPs.
|
* @dynamic: Dynamically added OPPs.
|
||||||
*
|
*
|
||||||
* This function adds an opp definition to the opp table and returns status.
|
* This function adds an opp definition to the opp table and returns status.
|
||||||
@ -2021,10 +2020,10 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
|
|||||||
* -ENOMEM Memory allocation failure
|
* -ENOMEM Memory allocation failure
|
||||||
*/
|
*/
|
||||||
int _opp_add_v1(struct opp_table *opp_table, struct device *dev,
|
int _opp_add_v1(struct opp_table *opp_table, struct device *dev,
|
||||||
unsigned long freq, long u_volt, bool dynamic)
|
struct dev_pm_opp_data *data, bool dynamic)
|
||||||
{
|
{
|
||||||
struct dev_pm_opp *new_opp;
|
struct dev_pm_opp *new_opp;
|
||||||
unsigned long tol;
|
unsigned long tol, u_volt = data->u_volt;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!assert_single_clk(opp_table))
|
if (!assert_single_clk(opp_table))
|
||||||
@ -2035,7 +2034,7 @@ int _opp_add_v1(struct opp_table *opp_table, struct device *dev,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* populate the opp table */
|
/* populate the opp table */
|
||||||
new_opp->rates[0] = freq;
|
new_opp->rates[0] = data->freq;
|
||||||
tol = u_volt * opp_table->voltage_tolerance_v1 / 100;
|
tol = u_volt * opp_table->voltage_tolerance_v1 / 100;
|
||||||
new_opp->supplies[0].u_volt = u_volt;
|
new_opp->supplies[0].u_volt = u_volt;
|
||||||
new_opp->supplies[0].u_volt_min = u_volt - tol;
|
new_opp->supplies[0].u_volt_min = u_volt - tol;
|
||||||
@ -2825,10 +2824,9 @@ unlock:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dev_pm_opp_add() - Add an OPP table from a table definitions
|
* dev_pm_opp_add_dynamic() - Add an OPP table from a table definitions
|
||||||
* @dev: device for which we do this operation
|
* @dev: The device for which we do this operation
|
||||||
* @freq: Frequency in Hz for this OPP
|
* @data: The OPP data for the OPP to add
|
||||||
* @u_volt: Voltage in uVolts for this OPP
|
|
||||||
*
|
*
|
||||||
* This function adds an opp definition to the opp table and returns status.
|
* This function adds an opp definition to the opp table and returns status.
|
||||||
* The opp is made available by default and it can be controlled using
|
* The opp is made available by default and it can be controlled using
|
||||||
@ -2841,7 +2839,7 @@ unlock:
|
|||||||
* Duplicate OPPs (both freq and volt are same) and !opp->available
|
* Duplicate OPPs (both freq and volt are same) and !opp->available
|
||||||
* -ENOMEM Memory allocation failure
|
* -ENOMEM Memory allocation failure
|
||||||
*/
|
*/
|
||||||
int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
|
int dev_pm_opp_add_dynamic(struct device *dev, struct dev_pm_opp_data *data)
|
||||||
{
|
{
|
||||||
struct opp_table *opp_table;
|
struct opp_table *opp_table;
|
||||||
int ret;
|
int ret;
|
||||||
@ -2853,13 +2851,13 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
|
|||||||
/* Fix regulator count for dynamic OPPs */
|
/* Fix regulator count for dynamic OPPs */
|
||||||
opp_table->regulator_count = 1;
|
opp_table->regulator_count = 1;
|
||||||
|
|
||||||
ret = _opp_add_v1(opp_table, dev, freq, u_volt, true);
|
ret = _opp_add_v1(opp_table, dev, data, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_pm_opp_put_opp_table(opp_table);
|
dev_pm_opp_put_opp_table(opp_table);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dev_pm_opp_add);
|
EXPORT_SYMBOL_GPL(dev_pm_opp_add_dynamic);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _opp_set_availability() - helper to set the availability of an opp
|
* _opp_set_availability() - helper to set the availability of an opp
|
||||||
|
@ -1077,13 +1077,15 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
|
|||||||
|
|
||||||
val = prop->value;
|
val = prop->value;
|
||||||
while (nr) {
|
while (nr) {
|
||||||
unsigned long freq = be32_to_cpup(val++) * 1000;
|
struct dev_pm_opp_data data = {
|
||||||
unsigned long volt = be32_to_cpup(val++);
|
.freq = be32_to_cpup(val++) * 1000,
|
||||||
|
.u_volt = be32_to_cpup(val++),
|
||||||
|
};
|
||||||
|
|
||||||
ret = _opp_add_v1(opp_table, dev, freq, volt, false);
|
ret = _opp_add_v1(opp_table, dev, &data, false);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "%s: Failed to add OPP %ld (%d)\n",
|
dev_err(dev, "%s: Failed to add OPP %ld (%d)\n",
|
||||||
__func__, freq, ret);
|
__func__, data.freq, ret);
|
||||||
goto remove_static_opp;
|
goto remove_static_opp;
|
||||||
}
|
}
|
||||||
nr -= 2;
|
nr -= 2;
|
||||||
|
@ -251,7 +251,7 @@ struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table);
|
|||||||
void _opp_free(struct dev_pm_opp *opp);
|
void _opp_free(struct dev_pm_opp *opp);
|
||||||
int _opp_compare_key(struct opp_table *opp_table, struct dev_pm_opp *opp1, struct dev_pm_opp *opp2);
|
int _opp_compare_key(struct opp_table *opp_table, struct dev_pm_opp *opp1, struct dev_pm_opp *opp2);
|
||||||
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);
|
||||||
int _opp_add_v1(struct opp_table *opp_table, struct device *dev, unsigned long freq, long u_volt, bool dynamic);
|
int _opp_add_v1(struct opp_table *opp_table, struct device *dev, struct dev_pm_opp_data *data, bool dynamic);
|
||||||
void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, int last_cpu);
|
void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, int last_cpu);
|
||||||
struct opp_table *_add_opp_table_indexed(struct device *dev, int index, bool getclk);
|
struct opp_table *_add_opp_table_indexed(struct device *dev, int index, bool getclk);
|
||||||
void _put_opp_list_kref(struct opp_table *opp_table);
|
void _put_opp_list_kref(struct opp_table *opp_table);
|
||||||
|
@ -92,6 +92,16 @@ struct dev_pm_opp_config {
|
|||||||
struct device ***virt_devs;
|
struct device ***virt_devs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct dev_pm_opp_data - The data to use to initialize an OPP.
|
||||||
|
* @freq: The clock rate in Hz for the OPP.
|
||||||
|
* @u_volt: The voltage in uV for the OPP.
|
||||||
|
*/
|
||||||
|
struct dev_pm_opp_data {
|
||||||
|
unsigned long freq;
|
||||||
|
unsigned long u_volt;
|
||||||
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_PM_OPP)
|
#if defined(CONFIG_PM_OPP)
|
||||||
|
|
||||||
struct opp_table *dev_pm_opp_get_opp_table(struct device *dev);
|
struct opp_table *dev_pm_opp_get_opp_table(struct device *dev);
|
||||||
@ -152,8 +162,8 @@ struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev,
|
|||||||
|
|
||||||
void dev_pm_opp_put(struct dev_pm_opp *opp);
|
void dev_pm_opp_put(struct dev_pm_opp *opp);
|
||||||
|
|
||||||
int dev_pm_opp_add(struct device *dev, unsigned long freq,
|
int dev_pm_opp_add_dynamic(struct device *dev, struct dev_pm_opp_data *opp);
|
||||||
unsigned long u_volt);
|
|
||||||
void dev_pm_opp_remove(struct device *dev, unsigned long freq);
|
void dev_pm_opp_remove(struct device *dev, unsigned long freq);
|
||||||
void dev_pm_opp_remove_all_dynamic(struct device *dev);
|
void dev_pm_opp_remove_all_dynamic(struct device *dev);
|
||||||
|
|
||||||
@ -322,8 +332,8 @@ static inline struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev,
|
|||||||
|
|
||||||
static inline void dev_pm_opp_put(struct dev_pm_opp *opp) {}
|
static inline void dev_pm_opp_put(struct dev_pm_opp *opp) {}
|
||||||
|
|
||||||
static inline int dev_pm_opp_add(struct device *dev, unsigned long freq,
|
static inline int
|
||||||
unsigned long u_volt)
|
dev_pm_opp_add_dynamic(struct device *dev, struct dev_pm_opp_data *opp)
|
||||||
{
|
{
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
@ -519,6 +529,17 @@ static inline int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_ta
|
|||||||
|
|
||||||
/* OPP Configuration helpers */
|
/* OPP Configuration helpers */
|
||||||
|
|
||||||
|
static inline int dev_pm_opp_add(struct device *dev, unsigned long freq,
|
||||||
|
unsigned long u_volt)
|
||||||
|
{
|
||||||
|
struct dev_pm_opp_data data = {
|
||||||
|
.freq = freq,
|
||||||
|
.u_volt = u_volt,
|
||||||
|
};
|
||||||
|
|
||||||
|
return dev_pm_opp_add_dynamic(dev, &data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Regulators helpers */
|
/* Regulators helpers */
|
||||||
static inline int dev_pm_opp_set_regulators(struct device *dev,
|
static inline int dev_pm_opp_set_regulators(struct device *dev,
|
||||||
const char * const names[])
|
const char * const names[])
|
||||||
|
Loading…
Reference in New Issue
Block a user