aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-05-08 17:59:58 -0400
committerH. Peter Anvin <hpa@zytor.com>2010-05-08 17:59:58 -0400
commitd7be0ce6afb1df60bc786f57410407ceae92b994 (patch)
tree5e91acfc12c833531ad3320f274e0cd96a129973 /drivers/cpufreq/cpufreq.c
parente08cae4181af9483b04ecfac48f01c8e5a5f27bf (diff)
parent66f41d4c5c8a5deed66fdcc84509376c9a0bf9d8 (diff)
Merge commit 'v2.6.34-rc6' into x86/cpu
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r--drivers/cpufreq/cpufreq.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index e02e4174c2c8..063b2184caf5 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1101,6 +1101,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
1101 unsigned int cpu = sys_dev->id; 1101 unsigned int cpu = sys_dev->id;
1102 unsigned long flags; 1102 unsigned long flags;
1103 struct cpufreq_policy *data; 1103 struct cpufreq_policy *data;
1104 struct kobject *kobj;
1105 struct completion *cmp;
1104#ifdef CONFIG_SMP 1106#ifdef CONFIG_SMP
1105 struct sys_device *cpu_sys_dev; 1107 struct sys_device *cpu_sys_dev;
1106 unsigned int j; 1108 unsigned int j;
@@ -1129,10 +1131,11 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
1129 dprintk("removing link\n"); 1131 dprintk("removing link\n");
1130 cpumask_clear_cpu(cpu, data->cpus); 1132 cpumask_clear_cpu(cpu, data->cpus);
1131 spin_unlock_irqrestore(&cpufreq_driver_lock, flags); 1133 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1132 sysfs_remove_link(&sys_dev->kobj, "cpufreq"); 1134 kobj = &sys_dev->kobj;
1133 cpufreq_cpu_put(data); 1135 cpufreq_cpu_put(data);
1134 cpufreq_debug_enable_ratelimit(); 1136 cpufreq_debug_enable_ratelimit();
1135 unlock_policy_rwsem_write(cpu); 1137 unlock_policy_rwsem_write(cpu);
1138 sysfs_remove_link(kobj, "cpufreq");
1136 return 0; 1139 return 0;
1137 } 1140 }
1138#endif 1141#endif
@@ -1169,7 +1172,10 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
1169 data->governor->name, CPUFREQ_NAME_LEN); 1172 data->governor->name, CPUFREQ_NAME_LEN);
1170#endif 1173#endif
1171 cpu_sys_dev = get_cpu_sysdev(j); 1174 cpu_sys_dev = get_cpu_sysdev(j);
1172 sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); 1175 kobj = &cpu_sys_dev->kobj;
1176 unlock_policy_rwsem_write(cpu);
1177 sysfs_remove_link(kobj, "cpufreq");
1178 lock_policy_rwsem_write(cpu);
1173 cpufreq_cpu_put(data); 1179 cpufreq_cpu_put(data);
1174 } 1180 }
1175 } 1181 }
@@ -1180,19 +1186,22 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
1180 if (cpufreq_driver->target) 1186 if (cpufreq_driver->target)
1181 __cpufreq_governor(data, CPUFREQ_GOV_STOP); 1187 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1182 1188
1183 kobject_put(&data->kobj); 1189 kobj = &data->kobj;
1190 cmp = &data->kobj_unregister;
1191 unlock_policy_rwsem_write(cpu);
1192 kobject_put(kobj);
1184 1193
1185 /* we need to make sure that the underlying kobj is actually 1194 /* we need to make sure that the underlying kobj is actually
1186 * not referenced anymore by anybody before we proceed with 1195 * not referenced anymore by anybody before we proceed with
1187 * unloading. 1196 * unloading.
1188 */ 1197 */
1189 dprintk("waiting for dropping of refcount\n"); 1198 dprintk("waiting for dropping of refcount\n");
1190 wait_for_completion(&data->kobj_unregister); 1199 wait_for_completion(cmp);
1191 dprintk("wait complete\n"); 1200 dprintk("wait complete\n");
1192 1201
1202 lock_policy_rwsem_write(cpu);
1193 if (cpufreq_driver->exit) 1203 if (cpufreq_driver->exit)
1194 cpufreq_driver->exit(data); 1204 cpufreq_driver->exit(data);
1195
1196 unlock_policy_rwsem_write(cpu); 1205 unlock_policy_rwsem_write(cpu);
1197 1206
1198 free_cpumask_var(data->related_cpus); 1207 free_cpumask_var(data->related_cpus);