diff options
author | Alex Chiang <achiang@hp.com> | 2010-02-22 14:11:29 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-03-14 21:17:20 -0400 |
commit | 5d554a7bb0643a6151a84319bfeba8270bf5269e (patch) | |
tree | 943d8107099270ced84f941f5b498f280132ff1f /drivers/acpi | |
parent | 78ed8bd2944b6400f742306e5fe9d1b9b6bf18ba (diff) |
ACPI: processor: add internal processor_physically_present()
Detect if a processor is physically present before evaluating _PDC.
We want this because some BIOS will provide a _PDC even for processors
that are not present. These bogus _PDC methods then attempt to load
non-existent tables, which causes problems.
Avoid those bogus landmines.
Acked-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Alex Chiang <achiang@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/processor_core.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 9ae5cc21f258..f0c68c1b86dd 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -194,6 +194,45 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | |||
194 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); | 194 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); |
195 | #endif | 195 | #endif |
196 | 196 | ||
197 | static bool processor_physically_present(acpi_handle handle) | ||
198 | { | ||
199 | int cpuid, type; | ||
200 | u32 acpi_id; | ||
201 | acpi_status status; | ||
202 | acpi_object_type acpi_type; | ||
203 | unsigned long long tmp; | ||
204 | union acpi_object object = { 0 }; | ||
205 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | ||
206 | |||
207 | status = acpi_get_type(handle, &acpi_type); | ||
208 | if (ACPI_FAILURE(status)) | ||
209 | return false; | ||
210 | |||
211 | switch (acpi_type) { | ||
212 | case ACPI_TYPE_PROCESSOR: | ||
213 | status = acpi_evaluate_object(handle, NULL, NULL, &buffer); | ||
214 | if (ACPI_FAILURE(status)) | ||
215 | return false; | ||
216 | acpi_id = object.processor.proc_id; | ||
217 | break; | ||
218 | case ACPI_TYPE_DEVICE: | ||
219 | status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp); | ||
220 | if (ACPI_FAILURE(status)) | ||
221 | return false; | ||
222 | acpi_id = tmp; | ||
223 | break; | ||
224 | default: | ||
225 | return false; | ||
226 | } | ||
227 | |||
228 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; | ||
229 | cpuid = acpi_get_cpuid(handle, type, acpi_id); | ||
230 | |||
231 | if (cpuid == -1) | ||
232 | return false; | ||
233 | |||
234 | return true; | ||
235 | } | ||
197 | 236 | ||
198 | static void acpi_set_pdc_bits(u32 *buf) | 237 | static void acpi_set_pdc_bits(u32 *buf) |
199 | { | 238 | { |
@@ -335,6 +374,9 @@ static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = { | |||
335 | static acpi_status | 374 | static acpi_status |
336 | early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) | 375 | early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) |
337 | { | 376 | { |
377 | if (processor_physically_present(handle) == false) | ||
378 | return AE_OK; | ||
379 | |||
338 | acpi_processor_set_pdc(handle); | 380 | acpi_processor_set_pdc(handle); |
339 | return AE_OK; | 381 | return AE_OK; |
340 | } | 382 | } |