diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-09-11 09:23:15 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-09-11 09:23:15 -0400 |
commit | 0df03a30c333d67ee9b4c37f32d423624f48fe05 (patch) | |
tree | c8f8304fb05926777defdc4607c95f91d340d6a3 /drivers | |
parent | 0a733e6effb4a429551d8b000aa02750cc7e04ba (diff) | |
parent | 6cdcdb793791f776ea9408581b1242b636d43b37 (diff) |
Merge branch 'pm-cpufreq'
* pm-cpufreq:
intel_pstate: Add Haswell CPU models
Revert "cpufreq: make sure frequency transitions are serialized"
cpufreq: Use signed type for 'ret' variable, to store negative error values
cpufreq: Remove temporary fix for race between CPU hotplug and sysfs-writes
cpufreq: Synchronize the cpufreq store_*() routines with CPU hotplug
cpufreq: Invoke __cpufreq_remove_dev_finish() after releasing cpu_hotplug.lock
cpufreq: Split __cpufreq_remove_dev() into two parts
cpufreq: Fix wrong time unit conversion
cpufreq: serialize calls to __cpufreq_governor()
cpufreq: don't allow governor limits to be changed when it is disabled
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 103 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq_stats.c | 2 | ||||
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 5 |
3 files changed, 76 insertions, 34 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 5c75e3147a60..5a64f66d36e0 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -280,13 +280,6 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy, | |||
280 | switch (state) { | 280 | switch (state) { |
281 | 281 | ||
282 | case CPUFREQ_PRECHANGE: | 282 | case CPUFREQ_PRECHANGE: |
283 | if (WARN(policy->transition_ongoing == | ||
284 | cpumask_weight(policy->cpus), | ||
285 | "In middle of another frequency transition\n")) | ||
286 | return; | ||
287 | |||
288 | policy->transition_ongoing++; | ||
289 | |||
290 | /* detect if the driver reported a value as "old frequency" | 283 | /* detect if the driver reported a value as "old frequency" |
291 | * which is not equal to what the cpufreq core thinks is | 284 | * which is not equal to what the cpufreq core thinks is |
292 | * "old frequency". | 285 | * "old frequency". |
@@ -306,12 +299,6 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy, | |||
306 | break; | 299 | break; |
307 | 300 | ||
308 | case CPUFREQ_POSTCHANGE: | 301 | case CPUFREQ_POSTCHANGE: |
309 | if (WARN(!policy->transition_ongoing, | ||
310 | "No frequency transition in progress\n")) | ||
311 | return; | ||
312 | |||
313 | policy->transition_ongoing--; | ||
314 | |||
315 | adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); | 302 | adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); |
316 | pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, | 303 | pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, |
317 | (unsigned long)freqs->cpu); | 304 | (unsigned long)freqs->cpu); |
@@ -437,7 +424,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *policy, | |||
437 | static ssize_t store_##file_name \ | 424 | static ssize_t store_##file_name \ |
438 | (struct cpufreq_policy *policy, const char *buf, size_t count) \ | 425 | (struct cpufreq_policy *policy, const char *buf, size_t count) \ |
439 | { \ | 426 | { \ |
440 | unsigned int ret; \ | 427 | int ret; \ |
441 | struct cpufreq_policy new_policy; \ | 428 | struct cpufreq_policy new_policy; \ |
442 | \ | 429 | \ |
443 | ret = cpufreq_get_policy(&new_policy, policy->cpu); \ | 430 | ret = cpufreq_get_policy(&new_policy, policy->cpu); \ |
@@ -490,7 +477,7 @@ static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf) | |||
490 | static ssize_t store_scaling_governor(struct cpufreq_policy *policy, | 477 | static ssize_t store_scaling_governor(struct cpufreq_policy *policy, |
491 | const char *buf, size_t count) | 478 | const char *buf, size_t count) |
492 | { | 479 | { |
493 | unsigned int ret; | 480 | int ret; |
494 | char str_governor[16]; | 481 | char str_governor[16]; |
495 | struct cpufreq_policy new_policy; | 482 | struct cpufreq_policy new_policy; |
496 | 483 | ||
@@ -694,8 +681,13 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, | |||
694 | struct freq_attr *fattr = to_attr(attr); | 681 | struct freq_attr *fattr = to_attr(attr); |
695 | ssize_t ret = -EINVAL; | 682 | ssize_t ret = -EINVAL; |
696 | 683 | ||
684 | get_online_cpus(); | ||
685 | |||
686 | if (!cpu_online(policy->cpu)) | ||
687 | goto unlock; | ||
688 | |||
697 | if (!down_read_trylock(&cpufreq_rwsem)) | 689 | if (!down_read_trylock(&cpufreq_rwsem)) |
698 | goto exit; | 690 | goto unlock; |
699 | 691 | ||
700 | if (lock_policy_rwsem_write(policy->cpu) < 0) | 692 | if (lock_policy_rwsem_write(policy->cpu) < 0) |
701 | goto up_read; | 693 | goto up_read; |
@@ -709,7 +701,9 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, | |||
709 | 701 | ||
710 | up_read: | 702 | up_read: |
711 | up_read(&cpufreq_rwsem); | 703 | up_read(&cpufreq_rwsem); |
712 | exit: | 704 | unlock: |
705 | put_online_cpus(); | ||
706 | |||
713 | return ret; | 707 | return ret; |
714 | } | 708 | } |
715 | 709 | ||
@@ -1141,22 +1135,14 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, | |||
1141 | return cpu_dev->id; | 1135 | return cpu_dev->id; |
1142 | } | 1136 | } |
1143 | 1137 | ||
1144 | /** | 1138 | static int __cpufreq_remove_dev_prepare(struct device *dev, |
1145 | * __cpufreq_remove_dev - remove a CPU device | 1139 | struct subsys_interface *sif, |
1146 | * | 1140 | bool frozen) |
1147 | * Removes the cpufreq interface for a CPU device. | ||
1148 | * Caller should already have policy_rwsem in write mode for this CPU. | ||
1149 | * This routine frees the rwsem before returning. | ||
1150 | */ | ||
1151 | static int __cpufreq_remove_dev(struct device *dev, | ||
1152 | struct subsys_interface *sif, bool frozen) | ||
1153 | { | 1141 | { |
1154 | unsigned int cpu = dev->id, cpus; | 1142 | unsigned int cpu = dev->id, cpus; |
1155 | int new_cpu, ret; | 1143 | int new_cpu, ret; |
1156 | unsigned long flags; | 1144 | unsigned long flags; |
1157 | struct cpufreq_policy *policy; | 1145 | struct cpufreq_policy *policy; |
1158 | struct kobject *kobj; | ||
1159 | struct completion *cmp; | ||
1160 | 1146 | ||
1161 | pr_debug("%s: unregistering CPU %u\n", __func__, cpu); | 1147 | pr_debug("%s: unregistering CPU %u\n", __func__, cpu); |
1162 | 1148 | ||
@@ -1213,6 +1199,33 @@ static int __cpufreq_remove_dev(struct device *dev, | |||
1213 | } | 1199 | } |
1214 | } | 1200 | } |
1215 | 1201 | ||
1202 | return 0; | ||
1203 | } | ||
1204 | |||
1205 | static int __cpufreq_remove_dev_finish(struct device *dev, | ||
1206 | struct subsys_interface *sif, | ||
1207 | bool frozen) | ||
1208 | { | ||
1209 | unsigned int cpu = dev->id, cpus; | ||
1210 | int ret; | ||
1211 | unsigned long flags; | ||
1212 | struct cpufreq_policy *policy; | ||
1213 | struct kobject *kobj; | ||
1214 | struct completion *cmp; | ||
1215 | |||
1216 | read_lock_irqsave(&cpufreq_driver_lock, flags); | ||
1217 | policy = per_cpu(cpufreq_cpu_data, cpu); | ||
1218 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
1219 | |||
1220 | if (!policy) { | ||
1221 | pr_debug("%s: No cpu_data found\n", __func__); | ||
1222 | return -EINVAL; | ||
1223 | } | ||
1224 | |||
1225 | lock_policy_rwsem_read(cpu); | ||
1226 | cpus = cpumask_weight(policy->cpus); | ||
1227 | unlock_policy_rwsem_read(cpu); | ||
1228 | |||
1216 | /* If cpu is last user of policy, free policy */ | 1229 | /* If cpu is last user of policy, free policy */ |
1217 | if (cpus == 1) { | 1230 | if (cpus == 1) { |
1218 | if (cpufreq_driver->target) { | 1231 | if (cpufreq_driver->target) { |
@@ -1272,6 +1285,27 @@ static int __cpufreq_remove_dev(struct device *dev, | |||
1272 | return 0; | 1285 | return 0; |
1273 | } | 1286 | } |
1274 | 1287 | ||
1288 | /** | ||
1289 | * __cpufreq_remove_dev - remove a CPU device | ||
1290 | * | ||
1291 | * Removes the cpufreq interface for a CPU device. | ||
1292 | * Caller should already have policy_rwsem in write mode for this CPU. | ||
1293 | * This routine frees the rwsem before returning. | ||
1294 | */ | ||
1295 | static inline int __cpufreq_remove_dev(struct device *dev, | ||
1296 | struct subsys_interface *sif, | ||
1297 | bool frozen) | ||
1298 | { | ||
1299 | int ret; | ||
1300 | |||
1301 | ret = __cpufreq_remove_dev_prepare(dev, sif, frozen); | ||
1302 | |||
1303 | if (!ret) | ||
1304 | ret = __cpufreq_remove_dev_finish(dev, sif, frozen); | ||
1305 | |||
1306 | return ret; | ||
1307 | } | ||
1308 | |||
1275 | static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) | 1309 | static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) |
1276 | { | 1310 | { |
1277 | unsigned int cpu = dev->id; | 1311 | unsigned int cpu = dev->id; |
@@ -1610,8 +1644,6 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1610 | 1644 | ||
1611 | if (cpufreq_disabled()) | 1645 | if (cpufreq_disabled()) |
1612 | return -ENODEV; | 1646 | return -ENODEV; |
1613 | if (policy->transition_ongoing) | ||
1614 | return -EBUSY; | ||
1615 | 1647 | ||
1616 | /* Make sure that target_freq is within supported range */ | 1648 | /* Make sure that target_freq is within supported range */ |
1617 | if (target_freq > policy->max) | 1649 | if (target_freq > policy->max) |
@@ -1692,8 +1724,9 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, | |||
1692 | policy->cpu, event); | 1724 | policy->cpu, event); |
1693 | 1725 | ||
1694 | mutex_lock(&cpufreq_governor_lock); | 1726 | mutex_lock(&cpufreq_governor_lock); |
1695 | if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) || | 1727 | if ((policy->governor_enabled && event == CPUFREQ_GOV_START) |
1696 | (policy->governor_enabled && (event == CPUFREQ_GOV_START))) { | 1728 | || (!policy->governor_enabled |
1729 | && (event == CPUFREQ_GOV_LIMITS || event == CPUFREQ_GOV_STOP))) { | ||
1697 | mutex_unlock(&cpufreq_governor_lock); | 1730 | mutex_unlock(&cpufreq_governor_lock); |
1698 | return -EBUSY; | 1731 | return -EBUSY; |
1699 | } | 1732 | } |
@@ -1994,7 +2027,11 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, | |||
1994 | break; | 2027 | break; |
1995 | 2028 | ||
1996 | case CPU_DOWN_PREPARE: | 2029 | case CPU_DOWN_PREPARE: |
1997 | __cpufreq_remove_dev(dev, NULL, frozen); | 2030 | __cpufreq_remove_dev_prepare(dev, NULL, frozen); |
2031 | break; | ||
2032 | |||
2033 | case CPU_POST_DEAD: | ||
2034 | __cpufreq_remove_dev_finish(dev, NULL, frozen); | ||
1998 | break; | 2035 | break; |
1999 | 2036 | ||
2000 | case CPU_DOWN_FAILED: | 2037 | case CPU_DOWN_FAILED: |
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 04452f026ed0..4cf0d2805cb2 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -74,7 +74,7 @@ static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) | |||
74 | for (i = 0; i < stat->state_num; i++) { | 74 | for (i = 0; i < stat->state_num; i++) { |
75 | len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], | 75 | len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], |
76 | (unsigned long long) | 76 | (unsigned long long) |
77 | cputime64_to_clock_t(stat->time_in_state[i])); | 77 | jiffies_64_to_clock_t(stat->time_in_state[i])); |
78 | } | 78 | } |
79 | return len; | 79 | return len; |
80 | } | 80 | } |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 6efd96c196b2..9733f29ed148 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -522,6 +522,11 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { | |||
522 | ICPU(0x2a, default_policy), | 522 | ICPU(0x2a, default_policy), |
523 | ICPU(0x2d, default_policy), | 523 | ICPU(0x2d, default_policy), |
524 | ICPU(0x3a, default_policy), | 524 | ICPU(0x3a, default_policy), |
525 | ICPU(0x3c, default_policy), | ||
526 | ICPU(0x3e, default_policy), | ||
527 | ICPU(0x3f, default_policy), | ||
528 | ICPU(0x45, default_policy), | ||
529 | ICPU(0x46, default_policy), | ||
525 | {} | 530 | {} |
526 | }; | 531 | }; |
527 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); | 532 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); |