diff options
| -rw-r--r-- | Documentation/ABI/testing/sysfs-devices-system-cpu | 15 | ||||
| -rw-r--r-- | drivers/cpufreq/acpi-cpufreq.c | 23 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 7 | ||||
| -rw-r--r-- | include/linux/cpufreq.h | 3 |
4 files changed, 44 insertions, 4 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 2447698aed41..468e4d48f884 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu | |||
| @@ -144,6 +144,21 @@ Description: Discover and change clock speed of CPUs | |||
| 144 | to learn how to control the knobs. | 144 | to learn how to control the knobs. |
| 145 | 145 | ||
| 146 | 146 | ||
| 147 | What: /sys/devices/system/cpu/cpu#/cpufreq/freqdomain_cpus | ||
| 148 | Date: June 2013 | ||
| 149 | Contact: cpufreq@vger.kernel.org | ||
| 150 | Description: Discover CPUs in the same CPU frequency coordination domain | ||
| 151 | |||
| 152 | freqdomain_cpus is the list of CPUs (online+offline) that share | ||
| 153 | the same clock/freq domain (possibly at the hardware level). | ||
| 154 | That information may be hidden from the cpufreq core and the | ||
| 155 | value of related_cpus may be different from freqdomain_cpus. This | ||
| 156 | attribute is useful for user space DVFS controllers to get better | ||
| 157 | power/performance results for platforms using acpi-cpufreq. | ||
| 158 | |||
| 159 | This file is only present if the acpi-cpufreq driver is in use. | ||
| 160 | |||
| 161 | |||
| 147 | What: /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1} | 162 | What: /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1} |
| 148 | Date: August 2008 | 163 | Date: August 2008 |
| 149 | KernelVersion: 2.6.27 | 164 | KernelVersion: 2.6.27 |
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 2c5906d71397..403dad646abe 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 03b3b69f64a7..6a015ada5285 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -585,7 +585,7 @@ out: | |||
| 585 | return i; | 585 | return i; |
| 586 | } | 586 | } |
| 587 | 587 | ||
| 588 | static ssize_t show_cpus(const struct cpumask *mask, char *buf) | 588 | ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf) |
| 589 | { | 589 | { |
| 590 | ssize_t i = 0; | 590 | ssize_t i = 0; |
| 591 | unsigned int cpu; | 591 | unsigned int cpu; |
| @@ -600,6 +600,7 @@ static ssize_t show_cpus(const struct cpumask *mask, char *buf) | |||
| 600 | i += sprintf(&buf[i], "\n"); | 600 | i += sprintf(&buf[i], "\n"); |
| 601 | return i; | 601 | return i; |
| 602 | } | 602 | } |
| 603 | EXPORT_SYMBOL_GPL(cpufreq_show_cpus); | ||
| 603 | 604 | ||
| 604 | /** | 605 | /** |
| 605 | * 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 |
| @@ -607,7 +608,7 @@ static ssize_t show_cpus(const struct cpumask *mask, char *buf) | |||
| 607 | */ | 608 | */ |
| 608 | 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) |
| 609 | { | 610 | { |
| 610 | return show_cpus(policy->related_cpus, buf); | 611 | return cpufreq_show_cpus(policy->related_cpus, buf); |
| 611 | } | 612 | } |
| 612 | 613 | ||
| 613 | /** | 614 | /** |
| @@ -615,7 +616,7 @@ static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf) | |||
| 615 | */ | 616 | */ |
| 616 | 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) |
| 617 | { | 618 | { |
| 618 | return show_cpus(policy->cpus, buf); | 619 | return cpufreq_show_cpus(policy->cpus, buf); |
| 619 | } | 620 | } |
| 620 | 621 | ||
| 621 | static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, | 622 | static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index c0bc7374445e..4d7390bc1727 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
| @@ -439,4 +439,7 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, | |||
| 439 | void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy); | 439 | void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy); |
| 440 | 440 | ||
| 441 | void cpufreq_frequency_table_put_attr(unsigned int cpu); | 441 | void cpufreq_frequency_table_put_attr(unsigned int cpu); |
| 442 | |||
| 443 | ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf); | ||
| 444 | |||
| 442 | #endif /* _LINUX_CPUFREQ_H */ | 445 | #endif /* _LINUX_CPUFREQ_H */ |
