rk: cpufreq_stats.c: fix boot time crash
author黄涛 <huangtao@rock-chips.com>
Mon, 16 Jul 2012 06:25:38 +0000 (14:25 +0800)
committer黄涛 <huangtao@rock-chips.com>
Mon, 16 Jul 2012 06:25:38 +0000 (14:25 +0800)
fix this bug:
[    2.300817] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[    2.308902] pgd = c0404000
[    2.311615] [00000000] *pgd=00000000
[    2.315198] Internal error: Oops: 5 [#1] PREEMPT SMP
[    2.320157] CPU: 1    Not tainted  (3.0.8+ #70)
[    2.324689] PC is at cpufreq_stat_notifier_trans+0x40/0xa8
[    2.330169] LR is at notifier_call_chain+0x2c/0x70
[    2.334954] pc : [<c06ce1d4>]    lr : [<c0481440>]    psr: 80000013
[    2.334959] sp : eee47e50  ip : c0a13104  fp : 30a32c00
[    2.346424] r10: eee47ec8  r9 : 00118c30  r8 : 00000000
[    2.351641] r7 : fffffffc  r6 : 00000000  r5 : ed8c1d80  r4 : 00000000
[    2.358158] r3 : 00000009  r2 : 000f6180  r1 : 00000000  r0 : 00000000
[    2.364678] Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
[    2.371976] Control: 10c53c7d  Table: 6040404a  DAC: 00000015
[    2.377712]
[    2.924838] [<c06ce1d4>] (cpufreq_stat_notifier_trans+0x40/0xa8) from [<c0481440>] (notifier_call_chain+0x2c/0x70)
[    2.935178] [<c0481440>] (notifier_call_chain+0x2c/0x70) from [<c04815a0>] (__srcu_notifier_call_chain+0x40/0x58)
[    2.945430] [<c04815a0>] (__srcu_notifier_call_chain+0x40/0x58) from [<c04815cc>] (srcu_notifier_call_chain+0x14/0x18)
[    2.956115] [<c04815cc>] (srcu_notifier_call_chain+0x14/0x18) from [<c06cccd8>] (cpufreq_notify_transition+0xb4/0xe8)
[    2.966721] [<c06cccd8>] (cpufreq_notify_transition+0xb4/0xe8) from [<c044b584>] (cpufreq_scale_rate_for_dvfs+0x10c/0x164)
[    2.977755] [<c044b584>] (cpufreq_scale_rate_for_dvfs+0x10c/0x164) from [<c044cb94>] (dvfs_target_cpu+0x378/0x67c)
[    2.988093] [<c044cb94>] (dvfs_target_cpu+0x378/0x67c) from [<c044c1dc>] (dvfs_set_rate+0x48/0x68)
[    2.997044] [<c044c1dc>] (dvfs_set_rate+0x48/0x68) from [<c044b1f0>] (rk30_target+0x1a8/0x200)
[    3.005648] [<c044b1f0>] (rk30_target+0x1a8/0x200) from [<c06cbff0>] (__cpufreq_driver_target+0x4c/0x60)
[    3.015121] [<c06cbff0>] (__cpufreq_driver_target+0x4c/0x60) from [<c06d05ec>] (cpufreq_interactive_up_task+0x128/0x184)
[    3.025981] [<c06d05ec>] (cpufreq_interactive_up_task+0x128/0x184) from [<c047c3d0>] (kthread+0x80/0x88)
[    3.035453] [<c047c3d0>] (kthread+0x80/0x88) from [<c04375f8>] (kernel_thread_exit+0x0/0x8)
[    3.043796] Code: e5956018 e5953010 ea000004 e5951020 (e7911104)

drivers/cpufreq/cpufreq_stats.c

index c315ec9d568650b25a10963646f14ca39cfacb1c..5ab2cc9c6c6ba3060b757b9983df2edb6df81149 100644 (file)
@@ -159,6 +159,10 @@ static struct attribute_group stats_attr_group = {
 static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
 {
        int index;
+#ifdef CONFIG_PLAT_RK
+       if (!stat->freq_table)
+               return -1;
+#endif
        for (index = 0; index < stat->max_state; index++)
                if (stat->freq_table[index] == freq)
                        return index;
@@ -215,7 +219,9 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
                goto error_out;
 
        stat->cpu = cpu;
+#ifndef CONFIG_PLAT_RK
        per_cpu(cpufreq_stats_table, cpu) = stat;
+#endif
 
        for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
                unsigned int freq = table[i].frequency;
@@ -253,6 +259,9 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
        stat->last_time = get_jiffies_64();
        stat->last_index = freq_table_get_index(stat, policy->cur);
        spin_unlock(&cpufreq_stats_lock);
+#ifdef CONFIG_PLAT_RK
+       per_cpu(cpufreq_stats_table, cpu) = stat;
+#endif
        cpufreq_cpu_put(data);
        return 0;
 error_out: