Commit a10214ef authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] Tell the BIOS Linux can handle

Enhanced Speed Step (EST). (Venkatesh Pallipadi)
http://bugzilla.kernel.org/show_bug.cgi?id=2712
parent 25bf3b3e
...@@ -286,6 +286,69 @@ acpi_cpufreq_guess_freq ( ...@@ -286,6 +286,69 @@ 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;
ACPI_FUNCTION_TRACE("acpi_processor_cpu_init_pdc_est");
if (!cpu_has(c, X86_FEATURE_EST))
return_VOID;
/* Initialize pdc. It will be used later. */
if (!obj_list)
return_VOID;
if (!(obj_list->count && obj_list->pointer))
return_VOID;
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_VOID;
}
/* 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;
ACPI_FUNCTION_TRACE("acpi_processor_cpu_init_pdc");
perf->pdc = NULL;
if (cpu_has(c, X86_FEATURE_EST))
acpi_processor_cpu_init_pdc_est(perf, cpu, obj_list);
return_VOID;
}
static int static int
acpi_cpufreq_cpu_init ( acpi_cpufreq_cpu_init (
struct cpufreq_policy *policy) struct cpufreq_policy *policy)
...@@ -295,7 +358,14 @@ acpi_cpufreq_cpu_init ( ...@@ -295,7 +358,14 @@ acpi_cpufreq_cpu_init (
struct cpufreq_acpi_io *data; struct cpufreq_acpi_io *data;
unsigned int result = 0; unsigned int result = 0;
union acpi_object arg0 = {ACPI_TYPE_BUFFER};
u32 arg0_buf[3];
struct acpi_object_list arg_list = {1, &arg0};
ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init"); ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init");
/* 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); data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
if (!data) if (!data)
...@@ -304,7 +374,10 @@ acpi_cpufreq_cpu_init ( ...@@ -304,7 +374,10 @@ acpi_cpufreq_cpu_init (
acpi_io_data[cpu] = data; 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); result = acpi_processor_register_performance(&data->acpi_data, cpu);
data->acpi_data.pdc = NULL;
if (result) if (result)
goto err_free; goto err_free;
......
...@@ -1049,6 +1049,8 @@ acpi_processor_get_performance_info ( ...@@ -1049,6 +1049,8 @@ acpi_processor_get_performance_info (
if (!pr || !pr->performance || !pr->handle) if (!pr || !pr->performance || !pr->handle)
return_VALUE(-EINVAL); return_VALUE(-EINVAL);
acpi_processor_set_pdc(pr);
status = acpi_get_handle(pr->handle, "_PCT", &handle); status = acpi_get_handle(pr->handle, "_PCT", &handle);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
...@@ -1056,8 +1058,6 @@ acpi_processor_get_performance_info ( ...@@ -1056,8 +1058,6 @@ acpi_processor_get_performance_info (
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
} }
acpi_processor_set_pdc(pr);
result = acpi_processor_get_performance_control(pr); result = acpi_processor_get_performance_control(pr);
if (result) if (result)
return_VALUE(result); return_VALUE(result);
......
...@@ -102,6 +102,12 @@ __acpi_release_global_lock (unsigned int *lock) ...@@ -102,6 +102,12 @@ __acpi_release_global_lock (unsigned int *lock)
:"0"(n_hi), "1"(n_lo)) :"0"(n_hi), "1"(n_lo))
/*
* Refer Intel ACPI _PDC support document for bit definitions
*/
#define ACPI_PDC_EST_CAPABILITY_SMP 0xa
#define ACPI_PDC_EST_CAPABILITY_MSR 0x1
#ifdef CONFIG_ACPI_BOOT #ifdef CONFIG_ACPI_BOOT
extern int acpi_lapic; extern int acpi_lapic;
extern int acpi_ioapic; extern int acpi_ioapic;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment