aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorThomas Renninger <trenn@suse.de>2012-01-19 12:18:42 -0500
committerLen Brown <len.brown@intel.com>2012-01-19 21:24:34 -0500
commit54d5dcc45af7adbb907072d042bbece4c2b4de6e (patch)
treea76ad45025545902b48aa6b58da630d7c87681a4 /drivers/acpi
parentdcd6c92267155e70a94b3927bce681ce74b80d1f (diff)
ACPI processor hotplug: Split up acpi_processor_add
No functional change. This is needed because: When a CPU gets hotplugged, it's totally uninitialized and offline. cpuinfo_x86 struct (cpu_data(cpu)) is mostly zero (CPU feature flags, model, family,..). When a CPU gets hotplugged, struct processor is alloc'd, some sysfs files are set up but acpi_processor_add() must not try to access a MSR on this CPU or try to read out CPU feature,family, etc. This must be done in acpi_processor_start(). The next patch will delay the call of acpi_processor_start() for physically hotpluggedcores, to the time when they are onlined the first time. There it is safe then to access cpu_data(cpu) cpuinfo_x86 struct or access MSRs which is needed to set up cpuidle, throttling and other features. Tested and Signed-off-by: Thomas Renninger <trenn@suse.de> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/processor_driver.c92
1 files changed, 54 insertions, 38 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 0034ede38710..bec55937cf10 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -440,6 +440,58 @@ static struct notifier_block acpi_cpu_notifier =
440 .notifier_call = acpi_cpu_soft_notify, 440 .notifier_call = acpi_cpu_soft_notify,
441}; 441};
442 442
443static int __cpuinit acpi_processor_start(struct acpi_processor *pr)
444{
445 struct acpi_device *device = per_cpu(processor_device_array, pr->id);
446 int result = 0;
447
448#ifdef CONFIG_CPU_FREQ
449 acpi_processor_ppc_has_changed(pr, 0);
450#endif
451 acpi_processor_get_throttling_info(pr);
452 acpi_processor_get_limit_info(pr);
453
454 if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
455 acpi_processor_power_init(pr, device);
456
457 pr->cdev = thermal_cooling_device_register("Processor", device,
458 &processor_cooling_ops);
459 if (IS_ERR(pr->cdev)) {
460 result = PTR_ERR(pr->cdev);
461 goto err_power_exit;
462 }
463
464 dev_dbg(&device->dev, "registered as cooling_device%d\n",
465 pr->cdev->id);
466
467 result = sysfs_create_link(&device->dev.kobj,
468 &pr->cdev->device.kobj,
469 "thermal_cooling");
470 if (result) {
471 printk(KERN_ERR PREFIX "Create sysfs link\n");
472 goto err_thermal_unregister;
473 }
474 result = sysfs_create_link(&pr->cdev->device.kobj,
475 &device->dev.kobj,
476 "device");
477 if (result) {
478 printk(KERN_ERR PREFIX "Create sysfs link\n");
479 goto err_remove_sysfs_thermal;
480 }
481
482 return 0;
483
484err_remove_sysfs_thermal:
485 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
486err_thermal_unregister:
487 thermal_cooling_device_unregister(pr->cdev);
488err_power_exit:
489 acpi_processor_power_exit(pr, device);
490
491 return result;
492}
493
494
443static int __cpuinit acpi_processor_add(struct acpi_device *device) 495static int __cpuinit acpi_processor_add(struct acpi_device *device)
444{ 496{
445 struct acpi_processor *pr = NULL; 497 struct acpi_processor *pr = NULL;
@@ -494,49 +546,13 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
494 result = -EFAULT; 546 result = -EFAULT;
495 goto err_free_cpumask; 547 goto err_free_cpumask;
496 } 548 }
497 549 result = acpi_processor_start(pr);
498#ifdef CONFIG_CPU_FREQ 550 if (result)
499 acpi_processor_ppc_has_changed(pr, 0);
500#endif
501 acpi_processor_get_throttling_info(pr);
502 acpi_processor_get_limit_info(pr);
503
504 if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
505 acpi_processor_power_init(pr, device);
506
507 pr->cdev = thermal_cooling_device_register("Processor", device,
508 &processor_cooling_ops);
509 if (IS_ERR(pr->cdev)) {
510 result = PTR_ERR(pr->cdev);
511 goto err_power_exit;
512 }
513
514 dev_dbg(&device->dev, "registered as cooling_device%d\n",
515 pr->cdev->id);
516
517 result = sysfs_create_link(&device->dev.kobj,
518 &pr->cdev->device.kobj,
519 "thermal_cooling");
520 if (result) {
521 printk(KERN_ERR PREFIX "Create sysfs link\n");
522 goto err_thermal_unregister;
523 }
524 result = sysfs_create_link(&pr->cdev->device.kobj,
525 &device->dev.kobj,
526 "device");
527 if (result) {
528 printk(KERN_ERR PREFIX "Create sysfs link\n");
529 goto err_remove_sysfs; 551 goto err_remove_sysfs;
530 }
531 552
532 return 0; 553 return 0;
533 554
534err_remove_sysfs: 555err_remove_sysfs:
535 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
536err_thermal_unregister:
537 thermal_cooling_device_unregister(pr->cdev);
538err_power_exit:
539 acpi_processor_power_exit(pr, device);
540 sysfs_remove_link(&device->dev.kobj, "sysdev"); 556 sysfs_remove_link(&device->dev.kobj, "sysdev");
541err_free_cpumask: 557err_free_cpumask:
542 free_cpumask_var(pr->throttling.shared_cpu_map); 558 free_cpumask_var(pr->throttling.shared_cpu_map);