diff options
Diffstat (limited to 'drivers/acpi/processor_driver.c')
-rw-r--r-- | drivers/acpi/processor_driver.c | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index d4d9cb7e016..0734086537b 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 | 67 | #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 |
68 | #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 | 68 | #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 |
69 | #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 | 69 | #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 |
70 | #define ACPI_PROCESSOR_DEVICE_HID "ACPI0007" | ||
70 | 71 | ||
71 | #define ACPI_PROCESSOR_LIMIT_USER 0 | 72 | #define ACPI_PROCESSOR_LIMIT_USER 0 |
72 | #define ACPI_PROCESSOR_LIMIT_THERMAL 1 | 73 | #define ACPI_PROCESSOR_LIMIT_THERMAL 1 |
@@ -87,7 +88,7 @@ static int acpi_processor_start(struct acpi_processor *pr); | |||
87 | 88 | ||
88 | static const struct acpi_device_id processor_device_ids[] = { | 89 | static const struct acpi_device_id processor_device_ids[] = { |
89 | {ACPI_PROCESSOR_OBJECT_HID, 0}, | 90 | {ACPI_PROCESSOR_OBJECT_HID, 0}, |
90 | {"ACPI0007", 0}, | 91 | {ACPI_PROCESSOR_DEVICE_HID, 0}, |
91 | {"", 0}, | 92 | {"", 0}, |
92 | }; | 93 | }; |
93 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); | 94 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); |
@@ -535,8 +536,8 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
535 | return -ENOMEM; | 536 | return -ENOMEM; |
536 | 537 | ||
537 | if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { | 538 | if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { |
538 | kfree(pr); | 539 | result = -ENOMEM; |
539 | return -ENOMEM; | 540 | goto err_free_pr; |
540 | } | 541 | } |
541 | 542 | ||
542 | pr->handle = device->handle; | 543 | pr->handle = device->handle; |
@@ -576,7 +577,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
576 | dev = get_cpu_device(pr->id); | 577 | dev = get_cpu_device(pr->id); |
577 | if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) { | 578 | if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) { |
578 | result = -EFAULT; | 579 | result = -EFAULT; |
579 | goto err_free_cpumask; | 580 | goto err_clear_processor; |
580 | } | 581 | } |
581 | 582 | ||
582 | /* | 583 | /* |
@@ -594,9 +595,15 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
594 | 595 | ||
595 | err_remove_sysfs: | 596 | err_remove_sysfs: |
596 | 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; | ||
597 | err_free_cpumask: | 603 | err_free_cpumask: |
598 | free_cpumask_var(pr->throttling.shared_cpu_map); | 604 | free_cpumask_var(pr->throttling.shared_cpu_map); |
599 | 605 | err_free_pr: | |
606 | kfree(pr); | ||
600 | return result; | 607 | return result; |
601 | } | 608 | } |
602 | 609 | ||
@@ -741,20 +748,46 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, | |||
741 | return; | 748 | return; |
742 | } | 749 | } |
743 | 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 | |||
744 | static acpi_status | 781 | static acpi_status |
745 | processor_walk_namespace_cb(acpi_handle handle, | 782 | processor_walk_namespace_cb(acpi_handle handle, |
746 | u32 lvl, void *context, void **rv) | 783 | u32 lvl, void *context, void **rv) |
747 | { | 784 | { |
748 | acpi_status status; | 785 | acpi_status status; |
749 | int *action = context; | 786 | int *action = context; |
750 | acpi_object_type type = 0; | ||
751 | 787 | ||
752 | status = acpi_get_type(handle, &type); | 788 | status = is_processor_device(handle); |
753 | if (ACPI_FAILURE(status)) | 789 | if (ACPI_FAILURE(status)) |
754 | return (AE_OK); | 790 | return AE_OK; /* not a processor; continue to walk */ |
755 | |||
756 | if (type != ACPI_TYPE_PROCESSOR) | ||
757 | return (AE_OK); | ||
758 | 791 | ||
759 | switch (*action) { | 792 | switch (*action) { |
760 | case INSTALL_NOTIFY_HANDLER: | 793 | case INSTALL_NOTIFY_HANDLER: |
@@ -772,7 +805,8 @@ processor_walk_namespace_cb(acpi_handle handle, | |||
772 | break; | 805 | break; |
773 | } | 806 | } |
774 | 807 | ||
775 | return (AE_OK); | 808 | /* found a processor; skip walking underneath */ |
809 | return AE_CTRL_DEPTH; | ||
776 | } | 810 | } |
777 | 811 | ||
778 | static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) | 812 | static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) |
@@ -830,7 +864,7 @@ void acpi_processor_install_hotplug_notify(void) | |||
830 | { | 864 | { |
831 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 865 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
832 | int action = INSTALL_NOTIFY_HANDLER; | 866 | int action = INSTALL_NOTIFY_HANDLER; |
833 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, | 867 | acpi_walk_namespace(ACPI_TYPE_ANY, |
834 | ACPI_ROOT_OBJECT, | 868 | ACPI_ROOT_OBJECT, |
835 | ACPI_UINT32_MAX, | 869 | ACPI_UINT32_MAX, |
836 | processor_walk_namespace_cb, NULL, &action, NULL); | 870 | processor_walk_namespace_cb, NULL, &action, NULL); |
@@ -843,7 +877,7 @@ void acpi_processor_uninstall_hotplug_notify(void) | |||
843 | { | 877 | { |
844 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 878 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
845 | int action = UNINSTALL_NOTIFY_HANDLER; | 879 | int action = UNINSTALL_NOTIFY_HANDLER; |
846 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, | 880 | acpi_walk_namespace(ACPI_TYPE_ANY, |
847 | ACPI_ROOT_OBJECT, | 881 | ACPI_ROOT_OBJECT, |
848 | ACPI_UINT32_MAX, | 882 | ACPI_UINT32_MAX, |
849 | processor_walk_namespace_cb, NULL, &action, NULL); | 883 | processor_walk_namespace_cb, NULL, &action, NULL); |