diff options
author | Niklas Cassel <niklas.cassel@linaro.org> | 2019-07-25 06:41:29 -0400 |
---|---|---|
committer | Viresh Kumar <viresh.kumar@linaro.org> | 2019-07-26 03:54:59 -0400 |
commit | 71419d84c216cee8da3b19fb843b4242f112cde4 (patch) | |
tree | 8826c9954f665303de987231a2498b14324e0d27 | |
parent | 17a8f868ae3e85a173843b1ac65e744e8585bc5a (diff) |
opp: Add dev_pm_opp_find_level_exact()
Since the performance states in the OPP table are unique, implement a
dev_pm_opp_find_level_exact() in order to be able to fetch a specific OPP.
Signed-off-by: Niklas Cassel <niklas.cassel@linaro.org>
[ Viresh: Updated commit log ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
-rw-r--r-- | drivers/opp/core.c | 48 | ||||
-rw-r--r-- | include/linux/pm_opp.h | 8 |
2 files changed, 56 insertions, 0 deletions
diff --git a/drivers/opp/core.c b/drivers/opp/core.c index bdb435822401..0ee8c0133d3e 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c | |||
@@ -401,6 +401,54 @@ struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, | |||
401 | } | 401 | } |
402 | EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); | 402 | EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); |
403 | 403 | ||
404 | /** | ||
405 | * dev_pm_opp_find_level_exact() - search for an exact level | ||
406 | * @dev: device for which we do this operation | ||
407 | * @level: level to search for | ||
408 | * | ||
409 | * Return: Searches for exact match in the opp table and returns pointer to the | ||
410 | * matching opp if found, else returns ERR_PTR in case of error and should | ||
411 | * be handled using IS_ERR. Error return values can be: | ||
412 | * EINVAL: for bad pointer | ||
413 | * ERANGE: no match found for search | ||
414 | * ENODEV: if device not found in list of registered devices | ||
415 | * | ||
416 | * The callers are required to call dev_pm_opp_put() for the returned OPP after | ||
417 | * use. | ||
418 | */ | ||
419 | struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, | ||
420 | unsigned int level) | ||
421 | { | ||
422 | struct opp_table *opp_table; | ||
423 | struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); | ||
424 | |||
425 | opp_table = _find_opp_table(dev); | ||
426 | if (IS_ERR(opp_table)) { | ||
427 | int r = PTR_ERR(opp_table); | ||
428 | |||
429 | dev_err(dev, "%s: OPP table not found (%d)\n", __func__, r); | ||
430 | return ERR_PTR(r); | ||
431 | } | ||
432 | |||
433 | mutex_lock(&opp_table->lock); | ||
434 | |||
435 | list_for_each_entry(temp_opp, &opp_table->opp_list, node) { | ||
436 | if (temp_opp->level == level) { | ||
437 | opp = temp_opp; | ||
438 | |||
439 | /* Increment the reference count of OPP */ | ||
440 | dev_pm_opp_get(opp); | ||
441 | break; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | mutex_unlock(&opp_table->lock); | ||
446 | dev_pm_opp_put_opp_table(opp_table); | ||
447 | |||
448 | return opp; | ||
449 | } | ||
450 | EXPORT_SYMBOL_GPL(dev_pm_opp_find_level_exact); | ||
451 | |||
404 | static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_table, | 452 | static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_table, |
405 | unsigned long *freq) | 453 | unsigned long *freq) |
406 | { | 454 | { |
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 5bdceca5125d..b8197ab014f2 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h | |||
@@ -96,6 +96,8 @@ unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev); | |||
96 | struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, | 96 | struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, |
97 | unsigned long freq, | 97 | unsigned long freq, |
98 | bool available); | 98 | bool available); |
99 | struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, | ||
100 | unsigned int level); | ||
99 | 101 | ||
100 | struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, | 102 | struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, |
101 | unsigned long *freq); | 103 | unsigned long *freq); |
@@ -200,6 +202,12 @@ static inline struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, | |||
200 | return ERR_PTR(-ENOTSUPP); | 202 | return ERR_PTR(-ENOTSUPP); |
201 | } | 203 | } |
202 | 204 | ||
205 | static inline struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, | ||
206 | unsigned int level) | ||
207 | { | ||
208 | return ERR_PTR(-ENOTSUPP); | ||
209 | } | ||
210 | |||
203 | static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, | 211 | static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, |
204 | unsigned long *freq) | 212 | unsigned long *freq) |
205 | { | 213 | { |