Loading drivers/cpufreq/cpufreq.c +90 −76 Original line number Diff line number Diff line Loading @@ -756,6 +756,75 @@ static struct kobj_type ktype_cpufreq = { .release = cpufreq_sysfs_release, }; int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy, struct sys_device *sys_dev) { int ret = 0; #ifdef CONFIG_SMP unsigned long flags; unsigned int j; #ifdef CONFIG_HOTPLUG_CPU if (per_cpu(cpufreq_cpu_governor, cpu)) { policy->governor = per_cpu(cpufreq_cpu_governor, cpu); dprintk("Restoring governor %s for cpu %d\n", policy->governor->name, cpu); } #endif for_each_cpu(j, policy->cpus) { struct cpufreq_policy *managed_policy; if (cpu == j) continue; /* Check for existing affected CPUs. * They may not be aware of it due to CPU Hotplug. * cpufreq_cpu_put is called when the device is removed * in __cpufreq_remove_dev() */ managed_policy = cpufreq_cpu_get(j); if (unlikely(managed_policy)) { /* Set proper policy_cpu */ unlock_policy_rwsem_write(cpu); per_cpu(policy_cpu, cpu) = managed_policy->cpu; if (lock_policy_rwsem_write(cpu) < 0) { /* Should not go through policy unlock path */ if (cpufreq_driver->exit) cpufreq_driver->exit(policy); cpufreq_cpu_put(managed_policy); return -EBUSY; } spin_lock_irqsave(&cpufreq_driver_lock, flags); cpumask_copy(managed_policy->cpus, policy->cpus); per_cpu(cpufreq_cpu_data, cpu) = managed_policy; spin_unlock_irqrestore(&cpufreq_driver_lock, flags); dprintk("CPU already managed, adding link\n"); ret = sysfs_create_link(&sys_dev->kobj, &managed_policy->kobj, "cpufreq"); if (ret) cpufreq_cpu_put(managed_policy); /* * Success. We only needed to be added to the mask. * Call driver->exit() because only the cpu parent of * the kobj needed to call init(). */ if (cpufreq_driver->exit) cpufreq_driver->exit(policy); return ret; } } #endif return ret; } /* symlink affected CPUs */ int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy) { Loading Loading @@ -787,6 +856,7 @@ int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy) int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy, struct sys_device *sys_dev) { struct cpufreq_policy new_policy; struct freq_attr **drv_attr; unsigned long flags; int ret = 0; Loading Loading @@ -827,6 +897,23 @@ int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy, spin_unlock_irqrestore(&cpufreq_driver_lock, flags); ret = cpufreq_add_dev_symlink(cpu, policy); if (ret) goto err_out_kobj_put; memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); /* assure that the starting sequence is run in __cpufreq_set_policy */ policy->governor = NULL; /* set default policy */ ret = __cpufreq_set_policy(policy, &new_policy); policy->user_policy.policy = policy->policy; policy->user_policy.governor = policy->governor; if (ret) { dprintk("setting policy failed\n"); if (cpufreq_driver->exit) cpufreq_driver->exit(policy); } return ret; err_out_kobj_put: Loading @@ -849,7 +936,6 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) { unsigned int cpu = sys_dev->id; int ret = 0; struct cpufreq_policy new_policy; struct cpufreq_policy *policy; unsigned long flags; unsigned int j; Loading Loading @@ -914,82 +1000,14 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_START, policy); #ifdef CONFIG_SMP #ifdef CONFIG_HOTPLUG_CPU if (per_cpu(cpufreq_cpu_governor, cpu)) { policy->governor = per_cpu(cpufreq_cpu_governor, cpu); dprintk("Restoring governor %s for cpu %d\n", policy->governor->name, cpu); } #endif for_each_cpu(j, policy->cpus) { struct cpufreq_policy *managed_policy; if (cpu == j) continue; /* Check for existing affected CPUs. * They may not be aware of it due to CPU Hotplug. * cpufreq_cpu_put is called when the device is removed * in __cpufreq_remove_dev() */ managed_policy = cpufreq_cpu_get(j); if (unlikely(managed_policy)) { /* Set proper policy_cpu */ unlock_policy_rwsem_write(cpu); per_cpu(policy_cpu, cpu) = managed_policy->cpu; if (lock_policy_rwsem_write(cpu) < 0) { /* Should not go through policy unlock path */ if (cpufreq_driver->exit) cpufreq_driver->exit(policy); ret = -EBUSY; cpufreq_cpu_put(managed_policy); goto err_free_cpumask; } spin_lock_irqsave(&cpufreq_driver_lock, flags); cpumask_copy(managed_policy->cpus, policy->cpus); per_cpu(cpufreq_cpu_data, cpu) = managed_policy; spin_unlock_irqrestore(&cpufreq_driver_lock, flags); dprintk("CPU already managed, adding link\n"); ret = sysfs_create_link(&sys_dev->kobj, &managed_policy->kobj, "cpufreq"); ret = cpufreq_add_dev_policy(cpu, policy, sys_dev); if (ret) cpufreq_cpu_put(managed_policy); /* * Success. We only needed to be added to the mask. * Call driver->exit() because only the cpu parent of * the kobj needed to call init(). */ goto out_driver_exit; /* call driver->exit() */ } } #endif memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); goto err_unlock_policy; ret = cpufreq_add_dev_interface(cpu, policy, sys_dev); if (ret) goto err_out_unregister; policy->governor = NULL; /* to assure that the starting sequence is * run in cpufreq_set_policy */ /* set default policy */ ret = __cpufreq_set_policy(policy, &new_policy); policy->user_policy.policy = policy->policy; policy->user_policy.governor = policy->governor; if (ret) { dprintk("setting policy failed\n"); goto err_out_unregister; } unlock_policy_rwsem_write(cpu); kobject_uevent(&policy->kobj, KOBJ_ADD); Loading @@ -1009,10 +1027,6 @@ err_out_unregister: kobject_put(&policy->kobj); wait_for_completion(&policy->kobj_unregister); out_driver_exit: if (cpufreq_driver->exit) cpufreq_driver->exit(policy); err_unlock_policy: unlock_policy_rwsem_write(cpu); err_free_cpumask: Loading Loading
drivers/cpufreq/cpufreq.c +90 −76 Original line number Diff line number Diff line Loading @@ -756,6 +756,75 @@ static struct kobj_type ktype_cpufreq = { .release = cpufreq_sysfs_release, }; int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy, struct sys_device *sys_dev) { int ret = 0; #ifdef CONFIG_SMP unsigned long flags; unsigned int j; #ifdef CONFIG_HOTPLUG_CPU if (per_cpu(cpufreq_cpu_governor, cpu)) { policy->governor = per_cpu(cpufreq_cpu_governor, cpu); dprintk("Restoring governor %s for cpu %d\n", policy->governor->name, cpu); } #endif for_each_cpu(j, policy->cpus) { struct cpufreq_policy *managed_policy; if (cpu == j) continue; /* Check for existing affected CPUs. * They may not be aware of it due to CPU Hotplug. * cpufreq_cpu_put is called when the device is removed * in __cpufreq_remove_dev() */ managed_policy = cpufreq_cpu_get(j); if (unlikely(managed_policy)) { /* Set proper policy_cpu */ unlock_policy_rwsem_write(cpu); per_cpu(policy_cpu, cpu) = managed_policy->cpu; if (lock_policy_rwsem_write(cpu) < 0) { /* Should not go through policy unlock path */ if (cpufreq_driver->exit) cpufreq_driver->exit(policy); cpufreq_cpu_put(managed_policy); return -EBUSY; } spin_lock_irqsave(&cpufreq_driver_lock, flags); cpumask_copy(managed_policy->cpus, policy->cpus); per_cpu(cpufreq_cpu_data, cpu) = managed_policy; spin_unlock_irqrestore(&cpufreq_driver_lock, flags); dprintk("CPU already managed, adding link\n"); ret = sysfs_create_link(&sys_dev->kobj, &managed_policy->kobj, "cpufreq"); if (ret) cpufreq_cpu_put(managed_policy); /* * Success. We only needed to be added to the mask. * Call driver->exit() because only the cpu parent of * the kobj needed to call init(). */ if (cpufreq_driver->exit) cpufreq_driver->exit(policy); return ret; } } #endif return ret; } /* symlink affected CPUs */ int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy) { Loading Loading @@ -787,6 +856,7 @@ int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy) int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy, struct sys_device *sys_dev) { struct cpufreq_policy new_policy; struct freq_attr **drv_attr; unsigned long flags; int ret = 0; Loading Loading @@ -827,6 +897,23 @@ int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy, spin_unlock_irqrestore(&cpufreq_driver_lock, flags); ret = cpufreq_add_dev_symlink(cpu, policy); if (ret) goto err_out_kobj_put; memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); /* assure that the starting sequence is run in __cpufreq_set_policy */ policy->governor = NULL; /* set default policy */ ret = __cpufreq_set_policy(policy, &new_policy); policy->user_policy.policy = policy->policy; policy->user_policy.governor = policy->governor; if (ret) { dprintk("setting policy failed\n"); if (cpufreq_driver->exit) cpufreq_driver->exit(policy); } return ret; err_out_kobj_put: Loading @@ -849,7 +936,6 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) { unsigned int cpu = sys_dev->id; int ret = 0; struct cpufreq_policy new_policy; struct cpufreq_policy *policy; unsigned long flags; unsigned int j; Loading Loading @@ -914,82 +1000,14 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_START, policy); #ifdef CONFIG_SMP #ifdef CONFIG_HOTPLUG_CPU if (per_cpu(cpufreq_cpu_governor, cpu)) { policy->governor = per_cpu(cpufreq_cpu_governor, cpu); dprintk("Restoring governor %s for cpu %d\n", policy->governor->name, cpu); } #endif for_each_cpu(j, policy->cpus) { struct cpufreq_policy *managed_policy; if (cpu == j) continue; /* Check for existing affected CPUs. * They may not be aware of it due to CPU Hotplug. * cpufreq_cpu_put is called when the device is removed * in __cpufreq_remove_dev() */ managed_policy = cpufreq_cpu_get(j); if (unlikely(managed_policy)) { /* Set proper policy_cpu */ unlock_policy_rwsem_write(cpu); per_cpu(policy_cpu, cpu) = managed_policy->cpu; if (lock_policy_rwsem_write(cpu) < 0) { /* Should not go through policy unlock path */ if (cpufreq_driver->exit) cpufreq_driver->exit(policy); ret = -EBUSY; cpufreq_cpu_put(managed_policy); goto err_free_cpumask; } spin_lock_irqsave(&cpufreq_driver_lock, flags); cpumask_copy(managed_policy->cpus, policy->cpus); per_cpu(cpufreq_cpu_data, cpu) = managed_policy; spin_unlock_irqrestore(&cpufreq_driver_lock, flags); dprintk("CPU already managed, adding link\n"); ret = sysfs_create_link(&sys_dev->kobj, &managed_policy->kobj, "cpufreq"); ret = cpufreq_add_dev_policy(cpu, policy, sys_dev); if (ret) cpufreq_cpu_put(managed_policy); /* * Success. We only needed to be added to the mask. * Call driver->exit() because only the cpu parent of * the kobj needed to call init(). */ goto out_driver_exit; /* call driver->exit() */ } } #endif memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); goto err_unlock_policy; ret = cpufreq_add_dev_interface(cpu, policy, sys_dev); if (ret) goto err_out_unregister; policy->governor = NULL; /* to assure that the starting sequence is * run in cpufreq_set_policy */ /* set default policy */ ret = __cpufreq_set_policy(policy, &new_policy); policy->user_policy.policy = policy->policy; policy->user_policy.governor = policy->governor; if (ret) { dprintk("setting policy failed\n"); goto err_out_unregister; } unlock_policy_rwsem_write(cpu); kobject_uevent(&policy->kobj, KOBJ_ADD); Loading @@ -1009,10 +1027,6 @@ err_out_unregister: kobject_put(&policy->kobj); wait_for_completion(&policy->kobj_unregister); out_driver_exit: if (cpufreq_driver->exit) cpufreq_driver->exit(policy); err_unlock_policy: unlock_policy_rwsem_write(cpu); err_free_cpumask: Loading