This helper peforms the same function as devfreq_recommended_opp(). However, it works on devices without OPPs by iterating over freq_table. Since freq_table is assumed to be sorted in ascending order, the algorithm is relatively simple. Devices with OPPs should continue using devfreq_recommended_opp(), as that function respects disabled OPPs. Signed-off-by: Samuel Holland <samuel@xxxxxxxxxxxx> --- drivers/devfreq/devfreq.c | 27 +++++++++++++++++++++++++++ include/linux/devfreq.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index f5d27f5285db..fd46792297ad 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -1984,6 +1984,33 @@ subsys_initcall(devfreq_init); * OPP framework. */ +/** + * devfreq_recommended_freq() - Helper function to get the proper frequency from + * freq_table for the value given to target callback. + * @devfreq: The devfreq device. + * @freq: The frequency given to target function. + * @flags: Flags handed from devfreq framework. + */ +void devfreq_recommended_freq(struct devfreq *devfreq, + unsigned long *freq, u32 flags) +{ + const unsigned long *min = devfreq->profile->freq_table; + const unsigned long *max = min + devfreq->profile->max_state - 1; + const unsigned long *f; + + if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) { + /* Find the first item lower than freq, or else min. */ + for (f = max; f > min && *f > *freq; --f) + ; + } else { + /* Find the first item higher than freq, or else max. */ + for (f = min; f < max && *f < *freq; ++f) + ; + } + *freq = *f; +} +EXPORT_SYMBOL(devfreq_recommended_freq); + /** * devfreq_recommended_opp() - Helper function to get proper OPP for the * freq value given to target callback. diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 142474b4af96..4d324fea8a78 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -239,6 +239,8 @@ void devfreq_resume(void); int update_devfreq(struct devfreq *devfreq); /* Helper functions for devfreq user device driver with OPP. */ +void devfreq_recommended_freq(struct devfreq *devfreq, + unsigned long *freq, u32 flags); struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags); int devfreq_register_opp_notifier(struct device *dev, -- 2.31.1