diff options
| author | Len Brown <len.brown@intel.com> | 2004-07-14 07:39:55 -0400 |
|---|---|---|
| committer | Len Brown <lenb@dhcppc3.> | 2004-07-14 07:39:55 -0400 |
| commit | 25bf3b3ea93d26d798595fe7b4e51c671d8fc0c6 (patch) | |
| tree | 1c62a80fb3310109a500314fc94c5f87fd325a7e /drivers/acpi/processor.c | |
| parent | 52fb97fa0cca1e3e1881eb0620299070d17bd1b2 (diff) | |
[ACPI] add SMP suport to processor driver (Venkatesh Pallipadi)
http://bugzilla.kernel.org/show_bug.cgi?id=2615
Diffstat (limited to 'drivers/acpi/processor.c')
| -rw-r--r-- | drivers/acpi/processor.c | 65 |
1 files changed, 55 insertions, 10 deletions
diff --git a/drivers/acpi/processor.c b/drivers/acpi/processor.c index 38e13a1a9098..627135287d71 100644 --- a/drivers/acpi/processor.c +++ b/drivers/acpi/processor.c @@ -44,6 +44,9 @@ #include <asm/system.h> #include <asm/delay.h> #include <asm/uaccess.h> +#include <asm/processor.h> +#include <asm/smp.h> +#include <asm/acpi.h> #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> @@ -859,7 +862,6 @@ static void acpi_processor_ppc_exit(void) { * _PCT and _PSS structures are read out and written into struct * acpi_processor_performance. */ - static int acpi_processor_set_pdc (struct acpi_processor *pr) { acpi_status status = AE_OK; @@ -2146,6 +2148,37 @@ acpi_processor_remove_fs ( return_VALUE(0); } +/* Use the acpiid in MADT to map cpus in case of SMP */ +#ifndef CONFIG_SMP +#define convert_acpiid_to_cpu(acpi_id) (0xff) +#else + +#ifdef CONFIG_IA64 +#define arch_acpiid_to_apicid ia64_acpiid_to_sapicid +#define arch_cpu_to_apicid ia64_cpu_to_sapicid +#define ARCH_BAD_APICID (0xffff) +#else +#define arch_acpiid_to_apicid x86_acpiid_to_apicid +#define arch_cpu_to_apicid x86_cpu_to_apicid +#define ARCH_BAD_APICID (0xff) +#endif + +static u8 convert_acpiid_to_cpu(u8 acpi_id) +{ + u16 apic_id; + int i; + + apic_id = arch_acpiid_to_apicid[acpi_id]; + if (apic_id == ARCH_BAD_APICID) + return -1; + + for (i = 0; i < NR_CPUS; i++) { + if (arch_cpu_to_apicid[i] == apic_id) + return i; + } + return -1; +} +#endif /* -------------------------------------------------------------------------- Driver Interface @@ -2158,7 +2191,8 @@ acpi_processor_get_info ( acpi_status status = 0; union acpi_object object = {0}; struct acpi_buffer buffer = {sizeof(union acpi_object), &object}; - static int cpu_index = 0; + u8 cpu_index; + static int cpu0_initialized; ACPI_FUNCTION_TRACE("acpi_processor_get_info"); @@ -2168,13 +2202,6 @@ acpi_processor_get_info ( if (num_online_cpus() > 1) errata.smp = TRUE; - /* - * Extra Processor objects may be enumerated on MP systems with - * less than the max # of CPUs. They should be ignored. - */ - if ((cpu_index + 1) > num_online_cpus()) - return_VALUE(-ENODEV); - acpi_processor_errata(pr); /* @@ -2206,9 +2233,27 @@ acpi_processor_get_info ( * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c */ - pr->id = cpu_index++; pr->acpi_id = object.processor.proc_id; + cpu_index = convert_acpiid_to_cpu(pr->acpi_id); + + if ( !cpu0_initialized && (cpu_index == 0xff)) { + /* Handle UP system running SMP kernel, with no LAPIC in MADT */ + cpu_index = 0; + } else if (cpu_index > num_online_cpus()) { + /* + * Extra Processor objects may be enumerated on MP systems with + * less than the max # of CPUs. They should be ignored. + */ + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error getting cpuindex for acpiid 0x%x\n", + pr->acpi_id)); + return_VALUE(-ENODEV); + } + cpu0_initialized = 1; + + pr->id = cpu_index; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, pr->acpi_id)); |
