diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-06-29 09:04:07 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-06-29 09:04:07 -0400 |
commit | 2cc6ced132f472b2bdb619960a650b9a85cdd34f (patch) | |
tree | 171d6613cd7117dcd750efdd665ec2eab6e24a8e /drivers/cpufreq | |
parent | 867a420b222b25e9608f4430bea3af50835b56b5 (diff) | |
parent | 419e172145cf6c51d436a8bf4afcd17511f0ff79 (diff) |
Merge branch 'pm-cpufreq'
* pm-cpufreq:
cpufreq: don't leave stale policy pointer in cdbs->cur_policy
acpi-cpufreq: Add new sysfs attribute freqdomain_cpus
cpufreq: make sure frequency transitions are serialized
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r-- | drivers/cpufreq/acpi-cpufreq.c | 23 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 21 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq_governor.c | 1 |
3 files changed, 41 insertions, 4 deletions
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index f4fef0acc183..39264020b88a 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
@@ -70,6 +70,7 @@ struct acpi_cpufreq_data { | |||
70 | struct cpufreq_frequency_table *freq_table; | 70 | struct cpufreq_frequency_table *freq_table; |
71 | unsigned int resume; | 71 | unsigned int resume; |
72 | unsigned int cpu_feature; | 72 | unsigned int cpu_feature; |
73 | cpumask_var_t freqdomain_cpus; | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data); | 76 | static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data); |
@@ -176,6 +177,15 @@ static struct global_attr global_boost = __ATTR(boost, 0644, | |||
176 | show_global_boost, | 177 | show_global_boost, |
177 | store_global_boost); | 178 | store_global_boost); |
178 | 179 | ||
180 | static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf) | ||
181 | { | ||
182 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); | ||
183 | |||
184 | return cpufreq_show_cpus(data->freqdomain_cpus, buf); | ||
185 | } | ||
186 | |||
187 | cpufreq_freq_attr_ro(freqdomain_cpus); | ||
188 | |||
179 | #ifdef CONFIG_X86_ACPI_CPUFREQ_CPB | 189 | #ifdef CONFIG_X86_ACPI_CPUFREQ_CPB |
180 | static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf, | 190 | static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf, |
181 | size_t count) | 191 | size_t count) |
@@ -704,6 +714,11 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
704 | if (!data) | 714 | if (!data) |
705 | return -ENOMEM; | 715 | return -ENOMEM; |
706 | 716 | ||
717 | if (!zalloc_cpumask_var(&data->freqdomain_cpus, GFP_KERNEL)) { | ||
718 | result = -ENOMEM; | ||
719 | goto err_free; | ||
720 | } | ||
721 | |||
707 | data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu); | 722 | data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu); |
708 | per_cpu(acfreq_data, cpu) = data; | 723 | per_cpu(acfreq_data, cpu) = data; |
709 | 724 | ||
@@ -712,7 +727,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
712 | 727 | ||
713 | result = acpi_processor_register_performance(data->acpi_data, cpu); | 728 | result = acpi_processor_register_performance(data->acpi_data, cpu); |
714 | if (result) | 729 | if (result) |
715 | goto err_free; | 730 | goto err_free_mask; |
716 | 731 | ||
717 | perf = data->acpi_data; | 732 | perf = data->acpi_data; |
718 | policy->shared_type = perf->shared_type; | 733 | policy->shared_type = perf->shared_type; |
@@ -725,6 +740,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
725 | policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { | 740 | policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { |
726 | cpumask_copy(policy->cpus, perf->shared_cpu_map); | 741 | cpumask_copy(policy->cpus, perf->shared_cpu_map); |
727 | } | 742 | } |
743 | cpumask_copy(data->freqdomain_cpus, perf->shared_cpu_map); | ||
728 | 744 | ||
729 | #ifdef CONFIG_SMP | 745 | #ifdef CONFIG_SMP |
730 | dmi_check_system(sw_any_bug_dmi_table); | 746 | dmi_check_system(sw_any_bug_dmi_table); |
@@ -736,6 +752,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
736 | if (check_amd_hwpstate_cpu(cpu) && !acpi_pstate_strict) { | 752 | if (check_amd_hwpstate_cpu(cpu) && !acpi_pstate_strict) { |
737 | cpumask_clear(policy->cpus); | 753 | cpumask_clear(policy->cpus); |
738 | cpumask_set_cpu(cpu, policy->cpus); | 754 | cpumask_set_cpu(cpu, policy->cpus); |
755 | cpumask_copy(data->freqdomain_cpus, cpu_sibling_mask(cpu)); | ||
739 | policy->shared_type = CPUFREQ_SHARED_TYPE_HW; | 756 | policy->shared_type = CPUFREQ_SHARED_TYPE_HW; |
740 | pr_info_once(PFX "overriding BIOS provided _PSD data\n"); | 757 | pr_info_once(PFX "overriding BIOS provided _PSD data\n"); |
741 | } | 758 | } |
@@ -870,6 +887,8 @@ err_freqfree: | |||
870 | kfree(data->freq_table); | 887 | kfree(data->freq_table); |
871 | err_unreg: | 888 | err_unreg: |
872 | acpi_processor_unregister_performance(perf, cpu); | 889 | acpi_processor_unregister_performance(perf, cpu); |
890 | err_free_mask: | ||
891 | free_cpumask_var(data->freqdomain_cpus); | ||
873 | err_free: | 892 | err_free: |
874 | kfree(data); | 893 | kfree(data); |
875 | per_cpu(acfreq_data, cpu) = NULL; | 894 | per_cpu(acfreq_data, cpu) = NULL; |
@@ -888,6 +907,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) | |||
888 | per_cpu(acfreq_data, policy->cpu) = NULL; | 907 | per_cpu(acfreq_data, policy->cpu) = NULL; |
889 | acpi_processor_unregister_performance(data->acpi_data, | 908 | acpi_processor_unregister_performance(data->acpi_data, |
890 | policy->cpu); | 909 | policy->cpu); |
910 | free_cpumask_var(data->freqdomain_cpus); | ||
891 | kfree(data->freq_table); | 911 | kfree(data->freq_table); |
892 | kfree(data); | 912 | kfree(data); |
893 | } | 913 | } |
@@ -908,6 +928,7 @@ static int acpi_cpufreq_resume(struct cpufreq_policy *policy) | |||
908 | 928 | ||
909 | static struct freq_attr *acpi_cpufreq_attr[] = { | 929 | static struct freq_attr *acpi_cpufreq_attr[] = { |
910 | &cpufreq_freq_attr_scaling_available_freqs, | 930 | &cpufreq_freq_attr_scaling_available_freqs, |
931 | &freqdomain_cpus, | ||
911 | NULL, /* this is a placeholder for cpb, do not remove */ | 932 | NULL, /* this is a placeholder for cpb, do not remove */ |
912 | NULL, | 933 | NULL, |
913 | }; | 934 | }; |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index d976e222f10f..6a015ada5285 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -312,6 +312,12 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy, | |||
312 | switch (state) { | 312 | switch (state) { |
313 | 313 | ||
314 | case CPUFREQ_PRECHANGE: | 314 | case CPUFREQ_PRECHANGE: |
315 | if (WARN(policy->transition_ongoing, | ||
316 | "In middle of another frequency transition\n")) | ||
317 | return; | ||
318 | |||
319 | policy->transition_ongoing = true; | ||
320 | |||
315 | /* detect if the driver reported a value as "old frequency" | 321 | /* detect if the driver reported a value as "old frequency" |
316 | * which is not equal to what the cpufreq core thinks is | 322 | * which is not equal to what the cpufreq core thinks is |
317 | * "old frequency". | 323 | * "old frequency". |
@@ -331,6 +337,12 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy, | |||
331 | break; | 337 | break; |
332 | 338 | ||
333 | case CPUFREQ_POSTCHANGE: | 339 | case CPUFREQ_POSTCHANGE: |
340 | if (WARN(!policy->transition_ongoing, | ||
341 | "No frequency transition in progress\n")) | ||
342 | return; | ||
343 | |||
344 | policy->transition_ongoing = false; | ||
345 | |||
334 | adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); | 346 | adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); |
335 | pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, | 347 | pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, |
336 | (unsigned long)freqs->cpu); | 348 | (unsigned long)freqs->cpu); |
@@ -573,7 +585,7 @@ out: | |||
573 | return i; | 585 | return i; |
574 | } | 586 | } |
575 | 587 | ||
576 | static ssize_t show_cpus(const struct cpumask *mask, char *buf) | 588 | ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf) |
577 | { | 589 | { |
578 | ssize_t i = 0; | 590 | ssize_t i = 0; |
579 | unsigned int cpu; | 591 | unsigned int cpu; |
@@ -588,6 +600,7 @@ static ssize_t show_cpus(const struct cpumask *mask, char *buf) | |||
588 | i += sprintf(&buf[i], "\n"); | 600 | i += sprintf(&buf[i], "\n"); |
589 | return i; | 601 | return i; |
590 | } | 602 | } |
603 | EXPORT_SYMBOL_GPL(cpufreq_show_cpus); | ||
591 | 604 | ||
592 | /** | 605 | /** |
593 | * show_related_cpus - show the CPUs affected by each transition even if | 606 | * show_related_cpus - show the CPUs affected by each transition even if |
@@ -595,7 +608,7 @@ static ssize_t show_cpus(const struct cpumask *mask, char *buf) | |||
595 | */ | 608 | */ |
596 | static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf) | 609 | static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf) |
597 | { | 610 | { |
598 | return show_cpus(policy->related_cpus, buf); | 611 | return cpufreq_show_cpus(policy->related_cpus, buf); |
599 | } | 612 | } |
600 | 613 | ||
601 | /** | 614 | /** |
@@ -603,7 +616,7 @@ static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf) | |||
603 | */ | 616 | */ |
604 | static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf) | 617 | static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf) |
605 | { | 618 | { |
606 | return show_cpus(policy->cpus, buf); | 619 | return cpufreq_show_cpus(policy->cpus, buf); |
607 | } | 620 | } |
608 | 621 | ||
609 | static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, | 622 | static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, |
@@ -1539,6 +1552,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1539 | 1552 | ||
1540 | if (cpufreq_disabled()) | 1553 | if (cpufreq_disabled()) |
1541 | return -ENODEV; | 1554 | return -ENODEV; |
1555 | if (policy->transition_ongoing) | ||
1556 | return -EBUSY; | ||
1542 | 1557 | ||
1543 | /* Make sure that target_freq is within supported range */ | 1558 | /* Make sure that target_freq is within supported range */ |
1544 | if (target_freq > policy->max) | 1559 | if (target_freq > policy->max) |
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index a849b2d499fa..464587697561 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c | |||
@@ -366,6 +366,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
366 | 366 | ||
367 | mutex_lock(&dbs_data->mutex); | 367 | mutex_lock(&dbs_data->mutex); |
368 | mutex_destroy(&cpu_cdbs->timer_mutex); | 368 | mutex_destroy(&cpu_cdbs->timer_mutex); |
369 | cpu_cdbs->cur_policy = NULL; | ||
369 | 370 | ||
370 | mutex_unlock(&dbs_data->mutex); | 371 | mutex_unlock(&dbs_data->mutex); |
371 | 372 | ||