diff options
Diffstat (limited to 'drivers/acpi/processor_driver.c')
-rw-r--r-- | drivers/acpi/processor_driver.c | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 2801b418d7bb..0734086537b8 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | 47 | ||
48 | #include <asm/io.h> | 48 | #include <asm/io.h> |
49 | #include <asm/system.h> | ||
50 | #include <asm/cpu.h> | 49 | #include <asm/cpu.h> |
51 | #include <asm/delay.h> | 50 | #include <asm/delay.h> |
52 | #include <asm/uaccess.h> | 51 | #include <asm/uaccess.h> |
@@ -68,6 +67,7 @@ | |||
68 | #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 | 67 | #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 |
69 | #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 | 68 | #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 |
70 | #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 | 69 | #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 |
70 | #define ACPI_PROCESSOR_DEVICE_HID "ACPI0007" | ||
71 | 71 | ||
72 | #define ACPI_PROCESSOR_LIMIT_USER 0 | 72 | #define ACPI_PROCESSOR_LIMIT_USER 0 |
73 | #define ACPI_PROCESSOR_LIMIT_THERMAL 1 | 73 | #define ACPI_PROCESSOR_LIMIT_THERMAL 1 |
@@ -88,7 +88,7 @@ static int acpi_processor_start(struct acpi_processor *pr); | |||
88 | 88 | ||
89 | static const struct acpi_device_id processor_device_ids[] = { | 89 | static const struct acpi_device_id processor_device_ids[] = { |
90 | {ACPI_PROCESSOR_OBJECT_HID, 0}, | 90 | {ACPI_PROCESSOR_OBJECT_HID, 0}, |
91 | {"ACPI0007", 0}, | 91 | {ACPI_PROCESSOR_DEVICE_HID, 0}, |
92 | {"", 0}, | 92 | {"", 0}, |
93 | }; | 93 | }; |
94 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); | 94 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); |
@@ -536,8 +536,8 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
536 | return -ENOMEM; | 536 | return -ENOMEM; |
537 | 537 | ||
538 | if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { | 538 | if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { |
539 | kfree(pr); | 539 | result = -ENOMEM; |
540 | return -ENOMEM; | 540 | goto err_free_pr; |
541 | } | 541 | } |
542 | 542 | ||
543 | pr->handle = device->handle; | 543 | pr->handle = device->handle; |
@@ -577,7 +577,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
577 | dev = get_cpu_device(pr->id); | 577 | dev = get_cpu_device(pr->id); |
578 | if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) { | 578 | if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) { |
579 | result = -EFAULT; | 579 | result = -EFAULT; |
580 | goto err_free_cpumask; | 580 | goto err_clear_processor; |
581 | } | 581 | } |
582 | 582 | ||
583 | /* | 583 | /* |
@@ -595,9 +595,15 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
595 | 595 | ||
596 | err_remove_sysfs: | 596 | err_remove_sysfs: |
597 | sysfs_remove_link(&device->dev.kobj, "sysdev"); | 597 | sysfs_remove_link(&device->dev.kobj, "sysdev"); |
598 | err_clear_processor: | ||
599 | /* | ||
600 | * processor_device_array is not cleared to allow checks for buggy BIOS | ||
601 | */ | ||
602 | per_cpu(processors, pr->id) = NULL; | ||
598 | err_free_cpumask: | 603 | err_free_cpumask: |
599 | free_cpumask_var(pr->throttling.shared_cpu_map); | 604 | free_cpumask_var(pr->throttling.shared_cpu_map); |
600 | 605 | err_free_pr: | |
606 | kfree(pr); | ||
601 | return result; | 607 | return result; |
602 | } | 608 | } |
603 | 609 | ||
@@ -742,20 +748,46 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, | |||
742 | return; | 748 | return; |
743 | } | 749 | } |
744 | 750 | ||
751 | static acpi_status is_processor_device(acpi_handle handle) | ||
752 | { | ||
753 | struct acpi_device_info *info; | ||
754 | char *hid; | ||
755 | acpi_status status; | ||
756 | |||
757 | status = acpi_get_object_info(handle, &info); | ||
758 | if (ACPI_FAILURE(status)) | ||
759 | return status; | ||
760 | |||
761 | if (info->type == ACPI_TYPE_PROCESSOR) { | ||
762 | kfree(info); | ||
763 | return AE_OK; /* found a processor object */ | ||
764 | } | ||
765 | |||
766 | if (!(info->valid & ACPI_VALID_HID)) { | ||
767 | kfree(info); | ||
768 | return AE_ERROR; | ||
769 | } | ||
770 | |||
771 | hid = info->hardware_id.string; | ||
772 | if ((hid == NULL) || strcmp(hid, ACPI_PROCESSOR_DEVICE_HID)) { | ||
773 | kfree(info); | ||
774 | return AE_ERROR; | ||
775 | } | ||
776 | |||
777 | kfree(info); | ||
778 | return AE_OK; /* found a processor device object */ | ||
779 | } | ||
780 | |||
745 | static acpi_status | 781 | static acpi_status |
746 | processor_walk_namespace_cb(acpi_handle handle, | 782 | processor_walk_namespace_cb(acpi_handle handle, |
747 | u32 lvl, void *context, void **rv) | 783 | u32 lvl, void *context, void **rv) |
748 | { | 784 | { |
749 | acpi_status status; | 785 | acpi_status status; |
750 | int *action = context; | 786 | int *action = context; |
751 | acpi_object_type type = 0; | ||
752 | 787 | ||
753 | status = acpi_get_type(handle, &type); | 788 | status = is_processor_device(handle); |
754 | if (ACPI_FAILURE(status)) | 789 | if (ACPI_FAILURE(status)) |
755 | return (AE_OK); | 790 | return AE_OK; /* not a processor; continue to walk */ |
756 | |||
757 | if (type != ACPI_TYPE_PROCESSOR) | ||
758 | return (AE_OK); | ||
759 | 791 | ||
760 | switch (*action) { | 792 | switch (*action) { |
761 | case INSTALL_NOTIFY_HANDLER: | 793 | case INSTALL_NOTIFY_HANDLER: |
@@ -773,7 +805,8 @@ processor_walk_namespace_cb(acpi_handle handle, | |||
773 | break; | 805 | break; |
774 | } | 806 | } |
775 | 807 | ||
776 | return (AE_OK); | 808 | /* found a processor; skip walking underneath */ |
809 | return AE_CTRL_DEPTH; | ||
777 | } | 810 | } |
778 | 811 | ||
779 | static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) | 812 | static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) |
@@ -831,7 +864,7 @@ void acpi_processor_install_hotplug_notify(void) | |||
831 | { | 864 | { |
832 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 865 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
833 | int action = INSTALL_NOTIFY_HANDLER; | 866 | int action = INSTALL_NOTIFY_HANDLER; |
834 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, | 867 | acpi_walk_namespace(ACPI_TYPE_ANY, |
835 | ACPI_ROOT_OBJECT, | 868 | ACPI_ROOT_OBJECT, |
836 | ACPI_UINT32_MAX, | 869 | ACPI_UINT32_MAX, |
837 | processor_walk_namespace_cb, NULL, &action, NULL); | 870 | processor_walk_namespace_cb, NULL, &action, NULL); |
@@ -844,7 +877,7 @@ void acpi_processor_uninstall_hotplug_notify(void) | |||
844 | { | 877 | { |
845 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 878 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
846 | int action = UNINSTALL_NOTIFY_HANDLER; | 879 | int action = UNINSTALL_NOTIFY_HANDLER; |
847 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, | 880 | acpi_walk_namespace(ACPI_TYPE_ANY, |
848 | ACPI_ROOT_OBJECT, | 881 | ACPI_ROOT_OBJECT, |
849 | ACPI_UINT32_MAX, | 882 | ACPI_UINT32_MAX, |
850 | processor_walk_namespace_cb, NULL, &action, NULL); | 883 | processor_walk_namespace_cb, NULL, &action, NULL); |