diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7fce038fa57e..6b73d163fa83 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -38,10 +38,10 @@ | |||
38 | * also protects the cpufreq_cpu_data array. | 38 | * also protects the cpufreq_cpu_data array. |
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 DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); |
42 | #ifdef CONFIG_HOTPLUG_CPU | 42 | #ifdef CONFIG_HOTPLUG_CPU |
43 | /* This one keeps track of the previously set governor of a removed 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]; | 44 | static DEFINE_PER_CPU(struct cpufreq_governor *, cpufreq_cpu_governor); |
45 | #endif | 45 | #endif |
46 | static DEFINE_SPINLOCK(cpufreq_driver_lock); | 46 | static DEFINE_SPINLOCK(cpufreq_driver_lock); |
47 | 47 | ||
@@ -135,7 +135,7 @@ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | |||
135 | struct cpufreq_policy *data; | 135 | struct cpufreq_policy *data; |
136 | unsigned long flags; | 136 | unsigned long flags; |
137 | 137 | ||
138 | if (cpu >= NR_CPUS) | 138 | if (cpu >= nr_cpu_ids) |
139 | goto err_out; | 139 | goto err_out; |
140 | 140 | ||
141 | /* get the cpufreq driver */ | 141 | /* get the cpufreq driver */ |
@@ -149,7 +149,7 @@ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | |||
149 | 149 | ||
150 | 150 | ||
151 | /* get the CPU */ | 151 | /* get the CPU */ |
152 | data = cpufreq_cpu_data[cpu]; | 152 | data = per_cpu(cpufreq_cpu_data, cpu); |
153 | 153 | ||
154 | if (!data) | 154 | if (!data) |
155 | goto err_out_put_module; | 155 | goto err_out_put_module; |
@@ -327,7 +327,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) | |||
327 | dprintk("notification %u of frequency transition to %u kHz\n", | 327 | dprintk("notification %u of frequency transition to %u kHz\n", |
328 | state, freqs->new); | 328 | state, freqs->new); |
329 | 329 | ||
330 | policy = cpufreq_cpu_data[freqs->cpu]; | 330 | policy = per_cpu(cpufreq_cpu_data, freqs->cpu); |
331 | switch (state) { | 331 | switch (state) { |
332 | 332 | ||
333 | case CPUFREQ_PRECHANGE: | 333 | case CPUFREQ_PRECHANGE: |
@@ -828,8 +828,8 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
828 | #ifdef CONFIG_SMP | 828 | #ifdef CONFIG_SMP |
829 | 829 | ||
830 | #ifdef CONFIG_HOTPLUG_CPU | 830 | #ifdef CONFIG_HOTPLUG_CPU |
831 | if (cpufreq_cpu_governor[cpu]){ | 831 | if (per_cpu(cpufreq_cpu_governor, cpu)) { |
832 | policy->governor = cpufreq_cpu_governor[cpu]; | 832 | policy->governor = per_cpu(cpufreq_cpu_governor, cpu); |
833 | dprintk("Restoring governor %s for cpu %d\n", | 833 | dprintk("Restoring governor %s for cpu %d\n", |
834 | policy->governor->name, cpu); | 834 | policy->governor->name, cpu); |
835 | } | 835 | } |
@@ -854,7 +854,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
854 | 854 | ||
855 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | 855 | spin_lock_irqsave(&cpufreq_driver_lock, flags); |
856 | managed_policy->cpus = policy->cpus; | 856 | managed_policy->cpus = policy->cpus; |
857 | cpufreq_cpu_data[cpu] = managed_policy; | 857 | per_cpu(cpufreq_cpu_data, cpu) = managed_policy; |
858 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 858 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
859 | 859 | ||
860 | dprintk("CPU already managed, adding link\n"); | 860 | dprintk("CPU already managed, adding link\n"); |
@@ -899,7 +899,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
899 | 899 | ||
900 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | 900 | spin_lock_irqsave(&cpufreq_driver_lock, flags); |
901 | for_each_cpu_mask(j, policy->cpus) { | 901 | for_each_cpu_mask(j, policy->cpus) { |
902 | cpufreq_cpu_data[j] = policy; | 902 | per_cpu(cpufreq_cpu_data, j) = policy; |
903 | per_cpu(policy_cpu, j) = policy->cpu; | 903 | per_cpu(policy_cpu, j) = policy->cpu; |
904 | } | 904 | } |
905 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 905 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
@@ -946,7 +946,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
946 | err_out_unregister: | 946 | err_out_unregister: |
947 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | 947 | spin_lock_irqsave(&cpufreq_driver_lock, flags); |
948 | for_each_cpu_mask(j, policy->cpus) | 948 | for_each_cpu_mask(j, policy->cpus) |
949 | cpufreq_cpu_data[j] = NULL; | 949 | per_cpu(cpufreq_cpu_data, j) = NULL; |
950 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 950 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
951 | 951 | ||
952 | kobject_put(&policy->kobj); | 952 | kobject_put(&policy->kobj); |
@@ -989,7 +989,7 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
989 | dprintk("unregistering CPU %u\n", cpu); | 989 | dprintk("unregistering CPU %u\n", cpu); |
990 | 990 | ||
991 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | 991 | spin_lock_irqsave(&cpufreq_driver_lock, flags); |
992 | data = cpufreq_cpu_data[cpu]; | 992 | data = per_cpu(cpufreq_cpu_data, cpu); |
993 | 993 | ||
994 | if (!data) { | 994 | if (!data) { |
995 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 995 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
@@ -997,7 +997,7 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
997 | unlock_policy_rwsem_write(cpu); | 997 | unlock_policy_rwsem_write(cpu); |
998 | return -EINVAL; | 998 | return -EINVAL; |
999 | } | 999 | } |
1000 | cpufreq_cpu_data[cpu] = NULL; | 1000 | per_cpu(cpufreq_cpu_data, cpu) = NULL; |
1001 | 1001 | ||
1002 | 1002 | ||
1003 | #ifdef CONFIG_SMP | 1003 | #ifdef CONFIG_SMP |
@@ -1019,19 +1019,19 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
1019 | #ifdef CONFIG_SMP | 1019 | #ifdef CONFIG_SMP |
1020 | 1020 | ||
1021 | #ifdef CONFIG_HOTPLUG_CPU | 1021 | #ifdef CONFIG_HOTPLUG_CPU |
1022 | cpufreq_cpu_governor[cpu] = data->governor; | 1022 | per_cpu(cpufreq_cpu_governor, cpu) = data->governor; |
1023 | #endif | 1023 | #endif |
1024 | 1024 | ||
1025 | /* if we have other CPUs still registered, we need to unlink them, | 1025 | /* if we have other CPUs still registered, we need to unlink them, |
1026 | * or else wait_for_completion below will lock up. Clean the | 1026 | * or else wait_for_completion below will lock up. Clean the |
1027 | * cpufreq_cpu_data[] while holding the lock, and remove the sysfs | 1027 | * per_cpu(cpufreq_cpu_data) while holding the lock, and remove |
1028 | * links afterwards. | 1028 | * the sysfs links afterwards. |
1029 | */ | 1029 | */ |
1030 | if (unlikely(cpus_weight(data->cpus) > 1)) { | 1030 | if (unlikely(cpus_weight(data->cpus) > 1)) { |
1031 | for_each_cpu_mask(j, data->cpus) { | 1031 | for_each_cpu_mask(j, data->cpus) { |
1032 | if (j == cpu) | 1032 | if (j == cpu) |
1033 | continue; | 1033 | continue; |
1034 | cpufreq_cpu_data[j] = NULL; | 1034 | per_cpu(cpufreq_cpu_data, j) = NULL; |
1035 | } | 1035 | } |
1036 | } | 1036 | } |
1037 | 1037 | ||
@@ -1043,7 +1043,7 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
1043 | continue; | 1043 | continue; |
1044 | dprintk("removing link for cpu %u\n", j); | 1044 | dprintk("removing link for cpu %u\n", j); |
1045 | #ifdef CONFIG_HOTPLUG_CPU | 1045 | #ifdef CONFIG_HOTPLUG_CPU |
1046 | cpufreq_cpu_governor[j] = data->governor; | 1046 | per_cpu(cpufreq_cpu_governor, j) = data->governor; |
1047 | #endif | 1047 | #endif |
1048 | cpu_sys_dev = get_cpu_sysdev(j); | 1048 | cpu_sys_dev = get_cpu_sysdev(j); |
1049 | sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); | 1049 | sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); |
@@ -1153,7 +1153,7 @@ EXPORT_SYMBOL(cpufreq_quick_get); | |||
1153 | 1153 | ||
1154 | static unsigned int __cpufreq_get(unsigned int cpu) | 1154 | static unsigned int __cpufreq_get(unsigned int cpu) |
1155 | { | 1155 | { |
1156 | struct cpufreq_policy *policy = cpufreq_cpu_data[cpu]; | 1156 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); |
1157 | unsigned int ret_freq = 0; | 1157 | unsigned int ret_freq = 0; |
1158 | 1158 | ||
1159 | if (!cpufreq_driver->get) | 1159 | if (!cpufreq_driver->get) |
@@ -1822,16 +1822,19 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
1822 | cpufreq_driver = driver_data; | 1822 | cpufreq_driver = driver_data; |
1823 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1823 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1824 | 1824 | ||
1825 | ret = sysdev_driver_register(&cpu_sysdev_class,&cpufreq_sysdev_driver); | 1825 | ret = sysdev_driver_register(&cpu_sysdev_class, |
1826 | &cpufreq_sysdev_driver); | ||
1826 | 1827 | ||
1827 | if ((!ret) && !(cpufreq_driver->flags & CPUFREQ_STICKY)) { | 1828 | if ((!ret) && !(cpufreq_driver->flags & CPUFREQ_STICKY)) { |
1828 | int i; | 1829 | int i; |
1829 | ret = -ENODEV; | 1830 | ret = -ENODEV; |
1830 | 1831 | ||
1831 | /* check for at least one working CPU */ | 1832 | /* check for at least one working CPU */ |
1832 | for (i=0; i<NR_CPUS; i++) | 1833 | for (i = 0; i < nr_cpu_ids; i++) |
1833 | if (cpufreq_cpu_data[i]) | 1834 | if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) { |
1834 | ret = 0; | 1835 | ret = 0; |
1836 | break; | ||
1837 | } | ||
1835 | 1838 | ||
1836 | /* if all ->init() calls failed, unregister */ | 1839 | /* if all ->init() calls failed, unregister */ |
1837 | if (ret) { | 1840 | if (ret) { |