diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 67bc2ec..8438f03 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1113,6 +1113,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) unsigned int cpu = sys_dev->id; unsigned long flags; struct cpufreq_policy *data; + struct kobject *kobj; + struct completion *cmp; #ifdef CONFIG_SMP struct sys_device *cpu_sys_dev; unsigned int j; @@ -1192,19 +1194,22 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) if (cpufreq_driver->target) __cpufreq_governor(data, CPUFREQ_GOV_STOP); - kobject_put(&data->kobj); + kobj = &data->kobj; + cmp = &data->kobj_unregister; + unlock_policy_rwsem_write(cpu); + kobject_put(kobj); /* we need to make sure that the underlying kobj is actually * not referenced anymore by anybody before we proceed with * unloading. */ dprintk("waiting for dropping of refcount\n"); - wait_for_completion(&data->kobj_unregister); + wait_for_completion(cmp); dprintk("wait complete\n"); + lock_policy_rwsem_write(cpu); if (cpufreq_driver->exit) cpufreq_driver->exit(data); - unlock_policy_rwsem_write(cpu); free_cpumask_var(data->related_cpus);