diff options
| author | Fenghua Yu <fenghua.yu@intel.com> | 2007-08-07 18:40:30 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2007-08-07 18:40:30 -0400 |
| commit | 501092929ccb8a1d2eb0ed700e38df4ae0de7108 (patch) | |
| tree | c8478b084056949f90ced4d381275cd3e0d634de | |
| parent | ed3110efb538d7acbf635095c1382118f7414f75 (diff) | |
acpi-cpufreq: Fix some x86/x86-64 acpi-cpufreq driver issues
This patch addresses some issues in x86/x86-64 acpi-cpufreq driver:
1. Current memory allocation for acpi_perf_data is actually open-coded
alloc_percpu(). The patch defines and handles acpi_perf_data as percpu
data. The code will be cleaner and easier to be maintained with this
change.
2. Won't load driver in acpi_cpufreq_early_init() failure case.
3. Add __init for acpi_cpufreq_early_init().
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Acked-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Dave Jones <davej@codemonkey.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
| -rw-r--r-- | arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 41 | ||||
| -rw-r--r-- | drivers/acpi/processor_perflib.c | 6 | ||||
| -rw-r--r-- | include/acpi/processor.h | 2 |
3 files changed, 19 insertions, 30 deletions
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 32d04b083e38..705e13a30781 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
| @@ -68,7 +68,8 @@ struct acpi_cpufreq_data { | |||
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | static struct acpi_cpufreq_data *drv_data[NR_CPUS]; | 70 | static struct acpi_cpufreq_data *drv_data[NR_CPUS]; |
| 71 | static struct acpi_processor_performance *acpi_perf_data[NR_CPUS]; | 71 | /* acpi_perf_data is a pointer to percpu data. */ |
| 72 | static struct acpi_processor_performance *acpi_perf_data; | ||
| 72 | 73 | ||
| 73 | static struct cpufreq_driver acpi_cpufreq_driver; | 74 | static struct cpufreq_driver acpi_cpufreq_driver; |
| 74 | 75 | ||
| @@ -508,24 +509,14 @@ acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) | |||
| 508 | * do _PDC and _PSD and find out the processor dependency for the | 509 | * do _PDC and _PSD and find out the processor dependency for the |
| 509 | * actual init that will happen later... | 510 | * actual init that will happen later... |
| 510 | */ | 511 | */ |
| 511 | static int acpi_cpufreq_early_init(void) | 512 | static int __init acpi_cpufreq_early_init(void) |
| 512 | { | 513 | { |
| 513 | struct acpi_processor_performance *data; | ||
| 514 | unsigned int i, j; | ||
| 515 | |||
| 516 | dprintk("acpi_cpufreq_early_init\n"); | 514 | dprintk("acpi_cpufreq_early_init\n"); |
| 517 | 515 | ||
| 518 | for_each_possible_cpu(i) { | 516 | acpi_perf_data = alloc_percpu(struct acpi_processor_performance); |
| 519 | data = kzalloc(sizeof(struct acpi_processor_performance), | 517 | if (!acpi_perf_data) { |
| 520 | GFP_KERNEL); | 518 | dprintk("Memory allocation error for acpi_perf_data.\n"); |
| 521 | if (!data) { | 519 | return -ENOMEM; |
| 522 | for_each_possible_cpu(j) { | ||
| 523 | kfree(acpi_perf_data[j]); | ||
| 524 | acpi_perf_data[j] = NULL; | ||
| 525 | } | ||
| 526 | return -ENOMEM; | ||
| 527 | } | ||
| 528 | acpi_perf_data[i] = data; | ||
| 529 | } | 520 | } |
| 530 | 521 | ||
| 531 | /* Do initialization in ACPI core */ | 522 | /* Do initialization in ACPI core */ |
| @@ -574,14 +565,11 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
| 574 | 565 | ||
| 575 | dprintk("acpi_cpufreq_cpu_init\n"); | 566 | dprintk("acpi_cpufreq_cpu_init\n"); |
| 576 | 567 | ||
| 577 | if (!acpi_perf_data[cpu]) | ||
| 578 | return -ENODEV; | ||
| 579 | |||
| 580 | data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); | 568 | data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); |
| 581 | if (!data) | 569 | if (!data) |
| 582 | return -ENOMEM; | 570 | return -ENOMEM; |
| 583 | 571 | ||
| 584 | data->acpi_data = acpi_perf_data[cpu]; | 572 | data->acpi_data = percpu_ptr(acpi_perf_data, cpu); |
| 585 | drv_data[cpu] = data; | 573 | drv_data[cpu] = data; |
| 586 | 574 | ||
| 587 | if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) | 575 | if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) |
| @@ -778,24 +766,25 @@ static struct cpufreq_driver acpi_cpufreq_driver = { | |||
| 778 | 766 | ||
| 779 | static int __init acpi_cpufreq_init(void) | 767 | static int __init acpi_cpufreq_init(void) |
| 780 | { | 768 | { |
| 769 | int ret; | ||
| 770 | |||
| 781 | dprintk("acpi_cpufreq_init\n"); | 771 | dprintk("acpi_cpufreq_init\n"); |
| 782 | 772 | ||
| 783 | acpi_cpufreq_early_init(); | 773 | ret = acpi_cpufreq_early_init(); |
| 774 | if (ret) | ||
| 775 | return ret; | ||
| 784 | 776 | ||
| 785 | return cpufreq_register_driver(&acpi_cpufreq_driver); | 777 | return cpufreq_register_driver(&acpi_cpufreq_driver); |
| 786 | } | 778 | } |
| 787 | 779 | ||
| 788 | static void __exit acpi_cpufreq_exit(void) | 780 | static void __exit acpi_cpufreq_exit(void) |
| 789 | { | 781 | { |
| 790 | unsigned int i; | ||
| 791 | dprintk("acpi_cpufreq_exit\n"); | 782 | dprintk("acpi_cpufreq_exit\n"); |
| 792 | 783 | ||
| 793 | cpufreq_unregister_driver(&acpi_cpufreq_driver); | 784 | cpufreq_unregister_driver(&acpi_cpufreq_driver); |
| 794 | 785 | ||
| 795 | for_each_possible_cpu(i) { | 786 | free_percpu(acpi_perf_data); |
| 796 | kfree(acpi_perf_data[i]); | 787 | |
| 797 | acpi_perf_data[i] = NULL; | ||
| 798 | } | ||
| 799 | return; | 788 | return; |
| 800 | } | 789 | } |
| 801 | 790 | ||
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index c4efc0c17f8f..463b0247cbc5 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
| @@ -539,7 +539,7 @@ end: | |||
| 539 | } | 539 | } |
| 540 | 540 | ||
| 541 | int acpi_processor_preregister_performance( | 541 | int acpi_processor_preregister_performance( |
| 542 | struct acpi_processor_performance **performance) | 542 | struct acpi_processor_performance *performance) |
| 543 | { | 543 | { |
| 544 | int count, count_target; | 544 | int count, count_target; |
| 545 | int retval = 0; | 545 | int retval = 0; |
| @@ -567,12 +567,12 @@ int acpi_processor_preregister_performance( | |||
| 567 | continue; | 567 | continue; |
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | if (!performance || !performance[i]) { | 570 | if (!performance || !percpu_ptr(performance, i)) { |
| 571 | retval = -EINVAL; | 571 | retval = -EINVAL; |
| 572 | continue; | 572 | continue; |
| 573 | } | 573 | } |
| 574 | 574 | ||
| 575 | pr->performance = performance[i]; | 575 | pr->performance = percpu_ptr(performance, i); |
| 576 | cpu_set(i, pr->performance->shared_cpu_map); | 576 | cpu_set(i, pr->performance->shared_cpu_map); |
| 577 | if (acpi_processor_get_psd(pr)) { | 577 | if (acpi_processor_get_psd(pr)) { |
| 578 | retval = -EINVAL; | 578 | retval = -EINVAL; |
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index f9f987f8e661..ec3ffdadb4d2 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
| @@ -232,7 +232,7 @@ struct acpi_processor_errata { | |||
| 232 | 232 | ||
| 233 | extern int acpi_processor_preregister_performance(struct | 233 | extern int acpi_processor_preregister_performance(struct |
| 234 | acpi_processor_performance | 234 | acpi_processor_performance |
| 235 | **performance); | 235 | *performance); |
| 236 | 236 | ||
| 237 | extern int acpi_processor_register_performance(struct acpi_processor_performance | 237 | extern int acpi_processor_register_performance(struct acpi_processor_performance |
| 238 | *performance, unsigned int cpu); | 238 | *performance, unsigned int cpu); |
