Commit 7f0fa40f authored by Viresh Kumar's avatar Viresh Kumar Committed by Rafael J. Wysocki
Browse files

cpufreq: Properly handle errors from cpufreq_init_policy()



cpufreq_init_policy() can fail, and we don't do anything except a call
to ->exit() on that. The policy should be freed if this happens.

Do it properly.

Reported-and-tested-by: default avatar"Jon Medhurst (Tixy)" <tixy@linaro.org>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 8101f997
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -1060,11 +1060,10 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
	return cpufreq_add_dev_symlink(policy);
}

static void cpufreq_init_policy(struct cpufreq_policy *policy)
static int cpufreq_init_policy(struct cpufreq_policy *policy)
{
	struct cpufreq_governor *gov = NULL;
	struct cpufreq_policy new_policy;
	int ret = 0;

	memcpy(&new_policy, policy, sizeof(*policy));

@@ -1083,12 +1082,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy)
		cpufreq_parse_governor(gov->name, &new_policy.policy, NULL);

	/* set default policy */
	ret = cpufreq_set_policy(policy, &new_policy);
	if (ret) {
		pr_debug("setting policy failed\n");
		if (cpufreq_driver->exit)
			cpufreq_driver->exit(policy);
	}
	return cpufreq_set_policy(policy, &new_policy);
}

static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
@@ -1386,7 +1380,12 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
		write_unlock_irqrestore(&cpufreq_driver_lock, flags);
	}

	cpufreq_init_policy(policy);
	ret = cpufreq_init_policy(policy);
	if (ret) {
		pr_err("%s: Failed to initialize policy for cpu: %d (%d)\n",
		       __func__, cpu, ret);
		goto out_remove_policy_notify;
	}

	if (!recover_policy) {
		policy->user_policy.policy = policy->policy;
@@ -1406,6 +1405,9 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)

	return 0;

out_remove_policy_notify:
	/* cpufreq_policy_free() will notify based on this */
	recover_policy = true;
out_exit_policy:
	up_write(&policy->rwsem);