diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2013-04-21 18:48:03 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-04-21 18:48:03 -0400 |
commit | 820c6ca293e99ae225dc9dd7e0e689c444b08f92 (patch) | |
tree | bb4baa6b7e3d27f7495d248ba3e0235470751ac2 /drivers/cpufreq/cpufreq.c | |
parent | 70eb0855b2f8fcf61f9f47626b9fa70e7b45ab06 (diff) |
cpufreq: Don't call __cpufreq_governor() for drivers without target()
Some cpufreq drivers implement their own governor and so don't need
us to call generic governors interface via __cpufreq_governor(). Few
recent commits haven't obeyed this law well and we saw some
regressions.
This patch is an attempt to fix the above issue.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reported-and-tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Tested-by: Dirk Brandewie <dirk.brandewie@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 3564947ea7ac..a6f65954b0ab 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -858,13 +858,18 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, | |||
858 | struct device *dev) | 858 | struct device *dev) |
859 | { | 859 | { |
860 | struct cpufreq_policy *policy; | 860 | struct cpufreq_policy *policy; |
861 | int ret = 0; | 861 | int ret = 0, has_target = 0; |
862 | unsigned long flags; | 862 | unsigned long flags; |
863 | 863 | ||
864 | policy = cpufreq_cpu_get(sibling); | 864 | policy = cpufreq_cpu_get(sibling); |
865 | WARN_ON(!policy); | 865 | WARN_ON(!policy); |
866 | 866 | ||
867 | __cpufreq_governor(policy, CPUFREQ_GOV_STOP); | 867 | rcu_read_lock(); |
868 | has_target = !!rcu_dereference(cpufreq_driver)->target; | ||
869 | rcu_read_unlock(); | ||
870 | |||
871 | if (has_target) | ||
872 | __cpufreq_governor(policy, CPUFREQ_GOV_STOP); | ||
868 | 873 | ||
869 | lock_policy_rwsem_write(sibling); | 874 | lock_policy_rwsem_write(sibling); |
870 | 875 | ||
@@ -877,8 +882,10 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, | |||
877 | 882 | ||
878 | unlock_policy_rwsem_write(sibling); | 883 | unlock_policy_rwsem_write(sibling); |
879 | 884 | ||
880 | __cpufreq_governor(policy, CPUFREQ_GOV_START); | 885 | if (has_target) { |
881 | __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | 886 | __cpufreq_governor(policy, CPUFREQ_GOV_START); |
887 | __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | ||
888 | } | ||
882 | 889 | ||
883 | ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); | 890 | ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); |
884 | if (ret) { | 891 | if (ret) { |
@@ -1146,7 +1153,8 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif | |||
1146 | 1153 | ||
1147 | /* If cpu is last user of policy, free policy */ | 1154 | /* If cpu is last user of policy, free policy */ |
1148 | if (cpus == 1) { | 1155 | if (cpus == 1) { |
1149 | __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); | 1156 | if (has_target) |
1157 | __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); | ||
1150 | 1158 | ||
1151 | lock_policy_rwsem_read(cpu); | 1159 | lock_policy_rwsem_read(cpu); |
1152 | kobj = &data->kobj; | 1160 | kobj = &data->kobj; |