Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2fc3384d authored by Viresh Kumar's avatar Viresh Kumar Committed by Rafael J. Wysocki
Browse files

cpufreq: Initialize policy->kobj while allocating policy



policy->kobj is required to be initialized once in the lifetime of a
policy.  Currently we are initializing it from __cpufreq_add_dev() and
that doesn't look to be the best place for doing so as we have to do
this on special cases (like: !recover_policy).

We can initialize it from a more obvious place cpufreq_policy_alloc()
and that will make code look cleaner, specially the error handling part.

The error handling part of __cpufreq_add_dev() was doing almost the same
thing while recover_policy is true or false. Fix that as well by always
calling cpufreq_policy_put_kobj() with an additional parameter to skip
notification part of it.

Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 87549141
Loading
Loading
Loading
Loading
+21 −25
Original line number Diff line number Diff line
@@ -1134,9 +1134,10 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
	return policy;
}

static struct cpufreq_policy *cpufreq_policy_alloc(int cpu)
static struct cpufreq_policy *cpufreq_policy_alloc(struct device *dev)
{
	struct cpufreq_policy *policy;
	int ret;

	policy = kzalloc(sizeof(*policy), GFP_KERNEL);
	if (!policy)
@@ -1148,6 +1149,13 @@ static struct cpufreq_policy *cpufreq_policy_alloc(int cpu)
	if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
		goto err_free_cpumask;

	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_rcpumask;
	}

	INIT_LIST_HEAD(&policy->policy_list);
	init_rwsem(&policy->rwsem);
	spin_lock_init(&policy->transition_lock);
@@ -1155,13 +1163,15 @@ static struct cpufreq_policy *cpufreq_policy_alloc(int cpu)
	init_completion(&policy->kobj_unregister);
	INIT_WORK(&policy->update, handle_update);

	policy->cpu = cpu;
	policy->cpu = dev->id;

	/* Set this once on allocation */
	policy->kobj_cpu = cpu;
	policy->kobj_cpu = dev->id;

	return policy;

err_free_rcpumask:
	free_cpumask_var(policy->related_cpus);
err_free_cpumask:
	free_cpumask_var(policy->cpus);
err_free_policy:
@@ -1170,11 +1180,12 @@ static struct cpufreq_policy *cpufreq_policy_alloc(int cpu)
	return NULL;
}

static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy)
static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy, bool notify)
{
	struct kobject *kobj;
	struct completion *cmp;

	if (notify)
		blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
					     CPUFREQ_REMOVE_POLICY, policy);

@@ -1270,7 +1281,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
	policy = recover_policy ? cpufreq_policy_restore(cpu) : NULL;
	if (!policy) {
		recover_policy = false;
		policy = cpufreq_policy_alloc(cpu);
		policy = cpufreq_policy_alloc(dev);
		if (!policy)
			goto nomem_out;
	}
@@ -1310,15 +1321,6 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
		policy->user_policy.min = policy->min;
		policy->user_policy.max = policy->max;

		/* prepare interface data */
		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_init_policy_kobj;
		}

		write_lock_irqsave(&cpufreq_driver_lock, flags);
		for_each_cpu(j, policy->related_cpus)
			per_cpu(cpufreq_cpu_data, j) = policy;
@@ -1410,18 +1412,12 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)

err_out_unregister:
err_get_freq:
	if (!recover_policy) {
		kobject_put(&policy->kobj);
		wait_for_completion(&policy->kobj_unregister);
	}
err_init_policy_kobj:
	up_write(&policy->rwsem);

	if (cpufreq_driver->exit)
		cpufreq_driver->exit(policy);
err_set_policy_cpu:
	if (recover_policy)
		cpufreq_policy_put_kobj(policy);
	cpufreq_policy_put_kobj(policy, recover_policy);
	cpufreq_policy_free(policy);

nomem_out:
@@ -1517,7 +1513,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev,

	/* Free the policy kobjects only if the driver is getting removed. */
	if (sif)
		cpufreq_policy_put_kobj(policy);
		cpufreq_policy_put_kobj(policy, true);

	/*
	 * Perform the ->exit() even during light-weight tear-down,
@@ -1567,7 +1563,7 @@ static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
			return 0;
		}

		cpufreq_policy_put_kobj(policy);
		cpufreq_policy_put_kobj(policy, true);
		cpufreq_policy_free(policy);
		return 0;
	}