diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index f8c28607ccd6..43cf60832468 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -49,6 +49,7 @@ static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); | |||
49 | static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); | 49 | static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); |
50 | #endif | 50 | #endif |
51 | static DEFINE_RWLOCK(cpufreq_driver_lock); | 51 | static DEFINE_RWLOCK(cpufreq_driver_lock); |
52 | static DEFINE_MUTEX(cpufreq_governor_lock); | ||
52 | 53 | ||
53 | /* | 54 | /* |
54 | * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure | 55 | * 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, | |||
1635 | 1636 | ||
1636 | pr_debug("__cpufreq_governor for CPU %u, event %u\n", | 1637 | pr_debug("__cpufreq_governor for CPU %u, event %u\n", |
1637 | policy->cpu, event); | 1638 | policy->cpu, event); |
1639 | |||
1640 | mutex_lock(&cpufreq_governor_lock); | ||
1641 | if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) || | ||
1642 | (policy->governor_enabled && (event == CPUFREQ_GOV_START))) { | ||
1643 | mutex_unlock(&cpufreq_governor_lock); | ||
1644 | return -EBUSY; | ||
1645 | } | ||
1646 | |||
1647 | if (event == CPUFREQ_GOV_STOP) | ||
1648 | policy->governor_enabled = false; | ||
1649 | else if (event == CPUFREQ_GOV_START) | ||
1650 | policy->governor_enabled = true; | ||
1651 | |||
1652 | mutex_unlock(&cpufreq_governor_lock); | ||
1653 | |||
1638 | ret = policy->governor->governor(policy, event); | 1654 | ret = policy->governor->governor(policy, event); |
1639 | 1655 | ||
1640 | if (!ret) { | 1656 | if (!ret) { |
@@ -1642,6 +1658,14 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, | |||
1642 | policy->governor->initialized++; | 1658 | policy->governor->initialized++; |
1643 | else if (event == CPUFREQ_GOV_POLICY_EXIT) | 1659 | else if (event == CPUFREQ_GOV_POLICY_EXIT) |
1644 | policy->governor->initialized--; | 1660 | policy->governor->initialized--; |
1661 | } else { | ||
1662 | /* Restore original values */ | ||
1663 | mutex_lock(&cpufreq_governor_lock); | ||
1664 | if (event == CPUFREQ_GOV_STOP) | ||
1665 | policy->governor_enabled = true; | ||
1666 | else if (event == CPUFREQ_GOV_START) | ||
1667 | policy->governor_enabled = false; | ||
1668 | mutex_unlock(&cpufreq_governor_lock); | ||
1645 | } | 1669 | } |
1646 | 1670 | ||
1647 | /* we keep one module reference alive for | 1671 | /* we keep one module reference alive for |