aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/cpufreq_interactive.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index c70ebf53415..7d1952c5cb1 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -34,7 +34,7 @@
34#define CREATE_TRACE_POINTS 34#define CREATE_TRACE_POINTS
35#include <trace/events/cpufreq_interactive.h> 35#include <trace/events/cpufreq_interactive.h>
36 36
37static atomic_t active_count = ATOMIC_INIT(0); 37static int active_count;
38 38
39struct cpufreq_interactive_cpuinfo { 39struct cpufreq_interactive_cpuinfo {
40 struct timer_list cpu_timer; 40 struct timer_list cpu_timer;
@@ -60,6 +60,7 @@ static DEFINE_PER_CPU(struct cpufreq_interactive_cpuinfo, cpuinfo);
60static struct task_struct *speedchange_task; 60static struct task_struct *speedchange_task;
61static cpumask_t speedchange_cpumask; 61static cpumask_t speedchange_cpumask;
62static spinlock_t speedchange_cpumask_lock; 62static spinlock_t speedchange_cpumask_lock;
63static struct mutex gov_lock;
63 64
64/* Hi speed to bump to from lo speed when load burst (default max) */ 65/* Hi speed to bump to from lo speed when load burst (default max) */
65static unsigned int hispeed_freq; 66static unsigned int hispeed_freq;
@@ -913,6 +914,8 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
913 if (!cpu_online(policy->cpu)) 914 if (!cpu_online(policy->cpu))
914 return -EINVAL; 915 return -EINVAL;
915 916
917 mutex_lock(&gov_lock);
918
916 freq_table = 919 freq_table =
917 cpufreq_frequency_get_table(policy->cpu); 920 cpufreq_frequency_get_table(policy->cpu);
918 if (!hispeed_freq) 921 if (!hispeed_freq)
@@ -947,20 +950,26 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
947 * Do not register the idle hook and create sysfs 950 * Do not register the idle hook and create sysfs
948 * entries if we have already done so. 951 * entries if we have already done so.
949 */ 952 */
950 if (atomic_inc_return(&active_count) > 1) 953 if (++active_count > 1) {
954 mutex_unlock(&gov_lock);
951 return 0; 955 return 0;
956 }
952 957
953 rc = sysfs_create_group(cpufreq_global_kobject, 958 rc = sysfs_create_group(cpufreq_global_kobject,
954 &interactive_attr_group); 959 &interactive_attr_group);
955 if (rc) 960 if (rc) {
961 mutex_unlock(&gov_lock);
956 return rc; 962 return rc;
963 }
957 964
958 idle_notifier_register(&cpufreq_interactive_idle_nb); 965 idle_notifier_register(&cpufreq_interactive_idle_nb);
959 cpufreq_register_notifier( 966 cpufreq_register_notifier(
960 &cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); 967 &cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
968 mutex_unlock(&gov_lock);
961 break; 969 break;
962 970
963 case CPUFREQ_GOV_STOP: 971 case CPUFREQ_GOV_STOP:
972 mutex_lock(&gov_lock);
964 for_each_cpu(j, policy->cpus) { 973 for_each_cpu(j, policy->cpus) {
965 pcpu = &per_cpu(cpuinfo, j); 974 pcpu = &per_cpu(cpuinfo, j);
966 down_write(&pcpu->enable_sem); 975 down_write(&pcpu->enable_sem);
@@ -970,14 +979,17 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
970 up_write(&pcpu->enable_sem); 979 up_write(&pcpu->enable_sem);
971 } 980 }
972 981
973 if (atomic_dec_return(&active_count) > 0) 982 if (--active_count > 0) {
983 mutex_unlock(&gov_lock);
974 return 0; 984 return 0;
985 }
975 986
976 cpufreq_unregister_notifier( 987 cpufreq_unregister_notifier(
977 &cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); 988 &cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
978 idle_notifier_unregister(&cpufreq_interactive_idle_nb); 989 idle_notifier_unregister(&cpufreq_interactive_idle_nb);
979 sysfs_remove_group(cpufreq_global_kobject, 990 sysfs_remove_group(cpufreq_global_kobject,
980 &interactive_attr_group); 991 &interactive_attr_group);
992 mutex_unlock(&gov_lock);
981 993
982 break; 994 break;
983 995
@@ -1017,6 +1029,7 @@ static int __init cpufreq_interactive_init(void)
1017 1029
1018 spin_lock_init(&target_loads_lock); 1030 spin_lock_init(&target_loads_lock);
1019 spin_lock_init(&speedchange_cpumask_lock); 1031 spin_lock_init(&speedchange_cpumask_lock);
1032 mutex_init(&gov_lock);
1020 speedchange_task = 1033 speedchange_task =
1021 kthread_create(cpufreq_interactive_speedchange_task, NULL, 1034 kthread_create(cpufreq_interactive_speedchange_task, NULL,
1022 "cfinteractive"); 1035 "cfinteractive");