]> git.hungrycats.org Git - linux/commitdiff
[ACPI] Tell the BIOS Linux can handle
authorLen Brown <len.brown@intel.com>
Wed, 14 Jul 2004 11:47:04 +0000 (07:47 -0400)
committerLen Brown <lenb@dhcppc3.>
Wed, 14 Jul 2004 11:47:04 +0000 (07:47 -0400)
Enhanced Speed Step (EST). (Venkatesh Pallipadi)
http://bugzilla.kernel.org/show_bug.cgi?id=2712

arch/i386/kernel/cpu/cpufreq/acpi.c
drivers/acpi/processor.c
include/asm-i386/acpi.h

index 8c56687f071b0a15a152fa763817e7d820d525c7..4ba912733cbd46a0e6600ab51ffa9167d6dd2db4 100644 (file)
@@ -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
 acpi_cpufreq_cpu_init (
        struct cpufreq_policy   *policy)
@@ -295,7 +358,14 @@ 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};
+
        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);
        if (!data)
@@ -304,7 +374,10 @@ 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;
 
index 627135287d71ee20a15cd283844b7dfbf61cb5fc..99819f492703c13069905ee3e31db8a842d7c5be 100644 (file)
@@ -1049,6 +1049,8 @@ acpi_processor_get_performance_info (
        if (!pr || !pr->performance || !pr->handle)
                return_VALUE(-EINVAL);
 
+       acpi_processor_set_pdc(pr);
+
        status = acpi_get_handle(pr->handle, "_PCT", &handle);
        if (ACPI_FAILURE(status)) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
@@ -1056,8 +1058,6 @@ acpi_processor_get_performance_info (
                return_VALUE(-ENODEV);
        }
 
-       acpi_processor_set_pdc(pr);
-
        result = acpi_processor_get_performance_control(pr);
        if (result)
                return_VALUE(result);
index ce1852636faa5fdd027e234896d3e04d5bae6a55..9ab8efc72889035edc3964a0b698a4169b57b101 100644 (file)
@@ -102,6 +102,12 @@ __acpi_release_global_lock (unsigned int *lock)
         :"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 
 extern int acpi_lapic;
 extern int acpi_ioapic;