diff options
| -rw-r--r-- | drivers/cpufreq/Kconfig.x86 | 12 | ||||
| -rw-r--r-- | drivers/cpufreq/acpi-cpufreq.c | 46 |
2 files changed, 56 insertions, 2 deletions
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index b36ca1f68bff..934854ae5eb4 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 | |||
| @@ -33,6 +33,18 @@ config X86_ACPI_CPUFREQ | |||
| 33 | 33 | ||
| 34 | If in doubt, say N. | 34 | If in doubt, say N. |
| 35 | 35 | ||
| 36 | config X86_ACPI_CPUFREQ_CPB | ||
| 37 | default y | ||
| 38 | bool "Legacy cpb sysfs knob support for AMD CPUs" | ||
| 39 | depends on X86_ACPI_CPUFREQ && CPU_SUP_AMD | ||
| 40 | help | ||
| 41 | The powernow-k8 driver used to provide a sysfs knob called "cpb" | ||
| 42 | to disable the Core Performance Boosting feature of AMD CPUs. This | ||
| 43 | file has now been superseeded by the more generic "boost" entry. | ||
| 44 | |||
| 45 | By enabling this option the acpi_cpufreq driver provides the old | ||
| 46 | entry in addition to the new boost ones, for compatibility reasons. | ||
| 47 | |||
| 36 | config ELAN_CPUFREQ | 48 | config ELAN_CPUFREQ |
| 37 | tristate "AMD Elan SC400 and SC410" | 49 | tristate "AMD Elan SC400 and SC410" |
| 38 | select CPU_FREQ_TABLE | 50 | select CPU_FREQ_TABLE |
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index dffa7af1db71..0d048f6a2b23 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
| @@ -133,8 +133,7 @@ static void boost_set_msrs(bool enable, const struct cpumask *cpumask) | |||
| 133 | wrmsr_on_cpus(cpumask, msr_addr, msrs); | 133 | wrmsr_on_cpus(cpumask, msr_addr, msrs); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | static ssize_t store_global_boost(struct kobject *kobj, struct attribute *attr, | 136 | static ssize_t _store_boost(const char *buf, size_t count) |
| 137 | const char *buf, size_t count) | ||
| 138 | { | 137 | { |
| 139 | int ret; | 138 | int ret; |
| 140 | unsigned long val = 0; | 139 | unsigned long val = 0; |
| @@ -161,6 +160,12 @@ static ssize_t store_global_boost(struct kobject *kobj, struct attribute *attr, | |||
| 161 | return count; | 160 | return count; |
| 162 | } | 161 | } |
| 163 | 162 | ||
| 163 | static ssize_t store_global_boost(struct kobject *kobj, struct attribute *attr, | ||
| 164 | const char *buf, size_t count) | ||
| 165 | { | ||
| 166 | return _store_boost(buf, count); | ||
| 167 | } | ||
| 168 | |||
| 164 | static ssize_t show_global_boost(struct kobject *kobj, | 169 | static ssize_t show_global_boost(struct kobject *kobj, |
| 165 | struct attribute *attr, char *buf) | 170 | struct attribute *attr, char *buf) |
| 166 | { | 171 | { |
| @@ -171,6 +176,21 @@ static struct global_attr global_boost = __ATTR(boost, 0644, | |||
| 171 | show_global_boost, | 176 | show_global_boost, |
| 172 | store_global_boost); | 177 | store_global_boost); |
| 173 | 178 | ||
| 179 | #ifdef CONFIG_X86_ACPI_CPUFREQ_CPB | ||
| 180 | static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf, | ||
| 181 | size_t count) | ||
| 182 | { | ||
| 183 | return _store_boost(buf, count); | ||
| 184 | } | ||
| 185 | |||
| 186 | static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf) | ||
| 187 | { | ||
| 188 | return sprintf(buf, "%u\n", boost_enabled); | ||
| 189 | } | ||
| 190 | |||
| 191 | static struct freq_attr cpb = __ATTR(cpb, 0644, show_cpb, store_cpb); | ||
| 192 | #endif | ||
| 193 | |||
| 174 | static int check_est_cpu(unsigned int cpuid) | 194 | static int check_est_cpu(unsigned int cpuid) |
| 175 | { | 195 | { |
| 176 | struct cpuinfo_x86 *cpu = &cpu_data(cpuid); | 196 | struct cpuinfo_x86 *cpu = &cpu_data(cpuid); |
| @@ -889,6 +909,7 @@ static int acpi_cpufreq_resume(struct cpufreq_policy *policy) | |||
| 889 | 909 | ||
| 890 | static struct freq_attr *acpi_cpufreq_attr[] = { | 910 | static struct freq_attr *acpi_cpufreq_attr[] = { |
| 891 | &cpufreq_freq_attr_scaling_available_freqs, | 911 | &cpufreq_freq_attr_scaling_available_freqs, |
| 912 | NULL, /* this is a placeholder for cpb, do not remove */ | ||
| 892 | NULL, | 913 | NULL, |
| 893 | }; | 914 | }; |
| 894 | 915 | ||
| @@ -960,6 +981,27 @@ static int __init acpi_cpufreq_init(void) | |||
| 960 | if (ret) | 981 | if (ret) |
| 961 | return ret; | 982 | return ret; |
| 962 | 983 | ||
| 984 | #ifdef CONFIG_X86_ACPI_CPUFREQ_CPB | ||
| 985 | /* this is a sysfs file with a strange name and an even stranger | ||
| 986 | * semantic - per CPU instantiation, but system global effect. | ||
| 987 | * Lets enable it only on AMD CPUs for compatibility reasons and | ||
| 988 | * only if configured. This is considered legacy code, which | ||
| 989 | * will probably be removed at some point in the future. | ||
| 990 | */ | ||
| 991 | if (check_amd_hwpstate_cpu(0)) { | ||
| 992 | struct freq_attr **iter; | ||
| 993 | |||
| 994 | pr_debug("adding sysfs entry for cpb\n"); | ||
| 995 | |||
| 996 | for (iter = acpi_cpufreq_attr; *iter != NULL; iter++) | ||
| 997 | ; | ||
| 998 | |||
| 999 | /* make sure there is a terminator behind it */ | ||
| 1000 | if (iter[1] == NULL) | ||
| 1001 | *iter = &cpb; | ||
| 1002 | } | ||
| 1003 | #endif | ||
| 1004 | |||
| 963 | ret = cpufreq_register_driver(&acpi_cpufreq_driver); | 1005 | ret = cpufreq_register_driver(&acpi_cpufreq_driver); |
| 964 | if (ret) | 1006 | if (ret) |
| 965 | free_acpi_perf_data(); | 1007 | free_acpi_perf_data(); |
