aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_driver.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-30 19:45:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-30 19:45:39 -0400
commita335750b9a039a9d4cd727cdccacfb90fd63c4e8 (patch)
tree8f3198984fb75fe494e771d9431f6799228623c5 /drivers/acpi/processor_driver.c
parent10f3cb41d48ab30f5c754b30eea557371892b4c2 (diff)
parentd326f44e5f2204c7a24db69bfc6dd3fe5f86182b (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
Pull ACPI & Power Management changes from Len Brown: - ACPI 5.0 after-ripples, ACPICA/Linux divergence cleanup - cpuidle evolving, more ARM use - thermal sub-system evolving, ditto - assorted other PM bits Fix up conflicts in various cpuidle implementations due to ARM cpuidle cleanups (ARM at91 self-refresh and cpu idle code rewritten into "standby" in asm conflicting with the consolidation of cpuidle time keeping), trivial SH include file context conflict and RCU tracing fixes in generic code. * 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux: (77 commits) ACPI throttling: fix endian bug in acpi_read_throttling_status() Disable MCP limit exceeded messages from Intel IPS driver ACPI video: Don't start video device until its associated input device has been allocated ACPI video: Harden video bus adding. ACPI: Add support for exposing BGRT data ACPI: export acpi_kobj ACPI: Fix logic for removing mappings in 'acpi_unmap' CPER failed to handle generic error records with multiple sections ACPI: Clean redundant codes in scan.c ACPI: Fix unprotected smp_processor_id() in acpi_processor_cst_has_changed() ACPI: consistently use should_use_kmap() PNPACPI: Fix device ref leaking in acpi_pnp_match ACPI: Fix use-after-free in acpi_map_lsapic ACPI: processor_driver: add missing kfree ACPI, APEI: Fix incorrect APEI register bit width check and usage Update documentation for parameter *notrigger* in einj.txt ACPI, APEI, EINJ, new parameter to control trigger action ACPI, APEI, EINJ, limit the range of einj_param ACPI, APEI, Fix ERST header length check cpuidle: power_usage should be declared signed integer ...
Diffstat (limited to 'drivers/acpi/processor_driver.c')
-rw-r--r--drivers/acpi/processor_driver.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index d4d9cb7e016a..0734086537b8 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
88static const struct acpi_device_id processor_device_ids[] = { 89static 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};
93MODULE_DEVICE_TABLE(acpi, processor_device_ids); 94MODULE_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
595err_remove_sysfs: 596err_remove_sysfs:
596 sysfs_remove_link(&device->dev.kobj, "sysdev"); 597 sysfs_remove_link(&device->dev.kobj, "sysdev");
598err_clear_processor:
599 /*
600 * processor_device_array is not cleared to allow checks for buggy BIOS
601 */
602 per_cpu(processors, pr->id) = NULL;
597err_free_cpumask: 603err_free_cpumask:
598 free_cpumask_var(pr->throttling.shared_cpu_map); 604 free_cpumask_var(pr->throttling.shared_cpu_map);
599 605err_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
751static 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
744static acpi_status 781static acpi_status
745processor_walk_namespace_cb(acpi_handle handle, 782processor_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
778static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) 812static 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);