diff options
author | Jiri Kosina <jkosina@suse.cz> | 2012-04-08 21:48:52 +0200 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-04-08 21:48:52 +0200 |
commit | e75d660672ddd11704b7f0fdb8ff21968587b266 (patch) | |
tree | ccb9c107744c10b553c0373e450bee3971d16c00 /drivers/acpi/processor_driver.c | |
parent | 61282f37927143e45b03153f3e7b48d6b702147a (diff) | |
parent | 0034102808e0dbbf3a2394b82b1bb40b5778de9e (diff) |
Merge branch 'master' into for-next
Merge with latest Linus' tree, as I have incoming patches
that fix code that is newer than current HEAD of for-next.
Conflicts:
drivers/net/ethernet/realtek/r8169.c
Diffstat (limited to 'drivers/acpi/processor_driver.c')
-rw-r--r-- | drivers/acpi/processor_driver.c | 71 |
1 files changed, 49 insertions, 22 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 2b805d7ef31..0734086537b 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -46,7 +46,6 @@ #include <linux/slab.h> #include <asm/io.h> -#include <asm/system.h> #include <asm/cpu.h> #include <asm/delay.h> #include <asm/uaccess.h> @@ -68,6 +67,7 @@ #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 +#define ACPI_PROCESSOR_DEVICE_HID "ACPI0007" #define ACPI_PROCESSOR_LIMIT_USER 0 #define ACPI_PROCESSOR_LIMIT_THERMAL 1 @@ -88,7 +88,7 @@ static int acpi_processor_start(struct acpi_processor *pr); static const struct acpi_device_id processor_device_ids[] = { {ACPI_PROCESSOR_OBJECT_HID, 0}, - {"ACPI0007", 0}, + {ACPI_PROCESSOR_DEVICE_HID, 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, processor_device_ids); @@ -474,6 +474,7 @@ static __ref int acpi_processor_start(struct acpi_processor *pr) #ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr, 0); + acpi_processor_load_module(pr); #endif acpi_processor_get_throttling_info(pr); acpi_processor_get_limit_info(pr); @@ -535,8 +536,8 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) return -ENOMEM; if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { - kfree(pr); - return -ENOMEM; + result = -ENOMEM; + goto err_free_pr; } pr->handle = device->handle; @@ -576,7 +577,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) dev = get_cpu_device(pr->id); if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) { result = -EFAULT; - goto err_free_cpumask; + goto err_clear_processor; } /* @@ -586,13 +587,6 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) if (pr->flags.need_hotplug_init) return 0; - /* - * Do not start hotplugged CPUs now, but when they - * are onlined the first time - */ - if (pr->flags.need_hotplug_init) - return 0; - result = acpi_processor_start(pr); if (result) goto err_remove_sysfs; @@ -601,9 +595,15 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) err_remove_sysfs: sysfs_remove_link(&device->dev.kobj, "sysdev"); +err_clear_processor: + /* + * processor_device_array is not cleared to allow checks for buggy BIOS + */ + per_cpu(processors, pr->id) = NULL; err_free_cpumask: free_cpumask_var(pr->throttling.shared_cpu_map); - +err_free_pr: + kfree(pr); return result; } @@ -748,20 +748,46 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, return; } +static acpi_status is_processor_device(acpi_handle handle) +{ + struct acpi_device_info *info; + char *hid; + acpi_status status; + + status = acpi_get_object_info(handle, &info); + if (ACPI_FAILURE(status)) + return status; + + if (info->type == ACPI_TYPE_PROCESSOR) { + kfree(info); + return AE_OK; /* found a processor object */ + } + + if (!(info->valid & ACPI_VALID_HID)) { + kfree(info); + return AE_ERROR; + } + + hid = info->hardware_id.string; + if ((hid == NULL) || strcmp(hid, ACPI_PROCESSOR_DEVICE_HID)) { + kfree(info); + return AE_ERROR; + } + + kfree(info); + return AE_OK; /* found a processor device object */ +} + static acpi_status processor_walk_namespace_cb(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; int *action = context; - acpi_object_type type = 0; - status = acpi_get_type(handle, &type); + status = is_processor_device(handle); if (ACPI_FAILURE(status)) - return (AE_OK); - - if (type != ACPI_TYPE_PROCESSOR) - return (AE_OK); + return AE_OK; /* not a processor; continue to walk */ switch (*action) { case INSTALL_NOTIFY_HANDLER: @@ -779,7 +805,8 @@ processor_walk_namespace_cb(acpi_handle handle, break; } - return (AE_OK); + /* found a processor; skip walking underneath */ + return AE_CTRL_DEPTH; } static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) @@ -837,7 +864,7 @@ void acpi_processor_install_hotplug_notify(void) { #ifdef CONFIG_ACPI_HOTPLUG_CPU int action = INSTALL_NOTIFY_HANDLER; - acpi_walk_namespace(ACPI_TYPE_PROCESSOR, + acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, processor_walk_namespace_cb, NULL, &action, NULL); @@ -850,7 +877,7 @@ void acpi_processor_uninstall_hotplug_notify(void) { #ifdef CONFIG_ACPI_HOTPLUG_CPU int action = UNINSTALL_NOTIFY_HANDLER; - acpi_walk_namespace(ACPI_TYPE_PROCESSOR, + acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, processor_walk_namespace_cb, NULL, &action, NULL); |