aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2014-02-17 09:23:24 -0500
committerJason Cooper <jason@lakedaemon.net>2014-02-21 19:43:59 -0500
commitca4a6f87150b2cec4feab2610ef7a0d6d7fcd800 (patch)
tree3892e52b17d43f9b1ba803ee188647cbf39a75e4
parentd3ce7f2594ad57caf72250d948fde0e68ea5940e (diff)
ARM: mvebu: add workaround for data abort issue on Armada 375
Early versions of Armada 375 SoC have a bug where the BootROM leaves an external data abort pending. The kernel is hit by this data abort as soon as it enters userspace, because it unmasks the data aborts at this moment. We register a custom abort handler below to ignore the first data abort to work around this problem. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--arch/arm/mach-mvebu/board-v7.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c
index a6234bfc1d69..087668c7d46a 100644
--- a/arch/arm/mach-mvebu/board-v7.c
+++ b/arch/arm/mach-mvebu/board-v7.c
@@ -31,6 +31,27 @@
31#include "coherency.h" 31#include "coherency.h"
32#include "mvebu-soc-id.h" 32#include "mvebu-soc-id.h"
33 33
34/*
35 * Early versions of Armada 375 SoC have a bug where the BootROM
36 * leaves an external data abort pending. The kernel is hit by this
37 * data abort as soon as it enters userspace, because it unmasks the
38 * data aborts at this moment. We register a custom abort handler
39 * below to ignore the first data abort to work around this
40 * problem.
41 */
42static int armada_375_external_abort_wa(unsigned long addr, unsigned int fsr,
43 struct pt_regs *regs)
44{
45 static int ignore_first;
46
47 if (!ignore_first && fsr == 0x1406) {
48 ignore_first = 1;
49 return 0;
50 }
51
52 return 1;
53}
54
34static void __init mvebu_timer_and_clk_init(void) 55static void __init mvebu_timer_and_clk_init(void)
35{ 56{
36 of_clk_init(NULL); 57 of_clk_init(NULL);
@@ -40,6 +61,10 @@ static void __init mvebu_timer_and_clk_init(void)
40#ifdef CONFIG_CACHE_L2X0 61#ifdef CONFIG_CACHE_L2X0
41 l2x0_of_init(0, ~0UL); 62 l2x0_of_init(0, ~0UL);
42#endif 63#endif
64
65 if (of_machine_is_compatible("marvell,armada375"))
66 hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0,
67 "imprecise external abort");
43} 68}
44 69
45static void __init i2c_quirk(void) 70static void __init i2c_quirk(void)