bcm53xx: add support for the PCIe controller
[openwrt/svn-archive/archive.git] / target / linux / bcm53xx / patches-3.14 / 042-ARM-BCM5301X-workaround-suppress-fault.patch
1 From fdf4850cb5b2e5e549a18b8b41abb001bfb19e9c Mon Sep 17 00:00:00 2001
2 From: Hauke Mehrtens <hauke@hauke-m.de>
3 Date: Tue, 4 Feb 2014 00:01:46 +0100
4 Subject: [PATCH 3/3] ARM: BCM5301X: workaround suppress fault
5
6 Without this patch I am getting a unhandled fault exception like this
7 one after "Freeing unused kernel memory":
8
9 Freeing unused kernel memory: 1260K (c02c1000 - c03fc000)
10 Unhandled fault: imprecise external abort (0x1c06) at 0xb6f89005
11 Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000007
12
13 The address which is here 0xb6f89005 changes from boot to boot, with a
14 new build the changes are bigger. With kernel 3.10 I have also seen
15 this fault at different places in the boot process, but starting with
16 3.11 they are always occurring after the "Freeing unused kernel memory"
17 message. I never was able to completely boot to userspace without this
18 handler. The abort code is constant 0x1c06. This fault just happens
19 once in the boot process I have never seen it happing twice or more.
20
21 I also tried changing the CPSR.A bit to 0 in init_early, with this code
22 like Afzal suggested, but that did not change anything:
23 asm volatile("mrs r12, cpsr\n"
24 "bic r12, r12, #0x00000100\n"
25 "msr cpsr_c, r12" ::: "r12", "cc", "memory");
26
27 Disabling the L2 cache by building with CONFIG_CACHE_L2X0 unset did not
28 help.
29
30 This workaround was copied from the vendor code including most of the
31 comments. It says it they think this is caused by the CFE boot loader
32 used on this device. I do not have any access to any datasheet or
33 errata document to check this.
34
35 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
36 Acked-by: Arnd Bergmann <arnd@arndb.de>
37 Acked-by: Christian Daudt <bcm@fixthebug.org>
38 Signed-off-by: Matt Porter <mporter@linaro.org>
39 ---
40 arch/arm/mach-bcm/bcm_5301x.c | 33 +++++++++++++++++++++++++++++++++
41 1 file changed, 33 insertions(+)
42
43 --- a/arch/arm/mach-bcm/bcm_5301x.c
44 +++ b/arch/arm/mach-bcm/bcm_5301x.c
45 @@ -9,8 +9,40 @@
46 #include <asm/hardware/cache-l2x0.h>
47
48 #include <asm/mach/arch.h>
49 +#include <asm/siginfo.h>
50 +#include <asm/signal.h>
51
52
53 +static bool first_fault = true;
54 +
55 +static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr,
56 + struct pt_regs *regs)
57 +{
58 + if (fsr == 0x1c06 && first_fault) {
59 + first_fault = false;
60 +
61 + /*
62 + * These faults with code 0x1c06 happens for no good reason,
63 + * possibly left over from the CFE boot loader.
64 + */
65 + pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n",
66 + addr, fsr);
67 +
68 + /* Returning non-zero causes fault display and panic */
69 + return 0;
70 + }
71 +
72 + /* Others should cause a fault */
73 + return 1;
74 +}
75 +
76 +static void __init bcm5301x_init_early(void)
77 +{
78 + /* Install our hook */
79 + hook_fault_code(16 + 6, bcm5301x_abort_handler, SIGBUS, BUS_OBJERR,
80 + "imprecise external abort");
81 +}
82 +
83 static void __init bcm5301x_dt_init(void)
84 {
85 l2x0_of_init(0, ~0UL);
86 @@ -23,6 +55,7 @@ static const char __initconst *bcm5301x_
87 };
88
89 DT_MACHINE_START(BCM5301X, "BCM5301X")
90 + .init_early = bcm5301x_init_early,
91 .init_machine = bcm5301x_dt_init,
92 .dt_compat = bcm5301x_dt_compat,
93 MACHINE_END