diff options
author | Len Brown <len.brown@intel.com> | 2009-12-24 01:17:21 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-12-24 01:17:21 -0500 |
commit | da3df858c88f7bb420f2517ee9aab238da2e6ed7 (patch) | |
tree | 49c9e69818d7a7fc59ebda96dc7abf17a0f3b088 /drivers/acpi | |
parent | 309ddc53be1766d6ed5411a3dc1782c2040198fa (diff) | |
parent | e59897fe443b5b0a71e135ef4020d1937c9f8901 (diff) |
Merge branch 'pdc' into release
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/processor_core.c | 2 | ||||
-rw-r--r-- | drivers/acpi/processor_pdc.c | 101 |
2 files changed, 80 insertions, 23 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index a19a4ff962ea..9863c98c81ba 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -763,7 +763,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
763 | } | 763 | } |
764 | 764 | ||
765 | /* _PDC call should be done before doing anything else (if reqd.). */ | 765 | /* _PDC call should be done before doing anything else (if reqd.). */ |
766 | acpi_processor_set_pdc(pr); | 766 | acpi_processor_set_pdc(pr->handle); |
767 | 767 | ||
768 | #ifdef CONFIG_CPU_FREQ | 768 | #ifdef CONFIG_CPU_FREQ |
769 | acpi_processor_ppc_has_changed(pr, 0); | 769 | acpi_processor_ppc_has_changed(pr, 0); |
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index b416c32dda04..30e4dc0cdf30 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c | |||
@@ -1,3 +1,12 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 Intel Corporation | ||
3 | * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. | ||
4 | * | ||
5 | * Alex Chiang <achiang@hp.com> | ||
6 | * - Unified x86/ia64 implementations | ||
7 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | ||
8 | * - Added _PDC for platforms with Intel CPUs | ||
9 | */ | ||
1 | #include <linux/dmi.h> | 10 | #include <linux/dmi.h> |
2 | 11 | ||
3 | #include <acpi/acpi_drivers.h> | 12 | #include <acpi/acpi_drivers.h> |
@@ -33,17 +42,66 @@ static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { | |||
33 | {}, | 42 | {}, |
34 | }; | 43 | }; |
35 | 44 | ||
45 | static void acpi_set_pdc_bits(u32 *buf) | ||
46 | { | ||
47 | buf[0] = ACPI_PDC_REVISION_ID; | ||
48 | buf[1] = 1; | ||
49 | |||
50 | /* Enable coordination with firmware's _TSD info */ | ||
51 | buf[2] = ACPI_PDC_SMP_T_SWCOORD; | ||
52 | |||
53 | /* Twiddle arch-specific bits needed for _PDC */ | ||
54 | arch_acpi_set_pdc_bits(buf); | ||
55 | } | ||
56 | |||
57 | static struct acpi_object_list *acpi_processor_alloc_pdc(void) | ||
58 | { | ||
59 | struct acpi_object_list *obj_list; | ||
60 | union acpi_object *obj; | ||
61 | u32 *buf; | ||
62 | |||
63 | /* allocate and initialize pdc. It will be used later. */ | ||
64 | obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); | ||
65 | if (!obj_list) { | ||
66 | printk(KERN_ERR "Memory allocation error\n"); | ||
67 | return NULL; | ||
68 | } | ||
69 | |||
70 | obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); | ||
71 | if (!obj) { | ||
72 | printk(KERN_ERR "Memory allocation error\n"); | ||
73 | kfree(obj_list); | ||
74 | return NULL; | ||
75 | } | ||
76 | |||
77 | buf = kmalloc(12, GFP_KERNEL); | ||
78 | if (!buf) { | ||
79 | printk(KERN_ERR "Memory allocation error\n"); | ||
80 | kfree(obj); | ||
81 | kfree(obj_list); | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
85 | acpi_set_pdc_bits(buf); | ||
86 | |||
87 | obj->type = ACPI_TYPE_BUFFER; | ||
88 | obj->buffer.length = 12; | ||
89 | obj->buffer.pointer = (u8 *) buf; | ||
90 | obj_list->count = 1; | ||
91 | obj_list->pointer = obj; | ||
92 | |||
93 | return obj_list; | ||
94 | } | ||
95 | |||
36 | /* | 96 | /* |
37 | * _PDC is required for a BIOS-OS handshake for most of the newer | 97 | * _PDC is required for a BIOS-OS handshake for most of the newer |
38 | * ACPI processor features. | 98 | * ACPI processor features. |
39 | */ | 99 | */ |
40 | static int acpi_processor_eval_pdc(struct acpi_processor *pr) | 100 | static int |
101 | acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) | ||
41 | { | 102 | { |
42 | struct acpi_object_list *pdc_in = pr->pdc; | ||
43 | acpi_status status = AE_OK; | 103 | acpi_status status = AE_OK; |
44 | 104 | ||
45 | if (!pdc_in) | ||
46 | return status; | ||
47 | if (idle_nomwait) { | 105 | if (idle_nomwait) { |
48 | /* | 106 | /* |
49 | * If mwait is disabled for CPU C-states, the C2C3_FFH access | 107 | * If mwait is disabled for CPU C-states, the C2C3_FFH access |
@@ -58,7 +116,7 @@ static int acpi_processor_eval_pdc(struct acpi_processor *pr) | |||
58 | buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); | 116 | buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); |
59 | 117 | ||
60 | } | 118 | } |
61 | status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL); | 119 | status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); |
62 | 120 | ||
63 | if (ACPI_FAILURE(status)) | 121 | if (ACPI_FAILURE(status)) |
64 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 122 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -67,30 +125,29 @@ static int acpi_processor_eval_pdc(struct acpi_processor *pr) | |||
67 | return status; | 125 | return status; |
68 | } | 126 | } |
69 | 127 | ||
70 | void acpi_processor_set_pdc(struct acpi_processor *pr) | 128 | void acpi_processor_set_pdc(acpi_handle handle) |
71 | { | 129 | { |
72 | arch_acpi_processor_init_pdc(pr); | 130 | struct acpi_object_list *obj_list; |
73 | acpi_processor_eval_pdc(pr); | 131 | |
74 | arch_acpi_processor_cleanup_pdc(pr); | 132 | if (arch_has_acpi_pdc() == false) |
133 | return; | ||
134 | |||
135 | obj_list = acpi_processor_alloc_pdc(); | ||
136 | if (!obj_list) | ||
137 | return; | ||
138 | |||
139 | acpi_processor_eval_pdc(handle, obj_list); | ||
140 | |||
141 | kfree(obj_list->pointer->buffer.pointer); | ||
142 | kfree(obj_list->pointer); | ||
143 | kfree(obj_list); | ||
75 | } | 144 | } |
76 | EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); | 145 | EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); |
77 | 146 | ||
78 | static acpi_status | 147 | static acpi_status |
79 | early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) | 148 | early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) |
80 | { | 149 | { |
81 | struct acpi_processor pr; | 150 | acpi_processor_set_pdc(handle); |
82 | |||
83 | pr.handle = handle; | ||
84 | |||
85 | /* x86 implementation looks at pr.id to determine some | ||
86 | * CPU capabilites. We can just hard code to 0 since we're | ||
87 | * assuming the CPUs in the system are homogenous and all | ||
88 | * have the same capabilities. | ||
89 | */ | ||
90 | pr.id = 0; | ||
91 | |||
92 | acpi_processor_set_pdc(&pr); | ||
93 | |||
94 | return AE_OK; | 151 | return AE_OK; |
95 | } | 152 | } |
96 | 153 | ||