aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/opp/core.c
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2016-02-09 00:00:35 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-02-09 19:11:53 -0500
commit655c9df961751ce21466f6e97e8033932c27a675 (patch)
tree948ced554152d5599dfe92c0aa24dab3db7f8aa1 /drivers/base/power/opp/core.c
parent7d34d56ef3349cd5f29cf7aab6650f3414fa81b9 (diff)
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>
Diffstat (limited to 'drivers/base/power/opp/core.c')
-rw-r--r--drivers/base/power/opp/core.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
index 71545becfca1..ffe2406af882 100644
--- a/drivers/base/power/opp/core.c
+++ b/drivers/base/power/opp/core.c
@@ -231,6 +231,65 @@ unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev)
231EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_clock_latency); 231EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_clock_latency);
232 232
233/** 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 */
241unsigned 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}
290EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_volt_latency);
291
292/**
234 * dev_pm_opp_get_suspend_opp() - Get suspend opp 293 * dev_pm_opp_get_suspend_opp() - Get suspend opp
235 * @dev: device for which we do this operation 294 * @dev: device for which we do this operation
236 * 295 *