diff options
-rw-r--r-- | Documentation/cpu-freq/user-guide.txt | 11 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 17 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k7.c | 19 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 17 | ||||
-rw-r--r-- | drivers/acpi/processor_perflib.c | 13 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 21 | ||||
-rw-r--r-- | include/acpi/processor.h | 6 | ||||
-rw-r--r-- | include/linux/cpufreq.h | 1 |
8 files changed, 81 insertions, 24 deletions
diff --git a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt index 2a5b850847c0..04f6b32993e6 100644 --- a/Documentation/cpu-freq/user-guide.txt +++ b/Documentation/cpu-freq/user-guide.txt | |||
@@ -203,6 +203,17 @@ scaling_cur_freq : Current frequency of the CPU as determined by | |||
203 | the frequency the kernel thinks the CPU runs | 203 | the frequency the kernel thinks the CPU runs |
204 | at. | 204 | at. |
205 | 205 | ||
206 | bios_limit : If the BIOS tells the OS to limit a CPU to | ||
207 | lower frequencies, the user can read out the | ||
208 | maximum available frequency from this file. | ||
209 | This typically can happen through (often not | ||
210 | intended) BIOS settings, restrictions | ||
211 | triggered through a service processor or other | ||
212 | BIOS/HW based implementations. | ||
213 | This does not cover thermal ACPI limitations | ||
214 | which can be detected through the generic | ||
215 | thermal driver. | ||
216 | |||
206 | If you have selected the "userspace" governor which allows you to | 217 | If you have selected the "userspace" governor which allows you to |
207 | set the CPU operating frequency to a specific value, you can read out | 218 | set the CPU operating frequency to a specific value, you can read out |
208 | the current frequency in | 219 | the current frequency in |
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 8b581d3905cb..d2e7c77c1ea4 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -764,14 +764,15 @@ static struct freq_attr *acpi_cpufreq_attr[] = { | |||
764 | }; | 764 | }; |
765 | 765 | ||
766 | static struct cpufreq_driver acpi_cpufreq_driver = { | 766 | static struct cpufreq_driver acpi_cpufreq_driver = { |
767 | .verify = acpi_cpufreq_verify, | 767 | .verify = acpi_cpufreq_verify, |
768 | .target = acpi_cpufreq_target, | 768 | .target = acpi_cpufreq_target, |
769 | .init = acpi_cpufreq_cpu_init, | 769 | .bios_limit = acpi_processor_get_bios_limit, |
770 | .exit = acpi_cpufreq_cpu_exit, | 770 | .init = acpi_cpufreq_cpu_init, |
771 | .resume = acpi_cpufreq_resume, | 771 | .exit = acpi_cpufreq_cpu_exit, |
772 | .name = "acpi-cpufreq", | 772 | .resume = acpi_cpufreq_resume, |
773 | .owner = THIS_MODULE, | 773 | .name = "acpi-cpufreq", |
774 | .attr = acpi_cpufreq_attr, | 774 | .owner = THIS_MODULE, |
775 | .attr = acpi_cpufreq_attr, | ||
775 | }; | 776 | }; |
776 | 777 | ||
777 | static int __init acpi_cpufreq_init(void) | 778 | static int __init acpi_cpufreq_init(void) |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c index d47c775eb0ab..9a97116f89e5 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c | |||
@@ -714,14 +714,17 @@ static struct freq_attr *powernow_table_attr[] = { | |||
714 | }; | 714 | }; |
715 | 715 | ||
716 | static struct cpufreq_driver powernow_driver = { | 716 | static struct cpufreq_driver powernow_driver = { |
717 | .verify = powernow_verify, | 717 | .verify = powernow_verify, |
718 | .target = powernow_target, | 718 | .target = powernow_target, |
719 | .get = powernow_get, | 719 | .get = powernow_get, |
720 | .init = powernow_cpu_init, | 720 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI |
721 | .exit = powernow_cpu_exit, | 721 | .bios_limit = acpi_processor_get_bios_limit, |
722 | .name = "powernow-k7", | 722 | #endif |
723 | .owner = THIS_MODULE, | 723 | .init = powernow_cpu_init, |
724 | .attr = powernow_table_attr, | 724 | .exit = powernow_cpu_exit, |
725 | .name = "powernow-k7", | ||
726 | .owner = THIS_MODULE, | ||
727 | .attr = powernow_table_attr, | ||
725 | }; | 728 | }; |
726 | 729 | ||
727 | static int __init powernow_init(void) | 730 | static int __init powernow_init(void) |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index f30d25383940..a9df9441a9a2 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -1398,14 +1398,15 @@ static struct freq_attr *powernow_k8_attr[] = { | |||
1398 | }; | 1398 | }; |
1399 | 1399 | ||
1400 | static struct cpufreq_driver cpufreq_amd64_driver = { | 1400 | static struct cpufreq_driver cpufreq_amd64_driver = { |
1401 | .verify = powernowk8_verify, | 1401 | .verify = powernowk8_verify, |
1402 | .target = powernowk8_target, | 1402 | .target = powernowk8_target, |
1403 | .init = powernowk8_cpu_init, | 1403 | .bios_limit = acpi_processor_get_bios_limit, |
1404 | .exit = __devexit_p(powernowk8_cpu_exit), | 1404 | .init = powernowk8_cpu_init, |
1405 | .get = powernowk8_get, | 1405 | .exit = __devexit_p(powernowk8_cpu_exit), |
1406 | .name = "powernow-k8", | 1406 | .get = powernowk8_get, |
1407 | .owner = THIS_MODULE, | 1407 | .name = "powernow-k8", |
1408 | .attr = powernow_k8_attr, | 1408 | .owner = THIS_MODULE, |
1409 | .attr = powernow_k8_attr, | ||
1409 | }; | 1410 | }; |
1410 | 1411 | ||
1411 | /* driver entry point for init */ | 1412 | /* driver entry point for init */ |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 8ba0ed0b9ddb..01e366d2b6fb 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -167,6 +167,19 @@ int acpi_processor_ppc_has_changed(struct acpi_processor *pr) | |||
167 | return cpufreq_update_policy(pr->id); | 167 | return cpufreq_update_policy(pr->id); |
168 | } | 168 | } |
169 | 169 | ||
170 | int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) | ||
171 | { | ||
172 | struct acpi_processor *pr; | ||
173 | |||
174 | pr = per_cpu(processors, cpu); | ||
175 | if (!pr || !pr->performance || !pr->performance->state_count) | ||
176 | return -ENODEV; | ||
177 | *limit = pr->performance->states[pr->performance_platform_limit]. | ||
178 | core_frequency * 1000; | ||
179 | return 0; | ||
180 | } | ||
181 | EXPORT_SYMBOL(acpi_processor_get_bios_limit); | ||
182 | |||
170 | void acpi_processor_ppc_init(void) | 183 | void acpi_processor_ppc_init(void) |
171 | { | 184 | { |
172 | if (!cpufreq_register_notifier | 185 | if (!cpufreq_register_notifier |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 5b9b1c8c4950..f20668c09ce0 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -647,6 +647,21 @@ static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf) | |||
647 | return policy->governor->show_setspeed(policy, buf); | 647 | return policy->governor->show_setspeed(policy, buf); |
648 | } | 648 | } |
649 | 649 | ||
650 | /** | ||
651 | * show_scaling_driver - show the current cpufreq HW/BIOS limitation | ||
652 | */ | ||
653 | static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf) | ||
654 | { | ||
655 | unsigned int limit; | ||
656 | int ret; | ||
657 | if (cpufreq_driver->bios_limit) { | ||
658 | ret = cpufreq_driver->bios_limit(policy->cpu, &limit); | ||
659 | if (!ret) | ||
660 | return sprintf(buf, "%u\n", limit); | ||
661 | } | ||
662 | return sprintf(buf, "%u\n", policy->cpuinfo.max_freq); | ||
663 | } | ||
664 | |||
650 | #define define_one_ro(_name) \ | 665 | #define define_one_ro(_name) \ |
651 | static struct freq_attr _name = \ | 666 | static struct freq_attr _name = \ |
652 | __ATTR(_name, 0444, show_##_name, NULL) | 667 | __ATTR(_name, 0444, show_##_name, NULL) |
@@ -666,6 +681,7 @@ define_one_ro(cpuinfo_transition_latency); | |||
666 | define_one_ro(scaling_available_governors); | 681 | define_one_ro(scaling_available_governors); |
667 | define_one_ro(scaling_driver); | 682 | define_one_ro(scaling_driver); |
668 | define_one_ro(scaling_cur_freq); | 683 | define_one_ro(scaling_cur_freq); |
684 | define_one_ro(bios_limit); | ||
669 | define_one_ro(related_cpus); | 685 | define_one_ro(related_cpus); |
670 | define_one_ro(affected_cpus); | 686 | define_one_ro(affected_cpus); |
671 | define_one_rw(scaling_min_freq); | 687 | define_one_rw(scaling_min_freq); |
@@ -905,6 +921,11 @@ static int cpufreq_add_dev_interface(unsigned int cpu, | |||
905 | if (ret) | 921 | if (ret) |
906 | goto err_out_kobj_put; | 922 | goto err_out_kobj_put; |
907 | } | 923 | } |
924 | if (cpufreq_driver->bios_limit) { | ||
925 | ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); | ||
926 | if (ret) | ||
927 | goto err_out_kobj_put; | ||
928 | } | ||
908 | 929 | ||
909 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | 930 | spin_lock_irqsave(&cpufreq_driver_lock, flags); |
910 | for_each_cpu(j, policy->cpus) { | 931 | for_each_cpu(j, policy->cpus) { |
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 740ac3ad8fd0..8b668ead6d6e 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
@@ -295,6 +295,7 @@ static inline void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx | |||
295 | void acpi_processor_ppc_init(void); | 295 | void acpi_processor_ppc_init(void); |
296 | void acpi_processor_ppc_exit(void); | 296 | void acpi_processor_ppc_exit(void); |
297 | int acpi_processor_ppc_has_changed(struct acpi_processor *pr); | 297 | int acpi_processor_ppc_has_changed(struct acpi_processor *pr); |
298 | extern int acpi_processor_get_bios_limit(int cpu, unsigned int *limit); | ||
298 | #else | 299 | #else |
299 | static inline void acpi_processor_ppc_init(void) | 300 | static inline void acpi_processor_ppc_init(void) |
300 | { | 301 | { |
@@ -316,6 +317,11 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) | |||
316 | } | 317 | } |
317 | return 0; | 318 | return 0; |
318 | } | 319 | } |
320 | static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) | ||
321 | { | ||
322 | return -ENODEV; | ||
323 | } | ||
324 | |||
319 | #endif /* CONFIG_CPU_FREQ */ | 325 | #endif /* CONFIG_CPU_FREQ */ |
320 | 326 | ||
321 | /* in processor_throttling.c */ | 327 | /* in processor_throttling.c */ |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 79a2340d83cd..4de02b10007f 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
@@ -232,6 +232,7 @@ struct cpufreq_driver { | |||
232 | /* optional */ | 232 | /* optional */ |
233 | unsigned int (*getavg) (struct cpufreq_policy *policy, | 233 | unsigned int (*getavg) (struct cpufreq_policy *policy, |
234 | unsigned int cpu); | 234 | unsigned int cpu); |
235 | int (*bios_limit) (int cpu, unsigned int *limit); | ||
235 | 236 | ||
236 | int (*exit) (struct cpufreq_policy *policy); | 237 | int (*exit) (struct cpufreq_policy *policy); |
237 | int (*suspend) (struct cpufreq_policy *policy, pm_message_t pmsg); | 238 | int (*suspend) (struct cpufreq_policy *policy, pm_message_t pmsg); |