aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r--drivers/cpufreq/cpufreq.c58
1 files changed, 26 insertions, 32 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 08ca8c9f41cd..199b52b7c3e1 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1109,12 +1109,27 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1109 goto err_set_policy_cpu; 1109 goto err_set_policy_cpu;
1110 } 1110 }
1111 1111
1112 /* related cpus should atleast have policy->cpus */
1113 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
1114
1115 /*
1116 * affected cpus must always be the one, which are online. We aren't
1117 * managing offline cpus here.
1118 */
1119 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
1120
1121 if (!frozen) {
1122 policy->user_policy.min = policy->min;
1123 policy->user_policy.max = policy->max;
1124 }
1125
1126 down_write(&policy->rwsem);
1112 write_lock_irqsave(&cpufreq_driver_lock, flags); 1127 write_lock_irqsave(&cpufreq_driver_lock, flags);
1113 for_each_cpu(j, policy->cpus) 1128 for_each_cpu(j, policy->cpus)
1114 per_cpu(cpufreq_cpu_data, j) = policy; 1129 per_cpu(cpufreq_cpu_data, j) = policy;
1115 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 1130 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1116 1131
1117 if (cpufreq_driver->get) { 1132 if (cpufreq_driver->get && !cpufreq_driver->setpolicy) {
1118 policy->cur = cpufreq_driver->get(policy->cpu); 1133 policy->cur = cpufreq_driver->get(policy->cpu);
1119 if (!policy->cur) { 1134 if (!policy->cur) {
1120 pr_err("%s: ->get() failed\n", __func__); 1135 pr_err("%s: ->get() failed\n", __func__);
@@ -1162,20 +1177,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1162 } 1177 }
1163 } 1178 }
1164 1179
1165 /* related cpus should atleast have policy->cpus */
1166 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
1167
1168 /*
1169 * affected cpus must always be the one, which are online. We aren't
1170 * managing offline cpus here.
1171 */
1172 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
1173
1174 if (!frozen) {
1175 policy->user_policy.min = policy->min;
1176 policy->user_policy.max = policy->max;
1177 }
1178
1179 blocking_notifier_call_chain(&cpufreq_policy_notifier_list, 1180 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1180 CPUFREQ_START, policy); 1181 CPUFREQ_START, policy);
1181 1182
@@ -1206,6 +1207,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1206 policy->user_policy.policy = policy->policy; 1207 policy->user_policy.policy = policy->policy;
1207 policy->user_policy.governor = policy->governor; 1208 policy->user_policy.governor = policy->governor;
1208 } 1209 }
1210 up_write(&policy->rwsem);
1209 1211
1210 kobject_uevent(&policy->kobj, KOBJ_ADD); 1212 kobject_uevent(&policy->kobj, KOBJ_ADD);
1211 up_read(&cpufreq_rwsem); 1213 up_read(&cpufreq_rwsem);
@@ -1323,8 +1325,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
1323 up_read(&policy->rwsem); 1325 up_read(&policy->rwsem);
1324 1326
1325 if (cpu != policy->cpu) { 1327 if (cpu != policy->cpu) {
1326 if (!frozen) 1328 sysfs_remove_link(&dev->kobj, "cpufreq");
1327 sysfs_remove_link(&dev->kobj, "cpufreq");
1328 } else if (cpus > 1) { 1329 } else if (cpus > 1) {
1329 new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu); 1330 new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu);
1330 if (new_cpu >= 0) { 1331 if (new_cpu >= 0) {
@@ -1547,23 +1548,16 @@ static unsigned int __cpufreq_get(unsigned int cpu)
1547 */ 1548 */
1548unsigned int cpufreq_get(unsigned int cpu) 1549unsigned int cpufreq_get(unsigned int cpu)
1549{ 1550{
1550 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); 1551 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1551 unsigned int ret_freq = 0; 1552 unsigned int ret_freq = 0;
1552 1553
1553 if (cpufreq_disabled() || !cpufreq_driver) 1554 if (policy) {
1554 return -ENOENT; 1555 down_read(&policy->rwsem);
1555 1556 ret_freq = __cpufreq_get(cpu);
1556 BUG_ON(!policy); 1557 up_read(&policy->rwsem);
1557
1558 if (!down_read_trylock(&cpufreq_rwsem))
1559 return 0;
1560
1561 down_read(&policy->rwsem);
1562
1563 ret_freq = __cpufreq_get(cpu);
1564 1558
1565 up_read(&policy->rwsem); 1559 cpufreq_cpu_put(policy);
1566 up_read(&cpufreq_rwsem); 1560 }
1567 1561
1568 return ret_freq; 1562 return ret_freq;
1569} 1563}
@@ -2149,7 +2143,7 @@ int cpufreq_update_policy(unsigned int cpu)
2149 * BIOS might change freq behind our back 2143 * BIOS might change freq behind our back
2150 * -> ask driver for current freq and notify governors about a change 2144 * -> ask driver for current freq and notify governors about a change
2151 */ 2145 */
2152 if (cpufreq_driver->get) { 2146 if (cpufreq_driver->get && !cpufreq_driver->setpolicy) {
2153 new_policy.cur = cpufreq_driver->get(cpu); 2147 new_policy.cur = cpufreq_driver->get(cpu);
2154 if (!policy->cur) { 2148 if (!policy->cur) {
2155 pr_debug("Driver did not initialize current freq"); 2149 pr_debug("Driver did not initialize current freq");