Commit fb430fb1 authored by Dave Jones's avatar Dave Jones

[CPUFREQ] Fix locking [4/11]

Make cpufreq_remove_dev a bit more readable. Also, assure that the
GOV_STOP and the cpufreq_driver->exit() call are indeed the last calls
done.
parent a5f5ddb8
...@@ -423,42 +423,41 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev) ...@@ -423,42 +423,41 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
{ {
unsigned int cpu = sys_dev->id; unsigned int cpu = sys_dev->id;
unsigned long flags; unsigned long flags;
struct cpufreq_policy *data;
spin_lock_irqsave(&cpufreq_driver_lock, flags); spin_lock_irqsave(&cpufreq_driver_lock, flags);
if (!cpufreq_cpu_data[cpu]) { data = cpufreq_cpu_data[cpu];
if (!data) {
spin_unlock_irqrestore(&cpufreq_driver_lock, flags); spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
return -EINVAL; return -EINVAL;
} }
cpufreq_cpu_data[cpu] = NULL; cpufreq_cpu_data[cpu] = NULL;
spin_unlock_irqrestore(&cpufreq_driver_lock, flags); spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
if (!kobject_get(&cpufreq_driver->policy[cpu].kobj)) if (!kobject_get(&data->kobj))
return -EFAULT; return -EFAULT;
down(&cpufreq_driver_sem); down(&cpufreq_driver_sem);
if ((cpufreq_driver->target) && kobject_unregister(&data->kobj);
(cpufreq_driver->policy[cpu].policy == CPUFREQ_POLICY_GOVERNOR)) {
cpufreq_driver->policy[cpu].governor->governor(&cpufreq_driver->policy[cpu], CPUFREQ_GOV_STOP);
module_put(cpufreq_driver->policy[cpu].governor->owner);
}
/* we may call driver->exit here without checking for try_module_exit
* as it's either the driver which wants to unload or we have a CPU
* removal AND driver removal at the same time...
*/
if (cpufreq_driver->exit)
cpufreq_driver->exit(&cpufreq_driver->policy[cpu]);
kobject_unregister(&cpufreq_driver->policy[cpu].kobj);
up(&cpufreq_driver_sem); up(&cpufreq_driver_sem);
kobject_put(&cpufreq_driver->policy[cpu].kobj);
kobject_put(&data->kobj);
/* we need to make sure that the underlying kobj is actually /* we need to make sure that the underlying kobj is actually
* destroyed before we proceed e.g. with cpufreq driver module * not referenced anymore by anybody before we proceed with
* unloading * unloading.
*/ */
wait_for_completion(&cpufreq_driver->policy[cpu].kobj_unregister); wait_for_completion(&data->kobj_unregister);
if ((cpufreq_driver->target) &&
(data->policy == CPUFREQ_POLICY_GOVERNOR)) {
data->governor->governor(data, CPUFREQ_GOV_STOP);
module_put(data->governor->owner);
}
if (cpufreq_driver->exit)
cpufreq_driver->exit(data);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment