Skip to content

Commit 525680c

Browse files
vireshkAlex Shi
authored andcommitted
PM / OPP: Introduce dev_pm_opp_get_max_volt_latency()
In few use cases (like: cpufreq), it is desired to get the maximum voltage latency for changing OPPs. Add support for that. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> (cherry picked from commit 655c9df961751ce21466f6e97e8033932c27a675) Signed-off-by: Alex Shi <alex.shi@linaro.org>
1 parent c3fae6d commit 525680c

2 files changed

Lines changed: 65 additions & 0 deletions

File tree

drivers/base/power/opp/core.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,65 @@ unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev)
230230
}
231231
EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_clock_latency);
232232

233+
/**
234+
* dev_pm_opp_get_max_volt_latency() - Get max voltage latency in nanoseconds
235+
* @dev: device for which we do this operation
236+
*
237+
* Return: This function returns the max voltage latency in nanoseconds.
238+
*
239+
* Locking: This function takes rcu_read_lock().
240+
*/
241+
unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev)
242+
{
243+
struct device_opp *dev_opp;
244+
struct dev_pm_opp *opp;
245+
struct regulator *reg;
246+
unsigned long latency_ns = 0;
247+
unsigned long min_uV = ~0, max_uV = 0;
248+
int ret;
249+
250+
rcu_read_lock();
251+
252+
dev_opp = _find_device_opp(dev);
253+
if (IS_ERR(dev_opp)) {
254+
rcu_read_unlock();
255+
return 0;
256+
}
257+
258+
reg = dev_opp->regulator;
259+
if (IS_ERR_OR_NULL(reg)) {
260+
/* Regulator may not be required for device */
261+
if (reg)
262+
dev_err(dev, "%s: Invalid regulator (%ld)\n", __func__,
263+
PTR_ERR(reg));
264+
rcu_read_unlock();
265+
return 0;
266+
}
267+
268+
list_for_each_entry_rcu(opp, &dev_opp->opp_list, node) {
269+
if (!opp->available)
270+
continue;
271+
272+
if (opp->u_volt_min < min_uV)
273+
min_uV = opp->u_volt_min;
274+
if (opp->u_volt_max > max_uV)
275+
max_uV = opp->u_volt_max;
276+
}
277+
278+
rcu_read_unlock();
279+
280+
/*
281+
* The caller needs to ensure that dev_opp (and hence the regulator)
282+
* isn't freed, while we are executing this routine.
283+
*/
284+
ret = regulator_set_voltage_time(reg, min_uV, max_uV);
285+
if (ret > 0)
286+
latency_ns = ret * 1000;
287+
288+
return latency_ns;
289+
}
290+
EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_volt_latency);
291+
233292
/**
234293
* dev_pm_opp_get_suspend_opp() - Get suspend opp
235294
* @dev: device for which we do this operation

include/linux/pm_opp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp);
3434

3535
int dev_pm_opp_get_opp_count(struct device *dev);
3636
unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev);
37+
unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev);
3738
struct dev_pm_opp *dev_pm_opp_get_suspend_opp(struct device *dev);
3839

3940
struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev,
@@ -88,6 +89,11 @@ static inline unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev)
8889
return 0;
8990
}
9091

92+
static inline unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev)
93+
{
94+
return 0;
95+
}
96+
9197
static inline struct dev_pm_opp *dev_pm_opp_get_suspend_opp(struct device *dev)
9298
{
9399
return NULL;

0 commit comments

Comments
 (0)