diff options
| -rw-r--r-- | drivers/cpufreq/acpi-cpufreq.c | 86 |
1 files changed, 29 insertions, 57 deletions
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index caf41ebea184..79e5608e71b5 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
| @@ -80,7 +80,6 @@ static struct acpi_processor_performance __percpu *acpi_perf_data; | |||
| 80 | static struct cpufreq_driver acpi_cpufreq_driver; | 80 | static struct cpufreq_driver acpi_cpufreq_driver; |
| 81 | 81 | ||
| 82 | static unsigned int acpi_pstate_strict; | 82 | static unsigned int acpi_pstate_strict; |
| 83 | static bool boost_enabled, boost_supported; | ||
| 84 | static struct msr __percpu *msrs; | 83 | static struct msr __percpu *msrs; |
| 85 | 84 | ||
| 86 | static bool boost_state(unsigned int cpu) | 85 | static bool boost_state(unsigned int cpu) |
| @@ -133,49 +132,16 @@ static void boost_set_msrs(bool enable, const struct cpumask *cpumask) | |||
| 133 | wrmsr_on_cpus(cpumask, msr_addr, msrs); | 132 | wrmsr_on_cpus(cpumask, msr_addr, msrs); |
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | static ssize_t _store_boost(const char *buf, size_t count) | 135 | static int _store_boost(int val) |
| 137 | { | 136 | { |
| 138 | int ret; | ||
| 139 | unsigned long val = 0; | ||
| 140 | |||
| 141 | if (!boost_supported) | ||
| 142 | return -EINVAL; | ||
| 143 | |||
| 144 | ret = kstrtoul(buf, 10, &val); | ||
| 145 | if (ret || (val > 1)) | ||
| 146 | return -EINVAL; | ||
| 147 | |||
| 148 | if ((val && boost_enabled) || (!val && !boost_enabled)) | ||
| 149 | return count; | ||
| 150 | |||
| 151 | get_online_cpus(); | 137 | get_online_cpus(); |
| 152 | |||
| 153 | boost_set_msrs(val, cpu_online_mask); | 138 | boost_set_msrs(val, cpu_online_mask); |
| 154 | |||
| 155 | put_online_cpus(); | 139 | put_online_cpus(); |
| 156 | |||
| 157 | boost_enabled = val; | ||
| 158 | pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis"); | 140 | pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis"); |
| 159 | 141 | ||
| 160 | return count; | 142 | return 0; |
| 161 | } | ||
| 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 | |||
| 169 | static ssize_t show_global_boost(struct kobject *kobj, | ||
| 170 | struct attribute *attr, char *buf) | ||
| 171 | { | ||
| 172 | return sprintf(buf, "%u\n", boost_enabled); | ||
| 173 | } | 143 | } |
| 174 | 144 | ||
| 175 | static struct global_attr global_boost = __ATTR(boost, 0644, | ||
| 176 | show_global_boost, | ||
| 177 | store_global_boost); | ||
| 178 | |||
| 179 | static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf) | 145 | static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf) |
| 180 | { | 146 | { |
| 181 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); | 147 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); |
| @@ -186,15 +152,32 @@ static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf) | |||
| 186 | cpufreq_freq_attr_ro(freqdomain_cpus); | 152 | cpufreq_freq_attr_ro(freqdomain_cpus); |
| 187 | 153 | ||
| 188 | #ifdef CONFIG_X86_ACPI_CPUFREQ_CPB | 154 | #ifdef CONFIG_X86_ACPI_CPUFREQ_CPB |
| 155 | static ssize_t store_boost(const char *buf, size_t count) | ||
| 156 | { | ||
| 157 | int ret; | ||
| 158 | unsigned long val = 0; | ||
| 159 | |||
| 160 | if (!acpi_cpufreq_driver.boost_supported) | ||
| 161 | return -EINVAL; | ||
| 162 | |||
| 163 | ret = kstrtoul(buf, 10, &val); | ||
| 164 | if (ret || (val > 1)) | ||
| 165 | return -EINVAL; | ||
| 166 | |||
| 167 | _store_boost((int) val); | ||
| 168 | |||
| 169 | return count; | ||
| 170 | } | ||
| 171 | |||
| 189 | static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf, | 172 | static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf, |
| 190 | size_t count) | 173 | size_t count) |
| 191 | { | 174 | { |
| 192 | return _store_boost(buf, count); | 175 | return store_boost(buf, count); |
| 193 | } | 176 | } |
| 194 | 177 | ||
| 195 | static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf) | 178 | static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf) |
| 196 | { | 179 | { |
| 197 | return sprintf(buf, "%u\n", boost_enabled); | 180 | return sprintf(buf, "%u\n", acpi_cpufreq_driver.boost_enabled); |
| 198 | } | 181 | } |
| 199 | 182 | ||
| 200 | cpufreq_freq_attr_rw(cpb); | 183 | cpufreq_freq_attr_rw(cpb); |
| @@ -554,7 +537,7 @@ static int boost_notify(struct notifier_block *nb, unsigned long action, | |||
| 554 | switch (action) { | 537 | switch (action) { |
| 555 | case CPU_UP_PREPARE: | 538 | case CPU_UP_PREPARE: |
| 556 | case CPU_UP_PREPARE_FROZEN: | 539 | case CPU_UP_PREPARE_FROZEN: |
| 557 | boost_set_msrs(boost_enabled, cpumask); | 540 | boost_set_msrs(acpi_cpufreq_driver.boost_enabled, cpumask); |
| 558 | break; | 541 | break; |
| 559 | 542 | ||
| 560 | case CPU_DOWN_PREPARE: | 543 | case CPU_DOWN_PREPARE: |
| @@ -911,6 +894,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = { | |||
| 911 | .resume = acpi_cpufreq_resume, | 894 | .resume = acpi_cpufreq_resume, |
| 912 | .name = "acpi-cpufreq", | 895 | .name = "acpi-cpufreq", |
| 913 | .attr = acpi_cpufreq_attr, | 896 | .attr = acpi_cpufreq_attr, |
| 897 | .set_boost = _store_boost, | ||
| 914 | }; | 898 | }; |
| 915 | 899 | ||
| 916 | static void __init acpi_cpufreq_boost_init(void) | 900 | static void __init acpi_cpufreq_boost_init(void) |
| @@ -921,33 +905,22 @@ static void __init acpi_cpufreq_boost_init(void) | |||
| 921 | if (!msrs) | 905 | if (!msrs) |
| 922 | return; | 906 | return; |
| 923 | 907 | ||
| 924 | boost_supported = true; | 908 | acpi_cpufreq_driver.boost_supported = true; |
| 925 | boost_enabled = boost_state(0); | 909 | acpi_cpufreq_driver.boost_enabled = boost_state(0); |
| 926 | |||
| 927 | get_online_cpus(); | 910 | get_online_cpus(); |
| 928 | 911 | ||
| 929 | /* Force all MSRs to the same value */ | 912 | /* Force all MSRs to the same value */ |
| 930 | boost_set_msrs(boost_enabled, cpu_online_mask); | 913 | boost_set_msrs(acpi_cpufreq_driver.boost_enabled, |
| 914 | cpu_online_mask); | ||
| 931 | 915 | ||
| 932 | register_cpu_notifier(&boost_nb); | 916 | register_cpu_notifier(&boost_nb); |
| 933 | 917 | ||
| 934 | put_online_cpus(); | 918 | put_online_cpus(); |
| 935 | } else | 919 | } |
| 936 | global_boost.attr.mode = 0444; | ||
| 937 | |||
| 938 | /* We create the boost file in any case, though for systems without | ||
| 939 | * hardware support it will be read-only and hardwired to return 0. | ||
| 940 | */ | ||
| 941 | if (cpufreq_sysfs_create_file(&(global_boost.attr))) | ||
| 942 | pr_warn(PFX "could not register global boost sysfs file\n"); | ||
| 943 | else | ||
| 944 | pr_debug("registered global boost sysfs file\n"); | ||
| 945 | } | 920 | } |
| 946 | 921 | ||
| 947 | static void __exit acpi_cpufreq_boost_exit(void) | 922 | static void __exit acpi_cpufreq_boost_exit(void) |
| 948 | { | 923 | { |
| 949 | cpufreq_sysfs_remove_file(&(global_boost.attr)); | ||
| 950 | |||
| 951 | if (msrs) { | 924 | if (msrs) { |
| 952 | unregister_cpu_notifier(&boost_nb); | 925 | unregister_cpu_notifier(&boost_nb); |
| 953 | 926 | ||
| @@ -993,12 +966,11 @@ static int __init acpi_cpufreq_init(void) | |||
| 993 | *iter = &cpb; | 966 | *iter = &cpb; |
| 994 | } | 967 | } |
| 995 | #endif | 968 | #endif |
| 969 | acpi_cpufreq_boost_init(); | ||
| 996 | 970 | ||
| 997 | ret = cpufreq_register_driver(&acpi_cpufreq_driver); | 971 | ret = cpufreq_register_driver(&acpi_cpufreq_driver); |
| 998 | if (ret) | 972 | if (ret) |
| 999 | free_acpi_perf_data(); | 973 | free_acpi_perf_data(); |
| 1000 | else | ||
| 1001 | acpi_cpufreq_boost_init(); | ||
| 1002 | 974 | ||
| 1003 | return ret; | 975 | return ret; |
| 1004 | } | 976 | } |
