Hi Chris, On Thu, Feb 9, 2017 at 8:12 PM, Chris Brandt <chris.brandt@xxxxxxxxxxx> wrote: > 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> Thanks for your patch! > --- > 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); This base address should come from a watchdog device node in DT... > + /* 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 Perhaps unsurprisingly, I'd recommend writing a watchdog driver instead. drivers/watchdog/renesas_wdt.c (currently supporting R-Car Gen3 only) may serve as an example. >From an earlier discussion during development of that driver: | The RWDT exists on various Renesas SoCs. | From digging into the datasheets, I had discovered two variants a while go: | 1. 32-bit registers | a. R-Car Gen2: using RST for restarting | b. R-Mobile APE6: using SYSC for restarting | 2. 8-bit registers (SH-Mobile AP4/AG5, R-Mobile A1) | | The differences are small: the variant with 8-bit registers has a smaller | maximum timeout, and no magic value to be stored in the upper bits. | | Wolfram discovered the third variant in RZ/A1H, which differs in | register layout. IIRC, apart from the different register layout, actual operation on RZ/A1H is similar to other Renesas SoCs. Depending on the differences, you may decide to write a new driver instead, though. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds