|
@@ -50,15 +50,14 @@ struct cpufreq_cooling_device {
|
|
|
unsigned int cpufreq_state;
|
|
|
unsigned int cpufreq_val;
|
|
|
struct cpumask allowed_cpus;
|
|
|
+ struct list_head node;
|
|
|
};
|
|
|
static DEFINE_IDR(cpufreq_idr);
|
|
|
static DEFINE_MUTEX(cooling_cpufreq_lock);
|
|
|
|
|
|
static unsigned int cpufreq_dev_count;
|
|
|
|
|
|
-/* notify_table passes value to the CPUFREQ_ADJUST callback function. */
|
|
|
-#define NOTIFY_INVALID NULL
|
|
|
-static struct cpufreq_cooling_device *notify_device;
|
|
|
+static LIST_HEAD(cpufreq_dev_list);
|
|
|
|
|
|
/**
|
|
|
* get_idr - function to get a unique id.
|
|
@@ -287,15 +286,12 @@ static int cpufreq_apply_cooling(struct cpufreq_cooling_device *cpufreq_device,
|
|
|
|
|
|
cpufreq_device->cpufreq_state = cooling_state;
|
|
|
cpufreq_device->cpufreq_val = clip_freq;
|
|
|
- notify_device = cpufreq_device;
|
|
|
|
|
|
for_each_cpu(cpuid, mask) {
|
|
|
if (is_cpufreq_valid(cpuid))
|
|
|
cpufreq_update_policy(cpuid);
|
|
|
}
|
|
|
|
|
|
- notify_device = NOTIFY_INVALID;
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -316,21 +312,28 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
|
|
|
{
|
|
|
struct cpufreq_policy *policy = data;
|
|
|
unsigned long max_freq = 0;
|
|
|
+ struct cpufreq_cooling_device *cpufreq_dev;
|
|
|
|
|
|
- if (event != CPUFREQ_ADJUST || notify_device == NOTIFY_INVALID)
|
|
|
+ if (event != CPUFREQ_ADJUST)
|
|
|
return 0;
|
|
|
|
|
|
- if (cpumask_test_cpu(policy->cpu, ¬ify_device->allowed_cpus))
|
|
|
- max_freq = notify_device->cpufreq_val;
|
|
|
- else
|
|
|
- return 0;
|
|
|
+ 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;
|
|
|
+
|
|
|
+ if (!cpufreq_dev->cpufreq_val)
|
|
|
+ cpufreq_dev->cpufreq_val = get_cpu_frequency(
|
|
|
+ cpumask_any(&cpufreq_dev->allowed_cpus),
|
|
|
+ cpufreq_dev->cpufreq_state);
|
|
|
|
|
|
- /* Never exceed user_policy.max */
|
|
|
- if (max_freq > policy->user_policy.max)
|
|
|
- max_freq = policy->user_policy.max;
|
|
|
+ max_freq = cpufreq_dev->cpufreq_val;
|
|
|
|
|
|
- if (policy->max != max_freq)
|
|
|
- cpufreq_verify_within_limits(policy, 0, max_freq);
|
|
|
+ if (policy->max != max_freq)
|
|
|
+ cpufreq_verify_within_limits(policy, 0, max_freq);
|
|
|
+ }
|
|
|
+ mutex_unlock(&cooling_cpufreq_lock);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -486,6 +489,7 @@ __cpufreq_cooling_register(struct device_node *np,
|
|
|
cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
|
|
|
CPUFREQ_POLICY_NOTIFIER);
|
|
|
cpufreq_dev_count++;
|
|
|
+ list_add(&cpufreq_dev->node, &cpufreq_dev_list);
|
|
|
|
|
|
mutex_unlock(&cooling_cpufreq_lock);
|
|
|
|
|
@@ -549,6 +553,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
|
|
|
|
|
|
cpufreq_dev = cdev->devdata;
|
|
|
mutex_lock(&cooling_cpufreq_lock);
|
|
|
+ list_del(&cpufreq_dev->node);
|
|
|
cpufreq_dev_count--;
|
|
|
|
|
|
/* Unregister the notifier for the last cpufreq cooling device */
|