CPU frequency tables don't update after the driver is registered and so we don't need to iterate over them to find total number of states every time cpufreq_get_max_state() is called. Do it once at boot time.
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/thermal/cpu_cooling.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 5815abf..05712d5 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -52,6 +52,8 @@ * cooling devices. * @cpufreq_val: integer value representing the absolute value of the clipped * frequency. + * @max_level: maximum cooling level. One less than total number of valid + * cpufreq frequencies. * @allowed_cpus: all the cpus involved for this cpufreq_cooling_device. * * This structure is required for keeping information of each registered @@ -62,6 +64,7 @@ struct cpufreq_cooling_device { struct thermal_cooling_device *cool_dev; unsigned int cpufreq_state; unsigned int cpufreq_val; + unsigned int max_level; struct cpumask allowed_cpus; }; static DEFINE_IDR(cpufreq_idr); @@ -246,19 +249,9 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) { struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; - struct cpumask *mask = &cpufreq_device->allowed_cpus; - unsigned int cpu; - unsigned int count = 0; - int ret;
- cpu = cpumask_any(mask); - - ret = get_property(cpu, 0, &count, GET_MAXL); - - if (count > 0) - *state = count; - - return ret; + *state = cpufreq_device->max_level; + return 0; }
/** @@ -351,11 +344,25 @@ __cpufreq_cooling_register(struct device_node *np, struct thermal_cooling_device *cool_dev; struct cpufreq_cooling_device *cpufreq_dev; char dev_name[THERMAL_NAME_LENGTH]; + struct cpufreq_frequency_table *pos, *table; + + table = cpufreq_frequency_get_table(cpumask_first(clip_cpus)); + if (!table) { + pr_debug("%s: CPUFreq table not found\n", __func__); + return ERR_PTR(-EPROBE_DEFER); + }
cpufreq_dev = kzalloc(sizeof(*cool_dev), GFP_KERNEL); if (!cpufreq_dev) return ERR_PTR(-ENOMEM);
+ /* Find max levels */ + cpufreq_for_each_valid_entry(pos, table) + cpufreq_dev->max_level++; + + /* max_level is an index, not a counter */ + cpufreq_dev->max_level--; + cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus);
cpufreq_dev->id = idr_alloc(&cpufreq_idr, NULL, 0, 0, GFP_KERNEL);