diff options
-rw-r--r-- | arch/arm/mach-mvebu/board-v7.c | 25 |
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 @@ #include "coherency.h" #include "mvebu-soc-id.h" +/* + * 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. + */ +static int armada_375_external_abort_wa(unsigned long addr, unsigned int fsr, + struct pt_regs *regs) +{ + static int ignore_first; + + if (!ignore_first && fsr == 0x1406) { + ignore_first = 1; + return 0; + } + + return 1; +} + static void __init mvebu_timer_and_clk_init(void) { of_clk_init(NULL); @@ -40,6 +61,10 @@ static void __init mvebu_timer_and_clk_init(void) #ifdef CONFIG_CACHE_L2X0 l2x0_of_init(0, ~0UL); #endif + + if (of_machine_is_compatible("marvell,armada375")) + hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0, + "imprecise external abort"); } static void __init i2c_quirk(void) |