diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 16:07:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 16:07:55 -0400 |
commit | b278240839e20fa9384ea430df463b367b90e04e (patch) | |
tree | f99f0c8cdd4cc7f177cd75440e6bd181cded7fb3 /arch/i386/kernel/acpi | |
parent | dd77a4ee0f3981693d4229aa1d57cea9e526ff47 (diff) | |
parent | 3f75f42d7733e73aca5c78326489efd4189e0111 (diff) |
Merge branch 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6
* 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6: (225 commits)
[PATCH] Don't set calgary iommu as default y
[PATCH] i386/x86-64: New Intel feature flags
[PATCH] x86: Add a cumulative thermal throttle event counter.
[PATCH] i386: Make the jiffies compares use the 64bit safe macros.
[PATCH] x86: Refactor thermal throttle processing
[PATCH] Add 64bit jiffies compares (for use with get_jiffies_64)
[PATCH] Fix unwinder warning in traps.c
[PATCH] x86: Allow disabling early pci scans with pci=noearly or disallowing conf1
[PATCH] x86: Move direct PCI scanning functions out of line
[PATCH] i386/x86-64: Make all early PCI scans dependent on CONFIG_PCI
[PATCH] Don't leak NT bit into next task
[PATCH] i386/x86-64: Work around gcc bug with noreturn functions in unwinder
[PATCH] Fix some broken white space in ia32_signal.c
[PATCH] Initialize argument registers for 32bit signal handlers.
[PATCH] Remove all traces of signal number conversion
[PATCH] Don't synchronize time reading on single core AMD systems
[PATCH] Remove outdated comment in x86-64 mmconfig code
[PATCH] Use string instructions for Core2 copy/clear
[PATCH] x86: - restore i8259A eoi status on resume
[PATCH] i386: Split multi-line printk in oops output.
...
Diffstat (limited to 'arch/i386/kernel/acpi')
-rw-r--r-- | arch/i386/kernel/acpi/Makefile | 2 | ||||
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 181 | ||||
-rw-r--r-- | arch/i386/kernel/acpi/earlyquirk.c | 6 |
3 files changed, 179 insertions, 10 deletions
diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile index 7e9ac99354f4..7f7be01f44e6 100644 --- a/arch/i386/kernel/acpi/Makefile +++ b/arch/i386/kernel/acpi/Makefile | |||
@@ -1,5 +1,7 @@ | |||
1 | obj-$(CONFIG_ACPI) += boot.o | 1 | obj-$(CONFIG_ACPI) += boot.o |
2 | ifneq ($(CONFIG_PCI),) | ||
2 | obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o | 3 | obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o |
4 | endif | ||
3 | obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o | 5 | obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o |
4 | 6 | ||
5 | ifneq ($(CONFIG_ACPI_PROCESSOR),) | 7 | ifneq ($(CONFIG_ACPI_PROCESSOR),) |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index ee003bc0e8b1..1aaea6ab8c46 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -26,9 +26,12 @@ | |||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/acpi.h> | 27 | #include <linux/acpi.h> |
28 | #include <linux/efi.h> | 28 | #include <linux/efi.h> |
29 | #include <linux/cpumask.h> | ||
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
30 | #include <linux/dmi.h> | 31 | #include <linux/dmi.h> |
31 | #include <linux/irq.h> | 32 | #include <linux/irq.h> |
33 | #include <linux/bootmem.h> | ||
34 | #include <linux/ioport.h> | ||
32 | 35 | ||
33 | #include <asm/pgtable.h> | 36 | #include <asm/pgtable.h> |
34 | #include <asm/io_apic.h> | 37 | #include <asm/io_apic.h> |
@@ -36,11 +39,17 @@ | |||
36 | #include <asm/io.h> | 39 | #include <asm/io.h> |
37 | #include <asm/mpspec.h> | 40 | #include <asm/mpspec.h> |
38 | 41 | ||
39 | #ifdef CONFIG_X86_64 | 42 | static int __initdata acpi_force = 0; |
40 | 43 | ||
41 | extern void __init clustered_apic_check(void); | 44 | #ifdef CONFIG_ACPI |
45 | int acpi_disabled = 0; | ||
46 | #else | ||
47 | int acpi_disabled = 1; | ||
48 | #endif | ||
49 | EXPORT_SYMBOL(acpi_disabled); | ||
50 | |||
51 | #ifdef CONFIG_X86_64 | ||
42 | 52 | ||
43 | extern int gsi_irq_sharing(int gsi); | ||
44 | #include <asm/proto.h> | 53 | #include <asm/proto.h> |
45 | 54 | ||
46 | static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; } | 55 | static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; } |
@@ -506,16 +515,76 @@ EXPORT_SYMBOL(acpi_register_gsi); | |||
506 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 515 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
507 | int acpi_map_lsapic(acpi_handle handle, int *pcpu) | 516 | int acpi_map_lsapic(acpi_handle handle, int *pcpu) |
508 | { | 517 | { |
509 | /* TBD */ | 518 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
510 | return -EINVAL; | 519 | union acpi_object *obj; |
520 | struct acpi_table_lapic *lapic; | ||
521 | cpumask_t tmp_map, new_map; | ||
522 | u8 physid; | ||
523 | int cpu; | ||
524 | |||
525 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) | ||
526 | return -EINVAL; | ||
527 | |||
528 | if (!buffer.length || !buffer.pointer) | ||
529 | return -EINVAL; | ||
530 | |||
531 | obj = buffer.pointer; | ||
532 | if (obj->type != ACPI_TYPE_BUFFER || | ||
533 | obj->buffer.length < sizeof(*lapic)) { | ||
534 | kfree(buffer.pointer); | ||
535 | return -EINVAL; | ||
536 | } | ||
537 | |||
538 | lapic = (struct acpi_table_lapic *)obj->buffer.pointer; | ||
539 | |||
540 | if ((lapic->header.type != ACPI_MADT_LAPIC) || | ||
541 | (!lapic->flags.enabled)) { | ||
542 | kfree(buffer.pointer); | ||
543 | return -EINVAL; | ||
544 | } | ||
545 | |||
546 | physid = lapic->id; | ||
547 | |||
548 | kfree(buffer.pointer); | ||
549 | buffer.length = ACPI_ALLOCATE_BUFFER; | ||
550 | buffer.pointer = NULL; | ||
551 | |||
552 | tmp_map = cpu_present_map; | ||
553 | mp_register_lapic(physid, lapic->flags.enabled); | ||
554 | |||
555 | /* | ||
556 | * If mp_register_lapic successfully generates a new logical cpu | ||
557 | * number, then the following will get us exactly what was mapped | ||
558 | */ | ||
559 | cpus_andnot(new_map, cpu_present_map, tmp_map); | ||
560 | if (cpus_empty(new_map)) { | ||
561 | printk ("Unable to map lapic to logical cpu number\n"); | ||
562 | return -EINVAL; | ||
563 | } | ||
564 | |||
565 | cpu = first_cpu(new_map); | ||
566 | |||
567 | *pcpu = cpu; | ||
568 | return 0; | ||
511 | } | 569 | } |
512 | 570 | ||
513 | EXPORT_SYMBOL(acpi_map_lsapic); | 571 | EXPORT_SYMBOL(acpi_map_lsapic); |
514 | 572 | ||
515 | int acpi_unmap_lsapic(int cpu) | 573 | int acpi_unmap_lsapic(int cpu) |
516 | { | 574 | { |
517 | /* TBD */ | 575 | int i; |
518 | return -EINVAL; | 576 | |
577 | for_each_possible_cpu(i) { | ||
578 | if (x86_acpiid_to_apicid[i] == x86_cpu_to_apicid[cpu]) { | ||
579 | x86_acpiid_to_apicid[i] = -1; | ||
580 | break; | ||
581 | } | ||
582 | } | ||
583 | x86_cpu_to_apicid[cpu] = -1; | ||
584 | cpu_clear(cpu, cpu_present_map); | ||
585 | num_processors--; | ||
586 | |||
587 | return (0); | ||
519 | } | 588 | } |
520 | 589 | ||
521 | EXPORT_SYMBOL(acpi_unmap_lsapic); | 590 | EXPORT_SYMBOL(acpi_unmap_lsapic); |
@@ -579,6 +648,8 @@ static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) | |||
579 | static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) | 648 | static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) |
580 | { | 649 | { |
581 | struct acpi_table_hpet *hpet_tbl; | 650 | struct acpi_table_hpet *hpet_tbl; |
651 | struct resource *hpet_res; | ||
652 | resource_size_t res_start; | ||
582 | 653 | ||
583 | if (!phys || !size) | 654 | if (!phys || !size) |
584 | return -EINVAL; | 655 | return -EINVAL; |
@@ -594,12 +665,26 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) | |||
594 | "memory.\n"); | 665 | "memory.\n"); |
595 | return -1; | 666 | return -1; |
596 | } | 667 | } |
668 | |||
669 | #define HPET_RESOURCE_NAME_SIZE 9 | ||
670 | hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE); | ||
671 | if (hpet_res) { | ||
672 | memset(hpet_res, 0, sizeof(*hpet_res)); | ||
673 | hpet_res->name = (void *)&hpet_res[1]; | ||
674 | hpet_res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
675 | snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, | ||
676 | "HPET %u", hpet_tbl->number); | ||
677 | hpet_res->end = (1 * 1024) - 1; | ||
678 | } | ||
679 | |||
597 | #ifdef CONFIG_X86_64 | 680 | #ifdef CONFIG_X86_64 |
598 | vxtime.hpet_address = hpet_tbl->addr.addrl | | 681 | vxtime.hpet_address = hpet_tbl->addr.addrl | |
599 | ((long)hpet_tbl->addr.addrh << 32); | 682 | ((long)hpet_tbl->addr.addrh << 32); |
600 | 683 | ||
601 | printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", | 684 | printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", |
602 | hpet_tbl->id, vxtime.hpet_address); | 685 | hpet_tbl->id, vxtime.hpet_address); |
686 | |||
687 | res_start = vxtime.hpet_address; | ||
603 | #else /* X86 */ | 688 | #else /* X86 */ |
604 | { | 689 | { |
605 | extern unsigned long hpet_address; | 690 | extern unsigned long hpet_address; |
@@ -607,9 +692,17 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) | |||
607 | hpet_address = hpet_tbl->addr.addrl; | 692 | hpet_address = hpet_tbl->addr.addrl; |
608 | printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", | 693 | printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", |
609 | hpet_tbl->id, hpet_address); | 694 | hpet_tbl->id, hpet_address); |
695 | |||
696 | res_start = hpet_address; | ||
610 | } | 697 | } |
611 | #endif /* X86 */ | 698 | #endif /* X86 */ |
612 | 699 | ||
700 | if (hpet_res) { | ||
701 | hpet_res->start = res_start; | ||
702 | hpet_res->end += res_start; | ||
703 | insert_resource(&iomem_resource, hpet_res); | ||
704 | } | ||
705 | |||
613 | return 0; | 706 | return 0; |
614 | } | 707 | } |
615 | #else | 708 | #else |
@@ -860,8 +953,6 @@ static void __init acpi_process_madt(void) | |||
860 | return; | 953 | return; |
861 | } | 954 | } |
862 | 955 | ||
863 | extern int acpi_force; | ||
864 | |||
865 | #ifdef __i386__ | 956 | #ifdef __i386__ |
866 | 957 | ||
867 | static int __init disable_acpi_irq(struct dmi_system_id *d) | 958 | static int __init disable_acpi_irq(struct dmi_system_id *d) |
@@ -1163,3 +1254,75 @@ int __init acpi_boot_init(void) | |||
1163 | 1254 | ||
1164 | return 0; | 1255 | return 0; |
1165 | } | 1256 | } |
1257 | |||
1258 | static int __init parse_acpi(char *arg) | ||
1259 | { | ||
1260 | if (!arg) | ||
1261 | return -EINVAL; | ||
1262 | |||
1263 | /* "acpi=off" disables both ACPI table parsing and interpreter */ | ||
1264 | if (strcmp(arg, "off") == 0) { | ||
1265 | disable_acpi(); | ||
1266 | } | ||
1267 | /* acpi=force to over-ride black-list */ | ||
1268 | else if (strcmp(arg, "force") == 0) { | ||
1269 | acpi_force = 1; | ||
1270 | acpi_ht = 1; | ||
1271 | acpi_disabled = 0; | ||
1272 | } | ||
1273 | /* acpi=strict disables out-of-spec workarounds */ | ||
1274 | else if (strcmp(arg, "strict") == 0) { | ||
1275 | acpi_strict = 1; | ||
1276 | } | ||
1277 | /* Limit ACPI just to boot-time to enable HT */ | ||
1278 | else if (strcmp(arg, "ht") == 0) { | ||
1279 | if (!acpi_force) | ||
1280 | disable_acpi(); | ||
1281 | acpi_ht = 1; | ||
1282 | } | ||
1283 | /* "acpi=noirq" disables ACPI interrupt routing */ | ||
1284 | else if (strcmp(arg, "noirq") == 0) { | ||
1285 | acpi_noirq_set(); | ||
1286 | } else { | ||
1287 | /* Core will printk when we return error. */ | ||
1288 | return -EINVAL; | ||
1289 | } | ||
1290 | return 0; | ||
1291 | } | ||
1292 | early_param("acpi", parse_acpi); | ||
1293 | |||
1294 | /* FIXME: Using pci= for an ACPI parameter is a travesty. */ | ||
1295 | static int __init parse_pci(char *arg) | ||
1296 | { | ||
1297 | if (arg && strcmp(arg, "noacpi") == 0) | ||
1298 | acpi_disable_pci(); | ||
1299 | return 0; | ||
1300 | } | ||
1301 | early_param("pci", parse_pci); | ||
1302 | |||
1303 | #ifdef CONFIG_X86_IO_APIC | ||
1304 | static int __init parse_acpi_skip_timer_override(char *arg) | ||
1305 | { | ||
1306 | acpi_skip_timer_override = 1; | ||
1307 | return 0; | ||
1308 | } | ||
1309 | early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override); | ||
1310 | #endif /* CONFIG_X86_IO_APIC */ | ||
1311 | |||
1312 | static int __init setup_acpi_sci(char *s) | ||
1313 | { | ||
1314 | if (!s) | ||
1315 | return -EINVAL; | ||
1316 | if (!strcmp(s, "edge")) | ||
1317 | acpi_sci_flags.trigger = 1; | ||
1318 | else if (!strcmp(s, "level")) | ||
1319 | acpi_sci_flags.trigger = 3; | ||
1320 | else if (!strcmp(s, "high")) | ||
1321 | acpi_sci_flags.polarity = 1; | ||
1322 | else if (!strcmp(s, "low")) | ||
1323 | acpi_sci_flags.polarity = 3; | ||
1324 | else | ||
1325 | return -EINVAL; | ||
1326 | return 0; | ||
1327 | } | ||
1328 | early_param("acpi_sci", setup_acpi_sci); | ||
diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index 1649a175a206..fe799b11ac0a 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c | |||
@@ -48,7 +48,11 @@ void __init check_acpi_pci(void) | |||
48 | int num, slot, func; | 48 | int num, slot, func; |
49 | 49 | ||
50 | /* Assume the machine supports type 1. If not it will | 50 | /* Assume the machine supports type 1. If not it will |
51 | always read ffffffff and should not have any side effect. */ | 51 | always read ffffffff and should not have any side effect. |
52 | Actually a few buggy systems can machine check. Allow the user | ||
53 | to disable it by command line option at least -AK */ | ||
54 | if (!early_pci_allowed()) | ||
55 | return; | ||
52 | 56 | ||
53 | /* Poor man's PCI discovery */ | 57 | /* Poor man's PCI discovery */ |
54 | for (num = 0; num < 32; num++) { | 58 | for (num = 0; num < 32; num++) { |