|
@@ -49,6 +49,7 @@ static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
|
|
|
static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
|
|
|
#endif
|
|
|
static DEFINE_RWLOCK(cpufreq_driver_lock);
|
|
|
+static DEFINE_MUTEX(cpufreq_governor_lock);
|
|
|
|
|
|
/*
|
|
|
* cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
|
|
@@ -1635,6 +1636,21 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
|
|
|
|
|
|
pr_debug("__cpufreq_governor for CPU %u, event %u\n",
|
|
|
policy->cpu, event);
|
|
|
+
|
|
|
+ mutex_lock(&cpufreq_governor_lock);
|
|
|
+ if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
|
|
|
+ (policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
|
|
|
+ mutex_unlock(&cpufreq_governor_lock);
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (event == CPUFREQ_GOV_STOP)
|
|
|
+ policy->governor_enabled = false;
|
|
|
+ else if (event == CPUFREQ_GOV_START)
|
|
|
+ policy->governor_enabled = true;
|
|
|
+
|
|
|
+ mutex_unlock(&cpufreq_governor_lock);
|
|
|
+
|
|
|
ret = policy->governor->governor(policy, event);
|
|
|
|
|
|
if (!ret) {
|
|
@@ -1642,6 +1658,14 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
|
|
|
policy->governor->initialized++;
|
|
|
else if (event == CPUFREQ_GOV_POLICY_EXIT)
|
|
|
policy->governor->initialized--;
|
|
|
+ } else {
|
|
|
+ /* Restore original values */
|
|
|
+ mutex_lock(&cpufreq_governor_lock);
|
|
|
+ if (event == CPUFREQ_GOV_STOP)
|
|
|
+ policy->governor_enabled = true;
|
|
|
+ else if (event == CPUFREQ_GOV_START)
|
|
|
+ policy->governor_enabled = false;
|
|
|
+ mutex_unlock(&cpufreq_governor_lock);
|
|
|
}
|
|
|
|
|
|
/* we keep one module reference alive for
|