diff options
author | Len Brown <len.brown@intel.com> | 2009-09-19 09:56:39 +0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-09-19 09:56:39 +0400 |
commit | 3b87bb640e77023c97cf209e3dd85887a1113ad0 (patch) | |
tree | c4531d2c954bcc28706837cc67a8865677e51fbf /drivers/acpi/processor_core.c | |
parent | 7a92d803227a523a9a5546e4e0dce1325a4b5926 (diff) | |
parent | dcf52fb71d988ba945054308f661bddf9b2455fb (diff) | |
download | linux-3b87bb640e77023c97cf209e3dd85887a1113ad0.tar.xz |
Merge branch 'bjorn-start-stop-2.6.32' into release
Diffstat (limited to 'drivers/acpi/processor_core.c')
-rw-r--r-- | drivers/acpi/processor_core.c | 219 |
1 files changed, 95 insertions, 124 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index b4a1ab297e7b..b972107a1ef2 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -81,7 +81,6 @@ MODULE_DESCRIPTION("ACPI Processor Driver"); MODULE_LICENSE("GPL"); static int acpi_processor_add(struct acpi_device *device); -static int acpi_processor_start(struct acpi_device *device); static int acpi_processor_remove(struct acpi_device *device, int type); static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); static void acpi_processor_notify(struct acpi_device *device, u32 event); @@ -103,7 +102,6 @@ static struct acpi_driver acpi_processor_driver = { .ops = { .add = acpi_processor_add, .remove = acpi_processor_remove, - .start = acpi_processor_start, .suspend = acpi_processor_suspend, .resume = acpi_processor_resume, .notify = acpi_processor_notify, @@ -700,92 +698,6 @@ static int acpi_processor_get_info(struct acpi_device *device) static DEFINE_PER_CPU(void *, processor_device_array); -static int __cpuinit acpi_processor_start(struct acpi_device *device) -{ - int result = 0; - struct acpi_processor *pr; - struct sys_device *sysdev; - - pr = acpi_driver_data(device); - - result = acpi_processor_get_info(device); - if (result) { - /* Processor is physically not present */ - return 0; - } - - BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); - - /* - * Buggy BIOS check - * ACPI id of processors can be reported wrongly by the BIOS. - * Don't trust it blindly - */ - if (per_cpu(processor_device_array, pr->id) != NULL && - per_cpu(processor_device_array, pr->id) != device) { - printk(KERN_WARNING "BIOS reported wrong ACPI id " - "for the processor\n"); - return -ENODEV; - } - per_cpu(processor_device_array, pr->id) = device; - - per_cpu(processors, pr->id) = pr; - - result = acpi_processor_add_fs(device); - if (result) - goto end; - - sysdev = get_cpu_sysdev(pr->id); - if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) - return -EFAULT; - - /* _PDC call should be done before doing anything else (if reqd.). */ - arch_acpi_processor_init_pdc(pr); - acpi_processor_set_pdc(pr); - arch_acpi_processor_cleanup_pdc(pr); - -#ifdef CONFIG_CPU_FREQ - acpi_processor_ppc_has_changed(pr); -#endif - acpi_processor_get_throttling_info(pr); - acpi_processor_get_limit_info(pr); - - - acpi_processor_power_init(pr, device); - - pr->cdev = thermal_cooling_device_register("Processor", device, - &processor_cooling_ops); - if (IS_ERR(pr->cdev)) { - result = PTR_ERR(pr->cdev); - goto end; - } - - dev_info(&device->dev, "registered as cooling_device%d\n", - pr->cdev->id); - - result = sysfs_create_link(&device->dev.kobj, - &pr->cdev->device.kobj, - "thermal_cooling"); - if (result) - printk(KERN_ERR PREFIX "Create sysfs link\n"); - result = sysfs_create_link(&pr->cdev->device.kobj, - &device->dev.kobj, - "device"); - if (result) - printk(KERN_ERR PREFIX "Create sysfs link\n"); - - if (pr->flags.throttling) { - printk(KERN_INFO PREFIX "%s [%s] (supports", - acpi_device_name(device), acpi_device_bid(device)); - printk(" %d throttling states", pr->throttling.state_count); - printk(")\n"); - } - - end: - - return result; -} - static void acpi_processor_notify(struct acpi_device *device, u32 event) { struct acpi_processor *pr = acpi_driver_data(device); @@ -848,10 +760,8 @@ static struct notifier_block acpi_cpu_notifier = static int acpi_processor_add(struct acpi_device *device) { struct acpi_processor *pr = NULL; - - - if (!device) - return -EINVAL; + int result = 0; + struct sys_device *sysdev; pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); if (!pr) @@ -867,7 +777,100 @@ static int acpi_processor_add(struct acpi_device *device) strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); device->driver_data = pr; + result = acpi_processor_get_info(device); + if (result) { + /* Processor is physically not present */ + return 0; + } + + BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); + + /* + * Buggy BIOS check + * ACPI id of processors can be reported wrongly by the BIOS. + * Don't trust it blindly + */ + if (per_cpu(processor_device_array, pr->id) != NULL && + per_cpu(processor_device_array, pr->id) != device) { + printk(KERN_WARNING "BIOS reported wrong ACPI id " + "for the processor\n"); + result = -ENODEV; + goto err_free_cpumask; + } + per_cpu(processor_device_array, pr->id) = device; + + per_cpu(processors, pr->id) = pr; + + result = acpi_processor_add_fs(device); + if (result) + goto err_free_cpumask; + + sysdev = get_cpu_sysdev(pr->id); + if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { + result = -EFAULT; + goto err_remove_fs; + } + + /* _PDC call should be done before doing anything else (if reqd.). */ + arch_acpi_processor_init_pdc(pr); + acpi_processor_set_pdc(pr); + arch_acpi_processor_cleanup_pdc(pr); + +#ifdef CONFIG_CPU_FREQ + acpi_processor_ppc_has_changed(pr); +#endif + acpi_processor_get_throttling_info(pr); + acpi_processor_get_limit_info(pr); + + + acpi_processor_power_init(pr, device); + + pr->cdev = thermal_cooling_device_register("Processor", device, + &processor_cooling_ops); + if (IS_ERR(pr->cdev)) { + result = PTR_ERR(pr->cdev); + goto err_power_exit; + } + + dev_info(&device->dev, "registered as cooling_device%d\n", + pr->cdev->id); + + result = sysfs_create_link(&device->dev.kobj, + &pr->cdev->device.kobj, + "thermal_cooling"); + if (result) { + printk(KERN_ERR PREFIX "Create sysfs link\n"); + goto err_thermal_unregister; + } + result = sysfs_create_link(&pr->cdev->device.kobj, + &device->dev.kobj, + "device"); + if (result) { + printk(KERN_ERR PREFIX "Create sysfs link\n"); + goto err_remove_sysfs; + } + + if (pr->flags.throttling) { + printk(KERN_INFO PREFIX "%s [%s] (supports", + acpi_device_name(device), acpi_device_bid(device)); + printk(" %d throttling states", pr->throttling.state_count); + printk(")\n"); + } + return 0; + +err_remove_sysfs: + sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); +err_thermal_unregister: + thermal_cooling_device_unregister(pr->cdev); +err_power_exit: + acpi_processor_power_exit(pr, device); +err_remove_fs: + acpi_processor_remove_fs(device); +err_free_cpumask: + free_cpumask_var(pr->throttling.shared_cpu_map); + + return result; } static int acpi_processor_remove(struct acpi_device *device, int type) @@ -944,7 +947,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) { acpi_handle phandle; struct acpi_device *pdev; - struct acpi_processor *pr; if (acpi_get_parent(handle, &phandle)) { @@ -959,15 +961,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) return -ENODEV; } - acpi_bus_start(*device); - - pr = acpi_driver_data(*device); - if (!pr) - return -ENODEV; - - if ((pr->id >= 0) && (pr->id < nr_cpu_ids)) { - kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE); - } return 0; } @@ -997,25 +990,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, "Unable to add the device\n"); break; } - - pr = acpi_driver_data(device); - if (!pr) { - printk(KERN_ERR PREFIX "Driver data is NULL\n"); - break; - } - - if (pr->id >= 0 && (pr->id < nr_cpu_ids)) { - kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); - break; - } - - result = acpi_processor_start(device); - if ((!result) && ((pr->id >= 0) && (pr->id < nr_cpu_ids))) { - kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); - } else { - printk(KERN_ERR PREFIX "Device [%s] failed to start\n", - acpi_device_bid(device)); - } break; case ACPI_NOTIFY_EJECT_REQUEST: ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -1032,9 +1006,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, "Driver data is NULL, dropping EJECT\n"); return; } - - if ((pr->id < nr_cpu_ids) && (cpu_present(pr->id))) - kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, |