aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFenghua Yu <fenghua.yu@intel.com>2007-08-07 18:40:30 -0400
committerLen Brown <len.brown@intel.com>2007-08-07 18:40:30 -0400
commit501092929ccb8a1d2eb0ed700e38df4ae0de7108 (patch)
treec8478b084056949f90ced4d381275cd3e0d634de
parented3110efb538d7acbf635095c1382118f7414f75 (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.c41
-rw-r--r--drivers/acpi/processor_perflib.c6
-rw-r--r--include/acpi/processor.h2
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
70static struct acpi_cpufreq_data *drv_data[NR_CPUS]; 70static struct acpi_cpufreq_data *drv_data[NR_CPUS];
71static struct acpi_processor_performance *acpi_perf_data[NR_CPUS]; 71/* acpi_perf_data is a pointer to percpu data. */
72static struct acpi_processor_performance *acpi_perf_data;
72 73
73static struct cpufreq_driver acpi_cpufreq_driver; 74static 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 */
511static int acpi_cpufreq_early_init(void) 512static 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
779static int __init acpi_cpufreq_init(void) 767static 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
788static void __exit acpi_cpufreq_exit(void) 780static 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
541int acpi_processor_preregister_performance( 541int 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
233extern int acpi_processor_preregister_performance(struct 233extern int acpi_processor_preregister_performance(struct
234 acpi_processor_performance 234 acpi_processor_performance
235 **performance); 235 *performance);
236 236
237extern int acpi_processor_register_performance(struct acpi_processor_performance 237extern int acpi_processor_register_performance(struct acpi_processor_performance
238 *performance, unsigned int cpu); 238 *performance, unsigned int cpu);