Random crashes occur in CPUFREQ code when resuming from suspend.
The root cause is due to freeing and allocating of common data structure
(frequency table) shared among all the CPUs.
Fix the code by ensuring that the common data structure is only
created and deleted once.
Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
cpu_freq_khz_min = cpu_op_tbl[0].cpu_rate / 1000;
cpu_freq_khz_max = cpu_op_tbl[0].cpu_rate / 1000;
cpu_freq_khz_min = cpu_op_tbl[0].cpu_rate / 1000;
cpu_freq_khz_max = cpu_op_tbl[0].cpu_rate / 1000;
- imx_freq_table = kmalloc(
- sizeof(struct cpufreq_frequency_table) * (cpu_op_nr + 1),
- GFP_KERNEL);
- if (!imx_freq_table) {
- ret = -ENOMEM;
- goto err1;
- }
-
- for (i = 0; i < cpu_op_nr; i++) {
- imx_freq_table[i].index = i;
- imx_freq_table[i].frequency = cpu_op_tbl[i].cpu_rate / 1000;
+ if (imx_freq_table == NULL) {
+ imx_freq_table = kmalloc(
+ sizeof(struct cpufreq_frequency_table) * (cpu_op_nr + 1),
+ GFP_KERNEL);
+ if (!imx_freq_table) {
+ ret = -ENOMEM;
+ goto err1;
+ }
- if ((cpu_op_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min)
- cpu_freq_khz_min = cpu_op_tbl[i].cpu_rate / 1000;
+ for (i = 0; i < cpu_op_nr; i++) {
+ imx_freq_table[i].index = i;
+ imx_freq_table[i].frequency = cpu_op_tbl[i].cpu_rate / 1000;
- if ((cpu_op_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max)
- cpu_freq_khz_max = cpu_op_tbl[i].cpu_rate / 1000;
- }
+ if ((cpu_op_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min)
+ cpu_freq_khz_min = cpu_op_tbl[i].cpu_rate / 1000;
- imx_freq_table[i].index = i;
- imx_freq_table[i].frequency = CPUFREQ_TABLE_END;
+ if ((cpu_op_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max)
+ cpu_freq_khz_max = cpu_op_tbl[i].cpu_rate / 1000;
+ }
+ imx_freq_table[i].index = i;
+ imx_freq_table[i].frequency = CPUFREQ_TABLE_END;
+ }
policy->cur = clk_get_rate(cpu_clk) / 1000;
policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min;
policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max;
policy->cur = clk_get_rate(cpu_clk) / 1000;
policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min;
policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max;
{
cpufreq_frequency_table_put_attr(policy->cpu);
{
cpufreq_frequency_table_put_attr(policy->cpu);
- set_cpu_freq(cpu_freq_khz_max * 1000);
- clk_put(cpu_clk);
- kfree(imx_freq_table);
+ if (policy->cpu == 0) {
+ set_cpu_freq(cpu_freq_khz_max * 1000);
+ clk_put(cpu_clk);
+ kfree(imx_freq_table);
+ }