aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r--drivers/cpufreq/cpufreq.c120
1 files changed, 25 insertions, 95 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 6633b3fa996e..7c48e7316d91 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -238,13 +238,13 @@ int cpufreq_generic_init(struct cpufreq_policy *policy,
}
EXPORT_SYMBOL_GPL(cpufreq_generic_init);
-/* Only for cpufreq core internal use */
-static struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu)
+struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu)
{
struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
return policy && cpumask_test_cpu(cpu, policy->cpus) ? policy : NULL;
}
+EXPORT_SYMBOL_GPL(cpufreq_cpu_get_raw);
unsigned int cpufreq_generic_get(unsigned int cpu)
{
@@ -843,18 +843,11 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
down_write(&policy->rwsem);
- /* Updating inactive policies is invalid, so avoid doing that. */
- if (unlikely(policy_is_inactive(policy))) {
- ret = -EBUSY;
- goto unlock_policy_rwsem;
- }
-
if (fattr->store)
ret = fattr->store(policy, buf, count);
else
ret = -EIO;
-unlock_policy_rwsem:
up_write(&policy->rwsem);
unlock:
put_online_cpus();
@@ -880,49 +873,6 @@ static struct kobj_type ktype_cpufreq = {
.release = cpufreq_sysfs_release,
};
-struct kobject *cpufreq_global_kobject;
-EXPORT_SYMBOL(cpufreq_global_kobject);
-
-static int cpufreq_global_kobject_usage;
-
-int cpufreq_get_global_kobject(void)
-{
- if (!cpufreq_global_kobject_usage++)
- return kobject_add(cpufreq_global_kobject,
- &cpu_subsys.dev_root->kobj, "%s", "cpufreq");
-
- return 0;
-}
-EXPORT_SYMBOL(cpufreq_get_global_kobject);
-
-void cpufreq_put_global_kobject(void)
-{
- if (!--cpufreq_global_kobject_usage)
- kobject_del(cpufreq_global_kobject);
-}
-EXPORT_SYMBOL(cpufreq_put_global_kobject);
-
-int cpufreq_sysfs_create_file(const struct attribute *attr)
-{
- int ret = cpufreq_get_global_kobject();
-
- if (!ret) {
- ret = sysfs_create_file(cpufreq_global_kobject, attr);
- if (ret)
- cpufreq_put_global_kobject();
- }
-
- return ret;
-}
-EXPORT_SYMBOL(cpufreq_sysfs_create_file);
-
-void cpufreq_sysfs_remove_file(const struct attribute *attr)
-{
- sysfs_remove_file(cpufreq_global_kobject, attr);
- cpufreq_put_global_kobject();
-}
-EXPORT_SYMBOL(cpufreq_sysfs_remove_file);
-
static int add_cpu_dev_symlink(struct cpufreq_policy *policy, int cpu)
{
struct device *cpu_dev;
@@ -960,9 +910,6 @@ static int cpufreq_add_dev_symlink(struct cpufreq_policy *policy)
/* Some related CPUs might not be present (physically hotplugged) */
for_each_cpu(j, policy->real_cpus) {
- if (j == policy->kobj_cpu)
- continue;
-
ret = add_cpu_dev_symlink(policy, j);
if (ret)
break;
@@ -976,12 +923,8 @@ static void cpufreq_remove_dev_symlink(struct cpufreq_policy *policy)
unsigned int j;
/* Some related CPUs might not be present (physically hotplugged) */
- for_each_cpu(j, policy->real_cpus) {
- if (j == policy->kobj_cpu)
- continue;
-
+ for_each_cpu(j, policy->real_cpus)
remove_cpu_dev_symlink(policy, j);
- }
}
static int cpufreq_add_dev_interface(struct cpufreq_policy *policy)
@@ -1079,7 +1022,6 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
{
struct device *dev = get_cpu_device(cpu);
struct cpufreq_policy *policy;
- int ret;
if (WARN_ON(!dev))
return NULL;
@@ -1097,13 +1039,7 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
if (!zalloc_cpumask_var(&policy->real_cpus, GFP_KERNEL))
goto err_free_rcpumask;
- ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &dev->kobj,
- "cpufreq");
- if (ret) {
- pr_err("%s: failed to init policy->kobj: %d\n", __func__, ret);
- goto err_free_real_cpus;
- }
-
+ kobject_init(&policy->kobj, &ktype_cpufreq);
INIT_LIST_HEAD(&policy->policy_list);
init_rwsem(&policy->rwsem);
spin_lock_init(&policy->transition_lock);
@@ -1112,14 +1048,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
INIT_WORK(&policy->update, handle_update);
policy->cpu = cpu;
-
- /* Set this once on allocation */
- policy->kobj_cpu = cpu;
-
return policy;
-err_free_real_cpus:
- free_cpumask_var(policy->real_cpus);
err_free_rcpumask:
free_cpumask_var(policy->related_cpus);
err_free_cpumask:
@@ -1221,9 +1151,19 @@ static int cpufreq_online(unsigned int cpu)
if (new_policy) {
/* related_cpus should at least include policy->cpus. */
- cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
+ cpumask_copy(policy->related_cpus, policy->cpus);
/* Remember CPUs present at the policy creation time. */
cpumask_and(policy->real_cpus, policy->cpus, cpu_present_mask);
+
+ /* Name and add the kobject */
+ ret = kobject_add(&policy->kobj, cpufreq_global_kobject,
+ "policy%u",
+ cpumask_first(policy->related_cpus));
+ if (ret) {
+ pr_err("%s: failed to add policy->kobj: %d\n", __func__,
+ ret);
+ goto out_exit_policy;
+ }
}
/*
@@ -1436,8 +1376,10 @@ static void cpufreq_offline_finish(unsigned int cpu)
* since this is a core component, and is essential for the
* subsequent light-weight ->init() to succeed.
*/
- if (cpufreq_driver->exit)
+ if (cpufreq_driver->exit) {
cpufreq_driver->exit(policy);
+ policy->freq_table = NULL;
+ }
}
/**
@@ -1465,22 +1407,7 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
return;
}
- if (cpu != policy->kobj_cpu) {
- remove_cpu_dev_symlink(policy, cpu);
- } else {
- /*
- * The CPU owning the policy object is going away. Move it to
- * another suitable CPU.
- */
- unsigned int new_cpu = cpumask_first(policy->real_cpus);
- struct device *new_dev = get_cpu_device(new_cpu);
-
- dev_dbg(dev, "%s: Moving policy object to CPU%u\n", __func__, new_cpu);
-
- sysfs_remove_link(&new_dev->kobj, "cpufreq");
- policy->kobj_cpu = new_cpu;
- WARN_ON(kobject_move(&policy->kobj, &new_dev->kobj));
- }
+ remove_cpu_dev_symlink(policy, cpu);
}
static void handle_update(struct work_struct *work)
@@ -2423,7 +2350,7 @@ static int create_boost_sysfs_file(void)
if (!cpufreq_driver->set_boost)
cpufreq_driver->set_boost = cpufreq_boost_set_sw;
- ret = cpufreq_sysfs_create_file(&boost.attr);
+ ret = sysfs_create_file(cpufreq_global_kobject, &boost.attr);
if (ret)
pr_err("%s: cannot register global BOOST sysfs file\n",
__func__);
@@ -2434,7 +2361,7 @@ static int create_boost_sysfs_file(void)
static void remove_boost_sysfs_file(void)
{
if (cpufreq_boost_supported())
- cpufreq_sysfs_remove_file(&boost.attr);
+ sysfs_remove_file(cpufreq_global_kobject, &boost.attr);
}
int cpufreq_enable_boost_support(void)
@@ -2582,12 +2509,15 @@ static struct syscore_ops cpufreq_syscore_ops = {
.shutdown = cpufreq_suspend,
};
+struct kobject *cpufreq_global_kobject;
+EXPORT_SYMBOL(cpufreq_global_kobject);
+
static int __init cpufreq_core_init(void)
{
if (cpufreq_disabled())
return -ENODEV;
- cpufreq_global_kobject = kobject_create();
+ cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
BUG_ON(!cpufreq_global_kobject);
register_syscore_ops(&cpufreq_syscore_ops);