diff options
author | Javi Merino <javi.merino@arm.com> | 2015-08-17 14:21:43 -0400 |
---|---|---|
committer | Eduardo Valentin <edubezval@gmail.com> | 2015-09-13 23:34:05 -0400 |
commit | eba4f88d5af84e0fcaa5d6eb4fe35a75c47203cb (patch) | |
tree | 06101b245ae62531cdb570117214499285b8b039 | |
parent | 459ac37506d195713b5e82271a2ac44a777e47df (diff) |
thermal: cpu_cooling: free power table on error or when unregistering
The power table is not being freed on error from cpufreq_cooling
register or when unregistering. Free it.
Fixes: c36cf0717631 ("thermal: cpu_cooling: implement the power cooling device API")
Cc: Zhang Rui <rui.zhang@intel.com>
Cc: Eduardo Valentin <edubezval@gmail.com>
Signed-off-by: Javi Merino <javi.merino@arm.com>
Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
-rw-r--r-- | drivers/thermal/cpu_cooling.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index b32755679395..42c6f71bdcc1 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c | |||
@@ -272,7 +272,7 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, | |||
272 | struct power_table *power_table; | 272 | struct power_table *power_table; |
273 | struct dev_pm_opp *opp; | 273 | struct dev_pm_opp *opp; |
274 | struct device *dev = NULL; | 274 | struct device *dev = NULL; |
275 | int num_opps = 0, cpu, i; | 275 | int num_opps = 0, cpu, i, ret = 0; |
276 | unsigned long freq; | 276 | unsigned long freq; |
277 | 277 | ||
278 | for_each_cpu(cpu, &cpufreq_device->allowed_cpus) { | 278 | for_each_cpu(cpu, &cpufreq_device->allowed_cpus) { |
@@ -307,7 +307,8 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, | |||
307 | 307 | ||
308 | if (i >= num_opps) { | 308 | if (i >= num_opps) { |
309 | rcu_read_unlock(); | 309 | rcu_read_unlock(); |
310 | return -EAGAIN; | 310 | ret = -EAGAIN; |
311 | goto free_power_table; | ||
311 | } | 312 | } |
312 | 313 | ||
313 | freq_mhz = freq / 1000000; | 314 | freq_mhz = freq / 1000000; |
@@ -329,14 +330,21 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, | |||
329 | 330 | ||
330 | rcu_read_unlock(); | 331 | rcu_read_unlock(); |
331 | 332 | ||
332 | if (i != num_opps) | 333 | if (i != num_opps) { |
333 | return PTR_ERR(opp); | 334 | ret = PTR_ERR(opp); |
335 | goto free_power_table; | ||
336 | } | ||
334 | 337 | ||
335 | cpufreq_device->cpu_dev = dev; | 338 | cpufreq_device->cpu_dev = dev; |
336 | cpufreq_device->dyn_power_table = power_table; | 339 | cpufreq_device->dyn_power_table = power_table; |
337 | cpufreq_device->dyn_power_table_entries = i; | 340 | cpufreq_device->dyn_power_table_entries = i; |
338 | 341 | ||
339 | return 0; | 342 | return 0; |
343 | |||
344 | free_power_table: | ||
345 | kfree(power_table); | ||
346 | |||
347 | return ret; | ||
340 | } | 348 | } |
341 | 349 | ||
342 | static u32 cpu_freq_to_power(struct cpufreq_cooling_device *cpufreq_device, | 350 | static u32 cpu_freq_to_power(struct cpufreq_cooling_device *cpufreq_device, |
@@ -846,7 +854,7 @@ __cpufreq_cooling_register(struct device_node *np, | |||
846 | ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); | 854 | ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); |
847 | if (ret) { | 855 | if (ret) { |
848 | cool_dev = ERR_PTR(ret); | 856 | cool_dev = ERR_PTR(ret); |
849 | goto free_table; | 857 | goto free_power_table; |
850 | } | 858 | } |
851 | 859 | ||
852 | snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", | 860 | snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", |
@@ -888,6 +896,8 @@ __cpufreq_cooling_register(struct device_node *np, | |||
888 | 896 | ||
889 | remove_idr: | 897 | remove_idr: |
890 | release_idr(&cpufreq_idr, cpufreq_dev->id); | 898 | release_idr(&cpufreq_idr, cpufreq_dev->id); |
899 | free_power_table: | ||
900 | kfree(cpufreq_dev->dyn_power_table); | ||
891 | free_table: | 901 | free_table: |
892 | kfree(cpufreq_dev->freq_table); | 902 | kfree(cpufreq_dev->freq_table); |
893 | free_time_in_idle_timestamp: | 903 | free_time_in_idle_timestamp: |
@@ -1038,6 +1048,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) | |||
1038 | 1048 | ||
1039 | thermal_cooling_device_unregister(cpufreq_dev->cool_dev); | 1049 | thermal_cooling_device_unregister(cpufreq_dev->cool_dev); |
1040 | release_idr(&cpufreq_idr, cpufreq_dev->id); | 1050 | release_idr(&cpufreq_idr, cpufreq_dev->id); |
1051 | kfree(cpufreq_dev->dyn_power_table); | ||
1041 | kfree(cpufreq_dev->time_in_idle_timestamp); | 1052 | kfree(cpufreq_dev->time_in_idle_timestamp); |
1042 | kfree(cpufreq_dev->time_in_idle); | 1053 | kfree(cpufreq_dev->time_in_idle); |
1043 | kfree(cpufreq_dev->freq_table); | 1054 | kfree(cpufreq_dev->freq_table); |