diff options
-rw-r--r-- | drivers/cpufreq/cpufreq_interactive.c | 21 |
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 | ||
37 | static atomic_t active_count = ATOMIC_INIT(0); | 37 | static int active_count; |
38 | 38 | ||
39 | struct cpufreq_interactive_cpuinfo { | 39 | struct 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); | |||
60 | static struct task_struct *speedchange_task; | 60 | static struct task_struct *speedchange_task; |
61 | static cpumask_t speedchange_cpumask; | 61 | static cpumask_t speedchange_cpumask; |
62 | static spinlock_t speedchange_cpumask_lock; | 62 | static spinlock_t speedchange_cpumask_lock; |
63 | static 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) */ |
65 | static unsigned int hispeed_freq; | 66 | static 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"); |