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
This commit is contained in:
commit
3bd8f7d87d
@ -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 {
|
|||||||
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 {
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
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)
|
||||||
|
|
||||||
case CPUFREQ_ADJUST:
|
|
||||||
mutex_lock(&cooling_cpufreq_lock);
|
|
||||||
list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
|
|
||||||
if (!cpumask_test_cpu(policy->cpu,
|
|
||||||
&cpufreq_dev->allowed_cpus))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
max_freq = cpufreq_dev->cpufreq_val;
|
|
||||||
|
|
||||||
if (policy->max != max_freq)
|
|
||||||
cpufreq_verify_within_limits(policy, 0,
|
|
||||||
max_freq);
|
|
||||||
}
|
|
||||||
mutex_unlock(&cooling_cpufreq_lock);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
|
mutex_lock(&cooling_list_lock);
|
||||||
|
list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
|
||||||
|
if (!cpumask_test_cpu(policy->cpu, &cpufreq_dev->allowed_cpus))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 > clipped_freq)
|
||||||
|
cpufreq_verify_within_limits(policy, 0, clipped_freq);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user