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

Commit 36223a22 authored by Junjie Wu's avatar Junjie Wu
Browse files

qcom-cpufreq: Fix frequency table registration



CPUfreq device is the provider of CPU frequency table, and
it should always keep track of freq tables for every CPU itself.
cpufreq_frequency_get_table() is an API for frequency table user.
qcom-cpufreq should not use this API to obtain CPU freq table in
the init function. Otherwise, the following sequence will lead to init
failure.

Assume CPU 0 and 1 are under control of same policy and online. Say
policy->cpu is CPU 0.

1) Hot unplug CPU0
   update_policy_cpu() will transfer ownership of policy to CPU1
   cpufreq_frequency_table_update_policy_cpu() is called during
   the process to set CPU1's freq table to be the same as CPU0's freq
   table. CPU0's freq table is now NULL.
2) Hot unplug CPU1
   All CPUs in policy are now offline.
3) Hot plug in CPU0
   cpufreq_driver->init() is called for initialization. If this init
   function calls cpufreq_frequency_get_table() on CPU0, the result
   will be NULL.

Current qcom-cpufreq checks return value of cpufreq_frequency_get_table()
and returns an error in init.

Remove the usage of cpufreq_frequency_get_table() and fill in frequency
table for policy->cpu in msm_cpufreq_init().

Change-Id: I2d41af776938c31b4444c9f280a341dd1bed1548
Signed-off-by: default avatarJunjie Wu <junjiew@codeaurora.org>
parent 93e2dd46
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -180,13 +180,10 @@ static int msm_cpufreq_init(struct cpufreq_policy *policy)
	int cur_freq;
	int index;
	int ret = 0;
	struct cpufreq_frequency_table *table;
	struct cpufreq_frequency_table *table = freq_table;
	struct cpufreq_work_struct *cpu_work = NULL;
	int cpu;

	table = cpufreq_frequency_get_table(policy->cpu);
	if (table == NULL)
		return -ENODEV;
	/*
	 * In some SoC, some cores are clocked by same source, and their
	 * frequencies can not be changed independently. Find all other
@@ -233,6 +230,7 @@ static int msm_cpufreq_init(struct cpufreq_policy *policy)
	pr_debug("cpufreq: cpu%d init at %d switching to %d\n",
			policy->cpu, cur_freq, table[index].frequency);
	policy->cur = table[index].frequency;
	cpufreq_frequency_table_get_attr(table, policy->cpu);

	return 0;
}
@@ -442,10 +440,6 @@ static int __init msm_cpufreq_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	for_each_possible_cpu(cpu) {
		cpufreq_frequency_table_get_attr(freq_table, cpu);
	}

	/* Use per-policy governor tunable for some targets */
	if (of_property_read_bool(dev->of_node, "qcom,governor-per-policy"))
		msm_cpufreq_driver.flags |= CPUFREQ_HAVE_GOVERNOR_PER_POLICY;