diff options
author | Ben Dooks <ben-linux@fluff.org> | 2007-05-28 18:19:16 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-05-30 13:15:23 +0100 |
commit | eca8c2424171b6b6b2dcb0faa92dfddd1e3297d9 (patch) | |
tree | 680afa1b68832a4a81f07d706e4249a0f4290afa /arch/arm | |
parent | 486cab2ba25b469f7a8822e84fd43960a472e3d9 (diff) |
[ARM] 4412/1: S3C2412: reset errata fix
The S3C2412 has an reset-errata where the clock
may cause a glitch switching back to EXTCLK. We
force a switch to EXTCLK before writing the
reset register to force use of the CLKCON sync
logic to properly switch.
Fix problem reported by Matthieu Castet.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-s3c2412/s3c2412.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c index c602aa39f9c..782b5814ced 100644 --- a/arch/arm/mach-s3c2412/s3c2412.c +++ b/arch/arm/mach-s3c2412/s3c2412.c @@ -16,6 +16,7 @@ #include <linux/list.h> #include <linux/timer.h> #include <linux/init.h> +#include <linux/delay.h> #include <linux/sysdev.h> #include <linux/serial_core.h> #include <linux/platform_device.h> @@ -29,6 +30,7 @@ #include <asm/io.h> #include <asm/irq.h> +#include <asm/arch/reset.h> #include <asm/arch/idle.h> #include <asm/arch/regs-clock.h> @@ -38,6 +40,7 @@ #include <asm/arch/regs-gpioj.h> #include <asm/arch/regs-dsc.h> #include <asm/arch/regs-spi.h> +#include <asm/arch/regs-s3c2412.h> #include <asm/plat-s3c24xx/s3c2412.h> #include <asm/plat-s3c24xx/cpu.h> @@ -106,6 +109,23 @@ static void s3c2412_idle(void) cpu_do_idle(); } +static void s3c2412_hard_reset(void) +{ + /* errata "Watch-dog/Software Reset Problem" specifies that + * this reset must be done with the SYSCLK sourced from + * EXTCLK instead of FOUT to avoid a glitch in the reset + * mechanism. + * + * See the watchdog section of the S3C2412 manual for more + * information on this fix. + */ + + __raw_writel(0x00, S3C2412_CLKSRC); + __raw_writel(S3C2412_SWRST_RESET, S3C2412_SWRST); + + mdelay(1); +} + /* s3c2412_map_io * * register the standard cpu IO areas, and any passed in from the @@ -122,6 +142,10 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size) s3c24xx_idle = s3c2412_idle; + /* set custom reset hook */ + + s3c24xx_reset_hook = s3c2412_hard_reset; + /* register our io-tables */ iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc)); |