[ACPI] Avoid BIOS inflicted crashes by evaluating _PDC only once
Linux invokes the AML _PDC method (Processor Driver Capabilities) to tell the BIOS what features it can handle. While the ACPI spec says nothing about the OS invoking _PDC multiple times, doing so with changing bits seems to hopelessly confuse the BIOS on multiple platforms up to and including crashing the system. Factor out the _PDC invocation so Linux invokes it only once. http://bugzilla.kernel.org/show_bug.cgi?id=5483 Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
parent
d2149b5423
commit
05131ecc99
|
@ -3,6 +3,6 @@ obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o
|
|||
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o
|
||||
|
||||
ifneq ($(CONFIG_ACPI_PROCESSOR),)
|
||||
obj-y += cstate.o
|
||||
obj-y += cstate.o processor.o
|
||||
endif
|
||||
|
||||
|
|
|
@ -14,64 +14,6 @@
|
|||
#include <acpi/processor.h>
|
||||
#include <asm/acpi.h>
|
||||
|
||||
static void acpi_processor_power_init_intel_pdc(struct acpi_processor_power
|
||||
*pow)
|
||||
{
|
||||
struct acpi_object_list *obj_list;
|
||||
union acpi_object *obj;
|
||||
u32 *buf;
|
||||
|
||||
/* allocate and initialize pdc. It will be used later. */
|
||||
obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
|
||||
if (!obj_list) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
|
||||
if (!obj) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
kfree(obj_list);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = kmalloc(12, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
kfree(obj);
|
||||
kfree(obj_list);
|
||||
return;
|
||||
}
|
||||
|
||||
buf[0] = ACPI_PDC_REVISION_ID;
|
||||
buf[1] = 1;
|
||||
buf[2] = ACPI_PDC_C_CAPABILITY_SMP;
|
||||
|
||||
obj->type = ACPI_TYPE_BUFFER;
|
||||
obj->buffer.length = 12;
|
||||
obj->buffer.pointer = (u8 *) buf;
|
||||
obj_list->count = 1;
|
||||
obj_list->pointer = obj;
|
||||
pow->pdc = obj_list;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize _PDC data based on the CPU vendor */
|
||||
void acpi_processor_power_init_pdc(struct acpi_processor_power *pow,
|
||||
unsigned int cpu)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data + cpu;
|
||||
|
||||
pow->pdc = NULL;
|
||||
if (c->x86_vendor == X86_VENDOR_INTEL)
|
||||
acpi_processor_power_init_intel_pdc(pow);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_processor_power_init_pdc);
|
||||
|
||||
/*
|
||||
* Initialize bm_flags based on the CPU cache properties
|
||||
* On SMP it depends on cache configuration
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* arch/i386/kernel/acpi/processor.c
|
||||
*
|
||||
* Copyright (C) 2005 Intel Corporation
|
||||
* Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
|
||||
* - Added _PDC for platforms with Intel CPUs
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <acpi/processor.h>
|
||||
#include <asm/acpi.h>
|
||||
|
||||
static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
|
||||
{
|
||||
struct acpi_object_list *obj_list;
|
||||
union acpi_object *obj;
|
||||
u32 *buf;
|
||||
|
||||
/* allocate and initialize pdc. It will be used later. */
|
||||
obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
|
||||
if (!obj_list) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
|
||||
if (!obj) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
kfree(obj_list);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = kmalloc(12, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
kfree(obj);
|
||||
kfree(obj_list);
|
||||
return;
|
||||
}
|
||||
|
||||
buf[0] = ACPI_PDC_REVISION_ID;
|
||||
buf[1] = 1;
|
||||
buf[2] = ACPI_PDC_C_CAPABILITY_SMP;
|
||||
|
||||
if (cpu_has(c, X86_FEATURE_EST))
|
||||
buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
|
||||
|
||||
obj->type = ACPI_TYPE_BUFFER;
|
||||
obj->buffer.length = 12;
|
||||
obj->buffer.pointer = (u8 *) buf;
|
||||
obj_list->count = 1;
|
||||
obj_list->pointer = obj;
|
||||
pr->pdc = obj_list;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize _PDC data based on the CPU vendor */
|
||||
void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
|
||||
{
|
||||
unsigned int cpu = pr->id;
|
||||
struct cpuinfo_x86 *c = cpu_data + cpu;
|
||||
|
||||
pr->pdc = NULL;
|
||||
if (c->x86_vendor == X86_VENDOR_INTEL)
|
||||
init_intel_pdc(pr, c);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(arch_acpi_processor_init_pdc);
|
|
@ -297,68 +297,6 @@ acpi_cpufreq_guess_freq (
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* acpi_processor_cpu_init_pdc_est - let BIOS know about the SMP capabilities
|
||||
* of this driver
|
||||
* @perf: processor-specific acpi_io_data struct
|
||||
* @cpu: CPU being initialized
|
||||
*
|
||||
* To avoid issues with legacy OSes, some BIOSes require to be informed of
|
||||
* the SMP capabilities of OS P-state driver. Here we set the bits in _PDC
|
||||
* accordingly, for Enhanced Speedstep. Actual call to _PDC is done in
|
||||
* driver/acpi/processor.c
|
||||
*/
|
||||
static void
|
||||
acpi_processor_cpu_init_pdc_est(
|
||||
struct acpi_processor_performance *perf,
|
||||
unsigned int cpu,
|
||||
struct acpi_object_list *obj_list
|
||||
)
|
||||
{
|
||||
union acpi_object *obj;
|
||||
u32 *buf;
|
||||
struct cpuinfo_x86 *c = cpu_data + cpu;
|
||||
dprintk("acpi_processor_cpu_init_pdc_est\n");
|
||||
|
||||
if (!cpu_has(c, X86_FEATURE_EST))
|
||||
return;
|
||||
|
||||
/* Initialize pdc. It will be used later. */
|
||||
if (!obj_list)
|
||||
return;
|
||||
|
||||
if (!(obj_list->count && obj_list->pointer))
|
||||
return;
|
||||
|
||||
obj = obj_list->pointer;
|
||||
if ((obj->buffer.length == 12) && obj->buffer.pointer) {
|
||||
buf = (u32 *)obj->buffer.pointer;
|
||||
buf[0] = ACPI_PDC_REVISION_ID;
|
||||
buf[1] = 1;
|
||||
buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
|
||||
perf->pdc = obj_list;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* CPU specific PDC initialization */
|
||||
static void
|
||||
acpi_processor_cpu_init_pdc(
|
||||
struct acpi_processor_performance *perf,
|
||||
unsigned int cpu,
|
||||
struct acpi_object_list *obj_list
|
||||
)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data + cpu;
|
||||
dprintk("acpi_processor_cpu_init_pdc\n");
|
||||
perf->pdc = NULL;
|
||||
if (cpu_has(c, X86_FEATURE_EST))
|
||||
acpi_processor_cpu_init_pdc_est(perf, cpu, obj_list);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
acpi_cpufreq_cpu_init (
|
||||
struct cpufreq_policy *policy)
|
||||
|
@ -373,9 +311,6 @@ acpi_cpufreq_cpu_init (
|
|||
struct acpi_object_list arg_list = {1, &arg0};
|
||||
|
||||
dprintk("acpi_cpufreq_cpu_init\n");
|
||||
/* setup arg_list for _PDC settings */
|
||||
arg0.buffer.length = 12;
|
||||
arg0.buffer.pointer = (u8 *) arg0_buf;
|
||||
|
||||
data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
|
||||
if (!data)
|
||||
|
@ -383,9 +318,7 @@ acpi_cpufreq_cpu_init (
|
|||
|
||||
acpi_io_data[cpu] = data;
|
||||
|
||||
acpi_processor_cpu_init_pdc(&data->acpi_data, cpu, &arg_list);
|
||||
result = acpi_processor_register_performance(&data->acpi_data, cpu);
|
||||
data->acpi_data.pdc = NULL;
|
||||
|
||||
if (result)
|
||||
goto err_free;
|
||||
|
|
|
@ -364,22 +364,10 @@ static struct acpi_processor_performance p;
|
|||
*/
|
||||
static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
|
||||
{
|
||||
union acpi_object arg0 = {ACPI_TYPE_BUFFER};
|
||||
u32 arg0_buf[3];
|
||||
struct acpi_object_list arg_list = {1, &arg0};
|
||||
unsigned long cur_freq;
|
||||
int result = 0, i;
|
||||
unsigned int cpu = policy->cpu;
|
||||
|
||||
/* _PDC settings */
|
||||
arg0.buffer.length = 12;
|
||||
arg0.buffer.pointer = (u8 *) arg0_buf;
|
||||
arg0_buf[0] = ACPI_PDC_REVISION_ID;
|
||||
arg0_buf[1] = 1;
|
||||
arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP_MSR;
|
||||
|
||||
p.pdc = &arg_list;
|
||||
|
||||
/* register with ACPI core */
|
||||
if (acpi_processor_register_performance(&p, cpu)) {
|
||||
dprintk(KERN_INFO PFX "obtaining ACPI data failed\n");
|
||||
|
|
|
@ -1 +1,6 @@
|
|||
obj-$(CONFIG_IA64_ACPI_CPUFREQ) += acpi-cpufreq.o
|
||||
|
||||
ifneq ($(CONFIG_ACPI_PROCESSOR),)
|
||||
obj-y += acpi-processor.o
|
||||
endif
|
||||
|
||||
|
|
|
@ -269,48 +269,6 @@ acpi_cpufreq_verify (
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* processor_init_pdc - let BIOS know about the SMP capabilities
|
||||
* of this driver
|
||||
* @perf: processor-specific acpi_io_data struct
|
||||
* @cpu: CPU being initialized
|
||||
*
|
||||
* To avoid issues with legacy OSes, some BIOSes require to be informed of
|
||||
* the SMP capabilities of OS P-state driver. Here we set the bits in _PDC
|
||||
* accordingly. Actual call to _PDC is done in driver/acpi/processor.c
|
||||
*/
|
||||
static void
|
||||
processor_init_pdc (
|
||||
struct acpi_processor_performance *perf,
|
||||
unsigned int cpu,
|
||||
struct acpi_object_list *obj_list
|
||||
)
|
||||
{
|
||||
union acpi_object *obj;
|
||||
u32 *buf;
|
||||
|
||||
dprintk("processor_init_pdc\n");
|
||||
|
||||
perf->pdc = NULL;
|
||||
/* Initialize pdc. It will be used later. */
|
||||
if (!obj_list)
|
||||
return;
|
||||
|
||||
if (!(obj_list->count && obj_list->pointer))
|
||||
return;
|
||||
|
||||
obj = obj_list->pointer;
|
||||
if ((obj->buffer.length == 12) && obj->buffer.pointer) {
|
||||
buf = (u32 *)obj->buffer.pointer;
|
||||
buf[0] = ACPI_PDC_REVISION_ID;
|
||||
buf[1] = 1;
|
||||
buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
|
||||
perf->pdc = obj_list;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
acpi_cpufreq_cpu_init (
|
||||
struct cpufreq_policy *policy)
|
||||
|
@ -320,14 +278,7 @@ acpi_cpufreq_cpu_init (
|
|||
struct cpufreq_acpi_io *data;
|
||||
unsigned int result = 0;
|
||||
|
||||
union acpi_object arg0 = {ACPI_TYPE_BUFFER};
|
||||
u32 arg0_buf[3];
|
||||
struct acpi_object_list arg_list = {1, &arg0};
|
||||
|
||||
dprintk("acpi_cpufreq_cpu_init\n");
|
||||
/* setup arg_list for _PDC settings */
|
||||
arg0.buffer.length = 12;
|
||||
arg0.buffer.pointer = (u8 *) arg0_buf;
|
||||
|
||||
data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
|
||||
if (!data)
|
||||
|
@ -337,9 +288,7 @@ acpi_cpufreq_cpu_init (
|
|||
|
||||
acpi_io_data[cpu] = data;
|
||||
|
||||
processor_init_pdc(&data->acpi_data, cpu, &arg_list);
|
||||
result = acpi_processor_register_performance(&data->acpi_data, cpu);
|
||||
data->acpi_data.pdc = NULL;
|
||||
|
||||
if (result)
|
||||
goto err_free;
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* arch/ia64/kernel/cpufreq/processor.c
|
||||
*
|
||||
* Copyright (C) 2005 Intel Corporation
|
||||
* Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
|
||||
* - Added _PDC for platforms with Intel CPUs
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <acpi/processor.h>
|
||||
#include <asm/acpi.h>
|
||||
|
||||
static void init_intel_pdc(struct acpi_processor *pr)
|
||||
{
|
||||
struct acpi_object_list *obj_list;
|
||||
union acpi_object *obj;
|
||||
u32 *buf;
|
||||
|
||||
/* allocate and initialize pdc. It will be used later. */
|
||||
obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
|
||||
if (!obj_list) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
|
||||
if (!obj) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
kfree(obj_list);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = kmalloc(12, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
kfree(obj);
|
||||
kfree(obj_list);
|
||||
return;
|
||||
}
|
||||
|
||||
buf[0] = ACPI_PDC_REVISION_ID;
|
||||
buf[1] = 1;
|
||||
buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
|
||||
|
||||
obj->type = ACPI_TYPE_BUFFER;
|
||||
obj->buffer.length = 12;
|
||||
obj->buffer.pointer = (u8 *) buf;
|
||||
obj_list->count = 1;
|
||||
obj_list->pointer = obj;
|
||||
pr->pdc = obj_list;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize _PDC data based on the CPU vendor */
|
||||
void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
|
||||
{
|
||||
pr->pdc = NULL;
|
||||
init_intel_pdc(pr);
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(arch_acpi_processor_init_pdc);
|
|
@ -1,3 +1,8 @@
|
|||
obj-y := boot.o
|
||||
boot-y := ../../../i386/kernel/acpi/boot.o
|
||||
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o
|
||||
|
||||
ifneq ($(CONFIG_ACPI_PROCESSOR),)
|
||||
obj-y += processor.o
|
||||
endif
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* arch/x86_64/kernel/acpi/processor.c
|
||||
*
|
||||
* Copyright (C) 2005 Intel Corporation
|
||||
* Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
|
||||
* - Added _PDC for platforms with Intel CPUs
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <acpi/processor.h>
|
||||
#include <asm/acpi.h>
|
||||
|
||||
static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
|
||||
{
|
||||
struct acpi_object_list *obj_list;
|
||||
union acpi_object *obj;
|
||||
u32 *buf;
|
||||
|
||||
/* allocate and initialize pdc. It will be used later. */
|
||||
obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
|
||||
if (!obj_list) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
|
||||
if (!obj) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
kfree(obj_list);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = kmalloc(12, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
printk(KERN_ERR "Memory allocation error\n");
|
||||
kfree(obj);
|
||||
kfree(obj_list);
|
||||
return;
|
||||
}
|
||||
|
||||
buf[0] = ACPI_PDC_REVISION_ID;
|
||||
buf[1] = 1;
|
||||
buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
|
||||
|
||||
obj->type = ACPI_TYPE_BUFFER;
|
||||
obj->buffer.length = 12;
|
||||
obj->buffer.pointer = (u8 *) buf;
|
||||
obj_list->count = 1;
|
||||
obj_list->pointer = obj;
|
||||
pr->pdc = obj_list;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize _PDC data based on the CPU vendor */
|
||||
void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
|
||||
{
|
||||
unsigned int cpu = pr->id;
|
||||
struct cpuinfo_x86 *c = cpu_data + cpu;
|
||||
|
||||
pr->pdc = NULL;
|
||||
if (c->x86_vendor == X86_VENDOR_INTEL && cpu_has(c, X86_FEATURE_EST))
|
||||
init_intel_pdc(pr, c);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(arch_acpi_processor_init_pdc);
|
|
@ -253,31 +253,21 @@ static int acpi_processor_errata(struct acpi_processor *pr)
|
|||
* _PDC is required for a BIOS-OS handshake for most of the newer
|
||||
* ACPI processor features.
|
||||
*/
|
||||
|
||||
int acpi_processor_set_pdc(struct acpi_processor *pr,
|
||||
struct acpi_object_list *pdc_in)
|
||||
static int acpi_processor_set_pdc(struct acpi_processor *pr)
|
||||
{
|
||||
struct acpi_object_list *pdc_in = pr->pdc;
|
||||
acpi_status status = AE_OK;
|
||||
u32 arg0_buf[3];
|
||||
union acpi_object arg0 = { ACPI_TYPE_BUFFER };
|
||||
struct acpi_object_list no_object = { 1, &arg0 };
|
||||
struct acpi_object_list *pdc;
|
||||
|
||||
ACPI_FUNCTION_TRACE("acpi_processor_set_pdc");
|
||||
|
||||
arg0.buffer.length = 12;
|
||||
arg0.buffer.pointer = (u8 *) arg0_buf;
|
||||
arg0_buf[0] = ACPI_PDC_REVISION_ID;
|
||||
arg0_buf[1] = 0;
|
||||
arg0_buf[2] = 0;
|
||||
if (!pdc_in)
|
||||
return_VALUE(status);
|
||||
|
||||
pdc = (pdc_in) ? pdc_in : &no_object;
|
||||
status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL);
|
||||
|
||||
status = acpi_evaluate_object(pr->handle, "_PDC", pdc, NULL);
|
||||
|
||||
if ((ACPI_FAILURE(status)) && (pdc_in))
|
||||
if (ACPI_FAILURE(status))
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Error evaluating _PDC, using legacy perf. control...\n"));
|
||||
"Could not evaluate _PDC, using legacy perf. control...\n"));
|
||||
|
||||
return_VALUE(status);
|
||||
}
|
||||
|
@ -574,6 +564,10 @@ static int acpi_processor_start(struct acpi_device *device)
|
|||
"Error installing device notify handler\n"));
|
||||
}
|
||||
|
||||
/* _PDC call should be done before doing anything else (if reqd.). */
|
||||
arch_acpi_processor_init_pdc(pr);
|
||||
acpi_processor_set_pdc(pr);
|
||||
|
||||
acpi_processor_power_init(pr, device);
|
||||
|
||||
if (pr->flags.throttling) {
|
||||
|
|
|
@ -1014,8 +1014,6 @@ int acpi_processor_power_init(struct acpi_processor *pr,
|
|||
}
|
||||
}
|
||||
|
||||
acpi_processor_power_init_pdc(&(pr->power), pr->id);
|
||||
acpi_processor_set_pdc(pr, pr->power.pdc);
|
||||
acpi_processor_get_power_info(pr);
|
||||
|
||||
/*
|
||||
|
|
|
@ -315,8 +315,6 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
|
|||
if (!pr || !pr->performance || !pr->handle)
|
||||
return_VALUE(-EINVAL);
|
||||
|
||||
acpi_processor_set_pdc(pr, pr->performance->pdc);
|
||||
|
||||
status = acpi_get_handle(pr->handle, "_PCT", &handle);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
#define ACPI_PDC_C_C1_FFH (0x0100)
|
||||
|
||||
#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \
|
||||
ACPI_PDC_C_C1_HALT)
|
||||
|
||||
#define ACPI_PDC_EST_CAPABILITY_SMP_MSR (ACPI_PDC_EST_CAPABILITY_SMP | \
|
||||
ACPI_PDC_C_C1_HALT | \
|
||||
ACPI_PDC_P_FFH)
|
||||
|
||||
#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \
|
||||
|
|
|
@ -62,9 +62,6 @@ struct acpi_processor_power {
|
|||
u32 bm_activity;
|
||||
int count;
|
||||
struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
|
||||
|
||||
/* the _PDC objects passed by the driver, if any */
|
||||
struct acpi_object_list *pdc;
|
||||
};
|
||||
|
||||
/* Performance Management */
|
||||
|
@ -96,8 +93,6 @@ struct acpi_processor_performance {
|
|||
unsigned int state_count;
|
||||
struct acpi_processor_px *states;
|
||||
|
||||
/* the _PDC objects passed by the driver, if any */
|
||||
struct acpi_object_list *pdc;
|
||||
};
|
||||
|
||||
/* Throttling Control */
|
||||
|
@ -151,6 +146,9 @@ struct acpi_processor {
|
|||
struct acpi_processor_performance *performance;
|
||||
struct acpi_processor_throttling throttling;
|
||||
struct acpi_processor_limit limit;
|
||||
|
||||
/* the _PDC objects for this processor, if any */
|
||||
struct acpi_object_list *pdc;
|
||||
};
|
||||
|
||||
struct acpi_processor_errata {
|
||||
|
@ -178,22 +176,12 @@ int acpi_processor_notify_smm(struct module *calling_module);
|
|||
extern struct acpi_processor *processors[NR_CPUS];
|
||||
extern struct acpi_processor_errata errata;
|
||||
|
||||
int acpi_processor_set_pdc(struct acpi_processor *pr,
|
||||
struct acpi_object_list *pdc_in);
|
||||
void arch_acpi_processor_init_pdc(struct acpi_processor *pr);
|
||||
|
||||
#ifdef ARCH_HAS_POWER_PDC_INIT
|
||||
void acpi_processor_power_init_pdc(struct acpi_processor_power *pow,
|
||||
unsigned int cpu);
|
||||
#ifdef ARCH_HAS_POWER_INIT
|
||||
void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
|
||||
unsigned int cpu);
|
||||
#else
|
||||
static inline void acpi_processor_power_init_pdc(struct acpi_processor_power
|
||||
*pow, unsigned int cpu)
|
||||
{
|
||||
pow->pdc = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void acpi_processor_power_init_bm_check(struct
|
||||
acpi_processor_flags
|
||||
*flags, unsigned int cpu)
|
||||
|
|
|
@ -179,7 +179,7 @@ extern void acpi_reserve_bootmem(void);
|
|||
|
||||
extern u8 x86_acpiid_to_apicid[];
|
||||
|
||||
#define ARCH_HAS_POWER_PDC_INIT 1
|
||||
#define ARCH_HAS_POWER_INIT 1
|
||||
|
||||
#endif /*__KERNEL__*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue