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); |