Commit 3bd8f7d8 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal

Pull thermal fixes from Eduardo Valentin:
 "Last minute fixes on the thermal-soc tree.  There is a fix of a long
  lasting bug in cpu cooling device, thanks for RMK for being pushing
  this"

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal:
  thermal/cpu_cooling: update policy limits if clipped_freq < policy->max
  thermal/cpu_cooling: rename max_freq as clipped_freq in notifier
  thermal/cpu_cooling: rename cpufreq_val as clipped_freq
  thermal/cpu_cooling: convert 'switch' block to 'if' block in notifier
  thermal/cpu_cooling: quit early after updating policy
  thermal/cpu_cooling: No need to initialize max_freq to 0
  thermal: cpu_cooling: fix lockdep problems in cpu_cooling
  thermal: power_allocator: do not use devm* interfaces
parents 1b647a16 1afb9c53
...@@ -68,7 +68,7 @@ struct power_table { ...@@ -68,7 +68,7 @@ struct power_table {
* registered cooling device. * registered cooling device.
* @cpufreq_state: integer value representing the current state of cpufreq * @cpufreq_state: integer value representing the current state of cpufreq
* cooling devices. * cooling devices.
* @cpufreq_val: integer value representing the absolute value of the clipped * @clipped_freq: integer value representing the absolute value of the clipped
* frequency. * frequency.
* @max_level: maximum cooling level. One less than total number of valid * @max_level: maximum cooling level. One less than total number of valid
* cpufreq frequencies. * cpufreq frequencies.
...@@ -91,7 +91,7 @@ struct cpufreq_cooling_device { ...@@ -91,7 +91,7 @@ struct cpufreq_cooling_device {
int id; int id;
struct thermal_cooling_device *cool_dev; struct thermal_cooling_device *cool_dev;
unsigned int cpufreq_state; unsigned int cpufreq_state;
unsigned int cpufreq_val; unsigned int clipped_freq;
unsigned int max_level; unsigned int max_level;
unsigned int *freq_table; /* In descending order */ unsigned int *freq_table; /* In descending order */
struct cpumask allowed_cpus; struct cpumask allowed_cpus;
...@@ -107,6 +107,9 @@ struct cpufreq_cooling_device { ...@@ -107,6 +107,9 @@ struct cpufreq_cooling_device {
static DEFINE_IDR(cpufreq_idr); static DEFINE_IDR(cpufreq_idr);
static DEFINE_MUTEX(cooling_cpufreq_lock); static DEFINE_MUTEX(cooling_cpufreq_lock);
static unsigned int cpufreq_dev_count;
static DEFINE_MUTEX(cooling_list_lock);
static LIST_HEAD(cpufreq_dev_list); static LIST_HEAD(cpufreq_dev_list);
/** /**
...@@ -185,14 +188,14 @@ unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq) ...@@ -185,14 +188,14 @@ unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq)
{ {
struct cpufreq_cooling_device *cpufreq_dev; struct cpufreq_cooling_device *cpufreq_dev;
mutex_lock(&cooling_cpufreq_lock); mutex_lock(&cooling_list_lock);
list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) { list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
if (cpumask_test_cpu(cpu, &cpufreq_dev->allowed_cpus)) { if (cpumask_test_cpu(cpu, &cpufreq_dev->allowed_cpus)) {
mutex_unlock(&cooling_cpufreq_lock); mutex_unlock(&cooling_list_lock);
return get_level(cpufreq_dev, freq); return get_level(cpufreq_dev, freq);
} }
} }
mutex_unlock(&cooling_cpufreq_lock); mutex_unlock(&cooling_list_lock);
pr_err("%s: cpu:%d not part of any cooling device\n", __func__, cpu); pr_err("%s: cpu:%d not part of any cooling device\n", __func__, cpu);
return THERMAL_CSTATE_INVALID; return THERMAL_CSTATE_INVALID;
...@@ -215,29 +218,35 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb, ...@@ -215,29 +218,35 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
unsigned long event, void *data) unsigned long event, void *data)
{ {
struct cpufreq_policy *policy = data; struct cpufreq_policy *policy = data;
unsigned long max_freq = 0; unsigned long clipped_freq;
struct cpufreq_cooling_device *cpufreq_dev; struct cpufreq_cooling_device *cpufreq_dev;
switch (event) { if (event != CPUFREQ_ADJUST)
return NOTIFY_DONE;
case CPUFREQ_ADJUST: mutex_lock(&cooling_list_lock);
mutex_lock(&cooling_cpufreq_lock);
list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) { list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
if (!cpumask_test_cpu(policy->cpu, if (!cpumask_test_cpu(policy->cpu, &cpufreq_dev->allowed_cpus))
&cpufreq_dev->allowed_cpus))
continue; continue;
max_freq = cpufreq_dev->cpufreq_val; /*
* policy->max is the maximum allowed frequency defined by user
* and clipped_freq is the maximum that thermal constraints
* allow.
*
* If clipped_freq is lower than policy->max, then we need to
* readjust policy->max.
*
* But, if clipped_freq is greater than policy->max, we don't
* need to do anything.
*/
clipped_freq = cpufreq_dev->clipped_freq;
if (policy->max != max_freq) if (policy->max > clipped_freq)
cpufreq_verify_within_limits(policy, 0, cpufreq_verify_within_limits(policy, 0, clipped_freq);
max_freq);
}
mutex_unlock(&cooling_cpufreq_lock);
break; break;
default:
return NOTIFY_DONE;
} }
mutex_unlock(&cooling_list_lock);
return NOTIFY_OK; return NOTIFY_OK;
} }
...@@ -519,7 +528,7 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, ...@@ -519,7 +528,7 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
clip_freq = cpufreq_device->freq_table[state]; clip_freq = cpufreq_device->freq_table[state];
cpufreq_device->cpufreq_state = state; cpufreq_device->cpufreq_state = state;
cpufreq_device->cpufreq_val = clip_freq; cpufreq_device->clipped_freq = clip_freq;
cpufreq_update_policy(cpu); cpufreq_update_policy(cpu);
...@@ -861,17 +870,19 @@ __cpufreq_cooling_register(struct device_node *np, ...@@ -861,17 +870,19 @@ __cpufreq_cooling_register(struct device_node *np,
pr_debug("%s: freq:%u KHz\n", __func__, freq); pr_debug("%s: freq:%u KHz\n", __func__, freq);
} }
cpufreq_dev->cpufreq_val = cpufreq_dev->freq_table[0]; cpufreq_dev->clipped_freq = cpufreq_dev->freq_table[0];
cpufreq_dev->cool_dev = cool_dev; cpufreq_dev->cool_dev = cool_dev;
mutex_lock(&cooling_cpufreq_lock); mutex_lock(&cooling_cpufreq_lock);
mutex_lock(&cooling_list_lock);
list_add(&cpufreq_dev->node, &cpufreq_dev_list);
mutex_unlock(&cooling_list_lock);
/* Register the notifier for first cpufreq cooling device */ /* Register the notifier for first cpufreq cooling device */
if (list_empty(&cpufreq_dev_list)) if (!cpufreq_dev_count++)
cpufreq_register_notifier(&thermal_cpufreq_notifier_block, cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
CPUFREQ_POLICY_NOTIFIER); CPUFREQ_POLICY_NOTIFIER);
list_add(&cpufreq_dev->node, &cpufreq_dev_list);
mutex_unlock(&cooling_cpufreq_lock); mutex_unlock(&cooling_cpufreq_lock);
return cool_dev; return cool_dev;
...@@ -1013,13 +1024,17 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) ...@@ -1013,13 +1024,17 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
return; return;
cpufreq_dev = cdev->devdata; cpufreq_dev = cdev->devdata;
mutex_lock(&cooling_cpufreq_lock);
list_del(&cpufreq_dev->node);
/* Unregister the notifier for the last cpufreq cooling device */ /* Unregister the notifier for the last cpufreq cooling device */
if (list_empty(&cpufreq_dev_list)) mutex_lock(&cooling_cpufreq_lock);
if (!--cpufreq_dev_count)
cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
CPUFREQ_POLICY_NOTIFIER); CPUFREQ_POLICY_NOTIFIER);
mutex_lock(&cooling_list_lock);
list_del(&cpufreq_dev->node);
mutex_unlock(&cooling_list_lock);
mutex_unlock(&cooling_cpufreq_lock); mutex_unlock(&cooling_cpufreq_lock);
thermal_cooling_device_unregister(cpufreq_dev->cool_dev); thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
......
...@@ -334,7 +334,7 @@ static int allocate_power(struct thermal_zone_device *tz, ...@@ -334,7 +334,7 @@ static int allocate_power(struct thermal_zone_device *tz,
max_allocatable_power, current_temp, max_allocatable_power, current_temp,
(s32)control_temp - (s32)current_temp); (s32)control_temp - (s32)current_temp);
devm_kfree(&tz->device, req_power); kfree(req_power);
unlock: unlock:
mutex_unlock(&tz->lock); mutex_unlock(&tz->lock);
...@@ -426,7 +426,7 @@ static int power_allocator_bind(struct thermal_zone_device *tz) ...@@ -426,7 +426,7 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
return -EINVAL; return -EINVAL;
} }
params = devm_kzalloc(&tz->device, sizeof(*params), GFP_KERNEL); params = kzalloc(sizeof(*params), GFP_KERNEL);
if (!params) if (!params)
return -ENOMEM; return -ENOMEM;
...@@ -468,14 +468,14 @@ static int power_allocator_bind(struct thermal_zone_device *tz) ...@@ -468,14 +468,14 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
return 0; return 0;
free: free:
devm_kfree(&tz->device, params); kfree(params);
return ret; return ret;
} }
static void power_allocator_unbind(struct thermal_zone_device *tz) static void power_allocator_unbind(struct thermal_zone_device *tz)
{ {
dev_dbg(&tz->device, "Unbinding from thermal zone %d\n", tz->id); dev_dbg(&tz->device, "Unbinding from thermal zone %d\n", tz->id);
devm_kfree(&tz->device, tz->governor_data); kfree(tz->governor_data);
tz->governor_data = NULL; tz->governor_data = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment