Add a simple restart handler which enables the watchdog timer with the device reset option enabled. This is the only way SW can cause a reset on this SoC. If someone has a board that needs more specific operations to be done first, they can override this function in another file. Signed-off-by: Chris Brandt <chris.brandt@xxxxxxxxxxx> --- arch/arm/mach-shmobile/setup-r7s72100.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c index d46639f..cc6237e 100644 --- a/arch/arm/mach-shmobile/setup-r7s72100.c +++ b/arch/arm/mach-shmobile/setup-r7s72100.c @@ -15,11 +15,40 @@ */ #include <linux/kernel.h> +#include <linux/io.h> #include <asm/mach/arch.h> #include "common.h" +/* + * This function is declared weak so if you need to do some board specific stuff + * before the reset occurs, you can override this function. + * + * CAUTION: A reboot command doesn't 'sync' before this function + * is called. See function reboot() in kernel/reboot.c + */ +extern void __attribute__ ((weak)) r7s72100_restart(enum reboot_mode mode, + const char *cmd) +{ +#define WTCSR 0 +#define WTCNT 2 +#define WRCSR 4 + void *base = ioremap(0xFCFE0000, 0x10); + + /* Dummy read (must read WRCSR:WOVF at least once before clearing) */ + readw(base + WRCSR); + + writew(0xA500, base + WRCSR); /* Clear WOVF */ + writew(0x5A5F, base + WRCSR); /* Reset Enable */ + writew(0x5A00, base + WTCNT); /* Counter to 00 */ + writew(0xA578, base + WTCSR); /* Start timer */ + + /* Wait for WDT overflow */ + while (1) + ; +} + static const char *const r7s72100_boards_compat_dt[] __initconst = { "renesas,r7s72100", NULL, @@ -29,4 +58,5 @@ DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)") .init_early = shmobile_init_delay, .init_late = shmobile_init_late, .dt_compat = r7s72100_boards_compat_dt, + .restart = r7s72100_restart, MACHINE_END -- 2.10.1