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>

authored by Fenghua Yu and committed by Len Brown 50109292 ed3110ef

+19 -30
+15 -26
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
··· 68 68 }; 69 69 70 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 74 static struct cpufreq_driver acpi_cpufreq_driver; 74 75 ··· 509 508 * do _PDC and _PSD and find out the processor dependency for the 510 509 * actual init that will happen later... 511 510 */ 512 - static int acpi_cpufreq_early_init(void) 511 + static int __init acpi_cpufreq_early_init(void) 513 512 { 514 - struct acpi_processor_performance *data; 515 - unsigned int i, j; 516 - 517 513 dprintk("acpi_cpufreq_early_init\n"); 518 514 519 - for_each_possible_cpu(i) { 520 - data = kzalloc(sizeof(struct acpi_processor_performance), 521 - GFP_KERNEL); 522 - if (!data) { 523 - for_each_possible_cpu(j) { 524 - kfree(acpi_perf_data[j]); 525 - acpi_perf_data[j] = NULL; 526 - } 527 - return -ENOMEM; 528 - } 529 - acpi_perf_data[i] = data; 515 + acpi_perf_data = alloc_percpu(struct acpi_processor_performance); 516 + if (!acpi_perf_data) { 517 + dprintk("Memory allocation error for acpi_perf_data.\n"); 518 + return -ENOMEM; 530 519 } 531 520 532 521 /* Do initialization in ACPI core */ ··· 565 574 566 575 dprintk("acpi_cpufreq_cpu_init\n"); 567 576 568 - if (!acpi_perf_data[cpu]) 569 - return -ENODEV; 570 - 571 577 data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); 572 578 if (!data) 573 579 return -ENOMEM; 574 580 575 - data->acpi_data = acpi_perf_data[cpu]; 581 + data->acpi_data = percpu_ptr(acpi_perf_data, cpu); 576 582 drv_data[cpu] = data; 577 583 578 584 if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) ··· 766 778 767 779 static int __init acpi_cpufreq_init(void) 768 780 { 781 + int ret; 782 + 769 783 dprintk("acpi_cpufreq_init\n"); 770 784 771 - acpi_cpufreq_early_init(); 785 + ret = acpi_cpufreq_early_init(); 786 + if (ret) 787 + return ret; 772 788 773 789 return cpufreq_register_driver(&acpi_cpufreq_driver); 774 790 } 775 791 776 792 static void __exit acpi_cpufreq_exit(void) 777 793 { 778 - unsigned int i; 779 794 dprintk("acpi_cpufreq_exit\n"); 780 795 781 796 cpufreq_unregister_driver(&acpi_cpufreq_driver); 782 797 783 - for_each_possible_cpu(i) { 784 - kfree(acpi_perf_data[i]); 785 - acpi_perf_data[i] = NULL; 786 - } 798 + free_percpu(acpi_perf_data); 799 + 787 800 return; 788 801 } 789 802
+3 -3
drivers/acpi/processor_perflib.c
··· 539 539 } 540 540 541 541 int acpi_processor_preregister_performance( 542 - struct acpi_processor_performance **performance) 542 + struct acpi_processor_performance *performance) 543 543 { 544 544 int count, count_target; 545 545 int retval = 0; ··· 567 567 continue; 568 568 } 569 569 570 - if (!performance || !performance[i]) { 570 + if (!performance || !percpu_ptr(performance, i)) { 571 571 retval = -EINVAL; 572 572 continue; 573 573 } 574 574 575 - pr->performance = performance[i]; 575 + pr->performance = percpu_ptr(performance, i); 576 576 cpu_set(i, pr->performance->shared_cpu_map); 577 577 if (acpi_processor_get_psd(pr)) { 578 578 retval = -EINVAL;
+1 -1
include/acpi/processor.h
··· 232 232 233 233 extern int acpi_processor_preregister_performance(struct 234 234 acpi_processor_performance 235 - **performance); 235 + *performance); 236 236 237 237 extern int acpi_processor_register_performance(struct acpi_processor_performance 238 238 *performance, unsigned int cpu);