From: Sibi Sankar <sibis@xxxxxxxxxxxxxx> Add and export 'dev_pm_opp_set_bw' to set the bandwidth levels associated with an OPP for a given frequency. Signed-off-by: Sibi Sankar <sibis@xxxxxxxxxxxxxx> Signed-off-by: Sharat Masetty <smasetty@xxxxxxxxxxxxxx> --- drivers/opp/core.c | 43 +++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_opp.h | 6 ++++++ 2 files changed, 49 insertions(+) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index f42b7c4..0f34077 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -828,6 +828,49 @@ static int _set_required_opps(struct device *dev, } /** + * dev_pm_opp_set_bw() - sets bandwidth levels corresponding to an available opp + * @dev: device for which we do this operation + * @opp: opp based on which the bandwidth levels are to be configured + * + * This configures the bandwidth to the levels specified + * by the OPP. + * + * Return: 0 on success or a negative error value. + */ +int dev_pm_opp_set_bw(struct device *dev, struct dev_pm_opp *opp) +{ + struct opp_table *opp_table; + int ret = -EINVAL; + int i; + + if (IS_ERR_OR_NULL(opp) || !opp->available) { + dev_err(dev, "%s: Invalid parameters\n", __func__); + return -EINVAL; + } + + opp_table = _find_opp_table(dev); + if (IS_ERR(opp_table)) { + dev_err(dev, "%s: device opp table doesn't exist\n", __func__); + return PTR_ERR(opp_table); + } + + if (opp_table->paths) { + for (i = 0; i < opp_table->path_count; i++) { + ret = icc_set_bw(opp_table->paths[i], + opp->bandwidth[i].avg, + opp->bandwidth[i].peak); + if (ret) + dev_err(dev, "Failed to set bandwidth[%d]: %d\n", + i, ret); + } + } + + dev_pm_opp_put_opp_table(opp_table); + return ret; +} +EXPORT_SYMBOL_GPL(dev_pm_opp_set_bw); + +/** * dev_pm_opp_set_rate() - Configure new OPP based on frequency * @dev: device for which we do this operation * @target_freq: frequency to achieve diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 76f8c6b..04f7fda 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -156,6 +156,7 @@ struct dev_pm_opp *dev_pm_opp_xlate_opp(struct opp_table *src_table, struct opp_table *dst_table, struct dev_pm_opp *src_opp); int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); +int dev_pm_opp_set_bw(struct device *dev, struct dev_pm_opp *opp); 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); void dev_pm_opp_remove_table(struct device *dev); @@ -354,6 +355,11 @@ static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_f return -ENOTSUPP; } +static inline int dev_pm_opp_set_bw(struct device *dev, struct dev_pm_opp *opp) +{ + return -ENOTSUPP; +} + static inline int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask) { return -ENOTSUPP; -- 2.7.4