summaryrefslogtreecommitdiff
path: root/arch/arm/plat-mxc/cpufreq.c
diff options
context:
space:
mode:
authorRanjani Vaidyanathan <ra5478@freescale.com>2011-09-02 12:04:48 -0500
committerJason Liu <r64343@freescale.com>2012-01-09 20:23:37 +0800
commite508a64a60e24dc42c53032c7e4c67c0406e07ee (patch)
tree5c16f8c94173e13d74e913059bf187d519c37c10 /arch/arm/plat-mxc/cpufreq.c
parentb587d0b6350bc418682a3c405154d194f0c9036d (diff)
ENGR00155981: MX6: Fix crash caused by cpufreq during suspend/resume
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>
Diffstat (limited to 'arch/arm/plat-mxc/cpufreq.c')
-rwxr-xr-xarch/arm/plat-mxc/cpufreq.c45
1 files changed, 24 insertions, 21 deletions
diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
index 88cfaa63f8ea..bb2a6c8c9900 100755
--- a/arch/arm/plat-mxc/cpufreq.c
+++ b/arch/arm/plat-mxc/cpufreq.c
@@ -207,28 +207,29 @@ static int __devinit mxc_cpufreq_init(struct cpufreq_policy *policy)
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;
@@ -265,9 +266,11 @@ static int mxc_cpufreq_exit(struct cpufreq_policy *policy)
{
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);
+ }
return 0;
}