aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_perflib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/processor_perflib.c')
-rw-r--r--drivers/acpi/processor_perflib.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index b4749969c6b4..dc98f7a6f2c4 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -38,6 +38,7 @@
38 38
39#include <asm/uaccess.h> 39#include <asm/uaccess.h>
40#endif 40#endif
41#include <asm/cpufeature.h>
41 42
42#include <acpi/acpi_bus.h> 43#include <acpi/acpi_bus.h>
43#include <acpi/processor.h> 44#include <acpi/processor.h>
@@ -64,15 +65,21 @@ static DEFINE_MUTEX(performance_mutex);
64 * policy is adjusted accordingly. 65 * policy is adjusted accordingly.
65 */ 66 */
66 67
67static unsigned int ignore_ppc = 0; 68/* ignore_ppc:
68module_param(ignore_ppc, uint, 0644); 69 * -1 -> cpufreq low level drivers not initialized -> _PSS, etc. not called yet
70 * ignore _PPC
71 * 0 -> cpufreq low level drivers initialized -> consider _PPC values
72 * 1 -> ignore _PPC totally -> forced by user through boot param
73 */
74static int ignore_ppc = -1;
75module_param(ignore_ppc, int, 0644);
69MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \ 76MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \
70 "limited by BIOS, this should help"); 77 "limited by BIOS, this should help");
71 78
72#define PPC_REGISTERED 1 79#define PPC_REGISTERED 1
73#define PPC_IN_USE 2 80#define PPC_IN_USE 2
74 81
75static int acpi_processor_ppc_status = 0; 82static int acpi_processor_ppc_status;
76 83
77static int acpi_processor_ppc_notifier(struct notifier_block *nb, 84static int acpi_processor_ppc_notifier(struct notifier_block *nb,
78 unsigned long event, void *data) 85 unsigned long event, void *data)
@@ -81,13 +88,18 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb,
81 struct acpi_processor *pr; 88 struct acpi_processor *pr;
82 unsigned int ppc = 0; 89 unsigned int ppc = 0;
83 90
84 if (ignore_ppc) 91 if (event == CPUFREQ_START && ignore_ppc <= 0) {
92 ignore_ppc = 0;
85 return 0; 93 return 0;
94 }
86 95
87 mutex_lock(&performance_mutex); 96 if (ignore_ppc)
97 return 0;
88 98
89 if (event != CPUFREQ_INCOMPATIBLE) 99 if (event != CPUFREQ_INCOMPATIBLE)
90 goto out; 100 return 0;
101
102 mutex_lock(&performance_mutex);
91 103
92 pr = per_cpu(processors, policy->cpu); 104 pr = per_cpu(processors, policy->cpu);
93 if (!pr || !pr->performance) 105 if (!pr || !pr->performance)
@@ -115,7 +127,7 @@ static struct notifier_block acpi_ppc_notifier_block = {
115static int acpi_processor_get_platform_limit(struct acpi_processor *pr) 127static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
116{ 128{
117 acpi_status status = 0; 129 acpi_status status = 0;
118 unsigned long ppc = 0; 130 unsigned long long ppc = 0;
119 131
120 132
121 if (!pr) 133 if (!pr)
@@ -323,7 +335,6 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
323 acpi_status status = AE_OK; 335 acpi_status status = AE_OK;
324 acpi_handle handle = NULL; 336 acpi_handle handle = NULL;
325 337
326
327 if (!pr || !pr->performance || !pr->handle) 338 if (!pr || !pr->performance || !pr->handle)
328 return -EINVAL; 339 return -EINVAL;
329 340
@@ -336,13 +347,25 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
336 347
337 result = acpi_processor_get_performance_control(pr); 348 result = acpi_processor_get_performance_control(pr);
338 if (result) 349 if (result)
339 return result; 350 goto update_bios;
340 351
341 result = acpi_processor_get_performance_states(pr); 352 result = acpi_processor_get_performance_states(pr);
342 if (result) 353 if (result)
343 return result; 354 goto update_bios;
344 355
345 return 0; 356 return 0;
357
358 /*
359 * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that
360 * the BIOS is older than the CPU and does not know its frequencies
361 */
362 update_bios:
363 if (ACPI_SUCCESS(acpi_get_handle(pr->handle, "_PPC", &handle))){
364 if(boot_cpu_has(X86_FEATURE_EST))
365 printk(KERN_WARNING FW_BUG "BIOS needs update for CPU "
366 "frequency support\n");
367 }
368 return result;
346} 369}
347 370
348int acpi_processor_notify_smm(struct module *calling_module) 371int acpi_processor_notify_smm(struct module *calling_module)
@@ -513,13 +536,13 @@ static int acpi_processor_get_psd(struct acpi_processor *pr)
513 536
514 psd = buffer.pointer; 537 psd = buffer.pointer;
515 if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { 538 if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
516 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); 539 printk(KERN_ERR PREFIX "Invalid _PSD data\n");
517 result = -EFAULT; 540 result = -EFAULT;
518 goto end; 541 goto end;
519 } 542 }
520 543
521 if (psd->package.count != 1) { 544 if (psd->package.count != 1) {
522 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); 545 printk(KERN_ERR PREFIX "Invalid _PSD data\n");
523 result = -EFAULT; 546 result = -EFAULT;
524 goto end; 547 goto end;
525 } 548 }
@@ -532,19 +555,19 @@ static int acpi_processor_get_psd(struct acpi_processor *pr)
532 status = acpi_extract_package(&(psd->package.elements[0]), 555 status = acpi_extract_package(&(psd->package.elements[0]),
533 &format, &state); 556 &format, &state);
534 if (ACPI_FAILURE(status)) { 557 if (ACPI_FAILURE(status)) {
535 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); 558 printk(KERN_ERR PREFIX "Invalid _PSD data\n");
536 result = -EFAULT; 559 result = -EFAULT;
537 goto end; 560 goto end;
538 } 561 }
539 562
540 if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) { 563 if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
541 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:num_entries\n")); 564 printk(KERN_ERR PREFIX "Unknown _PSD:num_entries\n");
542 result = -EFAULT; 565 result = -EFAULT;
543 goto end; 566 goto end;
544 } 567 }
545 568
546 if (pdomain->revision != ACPI_PSD_REV0_REVISION) { 569 if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
547 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:revision\n")); 570 printk(KERN_ERR PREFIX "Unknown _PSD:revision\n");
548 result = -EFAULT; 571 result = -EFAULT;
549 goto end; 572 goto end;
550 } 573 }