|
@@ -104,9 +104,6 @@ static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
|
|
|
static DEFINE_RWLOCK(cpufreq_driver_lock);
|
|
|
DEFINE_MUTEX(cpufreq_governor_lock);
|
|
|
|
|
|
-/* This one keeps track of the previously set governor of a removed CPU */
|
|
|
-static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
|
|
|
-
|
|
|
/* Flag to suspend/resume CPUFreq governors */
|
|
|
static bool cpufreq_suspended;
|
|
|
|
|
@@ -1017,7 +1014,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy)
|
|
|
memcpy(&new_policy, policy, sizeof(*policy));
|
|
|
|
|
|
/* Update governor of new_policy to the governor used before hotplug */
|
|
|
- gov = find_governor(per_cpu(cpufreq_cpu_governor, policy->cpu));
|
|
|
+ gov = find_governor(policy->last_governor);
|
|
|
if (gov)
|
|
|
pr_debug("Restoring governor %s for cpu %d\n",
|
|
|
policy->governor->name, policy->cpu);
|
|
@@ -1411,14 +1408,15 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
|
|
|
pr_err("%s: Failed to stop governor\n", __func__);
|
|
|
return ret;
|
|
|
}
|
|
|
-
|
|
|
- strncpy(per_cpu(cpufreq_cpu_governor, cpu),
|
|
|
- policy->governor->name, CPUFREQ_NAME_LEN);
|
|
|
}
|
|
|
|
|
|
- down_read(&policy->rwsem);
|
|
|
+ down_write(&policy->rwsem);
|
|
|
cpus = cpumask_weight(policy->cpus);
|
|
|
- up_read(&policy->rwsem);
|
|
|
+
|
|
|
+ if (has_target() && cpus == 1)
|
|
|
+ strncpy(policy->last_governor, policy->governor->name,
|
|
|
+ CPUFREQ_NAME_LEN);
|
|
|
+ up_write(&policy->rwsem);
|
|
|
|
|
|
if (cpu != policy->cpu) {
|
|
|
sysfs_remove_link(&dev->kobj, "cpufreq");
|
|
@@ -2135,7 +2133,8 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor);
|
|
|
|
|
|
void cpufreq_unregister_governor(struct cpufreq_governor *governor)
|
|
|
{
|
|
|
- int cpu;
|
|
|
+ struct cpufreq_policy *policy;
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
if (!governor)
|
|
|
return;
|
|
@@ -2143,12 +2142,13 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor)
|
|
|
if (cpufreq_disabled())
|
|
|
return;
|
|
|
|
|
|
- for_each_present_cpu(cpu) {
|
|
|
- if (cpu_online(cpu))
|
|
|
- continue;
|
|
|
- if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
|
|
|
- strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
|
|
|
+ /* clear last_governor for all inactive policies */
|
|
|
+ read_lock_irqsave(&cpufreq_driver_lock, flags);
|
|
|
+ for_each_inactive_policy(policy) {
|
|
|
+ if (!strcmp(policy->last_governor, governor->name))
|
|
|
+ strcpy(policy->last_governor, "\0");
|
|
|
}
|
|
|
+ read_unlock_irqrestore(&cpufreq_driver_lock, flags);
|
|
|
|
|
|
mutex_lock(&cpufreq_governor_mutex);
|
|
|
list_del(&governor->governor_list);
|