diff options
author | Eric Bénard <eric@eukrea.com> | 2010-10-05 11:20:21 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2010-10-19 18:44:58 +0200 |
commit | 4a66b5d980a244c403c3f6cb42c762ef5c112956 (patch) | |
tree | fda80b2fd8c4ae0c720f5122211434f407f37f59 | |
parent | ec4aac206b65d9764d601a7ee433e161878623b9 (diff) | |
download | lwn-4a66b5d980a244c403c3f6cb42c762ef5c112956.tar.gz lwn-4a66b5d980a244c403c3f6cb42c762ef5c112956.zip |
i.MX31 and i.MX35 : fix errate TLSbo65953 and ENGcm09472
Without this exiting WFI can result in cache corruption.
Code taken from Freescale's 2.6.27 BSP and tested on i.MX35
Signed-off-by: Eric Bénard <eric@eukrea.com>
-rw-r--r-- | arch/arm/plat-mxc/include/mach/system.h | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h index 4acd1143a9bd..95be51bfe9a9 100644 --- a/arch/arm/plat-mxc/include/mach/system.h +++ b/arch/arm/plat-mxc/include/mach/system.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,8 +28,34 @@ static inline void arch_idle(void) mxc91231_prepare_idle(); } #endif - - cpu_do_idle(); + /* fix i.MX31 errata TLSbo65953 and i.MX35 errata ENGcm09472 */ + if (cpu_is_mx31() || cpu_is_mx35()) { + unsigned long reg = 0; + __asm__ __volatile__( + /* disable I and D cache */ + "mrc p15, 0, %0, c1, c0, 0\n" + "bic %0, %0, #0x00001000\n" + "bic %0, %0, #0x00000004\n" + "mcr p15, 0, %0, c1, c0, 0\n" + /* invalidate I cache */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c5, 0\n" + /* clear and invalidate D cache */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c14, 0\n" + /* WFI */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c0, 4\n" + "nop\n" "nop\n" "nop\n" "nop\n" + "nop\n" "nop\n" "nop\n" + /* enable I and D cache */ + "mrc p15, 0, %0, c1, c0, 0\n" + "orr %0, %0, #0x00001000\n" + "orr %0, %0, #0x00000004\n" + "mcr p15, 0, %0, c1, c0, 0\n" + : "=r" (reg)); + } else + cpu_do_idle(); } void arch_reset(char mode, const char *cmd); |