diff options
| author | David Woodhouse <dwmw2@infradead.org> | 2007-04-26 04:31:28 -0400 |
|---|---|---|
| committer | David Woodhouse <dwmw2@infradead.org> | 2007-04-26 04:31:28 -0400 |
| commit | ef2e58ea6b9931c3a4816c66593da49bb20e3b24 (patch) | |
| tree | ce7432add3becbe78de4ea06425cd2d9e91f4ada /drivers/acpi/tables.c | |
| parent | 06d63cc51d47f572009138a7f3ac34d95773405d (diff) | |
| parent | de46c33745f5e2ad594c72f2cf5f490861b16ce1 (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/acpi/tables.c')
| -rw-r--r-- | drivers/acpi/tables.c | 57 |
1 files changed, 52 insertions, 5 deletions
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 849e2c361804..c3419182c9a7 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
| @@ -42,7 +42,9 @@ static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; | |||
| 42 | 42 | ||
| 43 | static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; | 43 | static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; |
| 44 | 44 | ||
| 45 | void acpi_table_print_madt_entry(struct acpi_subtable_header * header) | 45 | static int acpi_apic_instance __initdata; |
| 46 | |||
| 47 | void acpi_table_print_madt_entry(struct acpi_subtable_header *header) | ||
| 46 | { | 48 | { |
| 47 | if (!header) | 49 | if (!header) |
| 48 | return; | 50 | return; |
| @@ -183,8 +185,10 @@ acpi_table_parse_entries(char *id, | |||
| 183 | if (!handler) | 185 | if (!handler) |
| 184 | return -EINVAL; | 186 | return -EINVAL; |
| 185 | 187 | ||
| 186 | /* Locate the table (if exists). There should only be one. */ | 188 | if (strncmp(id, ACPI_SIG_MADT, 4) == 0) |
| 187 | acpi_get_table(id, 0, &table_header); | 189 | acpi_get_table(id, acpi_apic_instance, &table_header); |
| 190 | else | ||
| 191 | acpi_get_table(id, 0, &table_header); | ||
| 188 | 192 | ||
| 189 | if (!table_header) { | 193 | if (!table_header) { |
| 190 | printk(KERN_WARNING PREFIX "%4.4s not present\n", id); | 194 | printk(KERN_WARNING PREFIX "%4.4s not present\n", id); |
| @@ -237,10 +241,15 @@ acpi_table_parse_madt(enum acpi_madt_type id, | |||
| 237 | int __init acpi_table_parse(char *id, acpi_table_handler handler) | 241 | int __init acpi_table_parse(char *id, acpi_table_handler handler) |
| 238 | { | 242 | { |
| 239 | struct acpi_table_header *table = NULL; | 243 | struct acpi_table_header *table = NULL; |
| 244 | |||
| 240 | if (!handler) | 245 | if (!handler) |
| 241 | return -EINVAL; | 246 | return -EINVAL; |
| 242 | 247 | ||
| 243 | acpi_get_table(id, 0, &table); | 248 | if (strncmp(id, ACPI_SIG_MADT, 4) == 0) |
| 249 | acpi_get_table(id, acpi_apic_instance, &table); | ||
| 250 | else | ||
| 251 | acpi_get_table(id, 0, &table); | ||
| 252 | |||
| 244 | if (table) { | 253 | if (table) { |
| 245 | handler(table); | 254 | handler(table); |
| 246 | return 0; | 255 | return 0; |
| @@ -248,6 +257,31 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) | |||
| 248 | return 1; | 257 | return 1; |
| 249 | } | 258 | } |
| 250 | 259 | ||
| 260 | /* | ||
| 261 | * The BIOS is supposed to supply a single APIC/MADT, | ||
| 262 | * but some report two. Provide a knob to use either. | ||
| 263 | * (don't you wish instance 0 and 1 were not the same?) | ||
| 264 | */ | ||
| 265 | static void __init check_multiple_madt(void) | ||
| 266 | { | ||
| 267 | struct acpi_table_header *table = NULL; | ||
| 268 | |||
| 269 | acpi_get_table(ACPI_SIG_MADT, 2, &table); | ||
| 270 | if (table) { | ||
| 271 | printk(KERN_WARNING PREFIX | ||
| 272 | "BIOS bug: multiple APIC/MADT found," | ||
| 273 | " using %d\n", acpi_apic_instance); | ||
| 274 | printk(KERN_WARNING PREFIX | ||
| 275 | "If \"acpi_apic_instance=%d\" works better, " | ||
| 276 | "notify linux-acpi@vger.kernel.org\n", | ||
| 277 | acpi_apic_instance ? 0 : 2); | ||
| 278 | |||
| 279 | } else | ||
| 280 | acpi_apic_instance = 0; | ||
| 281 | |||
| 282 | return; | ||
| 283 | } | ||
| 284 | |||
| 251 | /* | 285 | /* |
| 252 | * acpi_table_init() | 286 | * acpi_table_init() |
| 253 | * | 287 | * |
| @@ -257,9 +291,22 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) | |||
| 257 | * result: sdt_entry[] is initialized | 291 | * result: sdt_entry[] is initialized |
| 258 | */ | 292 | */ |
| 259 | 293 | ||
| 260 | |||
| 261 | int __init acpi_table_init(void) | 294 | int __init acpi_table_init(void) |
| 262 | { | 295 | { |
| 263 | acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); | 296 | acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); |
| 297 | check_multiple_madt(); | ||
| 298 | return 0; | ||
| 299 | } | ||
| 300 | |||
| 301 | static int __init acpi_parse_apic_instance(char *str) | ||
| 302 | { | ||
| 303 | |||
| 304 | acpi_apic_instance = simple_strtoul(str, NULL, 0); | ||
| 305 | |||
| 306 | printk(KERN_NOTICE PREFIX "Shall use APIC/MADT table %d\n", | ||
| 307 | acpi_apic_instance); | ||
| 308 | |||
| 264 | return 0; | 309 | return 0; |
| 265 | } | 310 | } |
| 311 | |||
| 312 | early_param("acpi_apic_instance", acpi_parse_apic_instance); | ||
