diff options
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 23 |
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 | */ |
40 | static struct cpufreq_driver *cpufreq_driver; | 40 | static struct cpufreq_driver *cpufreq_driver; |
41 | static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; | 41 | static 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 */ | ||
44 | static struct cpufreq_governor *cpufreq_cpu_governor[NR_CPUS]; | ||
45 | #endif | ||
42 | static DEFINE_SPINLOCK(cpufreq_driver_lock); | 46 | static 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); |