diff options
Diffstat (limited to 'arch/x86/kernel/acpi/boot.c')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 90 |
1 files changed, 20 insertions, 70 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 40c76604199f..6c0b43bd024b 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -189,24 +189,31 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) | |||
189 | return 0; | 189 | return 0; |
190 | } | 190 | } |
191 | 191 | ||
192 | static void acpi_register_lapic(int id, u8 enabled) | 192 | /** |
193 | * acpi_register_lapic - register a local apic and generates a logic cpu number | ||
194 | * @id: local apic id to register | ||
195 | * @enabled: this cpu is enabled or not | ||
196 | * | ||
197 | * Returns the logic cpu number which maps to the local apic | ||
198 | */ | ||
199 | static int acpi_register_lapic(int id, u8 enabled) | ||
193 | { | 200 | { |
194 | unsigned int ver = 0; | 201 | unsigned int ver = 0; |
195 | 202 | ||
196 | if (id >= MAX_LOCAL_APIC) { | 203 | if (id >= MAX_LOCAL_APIC) { |
197 | printk(KERN_INFO PREFIX "skipped apicid that is too big\n"); | 204 | printk(KERN_INFO PREFIX "skipped apicid that is too big\n"); |
198 | return; | 205 | return -EINVAL; |
199 | } | 206 | } |
200 | 207 | ||
201 | if (!enabled) { | 208 | if (!enabled) { |
202 | ++disabled_cpus; | 209 | ++disabled_cpus; |
203 | return; | 210 | return -EINVAL; |
204 | } | 211 | } |
205 | 212 | ||
206 | if (boot_cpu_physical_apicid != -1U) | 213 | if (boot_cpu_physical_apicid != -1U) |
207 | ver = apic_version[boot_cpu_physical_apicid]; | 214 | ver = apic_version[boot_cpu_physical_apicid]; |
208 | 215 | ||
209 | generic_processor_info(id, ver); | 216 | return generic_processor_info(id, ver); |
210 | } | 217 | } |
211 | 218 | ||
212 | static int __init | 219 | static int __init |
@@ -614,84 +621,27 @@ static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) | |||
614 | #endif | 621 | #endif |
615 | } | 622 | } |
616 | 623 | ||
617 | static int _acpi_map_lsapic(acpi_handle handle, int *pcpu) | 624 | static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) |
618 | { | 625 | { |
619 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
620 | union acpi_object *obj; | ||
621 | struct acpi_madt_local_apic *lapic; | ||
622 | cpumask_var_t tmp_map, new_map; | ||
623 | u8 physid; | ||
624 | int cpu; | 626 | int cpu; |
625 | int retval = -ENOMEM; | ||
626 | |||
627 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) | ||
628 | return -EINVAL; | ||
629 | |||
630 | if (!buffer.length || !buffer.pointer) | ||
631 | return -EINVAL; | ||
632 | |||
633 | obj = buffer.pointer; | ||
634 | if (obj->type != ACPI_TYPE_BUFFER || | ||
635 | obj->buffer.length < sizeof(*lapic)) { | ||
636 | kfree(buffer.pointer); | ||
637 | return -EINVAL; | ||
638 | } | ||
639 | 627 | ||
640 | lapic = (struct acpi_madt_local_apic *)obj->buffer.pointer; | 628 | cpu = acpi_register_lapic(physid, ACPI_MADT_ENABLED); |
641 | 629 | if (cpu < 0) { | |
642 | if (lapic->header.type != ACPI_MADT_TYPE_LOCAL_APIC || | 630 | pr_info(PREFIX "Unable to map lapic to logical cpu number\n"); |
643 | !(lapic->lapic_flags & ACPI_MADT_ENABLED)) { | 631 | return cpu; |
644 | kfree(buffer.pointer); | ||
645 | return -EINVAL; | ||
646 | } | ||
647 | |||
648 | physid = lapic->id; | ||
649 | |||
650 | kfree(buffer.pointer); | ||
651 | buffer.length = ACPI_ALLOCATE_BUFFER; | ||
652 | buffer.pointer = NULL; | ||
653 | lapic = NULL; | ||
654 | |||
655 | if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL)) | ||
656 | goto out; | ||
657 | |||
658 | if (!alloc_cpumask_var(&new_map, GFP_KERNEL)) | ||
659 | goto free_tmp_map; | ||
660 | |||
661 | cpumask_copy(tmp_map, cpu_present_mask); | ||
662 | acpi_register_lapic(physid, ACPI_MADT_ENABLED); | ||
663 | |||
664 | /* | ||
665 | * If acpi_register_lapic successfully generates a new logical cpu | ||
666 | * number, then the following will get us exactly what was mapped | ||
667 | */ | ||
668 | cpumask_andnot(new_map, cpu_present_mask, tmp_map); | ||
669 | if (cpumask_empty(new_map)) { | ||
670 | printk ("Unable to map lapic to logical cpu number\n"); | ||
671 | retval = -EINVAL; | ||
672 | goto free_new_map; | ||
673 | } | 632 | } |
674 | 633 | ||
675 | acpi_processor_set_pdc(handle); | 634 | acpi_processor_set_pdc(handle); |
676 | |||
677 | cpu = cpumask_first(new_map); | ||
678 | acpi_map_cpu2node(handle, cpu, physid); | 635 | acpi_map_cpu2node(handle, cpu, physid); |
679 | 636 | ||
680 | *pcpu = cpu; | 637 | *pcpu = cpu; |
681 | retval = 0; | 638 | return 0; |
682 | |||
683 | free_new_map: | ||
684 | free_cpumask_var(new_map); | ||
685 | free_tmp_map: | ||
686 | free_cpumask_var(tmp_map); | ||
687 | out: | ||
688 | return retval; | ||
689 | } | 639 | } |
690 | 640 | ||
691 | /* wrapper to silence section mismatch warning */ | 641 | /* wrapper to silence section mismatch warning */ |
692 | int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu) | 642 | int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) |
693 | { | 643 | { |
694 | return _acpi_map_lsapic(handle, pcpu); | 644 | return _acpi_map_lsapic(handle, physid, pcpu); |
695 | } | 645 | } |
696 | EXPORT_SYMBOL(acpi_map_lsapic); | 646 | EXPORT_SYMBOL(acpi_map_lsapic); |
697 | 647 | ||
@@ -745,7 +695,7 @@ static int __init acpi_parse_sbf(struct acpi_table_header *table) | |||
745 | #ifdef CONFIG_HPET_TIMER | 695 | #ifdef CONFIG_HPET_TIMER |
746 | #include <asm/hpet.h> | 696 | #include <asm/hpet.h> |
747 | 697 | ||
748 | static struct __initdata resource *hpet_res; | 698 | static struct resource *hpet_res __initdata; |
749 | 699 | ||
750 | static int __init acpi_parse_hpet(struct acpi_table_header *table) | 700 | static int __init acpi_parse_hpet(struct acpi_table_header *table) |
751 | { | 701 | { |