aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq.c
diff options
context:
space:
mode:
authorThomas Renninger <trenn@suse.de>2007-07-09 14:35:28 -0400
committerDave Jones <davej@redhat.com>2007-07-13 01:29:51 -0400
commit084f34939424161669467c19280dbcf637730314 (patch)
tree85285adb98b7306a28152cf48bfae98d3f1f05c8 /drivers/cpufreq/cpufreq.c
parent91973de736bc97dc04156242c5a4b00993b6c902 (diff)
[CPUFREQ] Restore previously used governor on a hot-replugged CPU
Negative side effect: needs NR_CPUs pointer array of memory in CONFIG_HOTPLUG_CPU case. Still needs userspace track keeping and rewriting of governors if governors change while a CPU is not active (always the governor at CPU remove time is restored). Move of policy->user_policy.governor assignment is just a minor cleanup. http://bugzilla.kernel.org/show_bug.cgi?id=8671 Signed-off-by: Thomas Renninger <trenn@suse.de> Signed-off-by: Mattia Dongili <malattia@linux.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r--drivers/cpufreq/cpufreq.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 99f9c3c23845..2f6a73c01b71 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -39,6 +39,10 @@
39 */ 39 */
40static struct cpufreq_driver *cpufreq_driver; 40static struct cpufreq_driver *cpufreq_driver;
41static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; 41static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
42#ifdef CONFIG_HOTPLUG_CPU
43/* This one keeps track of the previously set governor of a removed CPU */
44static struct cpufreq_governor *cpufreq_cpu_governor[NR_CPUS];
45#endif
42static DEFINE_SPINLOCK(cpufreq_driver_lock); 46static DEFINE_SPINLOCK(cpufreq_driver_lock);
43 47
44/* 48/*
@@ -770,9 +774,17 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
770 } 774 }
771 policy->user_policy.min = policy->cpuinfo.min_freq; 775 policy->user_policy.min = policy->cpuinfo.min_freq;
772 policy->user_policy.max = policy->cpuinfo.max_freq; 776 policy->user_policy.max = policy->cpuinfo.max_freq;
773 policy->user_policy.governor = policy->governor;
774 777
775#ifdef CONFIG_SMP 778#ifdef CONFIG_SMP
779
780#ifdef CONFIG_HOTPLUG_CPU
781 if (cpufreq_cpu_governor[cpu]){
782 policy->governor = cpufreq_cpu_governor[cpu];
783 dprintk("Restoring governor %s for cpu %d\n",
784 policy->governor->name, cpu);
785 }
786#endif
787
776 for_each_cpu_mask(j, policy->cpus) { 788 for_each_cpu_mask(j, policy->cpus) {
777 if (cpu == j) 789 if (cpu == j)
778 continue; 790 continue;
@@ -873,6 +885,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
873 /* set default policy */ 885 /* set default policy */
874 ret = __cpufreq_set_policy(policy, &new_policy); 886 ret = __cpufreq_set_policy(policy, &new_policy);
875 policy->user_policy.policy = policy->policy; 887 policy->user_policy.policy = policy->policy;
888 policy->user_policy.governor = policy->governor;
876 889
877 unlock_policy_rwsem_write(cpu); 890 unlock_policy_rwsem_write(cpu);
878 891
@@ -969,6 +982,11 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev)
969 } 982 }
970 983
971#ifdef CONFIG_SMP 984#ifdef CONFIG_SMP
985
986#ifdef CONFIG_HOTPLUG_CPU
987 cpufreq_cpu_governor[cpu] = data->governor;
988#endif
989
972 /* if we have other CPUs still registered, we need to unlink them, 990 /* if we have other CPUs still registered, we need to unlink them,
973 * or else wait_for_completion below will lock up. Clean the 991 * or else wait_for_completion below will lock up. Clean the
974 * cpufreq_cpu_data[] while holding the lock, and remove the sysfs 992 * cpufreq_cpu_data[] while holding the lock, and remove the sysfs
@@ -989,6 +1007,9 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev)
989 if (j == cpu) 1007 if (j == cpu)
990 continue; 1008 continue;
991 dprintk("removing link for cpu %u\n", j); 1009 dprintk("removing link for cpu %u\n", j);
1010#ifdef CONFIG_HOTPLUG_CPU
1011 cpufreq_cpu_governor[j] = data->governor;
1012#endif
992 cpu_sys_dev = get_cpu_sysdev(j); 1013 cpu_sys_dev = get_cpu_sysdev(j);
993 sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); 1014 sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
994 cpufreq_cpu_put(data); 1015 cpufreq_cpu_put(data);