summaryrefslogtreecommitdiff
path: root/drivers/acpi/processor.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2004-07-14 07:39:55 -0400
committerLen Brown <lenb@dhcppc3.>2004-07-14 07:39:55 -0400
commit25bf3b3ea93d26d798595fe7b4e51c671d8fc0c6 (patch)
tree1c62a80fb3310109a500314fc94c5f87fd325a7e /drivers/acpi/processor.c
parent52fb97fa0cca1e3e1881eb0620299070d17bd1b2 (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.c65
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));