Dear All, while trying to add watchdog support to RZ/G1M and RZ/G1E I discovered that it couldn't work out of the box. R-Car Gen2 and RZ/G1 are very similar from a design perspective, and therefore the same problem is observable on R-Car Gen2 too. To deal with SMP on R-Car Gen2 and RZ/G1, we install a reset vector to ICRAM1 and we program the [S]BAR registers so that when we turn ON the non-boot CPUs they are redirected to the reset vector installed by Linux in ICRAM1, and eventually they continue the execution to RAM, where the SMP bring-up code will take care of the rest. The content of the [S]BAR registers survives a watchdog triggered reset, and as such after the watchdog fires the boot core will try and execute the SMP bring-up code instead of jumping to the bootrom code. This series is a proposal for a fix to the aforementioned problem. The main strategy for the solution is to let the reset vector decide if it needs to jump to shmobile_boot_fn or to the bootrom code. In a watchdog triggered reset scenario, since the [S]BAR registers keep their values, the boot CPU will jump into the newly designed reset vector, the assembly routine will eventually test WOVF (a bit in register RWTCSRA that indicates if the watchdog counter has overflown, the value of this bit gets retained in this scenario), and jump to the bootrom code which will in turn load up the bootloader, etc. When bringing up SMP or using CPU hotplug, the reset vector will jump to shmobile_boot_fn instead. I think it's worth giving an overview of the implementation here to make it easier for the reader to understand the full picture. Patch "ARM: shmobile: Add watchdog support" modifies the reset vector, and since the size in bytes of the reset vector changes we need to update all of the .dtsi accordingly with patches "Adjust SMP routine size" for the various SoC. In order for the watchdog IP to actually trigger a reset we need to clear bit RWDT_RSTMSK first, this leads to patches: * "soc: renesas: rcar-rst: Add generic compatible strings", * "soc: renesas: rcar-rst: Enable watchdog as reset trigger for Gen2", * "soc: renesas: rcar-rst: Document generic compatible strings", and * "Use fallback rst compatible string" for the various SoC. This RFC provides a driver specifically designed for R-Car Gen2 and RZ/G1, its implementation may be merged with the R-Car Gen3 one instead of being delivered by a new driver. The patches taking care of the driver are: * "ARM: shmobile: rcar-gen2: Export shmobile_set_wdt_clock_status function" * "watchdog: renesas_wdt_gen2: Add Gen2 specific driver" Patch "watchdog: renesas_wdt: Add restart support" is simply an ehancement to the Gen3 driver. The "Add rwdt clock" patches add the definitions required by the rwdt clock, please note that we are declaring the rwdt clocks as critical, and that's because having the rwdt always ON guarantees that it is (almost) always safe to read the WOVF bit and also purges the implementation from race conditions. The remaining patches define the rwdt DT node for the platforms we have tested, and finally add support watchdof to the iwg20m and iwg22m SoM. Speaking of testing, we tested this series on top of the following boards: * iwg20d, * iwg22d, * Lager (only running on the CA15s), * Koelsh, and * Alt This work was rebased on top of tag renesas-devel-20180122-v4.15-rc9 from the below repository: git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git What do you guys think about this? Any volunteer for testing this work on other platforms using the same reset vector? Comments welcome! Best Regards, Fabrizio Castro (37): ARM: shmobile: Add watchdog support ARM: dts: r8a7743: Adjust SMP routine size ARM: dts: r8a7745: Adjust SMP routine size ARM: dts: r8a7790: Adjust SMP routine size ARM: dts: r8a7791: Adjust SMP routine size ARM: dts: r8a7792: Adjust SMP routine size ARM: dts: r8a7793: Adjust SMP routine size ARM: dts: r8a7794: Adjust SMP routine size soc: renesas: rcar-rst: Add generic compatible strings soc: renesas: rcar-rst: Enable watchdog as reset trigger for Gen2 soc: renesas: rcar-rst: Document generic compatible strings ARM: dts: r8a7743: Use fallback rst compatible string ARM: dts: r8a7745: Use fallback rst compatible string ARM: dts: r8a7790: Use fallback rst compatible string ARM: dts: r8a7791: Use fallback rst compatible string ARM: dts: r8a7794: Use fallback rst compatible string arm64: dts: renesas: r8a7795: Use fallback rst compatible string arm64: dts: renesas: r8a7796: Use fallback rst compatible string arm64: dts: renesas: r8a77970: Use fallback rst compatible string arm64: dts: renesas: r8a77995: Use fallback rst compatible string dt-bindings: watchdog: renesas-wdt: Add R-Car Gen2 support watchdog: renesas_wdt: Add restart support ARM: shmobile: rcar-gen2: Export shmobile_set_wdt_clock_status function watchdog: renesas_wdt_gen2: Add Gen2 specific driver ARM: shmobile: defconfig: Enable RENESAS_WDT_GEN2 clk: renesas: r8a7743: Add rwdt clock clk: renesas: r8a7745: Add rwdt clock clk: renesas: r8a7790: Add rwdt clock clk: renesas: r8a7791/r8a7793: Add rwdt clock clk: renesas: r8a7794: Add rwdt clock ARM: dts: r8a7743: Add watchdog support to SoC dtsi ARM: dts: r8a7745: Add watchdog support to SoC dtsi ARM: dts: r8a7790: Add watchdog support to SoC dtsi ARM: dts: r8a7791: Add watchdog support to SoC dtsi ARM: dts: r8a7794: Add watchdog support to SoC dtsi ARM: dts: iwg20m: Add watchdog support to SoM dtsi ARM: dts: iwg22m: Add watchdog support to SoM dtsi .../devicetree/bindings/reset/renesas,rst.txt | 11 +- .../devicetree/bindings/watchdog/renesas-wdt.txt | 13 +- arch/arm/boot/dts/r8a7743-iwg20m.dtsi | 5 + arch/arm/boot/dts/r8a7743.dtsi | 15 +- arch/arm/boot/dts/r8a7745-iwg22m.dtsi | 5 + arch/arm/boot/dts/r8a7745.dtsi | 15 +- arch/arm/boot/dts/r8a7790.dtsi | 15 +- arch/arm/boot/dts/r8a7791.dtsi | 15 +- arch/arm/boot/dts/r8a7792.dtsi | 2 +- arch/arm/boot/dts/r8a7793.dtsi | 2 +- arch/arm/boot/dts/r8a7794.dtsi | 15 +- arch/arm/configs/shmobile_defconfig | 1 + arch/arm/mach-shmobile/common.h | 1 + arch/arm/mach-shmobile/headsmp.S | 53 ++++ arch/arm/mach-shmobile/pm-rcar-gen2.c | 16 +- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 3 +- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 3 +- arch/arm64/boot/dts/renesas/r8a77970.dtsi | 3 +- arch/arm64/boot/dts/renesas/r8a77995.dtsi | 3 +- drivers/clk/renesas/r8a7743-cpg-mssr.c | 2 + drivers/clk/renesas/r8a7745-cpg-mssr.c | 2 + drivers/clk/renesas/r8a7790-cpg-mssr.c | 2 + drivers/clk/renesas/r8a7791-cpg-mssr.c | 2 + drivers/clk/renesas/r8a7794-cpg-mssr.c | 2 + drivers/soc/renesas/rcar-rst.c | 41 +++- drivers/watchdog/Kconfig | 15 +- drivers/watchdog/Makefile | 1 + drivers/watchdog/renesas_wdt.c | 19 ++ drivers/watchdog/renesas_wdt_gen2.c | 270 +++++++++++++++++++++ drivers/watchdog/renesas_wdt_gen2.h | 22 ++ 30 files changed, 541 insertions(+), 33 deletions(-) create mode 100644 drivers/watchdog/renesas_wdt_gen2.c create mode 100644 drivers/watchdog/renesas_wdt_gen2.h -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On R-Car Gen2 and RZ/G1 platforms, we use the SBAR registers to make non boot CPUs run a routine designed to bring up SMP and deal with hot plug. The value contained in the SBAR registers is not initialized by a WDT triggered reset, which means that after a WDT triggered reset we jump to the SMP bring up routine, preventing the system from executing the bootrom code. The purpose of this patch is to jump to the bootrom code in case of a WDT triggered reset, and keep the SMP functionality untouched. In order to tell if the code had been called due to the WDT overflowing we need to inspect flag WOVF from register RWTCSRA, however for this to work smoothly we need to make sure that RWDT clock is ON. Since it's not wise to interfere with the clock configuration from within this routine, a flag has been put in place (shmobile_wdt_clock_status) so that the watchdog driver can tell shmobile_boot_vector when the clock is ON, and therefore there is no need for shmobile_boot_vector to mess up with the clock registers. Bit WOVF survives a watchdog triggered reset, and it is usually cleared by the bootloader. Checking the MMU enable bit from register SCTLR allows us to make the code a little bit more robust (just in case the bit wasn't cleared up), as right after a reset the MMU is disabled, and when Linux is running the MMU is enabled. Also, accessing RWTCSRA physical address is safe when the MMU is down. SMP bringup, CPU hot plug, and suspend to RAM work as normal. Since shmobile_boot_vector has become bigger, "reg" property of nodes compatible with "renesas,smp-sram" now need to be set to "<0 0x64>". Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/mach-shmobile/headsmp.S | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S index 32e0bf6..835bddc 100644 --- a/arch/arm/mach-shmobile/headsmp.S +++ b/arch/arm/mach-shmobile/headsmp.S @@ -16,6 +16,13 @@ #include <asm/assembler.h> #include <asm/memory.h> +#define RWDT_CLOCK_ON 0xdeadbeef +#define RWDT_CLOCK_OFF 0x00000000 +#define SCTLR_MMU 0x01 +#define BOOTROM_ADDRESS 0xE6340000 +#define RWTCSRA_ADDRESS 0xE6020004 +#define RWTCSRA_WOVF 0x10 + /* * Reset vector for secondary CPUs. * This will be mapped at address 0 by SBAR register. @@ -24,11 +31,57 @@ .arm .align 12 ENTRY(shmobile_boot_vector) +/* + if (SCTLR_MMU == 1) + goto shmobile_smp_continue; +*/ + mrc p15, 0, r1, c1, c0, 0 @ r1 = SCTLR + and r0, r1, #SCTLR_MMU + cmp r0, #SCTLR_MMU + beq shmobile_smp_continue +/* + if (shmobile_wdt_clock_status != RWDT_CLOCK_ON) + goto shmobile_smp_continue; +*/ + ldr r0, #shmobile_wdt_clock_status + ldr r1, #clock_on + cmp r0, r1 + bne shmobile_smp_continue + +/* + if (RWTCSRA_WOVF == 0) + goto shmobile_smp_continue; +*/ + ldr r0, rwtcsra + mov r1, #0 + ldrb r1, [r0] + and r0, r1, #RWTCSRA_WOVF + cmp r0, #RWTCSRA_WOVF + bne shmobile_smp_continue + +/* + goto bootrom; +*/ + ldr r0, bootrom + bx r0 + +shmobile_smp_continue: ldr r1, 1f bx r1 ENDPROC(shmobile_boot_vector) + .align 4 +rwtcsra: + .word RWTCSRA_ADDRESS +bootrom: + .word BOOTROM_ADDRESS +clock_on: + .word RWDT_CLOCK_ON + .globl shmobile_wdt_clock_status +shmobile_wdt_clock_status: + .word RWDT_CLOCK_OFF + .align 2 .globl shmobile_boot_fn shmobile_boot_fn: -- 2.7.4
This patch adjusts the definition of the SMP routine size according to the latest changes made by commit: "ARM: shmobile: Add watchdog support" Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/boot/dts/r8a7743.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi index 47b62f6..d5834b6 100644 --- a/arch/arm/boot/dts/r8a7743.dtsi +++ b/arch/arm/boot/dts/r8a7743.dtsi @@ -973,7 +973,7 @@ smp-sram@0 { compatible = "renesas,smp-sram"; - reg = <0 0x10>; + reg = <0 0x64>; }; }; -- 2.7.4
This patch adjusts the definition of the SMP routine size according to the latest changes made by commit: "ARM: shmobile: Add watchdog support" Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm/boot/dts/r8a7745.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi index ddc3da2..32e8784 100644 --- a/arch/arm/boot/dts/r8a7745.dtsi +++ b/arch/arm/boot/dts/r8a7745.dtsi @@ -755,7 +755,7 @@ smp-sram@0 { compatible = "renesas,smp-sram"; - reg = <0 0x10>; + reg = <0 0x64>; }; }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
This patch adjusts the definition of the SMP routine size according to the latest changes made by commit: "ARM: shmobile: Add watchdog support" Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm/boot/dts/r8a7790.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 3bbcc0b..8b34636 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -443,7 +443,7 @@ smp-sram@0 { compatible = "renesas,smp-sram"; - reg = <0 0x10>; + reg = <0 0x64>; }; }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
This patch adjusts the definition of the SMP routine size according to the latest changes made by commit: "ARM: shmobile: Add watchdog support" Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/boot/dts/r8a7791.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index dc65935..00932d9 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -407,7 +407,7 @@ smp-sram@0 { compatible = "renesas,smp-sram"; - reg = <0 0x10>; + reg = <0 0x64>; }; }; -- 2.7.4
This patch adjusts the definition of the SMP routine size according to the latest changes made by commit: "ARM: shmobile: Add watchdog support" Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm/boot/dts/r8a7792.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7792.dtsi b/arch/arm/boot/dts/r8a7792.dtsi index 268987f..7f9213c 100644 --- a/arch/arm/boot/dts/r8a7792.dtsi +++ b/arch/arm/boot/dts/r8a7792.dtsi @@ -341,7 +341,7 @@ smp-sram@0 { compatible = "renesas,smp-sram"; - reg = <0 0x10>; + reg = <0 0x64>; }; }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
This patch adjusts the definition of the SMP routine size according to the latest changes made by commit: "ARM: shmobile: Add watchdog support" Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/boot/dts/r8a7793.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index aa7d779..ca684d0 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -392,7 +392,7 @@ smp-sram@0 { compatible = "renesas,smp-sram"; - reg = <0 0x10>; + reg = <0 0x64>; }; }; -- 2.7.4
This patch adjusts the definition of the SMP routine size according to the latest changes made by commit: "ARM: shmobile: Add watchdog support" Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/boot/dts/r8a7794.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index d588efa..a5a23e9 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -348,7 +348,7 @@ smp-sram@0 { compatible = "renesas,smp-sram"; - reg = <0 0x10>; + reg = <0 0x64>; }; }; -- 2.7.4
This commit introduces generic compatible strings to use as fallback, so that devices compatible with the generic implementation may avoid changing the driver. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- drivers/soc/renesas/rcar-rst.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index 3316b02..f7a0d54 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c @@ -25,8 +25,16 @@ static const struct rst_config rcar_rst_gen2 __initconst = { .modemr = 0x60, }; +static const struct rst_config rcar_rst_gen3 __initconst = { + .modemr = 0x60, +}; + static const struct of_device_id rcar_rst_matches[] __initconst = { - /* RZ/G is handled like R-Car Gen2 */ + /* generic compatible strings */ + { .compatible = "renesas,rcar-gen1-rst", .data = &rcar_rst_gen1 }, + { .compatible = "renesas,rcar-gen2-rst", .data = &rcar_rst_gen2 }, + { .compatible = "renesas,rcar-gen3-rst", .data = &rcar_rst_gen3 }, + /* RZ/G */ { .compatible = "renesas,r8a7743-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7745-rst", .data = &rcar_rst_gen2 }, /* R-Car Gen1 */ @@ -38,11 +46,11 @@ static const struct of_device_id rcar_rst_matches[] __initconst = { { .compatible = "renesas,r8a7792-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7793-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7794-rst", .data = &rcar_rst_gen2 }, - /* R-Car Gen3 is handled like R-Car Gen2 */ - { .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen2 }, - { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 }, - { .compatible = "renesas,r8a77970-rst", .data = &rcar_rst_gen2 }, - { .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen2 }, + /* R-Car Gen3 */ + { .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen3 }, + { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen3 }, + { .compatible = "renesas,r8a77970-rst", .data = &rcar_rst_gen3 }, + { .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen3 }, { /* sentinel */ } }; -- 2.7.4
This patch allows for platform specific quirks as some of the SoC need further customization for the watchdog to work properly, like for R-Car Gen2 and for RZ/G. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- drivers/soc/renesas/rcar-rst.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index f7a0d54..5f52aea 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c @@ -13,8 +13,18 @@ #include <linux/of_address.h> #include <linux/soc/renesas/rcar-rst.h> +#define WDTRSTCR_RESET 0xA55A0002 +#define WDTRSTCR 0x0054 + +static int gen2_configuration(void __iomem *base) +{ + iowrite32(WDTRSTCR_RESET, base + WDTRSTCR); + return 0; +} + struct rst_config { - unsigned int modemr; /* Mode Monitoring Register Offset */ + unsigned int modemr; /* Mode Monitoring Register Offset */ + int (*configure)(void *base); /* Platform specific configuration */ }; static const struct rst_config rcar_rst_gen1 __initconst = { @@ -23,6 +33,7 @@ static const struct rst_config rcar_rst_gen1 __initconst = { static const struct rst_config rcar_rst_gen2 __initconst = { .modemr = 0x60, + .configure = gen2_configuration, }; static const struct rst_config rcar_rst_gen3 __initconst = { @@ -79,6 +90,14 @@ static int __init rcar_rst_init(void) rcar_rst_base = base; cfg = match->data; saved_mode = ioread32(base + cfg->modemr); + if (cfg->configure) { + error = cfg->configure(base); + if (error) { + pr_warn("%pOF: Cannot run SoC specific configuration\n", + np); + goto out_put; + } + } pr_debug("%pOF: MODE = 0x%08x\n", np, saved_mode); -- 2.7.4
>From now on, devices compatible with the generic compatible strings documented by this commit don't need to modify the corresponding driver anymore. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- Documentation/devicetree/bindings/reset/renesas,rst.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/reset/renesas,rst.txt b/Documentation/devicetree/bindings/reset/renesas,rst.txt index a8014f3..2602a19 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rst.txt +++ b/Documentation/devicetree/bindings/reset/renesas,rst.txt @@ -11,7 +11,10 @@ following functions: Required properties: - - compatible: Should be + - compatible: Should be a SoC specific string, followed by a generic + fallback compatible string when compatible with the generic + version. + The SoC specific compatible string should be: - "renesas,<soctype>-reset-wdt" for R-Car Gen1, - "renesas,<soctype>-rst" for R-Car Gen2 and Gen3, and RZ/G Examples with soctypes are: @@ -28,12 +31,16 @@ Required properties: - "renesas,r8a7796-rst" (R-Car M3-W) - "renesas,r8a77970-rst" (R-Car V3M) - "renesas,r8a77995-rst" (R-Car D3) + The generic compatible string should be: + - "renesas,rcar-gen1-rst" for R-Car Gen1 + - "renesas,rcar-gen2-rst" for R-Car Gen2 and RZ/G + - "renesas,rcar-gen3-rst" for R-Car Gen3 - reg: Address start and address range for the device. Example: rst: reset-controller@e6160000 { - compatible = "renesas,r8a7795-rst"; + compatible = "renesas,r8a7795-rst", "renesas,rcar-gen3-rst"; reg = <0 0xe6160000 0 0x0200>; }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Add the generic fallback compatible string for the rst node. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/boot/dts/r8a7743.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi index d5834b6..8606955 100644 --- a/arch/arm/boot/dts/r8a7743.dtsi +++ b/arch/arm/boot/dts/r8a7743.dtsi @@ -364,7 +364,8 @@ }; rst: reset-controller@e6160000 { - compatible = "renesas,r8a7743-rst"; + compatible = "renesas,r8a7743-rst", + "renesas,rcar-gen2-rst"; reg = <0 0xe6160000 0 0x100>; }; -- 2.7.4
Add the generic fallback compatible string for the rst node. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm/boot/dts/r8a7745.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi index 32e8784..9009056 100644 --- a/arch/arm/boot/dts/r8a7745.dtsi +++ b/arch/arm/boot/dts/r8a7745.dtsi @@ -317,7 +317,8 @@ }; rst: reset-controller@e6160000 { - compatible = "renesas,r8a7745-rst"; + compatible = "renesas,r8a7745-rst", + "renesas,rcar-gen2-rst"; reg = <0 0xe6160000 0 0x100>; }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Add the generic fallback compatible string for the rst node. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm/boot/dts/r8a7790.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 8b34636..88ab60a 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -336,7 +336,8 @@ }; rst: reset-controller@e6160000 { - compatible = "renesas,r8a7790-rst"; + compatible = "renesas,r8a7790-rst", + "renesas,rcar-gen2-rst"; reg = <0 0xe6160000 0 0x0100>; }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Add the generic fallback compatible string for the rst node. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/boot/dts/r8a7791.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 00932d9..09d1e4f 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -284,7 +284,8 @@ }; rst: reset-controller@e6160000 { - compatible = "renesas,r8a7791-rst"; + compatible = "renesas,r8a7791-rst", + "renesas,rcar-gen2-rst"; reg = <0 0xe6160000 0 0x0100>; }; -- 2.7.4
Add the generic fallback compatible string for the rst node. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm/boot/dts/r8a7794.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index a5a23e9..9309887 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -246,7 +246,8 @@ }; rst: reset-controller@e6160000 { - compatible = "renesas,r8a7794-rst"; + compatible = "renesas,r8a7794-rst", + "renesas,rcar-gen2-rst"; reg = <0 0xe6160000 0 0x0100>; }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Add the generic fallback compatible string for the rst node. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index ce85704..853ca99 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -438,7 +438,8 @@ }; rst: reset-controller@e6160000 { - compatible = "renesas,r8a7795-rst"; + compatible = "renesas,r8a7795-rst", + "renesas,rcar-gen3-rst"; reg = <0 0xe6160000 0 0x0200>; }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Add the generic fallback compatible string for the rst node. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index f8e9313..7b347d8 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -510,7 +510,8 @@ }; rst: reset-controller@e6160000 { - compatible = "renesas,r8a7796-rst"; + compatible = "renesas,r8a7796-rst", + "renesas,rcar-gen3-rst"; reg = <0 0xe6160000 0 0x0200>; }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Add the generic fallback compatible string for the rst node. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm64/boot/dts/renesas/r8a77970.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi index 566a7f7..0fda66f 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -113,7 +113,8 @@ }; rst: reset-controller@e6160000 { - compatible = "renesas,r8a77970-rst"; + compatible = "renesas,r8a77970-rst", + "renesas,rcar-gen3-rst"; reg = <0 0xe6160000 0 0x200>; }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Add the generic fallback compatible string for the rst node. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm64/boot/dts/renesas/r8a77995.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi index 23f763b..2cd8ef0 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi @@ -196,7 +196,8 @@ }; rst: reset-controller@e6160000 { - compatible = "renesas,r8a77995-rst"; + compatible = "renesas,r8a77995-rst", + "renesas,rcar-gen3-rst"; reg = <0 0xe6160000 0 0x0200>; }; -- 2.7.4
This commit documents the compatibility with R-Car Gen2 and RZ/G devices by defining the generifc compatible string "renesas,rcar-gen2-wdt". Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- Documentation/devicetree/bindings/watchdog/renesas-wdt.txt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt index bf6d1ca..436dca5 100644 --- a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt @@ -1,17 +1,20 @@ Renesas Watchdog Timer (WDT) Controller Required properties: -- compatible : Should be "renesas,<soctype>-wdt", and - "renesas,rcar-gen3-wdt" or "renesas,rza-wdt" as fallback. + - compatible : Must be "renesas,<soctype>-wdt", followed by a generic + fallback compatible string when compatible with the generic + version. Examples with soctypes are: + - "renesas,r8a7743-wdt" (RZ/G1M) + - "renesas,r8a7745-wdt" (RZ/G1E) - "renesas,r8a7795-wdt" (R-Car H3) - "renesas,r8a7796-wdt" (R-Car M3-W) - "renesas,r8a77995-wdt" (R-Car D3) - "renesas,r7s72100-wdt" (RZ/A1) + The generic compatible string must be: + - "renesas,rcar-gen2-wdt" for R-Car Gen2 and RZ/G + - "renesas,rcar-gen3-wdt" for R-Car Gen3 - When compatible with the generic version, nodes must list the SoC-specific - version corresponding to the platform first, followed by the generic - version. - reg : Should contain WDT registers location and length - clocks : the clock feeding the watchdog timer. -- 2.7.4
This commit extends the driver to add restart support by implementing the restart callback to trigger the watchdog as quickly as possible. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- drivers/watchdog/renesas_wdt.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index 831ef83..120ddac 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c @@ -107,6 +107,24 @@ static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); } +static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, + void *data) +{ + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + + pm_runtime_get_sync(wdev->parent); + + rwdt_write(priv, 0x00, RWTCSRB); + rwdt_write(priv, 0x00, RWTCSRA); + rwdt_write(priv, 0xffff, RWTCNT); + + while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) + cpu_relax(); + + rwdt_write(priv, 0x80, RWTCSRA); + return 0; +} + static const struct watchdog_info rwdt_ident = { .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, .identity = "Renesas WDT Watchdog", @@ -118,6 +136,7 @@ static const struct watchdog_ops rwdt_ops = { .stop = rwdt_stop, .ping = rwdt_init_timeout, .get_timeleft = rwdt_get_timeleft, + .restart = rwdt_restart, }; static int rwdt_probe(struct platform_device *pdev) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
This patch exposes a function to set the value of variable "shmobile_wdt_clock_status" so that the watchdog driver may communicate critical information to the SMP bring up assembly routine. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm/mach-shmobile/common.h | 1 + arch/arm/mach-shmobile/pm-rcar-gen2.c | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index a8fa4f7..e4ffca8 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h @@ -5,6 +5,7 @@ extern void shmobile_init_cntvoff(void); extern void shmobile_init_delay(void); extern void shmobile_boot_vector(void); +extern unsigned long shmobile_wdt_clock_status; extern unsigned long shmobile_boot_fn; extern unsigned long shmobile_boot_size; extern void shmobile_smp_boot(void); diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c index e5f215c..cfdc3cd 100644 --- a/arch/arm/mach-shmobile/pm-rcar-gen2.c +++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c @@ -50,6 +50,16 @@ static inline u32 phys_to_sbar(phys_addr_t addr) #define SYSCIER 0x0c #define SYSCIMR 0x10 +static void __iomem *shmobile_boot_vector_start; +static unsigned long clock_status; + +void shmobile_set_wdt_clock_status(unsigned long value) +{ + memcpy_toio(shmobile_boot_vector_start + clock_status, + &value, sizeof(value)); +} +EXPORT_SYMBOL(shmobile_set_wdt_clock_status); + #if defined(CONFIG_SMP) static void __init rcar_gen2_sysc_init(u32 syscier) @@ -120,8 +130,12 @@ void __init rcar_gen2_pm_init(void) if (!p) return; + shmobile_boot_vector_start = p; + clock_status = (&shmobile_wdt_clock_status - + (unsigned long *)shmobile_boot_vector) * + sizeof(shmobile_wdt_clock_status); + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); - iounmap(p); /* setup reset vectors */ p = ioremap_nocache(RST, 0x63); -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
R-Car Gen2 (and RZ/G1) platforms need some tweaking for SMP and watchdog to coexist nicely. This new driver is based on top of Wolfram Sang's driver (drivers/watchdog/renesas_wdt.c), and it contains the quirks necessary for R-Car Gen2 and RZ/G1 to work properly and in harmony with the rest of the system. In particular, the driver: * expects the device clock to be ON all the time, * "pauses" the watchdog operation during suspend, and * "reassures" the SMP bringup function about the availability of the watchdog registers. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- drivers/watchdog/Kconfig | 15 +- drivers/watchdog/Makefile | 1 + drivers/watchdog/renesas_wdt_gen2.c | 270 ++++++++++++++++++++++++++++++++++++ drivers/watchdog/renesas_wdt_gen2.h | 22 +++ 4 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 drivers/watchdog/renesas_wdt_gen2.c create mode 100644 drivers/watchdog/renesas_wdt_gen2.h diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index ca200d1..e580c72 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -725,12 +725,23 @@ config ATLAS7_WATCHDOG module will be called atlas7_wdt. config RENESAS_WDT - tristate "Renesas WDT Watchdog" + tristate "Renesas R-Car Gen3 WDT Watchdog" depends on ARCH_RENESAS || COMPILE_TEST select WATCHDOG_CORE help This driver adds watchdog support for the integrated watchdogs in the - Renesas R-Car and other SH-Mobile SoCs (usually named RWDT or SWDT). + Renesas R-Car Gen3 devices. + +config RENESAS_WDT_GEN2 + tristate "Renesas R-Car Gen2 and RZ/G1 WDT Watchdog" + depends on ARCH_RENESAS || COMPILE_TEST + select WATCHDOG_CORE + help + This driver adds watchdog support for the integrated watchdogs in the + Renesas R-Car Gen2 and RZ/G1 devices. + + To compile this driver as a module, choose M here: the + module will be called renesas_wdt_gen2. config RENESAS_RZAWDT tristate "Renesas RZ/A WDT Watchdog" diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 715a210..57ab810 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -83,6 +83,7 @@ obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o +obj-$(CONFIG_RENESAS_WDT_GEN2) += renesas_wdt_gen2.o obj-$(CONFIG_RENESAS_RZAWDT) += rza_wdt.o obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o diff --git a/drivers/watchdog/renesas_wdt_gen2.c b/drivers/watchdog/renesas_wdt_gen2.c new file mode 100644 index 0000000..c841636 --- /dev/null +++ b/drivers/watchdog/renesas_wdt_gen2.c @@ -0,0 +1,270 @@ +/* + * Watchdog driver for Renesas WDT watchdog + * + * Copyright (C) 2015-17 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com> + * Copyright (C) 2018 Renesas Electronics Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#include <linux/bitops.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/watchdog.h> +#include "renesas_wdt_gen2.h" + +#define RWTCNT 0 +#define RWTCSRA 4 +#define RWTCSRA_WOVF BIT(4) +#define RWTCSRA_WRFLG BIT(5) +#define RWTCSRA_TME BIT(7) +#define RWTCSRB 8 + +#define RWDT_DEFAULT_TIMEOUT 60U + +/* + * In probe, clk_rate is checked to be not more than 16 bit * biggest clock + * divider (12 bits). d is only a factor to fully utilize the WDT counter and + * will not exceed its 16 bits. Thus, no overflow, we stay below 32 bits. + */ +#define MUL_BY_CLKS_PER_SEC(p, d) \ + DIV_ROUND_UP((d) * (p)->clk_rate, clk_divs[(p)->cks]) + +/* d is 16 bit, clk_divs 12 bit -> no 32 bit overflow */ +#define DIV_BY_CLKS_PER_SEC(p, d) ((d) * clk_divs[(p)->cks] / (p)->clk_rate) + +static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024, 4096 }; + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +struct rwdt_priv { + void __iomem *base; + struct watchdog_device wdev; + unsigned long clk_rate; + bool enabled; + u8 cks; +}; + +static void rwdt_write(struct rwdt_priv *priv, u32 val, unsigned int reg) +{ + if (reg == RWTCNT) + val |= 0x5a5a0000; + else + val |= 0xa5a5a500; + + writel_relaxed(val, priv->base + reg); +} + +static int rwdt_init_timeout(struct watchdog_device *wdev) +{ + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + + rwdt_write(priv, 65536 - MUL_BY_CLKS_PER_SEC(priv, wdev->timeout), + RWTCNT); + + return 0; +} + +static int rwdt_start(struct watchdog_device *wdev) +{ + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + + rwdt_write(priv, 0, RWTCSRB); + rwdt_write(priv, priv->cks, RWTCSRA); + rwdt_init_timeout(wdev); + + while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) + cpu_relax(); + + rwdt_write(priv, priv->cks | RWTCSRA_TME, RWTCSRA); + + return 0; +} + +static int rwdt_stop(struct watchdog_device *wdev) +{ + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + + rwdt_write(priv, priv->cks, RWTCSRA); + + return 0; +} + +static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) +{ + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + u16 val = readw_relaxed(priv->base + RWTCNT); + + return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); +} + +static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, + void *data) +{ + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); + + rwdt_write(priv, 0x00, RWTCSRB); + rwdt_write(priv, 0x00, RWTCSRA); + rwdt_write(priv, 0xffff, RWTCNT); + + while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) + cpu_relax(); + + rwdt_write(priv, 0x80, RWTCSRA); + return 0; +} + +static const struct watchdog_info rwdt_ident = { + .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, + .identity = "Renesas WDT Watchdog", +}; + +static const struct watchdog_ops rwdt_ops = { + .owner = THIS_MODULE, + .start = rwdt_start, + .stop = rwdt_stop, + .ping = rwdt_init_timeout, + .get_timeleft = rwdt_get_timeleft, + .restart = rwdt_restart, +}; + +static int rwdt_probe(struct platform_device *pdev) +{ + struct rwdt_priv *priv; + struct resource *res; + struct clk *clk; + unsigned long clks_per_sec; + int ret, i; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + + priv->clk_rate = clk_get_rate(clk); + + if (!priv->clk_rate) + return -ENOENT; + + for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { + clks_per_sec = priv->clk_rate / clk_divs[i]; + if (clks_per_sec && clks_per_sec < 65536) { + priv->cks = i; + break; + } + } + + if (i < 0) { + dev_err(&pdev->dev, "Can't find suitable clock divider\n"); + return -ERANGE; + } + + priv->wdev.info = &rwdt_ident, + priv->wdev.ops = &rwdt_ops, + priv->wdev.parent = &pdev->dev; + priv->wdev.min_timeout = 1; + priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536); + priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT); + + platform_set_drvdata(pdev, priv); + watchdog_set_drvdata(&priv->wdev, priv); + watchdog_set_nowayout(&priv->wdev, nowayout); + + ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev); + if (ret) + dev_warn(&pdev->dev, + "Specified timeout value invalid, using default\n"); + shmobile_set_wdt_clock_status(RWDT_CLOCK_ON); + + ret = watchdog_register_device(&priv->wdev); + return ret; +} + +static int rwdt_remove(struct platform_device *pdev) +{ + struct rwdt_priv *priv = platform_get_drvdata(pdev); + + watchdog_unregister_device(&priv->wdev); + + return 0; +} + +#ifdef CONFIG_PM +static int rwdt_suspend(struct device *dev) +{ + struct platform_device *pdev; + struct rwdt_priv *priv; + u8 val; + + pdev = to_platform_device(dev); + priv = platform_get_drvdata(pdev); + val = readb_relaxed(priv->base + RWTCSRA); + if (val & RWTCSRA_TME) { + priv->enabled = true; + rwdt_write(priv, val & ~RWTCSRA_TME, RWTCSRA); + } else { + priv->enabled = false; + } + return 0; +} + +static int rwdt_resume(struct device *dev) +{ + struct platform_device *pdev; + struct rwdt_priv *priv; + u8 val; + + pdev = to_platform_device(dev); + priv = platform_get_drvdata(pdev); + if (priv->enabled) { + val = readb_relaxed(priv->base + RWTCSRA); + rwdt_write(priv, val | RWTCSRA_TME, RWTCSRA); + } + return 0; +} + +static const struct dev_pm_ops rwdt_pm = { + .suspend = rwdt_suspend, + .resume = rwdt_resume, +}; +#endif + +static const struct of_device_id rwdt_ids[] = { + { .compatible = "renesas,rcar-gen2-wdt", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rwdt_ids); + +static struct platform_driver rwdt_driver = { + .driver = { + .name = "renesas_wdt_gen2", + .of_match_table = rwdt_ids, +#ifdef CONFIG_PM + .pm = &rwdt_pm, +#endif + }, + .probe = rwdt_probe, + .remove = rwdt_remove, +}; +module_platform_driver(rwdt_driver); + +MODULE_DESCRIPTION("Renesas R-Car Gen2 Watchdog Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro@bp.renesas.com>"); diff --git a/drivers/watchdog/renesas_wdt_gen2.h b/drivers/watchdog/renesas_wdt_gen2.h new file mode 100644 index 0000000..41b9e9c --- /dev/null +++ b/drivers/watchdog/renesas_wdt_gen2.h @@ -0,0 +1,22 @@ +/* + * drivers/watchdog/renesas_wdt_gen2.h + * + * Copyright (C) 2018 Renesas Electronics Corporation + * + * R-Car Gen2 and RZ/G specific symbols + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef RENESAS_WDT_GEN2_H +#define RENESAS_WDT_GEN2_H + +#define RWDT_CLOCK_ON 0xdeadbeef +#define RWDT_CLOCK_OFF 0x00000000 + +extern void shmobile_set_wdt_clock_status(unsigned long value); + +#endif /* RENESAS_WDT_GEN2_H */ -- 2.7.4
R-Car Gen2 and RZ/G1 platforms come with a watchdog IP, therefore enable its driver by default. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/configs/shmobile_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 578434c..f25bd1c 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -132,6 +132,7 @@ CONFIG_CPU_THERMAL=y CONFIG_RCAR_THERMAL=y CONFIG_WATCHDOG=y CONFIG_DA9063_WATCHDOG=y +CONFIG_RENESAS_WDT_GEN2=y CONFIG_MFD_AS3711=y CONFIG_MFD_DA9063=y CONFIG_REGULATOR_FIXED_VOLTAGE=y -- 2.7.4
Add "rwdt" clock to r8a7743_mod_clks. Also, since we may need to access the watchdog registers at any time, declare the clock as critical. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- drivers/clk/renesas/r8a7743-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/renesas/r8a7743-cpg-mssr.c b/drivers/clk/renesas/r8a7743-cpg-mssr.c index 6dc0b30..d3c8b1e 100644 --- a/drivers/clk/renesas/r8a7743-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7743-cpg-mssr.c @@ -117,6 +117,7 @@ static const struct mssr_mod_clk r8a7743_mod_clks[] __initconst = { DEF_MOD("cmt1", 329, R8A7743_CLK_R), DEF_MOD("usbhs-dmac0", 330, R8A7743_CLK_HP), DEF_MOD("usbhs-dmac1", 331, R8A7743_CLK_HP), + DEF_MOD("rwdt", 402, R8A7743_CLK_R), DEF_MOD("irqc", 407, R8A7743_CLK_CP), DEF_MOD("intc-sys", 408, R8A7743_CLK_ZS), DEF_MOD("audio-dmac1", 501, R8A7743_CLK_HP), @@ -195,6 +196,7 @@ static const struct mssr_mod_clk r8a7743_mod_clks[] __initconst = { }; static const unsigned int r8a7743_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ MOD_CLK_ID(408), /* INTC-SYS (GIC) */ }; -- 2.7.4
Add "rwdt" clock to r8a7745_mod_clks. Also, since we may need to access the watchdog registers at any time, declare the clock as critical. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- drivers/clk/renesas/r8a7745-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/renesas/r8a7745-cpg-mssr.c b/drivers/clk/renesas/r8a7745-cpg-mssr.c index 2859504..87f5a36 100644 --- a/drivers/clk/renesas/r8a7745-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7745-cpg-mssr.c @@ -114,6 +114,7 @@ static const struct mssr_mod_clk r8a7745_mod_clks[] __initconst = { DEF_MOD("cmt1", 329, R8A7745_CLK_R), DEF_MOD("usbhs-dmac0", 330, R8A7745_CLK_HP), DEF_MOD("usbhs-dmac1", 331, R8A7745_CLK_HP), + DEF_MOD("rwdt", 402, R8A7745_CLK_R), DEF_MOD("irqc", 407, R8A7745_CLK_CP), DEF_MOD("intc-sys", 408, R8A7745_CLK_ZS), DEF_MOD("audio-dmac0", 502, R8A7745_CLK_HP), @@ -180,6 +181,7 @@ static const struct mssr_mod_clk r8a7745_mod_clks[] __initconst = { }; static const unsigned int r8a7745_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ MOD_CLK_ID(408), /* INTC-SYS (GIC) */ }; -- 2.7.4
Add "rwdt" clock to r8a7790_mod_clks. Also, since we may need to access the watchdog registers at any time, declare the clock as critical. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- drivers/clk/renesas/r8a7790-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/renesas/r8a7790-cpg-mssr.c b/drivers/clk/renesas/r8a7790-cpg-mssr.c index 46bb55b..f936cb7 100644 --- a/drivers/clk/renesas/r8a7790-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7790-cpg-mssr.c @@ -140,6 +140,7 @@ static const struct mssr_mod_clk r8a7790_mod_clks[] __initconst = { DEF_MOD("cmt1", 329, R8A7790_CLK_R), DEF_MOD("usbhs-dmac0", 330, R8A7790_CLK_HP), DEF_MOD("usbhs-dmac1", 331, R8A7790_CLK_HP), + DEF_MOD("rwdt", 402, R8A7790_CLK_R), DEF_MOD("irqc", 407, R8A7790_CLK_CP), DEF_MOD("intc-sys", 408, R8A7790_CLK_ZS), DEF_MOD("audio-dmac1", 501, R8A7790_CLK_HP), @@ -211,6 +212,7 @@ static const struct mssr_mod_clk r8a7790_mod_clks[] __initconst = { }; static const unsigned int r8a7790_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ MOD_CLK_ID(408), /* INTC-SYS (GIC) */ }; -- 2.7.4
Add "rwdt" clock to r8a7791_mod_clks. Also, since we may need to access the watchdog registers at any time, declare the clock as critical. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- drivers/clk/renesas/r8a7791-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/renesas/r8a7791-cpg-mssr.c b/drivers/clk/renesas/r8a7791-cpg-mssr.c index c0b51f9..820b220 100644 --- a/drivers/clk/renesas/r8a7791-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7791-cpg-mssr.c @@ -128,6 +128,7 @@ static const struct mssr_mod_clk r8a7791_mod_clks[] __initconst = { DEF_MOD("cmt1", 329, R8A7791_CLK_R), DEF_MOD("usbhs-dmac0", 330, R8A7791_CLK_HP), DEF_MOD("usbhs-dmac1", 331, R8A7791_CLK_HP), + DEF_MOD("rwdt", 402, R8A7791_CLK_R), DEF_MOD("irqc", 407, R8A7791_CLK_CP), DEF_MOD("intc-sys", 408, R8A7791_CLK_ZS), DEF_MOD("audio-dmac1", 501, R8A7791_CLK_HP), @@ -209,6 +210,7 @@ static const struct mssr_mod_clk r8a7791_mod_clks[] __initconst = { }; static const unsigned int r8a7791_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ MOD_CLK_ID(408), /* INTC-SYS (GIC) */ }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Add "rwdt" clock to r8a7794_mod_clks. Also, since we may need to access the watchdog registers at any time, declare the clock as critical. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- drivers/clk/renesas/r8a7794-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/renesas/r8a7794-cpg-mssr.c b/drivers/clk/renesas/r8a7794-cpg-mssr.c index ec091a4..2a40bbe 100644 --- a/drivers/clk/renesas/r8a7794-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7794-cpg-mssr.c @@ -121,6 +121,7 @@ static const struct mssr_mod_clk r8a7794_mod_clks[] __initconst = { DEF_MOD("cmt1", 329, R8A7794_CLK_R), DEF_MOD("usbhs-dmac0", 330, R8A7794_CLK_HP), DEF_MOD("usbhs-dmac1", 331, R8A7794_CLK_HP), + DEF_MOD("rwdt", 402, R8A7794_CLK_R), DEF_MOD("irqc", 407, R8A7794_CLK_CP), DEF_MOD("intc-sys", 408, R8A7794_CLK_ZS), DEF_MOD("audio-dmac0", 502, R8A7794_CLK_HP), @@ -190,6 +191,7 @@ static const struct mssr_mod_clk r8a7794_mod_clks[] __initconst = { }; static const unsigned int r8a7794_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ MOD_CLK_ID(408), /* INTC-SYS (GIC) */ }; -- 2.7.4
This patch adds watchdog support to the r8a7743 SoC dtsi. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/boot/dts/r8a7743.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi index 8606955..b44f53f 100644 --- a/arch/arm/boot/dts/r8a7743.dtsi +++ b/arch/arm/boot/dts/r8a7743.dtsi @@ -369,6 +369,16 @@ reg = <0 0xe6160000 0 0x100>; }; + rwdt: watchdog@e6020000 { + compatible = "renesas,r8a7743-wdt", + "renesas,rcar-gen2-wdt"; + reg = <0 0xe6020000 0 0x0c>; + clocks = <&cpg CPG_MOD 402>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 402>; + status = "disabled"; + }; + sysc: system-controller@e6180000 { compatible = "renesas,r8a7743-sysc"; reg = <0 0xe6180000 0 0x200>; -- 2.7.4
This patch adds watchdog support to the r8a7745 SoC dtsi. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/boot/dts/r8a7745.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi index 9009056..bf24c2e4 100644 --- a/arch/arm/boot/dts/r8a7745.dtsi +++ b/arch/arm/boot/dts/r8a7745.dtsi @@ -322,6 +322,16 @@ reg = <0 0xe6160000 0 0x100>; }; + rwdt: watchdog@e6020000 { + compatible = "renesas,r8a7745-wdt", + "renesas,rcar-gen2-wdt"; + reg = <0 0xe6020000 0 0x0c>; + clocks = <&cpg CPG_MOD 402>; + power-domains = <&sysc R8A7745_PD_ALWAYS_ON>; + resets = <&cpg 402>; + status = "disabled"; + }; + sysc: system-controller@e6180000 { compatible = "renesas,r8a7745-sysc"; reg = <0 0xe6180000 0 0x200>; -- 2.7.4
This commit adds watchdog support to the r8a7790 dtsi. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm/boot/dts/r8a7790.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 88ab60a..d10ae89 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -341,6 +341,16 @@ reg = <0 0xe6160000 0 0x0100>; }; + rwdt: watchdog@e6020000 { + compatible = "renesas,r8a7790-wdt", + "renesas,rcar-gen2-wdt"; + reg = <0 0xe6020000 0 0x0c>; + clocks = <&cpg CPG_MOD 402>; + power-domains = <&sysc R8A7790_PD_ALWAYS_ON>; + resets = <&cpg 402>; + status = "disabled"; + }; + sysc: system-controller@e6180000 { compatible = "renesas,r8a7790-sysc"; reg = <0 0xe6180000 0 0x0200>; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
This commit adds watchdog support to the r8a7791 dtsi. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/boot/dts/r8a7791.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 09d1e4f..dacec25 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -289,6 +289,16 @@ reg = <0 0xe6160000 0 0x0100>; }; + rwdt: watchdog@e6020000 { + compatible = "renesas,r8a7791-wdt", + "renesas,rcar-gen2-wdt"; + reg = <0 0xe6020000 0 0x0c>; + clocks = <&cpg CPG_MOD 402>; + power-domains = <&sysc R8A7791_PD_ALWAYS_ON>; + resets = <&cpg 402>; + status = "disabled"; + }; + sysc: system-controller@e6180000 { compatible = "renesas,r8a7791-sysc"; reg = <0 0xe6180000 0 0x0200>; -- 2.7.4
This commit adds watchdog support to the r8a7794 dtsi. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm/boot/dts/r8a7794.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index 9309887..5f9e6d3 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -251,6 +251,16 @@ reg = <0 0xe6160000 0 0x0100>; }; + rwdt: watchdog@e6020000 { + compatible = "renesas,r8a7794-wdt", + "renesas,rcar-gen2-wdt"; + reg = <0 0xe6020000 0 0x0c>; + clocks = <&cpg CPG_MOD 402>; + power-domains = <&sysc R8A7794_PD_ALWAYS_ON>; + resets = <&cpg 402>; + status = "disabled"; + }; + sysc: system-controller@e6180000 { compatible = "renesas,r8a7794-sysc"; reg = <0 0xe6180000 0 0x0200>; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
This patch enables the watchdog from within the iwg20m SoM dtsi. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/boot/dts/r8a7743-iwg20m.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/r8a7743-iwg20m.dtsi b/arch/arm/boot/dts/r8a7743-iwg20m.dtsi index 1d3e950..d364685 100644 --- a/arch/arm/boot/dts/r8a7743-iwg20m.dtsi +++ b/arch/arm/boot/dts/r8a7743-iwg20m.dtsi @@ -91,6 +91,11 @@ }; }; +&rwdt { + timeout-sec = <60>; + status = "okay"; +}; + &sdhi0 { pinctrl-0 = <&sdhi0_pins>; pinctrl-names = "default"; -- 2.7.4
This patch enables the watchdog from within the iwg20m SoM dtsi. Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> --- arch/arm/boot/dts/r8a7745-iwg22m.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/r8a7745-iwg22m.dtsi b/arch/arm/boot/dts/r8a7745-iwg22m.dtsi index 8d0a392b..29b6e10 100644 --- a/arch/arm/boot/dts/r8a7745-iwg22m.dtsi +++ b/arch/arm/boot/dts/r8a7745-iwg22m.dtsi @@ -91,6 +91,11 @@ }; }; +&rwdt { + timeout-sec = <60>; + status = "okay"; +}; + &sdhi1 { pinctrl-0 = <&sdhi1_pins>; pinctrl-names = "default"; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hello! On 1/25/2018 9:02 PM, Fabrizio Castro wrote: > This patch allows for platform specific quirks as some of the SoC need > further customization for the watchdog to work properly, like for R-Car > Gen2 and for RZ/G. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > --- > drivers/soc/renesas/rcar-rst.c | 21 ++++++++++++++++++++- > 1 file changed, 20 insertions(+), 1 deletion(-) > > diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c > index f7a0d54..5f52aea 100644 > --- a/drivers/soc/renesas/rcar-rst.c > +++ b/drivers/soc/renesas/rcar-rst.c > @@ -13,8 +13,18 @@ > #include <linux/of_address.h> > #include <linux/soc/renesas/rcar-rst.h> > > +#define WDTRSTCR_RESET 0xA55A0002 > +#define WDTRSTCR 0x0054 > + > +static int gen2_configuration(void __iomem *base) > +{ > + iowrite32(WDTRSTCR_RESET, base + WDTRSTCR); > + return 0; > +} > + > struct rst_config { > - unsigned int modemr; /* Mode Monitoring Register Offset */ > + unsigned int modemr; /* Mode Monitoring Register Offset */ > + int (*configure)(void *base); /* Platform specific configuration */ > }; > > static const struct rst_config rcar_rst_gen1 __initconst = { > @@ -23,6 +33,7 @@ static const struct rst_config rcar_rst_gen1 __initconst = { > > static const struct rst_config rcar_rst_gen2 __initconst = { > .modemr = 0x60, > + .configure = gen2_configuration, Why not call the method gen2_configure() then? [...] MBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Fabrizio, On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > On R-Car Gen2 and RZ/G1 platforms, we use the SBAR registers to make non > boot CPUs run a routine designed to bring up SMP and deal with hot plug. > The value contained in the SBAR registers is not initialized by a WDT > triggered reset, which means that after a WDT triggered reset we jump > to the SMP bring up routine, preventing the system from executing the > bootrom code. Thanks for your patch! > The purpose of this patch is to jump to the bootrom code in case of a > WDT triggered reset, and keep the SMP functionality untouched. > In order to tell if the code had been called due to the WDT overflowing > we need to inspect flag WOVF from register RWTCSRA, however for this > to work smoothly we need to make sure that RWDT clock is ON. > Since it's not wise to interfere with the clock configuration from > within this routine, a flag has been put in place > (shmobile_wdt_clock_status) so that the watchdog driver can tell > shmobile_boot_vector when the clock is ON, and therefore there is no > need for shmobile_boot_vector to mess up with the clock registers. > > Bit WOVF survives a watchdog triggered reset, and it is usually cleared > by the bootloader. Checking the MMU enable bit from register SCTLR > allows us to make the code a little bit more robust (just in case the > bit wasn't cleared up), as right after a reset the MMU is disabled, > and when Linux is running the MMU is enabled. Also, accessing RWTCSRA > physical address is safe when the MMU is down. Checking a hardware register is indeed a better solution than my original idea to let SMP bringup set a flag in RAM, as the former is less racy. However, as you can probably imagine, I don't like the shmobile_wdt_clock_status part ;-) Isn't is sufficient to check the MMU enable bit? However, that would precludes uClinux (do we care?). Is there any other register/bit that's reset when the watchdog is triggered, and always set by Linux? > SMP bringup, CPU hot plug, and suspend to RAM work as normal. shmobile_boot_vector is not only used for R-Car Gen2 and RZ/G1 SoCs, but also for EMMA Mobile, SH/R-Mobile, and R-Car H1. Hence this breaks SMP for the latter (and their build if ARCH_RENESAS=n, due to missing shmobile_wdt_clock_status). > Since shmobile_boot_vector has become bigger, "reg" property of nodes > compatible with "renesas,smp-sram" now need to be set to "<0 0x64>". This breaks backwards compatibility with old DTs declaring a too small smp-sram area. If the area is too small, you should fallback to the old and smaller code. > --- a/arch/arm/mach-shmobile/headsmp.S > +++ b/arch/arm/mach-shmobile/headsmp.S > @@ -16,6 +16,13 @@ > #include <asm/assembler.h> > #include <asm/memory.h> > > +#define RWDT_CLOCK_ON 0xdeadbeef > +#define RWDT_CLOCK_OFF 0x00000000 > +#define SCTLR_MMU 0x01 > +#define BOOTROM_ADDRESS 0xE6340000 > +#define RWTCSRA_ADDRESS 0xE6020004 > +#define RWTCSRA_WOVF 0x10 > + > /* > * Reset vector for secondary CPUs. > * This will be mapped at address 0 by SBAR register. > @@ -24,11 +31,57 @@ > .arm > .align 12 > ENTRY(shmobile_boot_vector) This should become e.g. rcar_gen2_boot_vector_wdt > +/* > + if (SCTLR_MMU == 1) > + goto shmobile_smp_continue; > +*/ > + mrc p15, 0, r1, c1, c0, 0 @ r1 = SCTLR > + and r0, r1, #SCTLR_MMU > + cmp r0, #SCTLR_MMU > + beq shmobile_smp_continue > +/* > + if (shmobile_wdt_clock_status != RWDT_CLOCK_ON) > + goto shmobile_smp_continue; > +*/ > + ldr r0, #shmobile_wdt_clock_status > + ldr r1, #clock_on > + cmp r0, r1 > + bne shmobile_smp_continue > + > +/* > + if (RWTCSRA_WOVF == 0) > + goto shmobile_smp_continue; > +*/ > + ldr r0, rwtcsra > + mov r1, #0 > + ldrb r1, [r0] > + and r0, r1, #RWTCSRA_WOVF > + cmp r0, #RWTCSRA_WOVF > + bne shmobile_smp_continue > + > +/* > + goto bootrom; > +*/ > + ldr r0, bootrom > + bx r0 > + > +shmobile_smp_continue: This should become ENTRY(shmobile_boot_vector) Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, Jan 26, 2018 at 10:46 AM, Geert Uytterhoeven <geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org> wrote: > On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro > <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: >> SMP bringup, CPU hot plug, and suspend to RAM work as normal. > > shmobile_boot_vector is not only used for R-Car Gen2 and RZ/G1 SoCs, but > also for EMMA Mobile, SH/R-Mobile, and R-Car H1. Hence this breaks SMP > for the latter (and their build if ARCH_RENESAS=n, due to missing > shmobile_wdt_clock_status). Sorry, please ignore my comment about build failures. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > This patch adjusts the definition of the SMP routine size according > to the latest changes made by commit: > "ARM: shmobile: Add watchdog support" > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> I would make it a bit larger, though. "0x64" is the strict minimum => 0x80? 0x100? Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> > --- a/arch/arm/boot/dts/r8a7743.dtsi > +++ b/arch/arm/boot/dts/r8a7743.dtsi > @@ -973,7 +973,7 @@ > > smp-sram@0 { > compatible = "renesas,smp-sram"; > - reg = <0 0x10>; > + reg = <0 0x64>; > }; > }; Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro
<fabrizio.castro@bp.renesas.com> wrote:
> This patch adjusts the definition of the SMP routine size according
> to the latest changes made by commit:
> "ARM: shmobile: Add watchdog support"
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
I would make it a bit larger, though. "0x64" is the strict minimum =>
0x80? 0x100?
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
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
On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro
<fabrizio.castro@bp.renesas.com> wrote:
> This patch adjusts the definition of the SMP routine size according
> to the latest changes made by commit:
> "ARM: shmobile: Add watchdog support"
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
I would make it a bit larger, though. "0x64" is the strict minimum =>
0x80? 0x100?
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
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
On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro
<fabrizio.castro@bp.renesas.com> wrote:
> This patch adjusts the definition of the SMP routine size according
> to the latest changes made by commit:
> "ARM: shmobile: Add watchdog support"
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
I would make it a bit larger, though. "0x64" is the strict minimum =>
0x80? 0x100?
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
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
On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro
<fabrizio.castro@bp.renesas.com> wrote:
> This patch adjusts the definition of the SMP routine size according
> to the latest changes made by commit:
> "ARM: shmobile: Add watchdog support"
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
I would make it a bit larger, though. "0x64" is the strict minimum =>
0x80? 0x100?
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
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
On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > This patch adjusts the definition of the SMP routine size according > to the latest changes made by commit: > "ARM: shmobile: Add watchdog support" > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> I would make it a bit larger, though. "0x64" is the strict minimum => 0x80? 0x100? Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro
<fabrizio.castro@bp.renesas.com> wrote:
> This patch adjusts the definition of the SMP routine size according
> to the latest changes made by commit:
> "ARM: shmobile: Add watchdog support"
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
I would make it a bit larger, though. "0x64" is the strict minimum =>
0x80? 0x100?
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
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
Hi Fabrizio, On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > This commit introduces generic compatible strings to use as fallback, > so that devices compatible with the generic implementation may avoid > changing the driver. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Thanks for your patch! >From commit 527c02f66d263d2e ("soc: renesas: Add R-Car RST driver"): Despite the current simple and almost identical handling for all supported SoCs, the driver matches against SoC-specific compatible values, as the features provided by the hardware module differ a lot across the various SoC families and members. In fact the only commonalities are the presence of the MODEMR register (the mode bits differ), and the Watchdog Timer Reset Control Register. All other registers and bits depend on the SoC's CPU core configuration. Hence that's why I did not add generic compatible values. So unless you really need them (from this series, it looks like you don't?), I wouldn't add them. > --- a/drivers/soc/renesas/rcar-rst.c > +++ b/drivers/soc/renesas/rcar-rst.c > @@ -25,8 +25,16 @@ static const struct rst_config rcar_rst_gen2 __initconst = { > .modemr = 0x60, > }; > > +static const struct rst_config rcar_rst_gen3 __initconst = { > + .modemr = 0x60, > +}; > + > static const struct of_device_id rcar_rst_matches[] __initconst = { > - /* RZ/G is handled like R-Car Gen2 */ > + /* generic compatible strings */ > + { .compatible = "renesas,rcar-gen1-rst", .data = &rcar_rst_gen1 }, > + { .compatible = "renesas,rcar-gen2-rst", .data = &rcar_rst_gen2 }, > + { .compatible = "renesas,rcar-gen3-rst", .data = &rcar_rst_gen3 }, Usually we put generic compatible values at the bottom. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Fabrizio, On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > This patch allows for platform specific quirks as some of the SoC need > further customization for the watchdog to work properly, like for R-Car > Gen2 and for RZ/G. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Thanks for your patch! > --- a/drivers/soc/renesas/rcar-rst.c > +++ b/drivers/soc/renesas/rcar-rst.c > @@ -13,8 +13,18 @@ > #include <linux/of_address.h> > #include <linux/soc/renesas/rcar-rst.h> > > +#define WDTRSTCR_RESET 0xA55A0002 > +#define WDTRSTCR 0x0054 > + > +static int gen2_configuration(void __iomem *base) rcar_rst_enable_wdt_reset()? > +{ > + iowrite32(WDTRSTCR_RESET, base + WDTRSTCR); > + return 0; > +} > + > struct rst_config { > - unsigned int modemr; /* Mode Monitoring Register Offset */ > + unsigned int modemr; /* Mode Monitoring Register Offset */ > + int (*configure)(void *base); /* Platform specific configuration */ > }; > > static const struct rst_config rcar_rst_gen1 __initconst = { > @@ -23,6 +33,7 @@ static const struct rst_config rcar_rst_gen1 __initconst = { > > static const struct rst_config rcar_rst_gen2 __initconst = { > .modemr = 0x60, > + .configure = gen2_configuration, BTW, does it hurt to do this on R-Car Gen3, too? Instead of a function pointer, you could also just have a feature bit. > }; > > static const struct rst_config rcar_rst_gen3 __initconst = { > @@ -79,6 +90,14 @@ static int __init rcar_rst_init(void) > rcar_rst_base = base; > cfg = match->data; > saved_mode = ioread32(base + cfg->modemr); > + if (cfg->configure) { > + error = cfg->configure(base); > + if (error) { > + pr_warn("%pOF: Cannot run SoC specific configuration\n", > + np); > + goto out_put; > + } > + } > > pr_debug("%pOF: MODE = 0x%08x\n", np, saved_mode); Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro <fabrizio.castro@bp.renesas.com> wrote: > From now on, devices compatible with the generic compatible strings > documented by this commit don't need to modify the corresponding driver > anymore. > > Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> Thanks for your patch! >From commit 362922a1a5345d17 ("reset: Add renesas,rst DT bindings") As the features provided by the hardware module differ a lot across the various SoC families and members, only SoC-specific compatible values are defined. In fact the only commonalities are the presence of the MODEMR register (the mode bits differ), and the Watchdog Timer Reset Control Register. All other registers and bits depend on the SoC's CPU core configuration. Hence that's why I did not add generic compatible values. So unless you really need them (from this series, it looks like you don't?), I wouldn't add them. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org 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
Hi Fabrizio, On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > This commit documents the compatibility with R-Car Gen2 and RZ/G > devices by defining the generifc compatible string "renesas,rcar-gen2-wdt". generic + SoC-specific compatible values. > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > --- > Documentation/devicetree/bindings/watchdog/renesas-wdt.txt | 13 ++++++++----- > 1 file changed, 8 insertions(+), 5 deletions(-) > > diff --git a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt > index bf6d1ca..436dca5 100644 > --- a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt > +++ b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt > @@ -1,17 +1,20 @@ > Renesas Watchdog Timer (WDT) Controller > > Required properties: > -- compatible : Should be "renesas,<soctype>-wdt", and > - "renesas,rcar-gen3-wdt" or "renesas,rza-wdt" as fallback. > + - compatible : Must be "renesas,<soctype>-wdt", followed by a generic > + fallback compatible string when compatible with the generic > + version. > Examples with soctypes are: > + - "renesas,r8a7743-wdt" (RZ/G1M) > + - "renesas,r8a7745-wdt" (RZ/G1E) I guess you wanted to add r8a779[0-4], too, as you use (some of) them in later patches in this series? > - "renesas,r8a7795-wdt" (R-Car H3) > - "renesas,r8a7796-wdt" (R-Car M3-W) > - "renesas,r8a77995-wdt" (R-Car D3) > - "renesas,r7s72100-wdt" (RZ/A1) > + The generic compatible string must be: > + - "renesas,rcar-gen2-wdt" for R-Car Gen2 and RZ/G > + - "renesas,rcar-gen3-wdt" for R-Car Gen3 > > - When compatible with the generic version, nodes must list the SoC-specific > - version corresponding to the platform first, followed by the generic > - version. > > - reg : Should contain WDT registers location and length > - clocks : the clock feeding the watchdog timer. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
CC Wolfram
On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro
<fabrizio.castro@bp.renesas.com> wrote:
> This commit extends the driver to add restart support by implementing
> the restart callback to trigger the watchdog as quickly as possible.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
> ---
> drivers/watchdog/renesas_wdt.c | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c
> index 831ef83..120ddac 100644
> --- a/drivers/watchdog/renesas_wdt.c
> +++ b/drivers/watchdog/renesas_wdt.c
> @@ -107,6 +107,24 @@ static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev)
> return DIV_BY_CLKS_PER_SEC(priv, 65536 - val);
> }
>
> +static int rwdt_restart(struct watchdog_device *wdev, unsigned long action,
> + void *data)
> +{
> + struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
> +
> + pm_runtime_get_sync(wdev->parent);
> +
> + rwdt_write(priv, 0x00, RWTCSRB);
> + rwdt_write(priv, 0x00, RWTCSRA);
> + rwdt_write(priv, 0xffff, RWTCNT);
> +
> + while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG)
> + cpu_relax();
> +
> + rwdt_write(priv, 0x80, RWTCSRA);
> + return 0;
> +}
> +
> static const struct watchdog_info rwdt_ident = {
> .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
> .identity = "Renesas WDT Watchdog",
> @@ -118,6 +136,7 @@ static const struct watchdog_ops rwdt_ops = {
> .stop = rwdt_stop,
> .ping = rwdt_init_timeout,
> .get_timeleft = rwdt_get_timeleft,
> + .restart = rwdt_restart,
> };
>
> static int rwdt_probe(struct platform_device *pdev)
> --
> 2.7.4
Hi Fabrizio, On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > This patch exposes a function to set the value of variable > "shmobile_wdt_clock_status" so that the watchdog driver may communicate > critical information to the SMP bring up assembly routine. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Thanks for your patch, but this is the part I don't like, as it calls into deep platform code from a driver. Some generic comments below... > --- a/arch/arm/mach-shmobile/pm-rcar-gen2.c > +++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c > @@ -50,6 +50,16 @@ static inline u32 phys_to_sbar(phys_addr_t addr) > #define SYSCIER 0x0c > #define SYSCIMR 0x10 > > +static void __iomem *shmobile_boot_vector_start; > +static unsigned long clock_status; > + > +void shmobile_set_wdt_clock_status(unsigned long value) > +{ > + memcpy_toio(shmobile_boot_vector_start + clock_status, > + &value, sizeof(value)); writel(shmobile_boot_vector_start + clock_status, value)? > @@ -120,8 +130,12 @@ void __init rcar_gen2_pm_init(void) > if (!p) > return; > > + shmobile_boot_vector_start = p; > + clock_status = (&shmobile_wdt_clock_status - > + (unsigned long *)shmobile_boot_vector) * > + sizeof(shmobile_wdt_clock_status); clock_status = (unsigned long)shmobile_wdt_clock_status - (unsigned long)shmobile_boot_vector? > + > memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); > - iounmap(p); > > /* setup reset vectors */ > p = ioremap_nocache(RST, 0x63); Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Fabrizio, CC Wolfram On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro <fabrizio.castro@bp.renesas.com> wrote: > R-Car Gen2 (and RZ/G1) platforms need some tweaking for SMP and watchdog > to coexist nicely. > This new driver is based on top of Wolfram Sang's driver > (drivers/watchdog/renesas_wdt.c), and it contains the quirks necessary > for R-Car Gen2 and RZ/G1 to work properly and in harmony with the rest of > the system. In particular, the driver: Thanks for your patch! IMHO, having a unified driver would be better from a maintenance point of view. > * expects the device clock to be ON all the time, That can be handled in the driver, instead of through a critical clock. > * "pauses" the watchdog operation during suspend, and Isn't that needed in the original driver, too? > * "reassures" the SMP bringup function about the availability of the > watchdog registers. Through shmobile_set_wdt_clock_status(), which I don't like very much... Can this be handled differently? > Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> > --- > drivers/watchdog/Kconfig | 15 +- > drivers/watchdog/Makefile | 1 + > drivers/watchdog/renesas_wdt_gen2.c | 270 ++++++++++++++++++++++++++++++++++++ > drivers/watchdog/renesas_wdt_gen2.h | 22 +++ > 4 files changed, 306 insertions(+), 2 deletions(-) > create mode 100644 drivers/watchdog/renesas_wdt_gen2.c > create mode 100644 drivers/watchdog/renesas_wdt_gen2.h > > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig > index ca200d1..e580c72 100644 > --- a/drivers/watchdog/Kconfig > +++ b/drivers/watchdog/Kconfig > @@ -725,12 +725,23 @@ config ATLAS7_WATCHDOG > module will be called atlas7_wdt. > > config RENESAS_WDT > - tristate "Renesas WDT Watchdog" > + tristate "Renesas R-Car Gen3 WDT Watchdog" > depends on ARCH_RENESAS || COMPILE_TEST > select WATCHDOG_CORE > help > This driver adds watchdog support for the integrated watchdogs in the > - Renesas R-Car and other SH-Mobile SoCs (usually named RWDT or SWDT). > + Renesas R-Car Gen3 devices. > + > +config RENESAS_WDT_GEN2 > + tristate "Renesas R-Car Gen2 and RZ/G1 WDT Watchdog" > + depends on ARCH_RENESAS || COMPILE_TEST Note that compile-testing will fail if ARCH_RENESAS=n, due to the reference to shmobile_set_wdt_clock_status(). > + select WATCHDOG_CORE > + help > + This driver adds watchdog support for the integrated watchdogs in the > + Renesas R-Car Gen2 and RZ/G1 devices. > + > + To compile this driver as a module, choose M here: the > + module will be called renesas_wdt_gen2. > > config RENESAS_RZAWDT > tristate "Renesas RZ/A WDT Watchdog" > diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile > index 715a210..57ab810 100644 > --- a/drivers/watchdog/Makefile > +++ b/drivers/watchdog/Makefile > @@ -83,6 +83,7 @@ obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o > obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o > obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o > obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o > +obj-$(CONFIG_RENESAS_WDT_GEN2) += renesas_wdt_gen2.o > obj-$(CONFIG_RENESAS_RZAWDT) += rza_wdt.o > obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o > obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o > diff --git a/drivers/watchdog/renesas_wdt_gen2.c b/drivers/watchdog/renesas_wdt_gen2.c > new file mode 100644 > index 0000000..c841636 > --- /dev/null > +++ b/drivers/watchdog/renesas_wdt_gen2.c > @@ -0,0 +1,270 @@ > +/* > + * Watchdog driver for Renesas WDT watchdog > + * > + * Copyright (C) 2015-17 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com> > + * Copyright (C) 2018 Renesas Electronics Corporation > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License version 2 as published by > + * the Free Software Foundation. > + */ > +#include <linux/bitops.h> > +#include <linux/clk.h> > +#include <linux/io.h> > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/platform_device.h> > +#include <linux/pm_runtime.h> > +#include <linux/watchdog.h> > +#include "renesas_wdt_gen2.h" > + > +#define RWTCNT 0 > +#define RWTCSRA 4 > +#define RWTCSRA_WOVF BIT(4) > +#define RWTCSRA_WRFLG BIT(5) > +#define RWTCSRA_TME BIT(7) > +#define RWTCSRB 8 > + > +#define RWDT_DEFAULT_TIMEOUT 60U > + > +/* > + * In probe, clk_rate is checked to be not more than 16 bit * biggest clock > + * divider (12 bits). d is only a factor to fully utilize the WDT counter and > + * will not exceed its 16 bits. Thus, no overflow, we stay below 32 bits. > + */ > +#define MUL_BY_CLKS_PER_SEC(p, d) \ > + DIV_ROUND_UP((d) * (p)->clk_rate, clk_divs[(p)->cks]) > + > +/* d is 16 bit, clk_divs 12 bit -> no 32 bit overflow */ > +#define DIV_BY_CLKS_PER_SEC(p, d) ((d) * clk_divs[(p)->cks] / (p)->clk_rate) > + > +static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024, 4096 }; > + > +static bool nowayout = WATCHDOG_NOWAYOUT; > +module_param(nowayout, bool, 0); > +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" > + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); > + > +struct rwdt_priv { > + void __iomem *base; > + struct watchdog_device wdev; > + unsigned long clk_rate; > + bool enabled; > + u8 cks; > +}; > + > +static void rwdt_write(struct rwdt_priv *priv, u32 val, unsigned int reg) > +{ > + if (reg == RWTCNT) > + val |= 0x5a5a0000; > + else > + val |= 0xa5a5a500; > + > + writel_relaxed(val, priv->base + reg); > +} > + > +static int rwdt_init_timeout(struct watchdog_device *wdev) > +{ > + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > + > + rwdt_write(priv, 65536 - MUL_BY_CLKS_PER_SEC(priv, wdev->timeout), > + RWTCNT); > + > + return 0; > +} > + > +static int rwdt_start(struct watchdog_device *wdev) > +{ > + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > + > + rwdt_write(priv, 0, RWTCSRB); > + rwdt_write(priv, priv->cks, RWTCSRA); > + rwdt_init_timeout(wdev); > + > + while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) > + cpu_relax(); > + > + rwdt_write(priv, priv->cks | RWTCSRA_TME, RWTCSRA); > + > + return 0; > +} > + > +static int rwdt_stop(struct watchdog_device *wdev) > +{ > + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > + > + rwdt_write(priv, priv->cks, RWTCSRA); > + > + return 0; > +} > + > +static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) > +{ > + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > + u16 val = readw_relaxed(priv->base + RWTCNT); > + > + return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); > +} > + > +static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, > + void *data) > +{ > + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > + > + rwdt_write(priv, 0x00, RWTCSRB); > + rwdt_write(priv, 0x00, RWTCSRA); > + rwdt_write(priv, 0xffff, RWTCNT); > + > + while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) > + cpu_relax(); > + > + rwdt_write(priv, 0x80, RWTCSRA); > + return 0; > +} > + > +static const struct watchdog_info rwdt_ident = { > + .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, > + .identity = "Renesas WDT Watchdog", > +}; > + > +static const struct watchdog_ops rwdt_ops = { > + .owner = THIS_MODULE, > + .start = rwdt_start, > + .stop = rwdt_stop, > + .ping = rwdt_init_timeout, > + .get_timeleft = rwdt_get_timeleft, > + .restart = rwdt_restart, > +}; > + > +static int rwdt_probe(struct platform_device *pdev) > +{ > + struct rwdt_priv *priv; > + struct resource *res; > + struct clk *clk; > + unsigned long clks_per_sec; > + int ret, i; > + > + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + priv->base = devm_ioremap_resource(&pdev->dev, res); > + if (IS_ERR(priv->base)) > + return PTR_ERR(priv->base); > + > + clk = devm_clk_get(&pdev->dev, NULL); > + if (IS_ERR(clk)) > + return PTR_ERR(clk); > + > + > + priv->clk_rate = clk_get_rate(clk); > + > + if (!priv->clk_rate) > + return -ENOENT; > + > + for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { > + clks_per_sec = priv->clk_rate / clk_divs[i]; > + if (clks_per_sec && clks_per_sec < 65536) { > + priv->cks = i; > + break; > + } > + } > + > + if (i < 0) { > + dev_err(&pdev->dev, "Can't find suitable clock divider\n"); > + return -ERANGE; > + } > + > + priv->wdev.info = &rwdt_ident, > + priv->wdev.ops = &rwdt_ops, > + priv->wdev.parent = &pdev->dev; > + priv->wdev.min_timeout = 1; > + priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536); > + priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT); > + > + platform_set_drvdata(pdev, priv); > + watchdog_set_drvdata(&priv->wdev, priv); > + watchdog_set_nowayout(&priv->wdev, nowayout); > + > + ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev); > + if (ret) > + dev_warn(&pdev->dev, > + "Specified timeout value invalid, using default\n"); > + shmobile_set_wdt_clock_status(RWDT_CLOCK_ON); > + > + ret = watchdog_register_device(&priv->wdev); > + return ret; > +} > + > +static int rwdt_remove(struct platform_device *pdev) > +{ > + struct rwdt_priv *priv = platform_get_drvdata(pdev); > + > + watchdog_unregister_device(&priv->wdev); > + > + return 0; > +} > + > +#ifdef CONFIG_PM > +static int rwdt_suspend(struct device *dev) > +{ > + struct platform_device *pdev; > + struct rwdt_priv *priv; > + u8 val; > + > + pdev = to_platform_device(dev); > + priv = platform_get_drvdata(pdev); > + val = readb_relaxed(priv->base + RWTCSRA); > + if (val & RWTCSRA_TME) { > + priv->enabled = true; > + rwdt_write(priv, val & ~RWTCSRA_TME, RWTCSRA); > + } else { > + priv->enabled = false; > + } > + return 0; > +} > + > +static int rwdt_resume(struct device *dev) > +{ > + struct platform_device *pdev; > + struct rwdt_priv *priv; > + u8 val; > + > + pdev = to_platform_device(dev); > + priv = platform_get_drvdata(pdev); > + if (priv->enabled) { > + val = readb_relaxed(priv->base + RWTCSRA); > + rwdt_write(priv, val | RWTCSRA_TME, RWTCSRA); > + } > + return 0; > +} > + > +static const struct dev_pm_ops rwdt_pm = { > + .suspend = rwdt_suspend, > + .resume = rwdt_resume, > +}; > +#endif > + > +static const struct of_device_id rwdt_ids[] = { > + { .compatible = "renesas,rcar-gen2-wdt", }, > + { /* sentinel */ } > +}; > +MODULE_DEVICE_TABLE(of, rwdt_ids); > + > +static struct platform_driver rwdt_driver = { > + .driver = { > + .name = "renesas_wdt_gen2", > + .of_match_table = rwdt_ids, > +#ifdef CONFIG_PM > + .pm = &rwdt_pm, > +#endif > + }, > + .probe = rwdt_probe, > + .remove = rwdt_remove, > +}; > +module_platform_driver(rwdt_driver); > + > +MODULE_DESCRIPTION("Renesas R-Car Gen2 Watchdog Driver"); > +MODULE_LICENSE("GPL v2"); > +MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro@bp.renesas.com>"); > diff --git a/drivers/watchdog/renesas_wdt_gen2.h b/drivers/watchdog/renesas_wdt_gen2.h > new file mode 100644 > index 0000000..41b9e9c > --- /dev/null > +++ b/drivers/watchdog/renesas_wdt_gen2.h > @@ -0,0 +1,22 @@ > +/* > + * drivers/watchdog/renesas_wdt_gen2.h > + * > + * Copyright (C) 2018 Renesas Electronics Corporation > + * > + * R-Car Gen2 and RZ/G specific symbols > + * > + * 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 > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + */ > + > +#ifndef RENESAS_WDT_GEN2_H > +#define RENESAS_WDT_GEN2_H > + > +#define RWDT_CLOCK_ON 0xdeadbeef > +#define RWDT_CLOCK_OFF 0x00000000 > + > +extern void shmobile_set_wdt_clock_status(unsigned long value); > + > +#endif /* RENESAS_WDT_GEN2_H */ > -- > 2.7.4
Hi Fabrizio, On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro <fabrizio.castro@bp.renesas.com> wrote: > Add "rwdt" clock to r8a7745_mod_clks. Also, since we may need to access > the watchdog registers at any time, declare the clock as critical. > > Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> With the critical clock handling removed (that can be done by the driver, if really needed) Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > --- a/drivers/clk/renesas/r8a7745-cpg-mssr.c > +++ b/drivers/clk/renesas/r8a7745-cpg-mssr.c > @@ -114,6 +114,7 @@ static const struct mssr_mod_clk r8a7745_mod_clks[] __initconst = { > DEF_MOD("cmt1", 329, R8A7745_CLK_R), > DEF_MOD("usbhs-dmac0", 330, R8A7745_CLK_HP), > DEF_MOD("usbhs-dmac1", 331, R8A7745_CLK_HP), > + DEF_MOD("rwdt", 402, R8A7745_CLK_R), > DEF_MOD("irqc", 407, R8A7745_CLK_CP), > DEF_MOD("intc-sys", 408, R8A7745_CLK_ZS), > DEF_MOD("audio-dmac0", 502, R8A7745_CLK_HP), > @@ -180,6 +181,7 @@ static const struct mssr_mod_clk r8a7745_mod_clks[] __initconst = { > }; > > static const unsigned int r8a7745_crit_mod_clks[] __initconst = { > + MOD_CLK_ID(402), /* RWDT */ > MOD_CLK_ID(408), /* INTC-SYS (GIC) */ > }; Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org 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
On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > Add "rwdt" clock to r8a7790_mod_clks. Also, since we may need to access > the watchdog registers at any time, declare the clock as critical. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> With the critical clock handling removed (that can be done by the driver, if really needed) Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> > --- a/drivers/clk/renesas/r8a7790-cpg-mssr.c > +++ b/drivers/clk/renesas/r8a7790-cpg-mssr.c > @@ -140,6 +140,7 @@ static const struct mssr_mod_clk r8a7790_mod_clks[] __initconst = { > DEF_MOD("cmt1", 329, R8A7790_CLK_R), > DEF_MOD("usbhs-dmac0", 330, R8A7790_CLK_HP), > DEF_MOD("usbhs-dmac1", 331, R8A7790_CLK_HP), > + DEF_MOD("rwdt", 402, R8A7790_CLK_R), > DEF_MOD("irqc", 407, R8A7790_CLK_CP), > DEF_MOD("intc-sys", 408, R8A7790_CLK_ZS), > DEF_MOD("audio-dmac1", 501, R8A7790_CLK_HP), > @@ -211,6 +212,7 @@ static const struct mssr_mod_clk r8a7790_mod_clks[] __initconst = { > }; > > static const unsigned int r8a7790_crit_mod_clks[] __initconst = { > + MOD_CLK_ID(402), /* RWDT */ > MOD_CLK_ID(408), /* INTC-SYS (GIC) */ > }; Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > Add "rwdt" clock to r8a7791_mod_clks. Also, since we may need to access > the watchdog registers at any time, declare the clock as critical. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> With the critical clock handling removed (that can be done by the driver, if really needed) Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> > --- a/drivers/clk/renesas/r8a7791-cpg-mssr.c > +++ b/drivers/clk/renesas/r8a7791-cpg-mssr.c > @@ -128,6 +128,7 @@ static const struct mssr_mod_clk r8a7791_mod_clks[] __initconst = { > DEF_MOD("cmt1", 329, R8A7791_CLK_R), > DEF_MOD("usbhs-dmac0", 330, R8A7791_CLK_HP), > DEF_MOD("usbhs-dmac1", 331, R8A7791_CLK_HP), > + DEF_MOD("rwdt", 402, R8A7791_CLK_R), > DEF_MOD("irqc", 407, R8A7791_CLK_CP), > DEF_MOD("intc-sys", 408, R8A7791_CLK_ZS), > DEF_MOD("audio-dmac1", 501, R8A7791_CLK_HP), > @@ -209,6 +210,7 @@ static const struct mssr_mod_clk r8a7791_mod_clks[] __initconst = { > }; > > static const unsigned int r8a7791_crit_mod_clks[] __initconst = { > + MOD_CLK_ID(402), /* RWDT */ > MOD_CLK_ID(408), /* INTC-SYS (GIC) */ > }; Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > Add "rwdt" clock to r8a7794_mod_clks. Also, since we may need to access > the watchdog registers at any time, declare the clock as critical. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> With the critical clock handling removed (that can be done by the driver, if really needed) Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> > --- a/drivers/clk/renesas/r8a7794-cpg-mssr.c > +++ b/drivers/clk/renesas/r8a7794-cpg-mssr.c > @@ -121,6 +121,7 @@ static const struct mssr_mod_clk r8a7794_mod_clks[] __initconst = { > DEF_MOD("cmt1", 329, R8A7794_CLK_R), > DEF_MOD("usbhs-dmac0", 330, R8A7794_CLK_HP), > DEF_MOD("usbhs-dmac1", 331, R8A7794_CLK_HP), > + DEF_MOD("rwdt", 402, R8A7794_CLK_R), > DEF_MOD("irqc", 407, R8A7794_CLK_CP), > DEF_MOD("intc-sys", 408, R8A7794_CLK_ZS), > DEF_MOD("audio-dmac0", 502, R8A7794_CLK_HP), > @@ -190,6 +191,7 @@ static const struct mssr_mod_clk r8a7794_mod_clks[] __initconst = { > }; > > static const unsigned int r8a7794_crit_mod_clks[] __initconst = { > + MOD_CLK_ID(402), /* RWDT */ > MOD_CLK_ID(408), /* INTC-SYS (GIC) */ > }; Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro
<fabrizio.castro@bp.renesas.com> wrote:
> This patch adds watchdog support to the r8a7743 SoC dtsi.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
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
On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro
<fabrizio.castro@bp.renesas.com> wrote:
> This patch adds watchdog support to the r8a7745 SoC dtsi.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
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
On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro
<fabrizio.castro@bp.renesas.com> wrote:
> This commit adds watchdog support to the r8a7790 dtsi.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
If inserted before gpio@e6050000:
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
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
On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > This commit adds watchdog support to the r8a7791 dtsi. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> If inserted before gpio@e6050000: Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > This commit adds watchdog support to the r8a7794 dtsi. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> If inserted before gpio@e6050000: Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > This patch enables the watchdog from within the iwg20m SoM dtsi. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> wrote: > This patch enables the watchdog from within the iwg20m SoM dtsi. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org 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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 7:03 PM, Fabrizio Castro
<fabrizio.castro@bp.renesas.com> wrote:
> Add "rwdt" clock to r8a7743_mod_clks. Also, since we may need to access
> the watchdog registers at any time, declare the clock as critical.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
With the critical clock handling removed (that can be done by the driver,
if really needed)
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
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
Hello Geert, > Subject: Re: [RFC 01/37] ARM: shmobile: Add watchdog support > > Hi Fabrizio, > > On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro > <fabrizio.castro@bp.renesas.com> wrote: > > On R-Car Gen2 and RZ/G1 platforms, we use the SBAR registers to make non > > boot CPUs run a routine designed to bring up SMP and deal with hot plug. > > The value contained in the SBAR registers is not initialized by a WDT > > triggered reset, which means that after a WDT triggered reset we jump > > to the SMP bring up routine, preventing the system from executing the > > bootrom code. > > Thanks for your patch! Thank you for looking into this! I am not going to reply to your comments on the other patches for now, as we need to find a solution for this particular patch we are all happy with first. A change to this patch may impact the other patches as well. > > > The purpose of this patch is to jump to the bootrom code in case of a > > WDT triggered reset, and keep the SMP functionality untouched. > > In order to tell if the code had been called due to the WDT overflowing > > we need to inspect flag WOVF from register RWTCSRA, however for this > > to work smoothly we need to make sure that RWDT clock is ON. > > Since it's not wise to interfere with the clock configuration from > > within this routine, a flag has been put in place > > (shmobile_wdt_clock_status) so that the watchdog driver can tell > > shmobile_boot_vector when the clock is ON, and therefore there is no > > need for shmobile_boot_vector to mess up with the clock registers. > > > > Bit WOVF survives a watchdog triggered reset, and it is usually cleared > > by the bootloader. Checking the MMU enable bit from register SCTLR > > allows us to make the code a little bit more robust (just in case the > > bit wasn't cleared up), as right after a reset the MMU is disabled, > > and when Linux is running the MMU is enabled. Also, accessing RWTCSRA > > physical address is safe when the MMU is down. > > Checking a hardware register is indeed a better solution than my original > idea to let SMP bringup set a flag in RAM, as the former is less racy. Also, such a flag would not be accessible after the reset gets triggered. > However, as you can probably imagine, I don't like the > shmobile_wdt_clock_status part ;-) Neither do I! :-D > > Isn't is sufficient to check the MMU enable bit? I am afraid it isn't, when bringing up SMP the cores will read the MMU flag as disabled, to make things worse at that precise point in time the rwdt clock is disabled. If the system just restarted due to the watchdog, then when you read WOVF chances are you are going to read '1', hence the system will fail to bring up SMP. > However, that would precludes uClinux (do we care?). The MMU will be constantly disabled in this case, wouldn't it? Therefore the reset vector will always proceed with the testing of variable "shmobile_wdt_clock_status", and it'll finally test WOVF only when it's safe to do so. If WOVF is set, then we still jump to the bootrom code. if WOVF is not set, then we jump to shmobile_boot_fn. Could you please elaborate your thoughts a little bit more? > Is there any other register/bit that's reset when the watchdog is > triggered, and always set by Linux? Not that I know of, but you may know better ;-P Any suggestion? > > > SMP bringup, CPU hot plug, and suspend to RAM work as normal. > > shmobile_boot_vector is not only used for R-Car Gen2 and RZ/G1 SoCs, but > also for EMMA Mobile, SH/R-Mobile, and R-Car H1. Hence this breaks SMP > for the latter (and their build if ARCH_RENESAS=n, due to missing > shmobile_wdt_clock_status). As per your suggestion, I am ignoring this. > > > Since shmobile_boot_vector has become bigger, "reg" property of nodes > > compatible with "renesas,smp-sram" now need to be set to "<0 0x64>". > > This breaks backwards compatibility with old DTs declaring a too small > smp-sram area. If the area is too small, you should fallback to the old and > smaller code. Good point. I'll look into this. Thanks, Fab > > > --- a/arch/arm/mach-shmobile/headsmp.S > > +++ b/arch/arm/mach-shmobile/headsmp.S > > @@ -16,6 +16,13 @@ > > #include <asm/assembler.h> > > #include <asm/memory.h> > > > > +#define RWDT_CLOCK_ON 0xdeadbeef > > +#define RWDT_CLOCK_OFF 0x00000000 > > +#define SCTLR_MMU 0x01 > > +#define BOOTROM_ADDRESS 0xE6340000 > > +#define RWTCSRA_ADDRESS 0xE6020004 > > +#define RWTCSRA_WOVF 0x10 > > + > > /* > > * Reset vector for secondary CPUs. > > * This will be mapped at address 0 by SBAR register. > > @@ -24,11 +31,57 @@ > > .arm > > .align 12 > > ENTRY(shmobile_boot_vector) > > This should become e.g. rcar_gen2_boot_vector_wdt > > > +/* > > + if (SCTLR_MMU == 1) > > + goto shmobile_smp_continue; > > +*/ > > + mrc p15, 0, r1, c1, c0, 0 @ r1 = SCTLR > > + and r0, r1, #SCTLR_MMU > > + cmp r0, #SCTLR_MMU > > + beq shmobile_smp_continue > > +/* > > + if (shmobile_wdt_clock_status != RWDT_CLOCK_ON) > > + goto shmobile_smp_continue; > > +*/ > > + ldr r0, #shmobile_wdt_clock_status > > + ldr r1, #clock_on > > + cmp r0, r1 > > + bne shmobile_smp_continue > > + > > +/* > > + if (RWTCSRA_WOVF == 0) > > + goto shmobile_smp_continue; > > +*/ > > + ldr r0, rwtcsra > > + mov r1, #0 > > + ldrb r1, [r0] > > + and r0, r1, #RWTCSRA_WOVF > > + cmp r0, #RWTCSRA_WOVF > > + bne shmobile_smp_continue > > + > > +/* > > + goto bootrom; > > +*/ > > + ldr r0, bootrom > > + bx r0 > > + > > +shmobile_smp_continue: > > This should become > > ENTRY(shmobile_boot_vector) > > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org > > 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 Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered No. 04586709.
Hi Fabrizio, On Fri, Jan 26, 2018 at 12:52 PM, Fabrizio Castro <fabrizio.castro@bp.renesas.com> wrote: >> Subject: Re: [RFC 01/37] ARM: shmobile: Add watchdog support >> On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro >> <fabrizio.castro@bp.renesas.com> wrote: >> > On R-Car Gen2 and RZ/G1 platforms, we use the SBAR registers to make non >> > boot CPUs run a routine designed to bring up SMP and deal with hot plug. >> > The value contained in the SBAR registers is not initialized by a WDT >> > triggered reset, which means that after a WDT triggered reset we jump >> > to the SMP bring up routine, preventing the system from executing the >> > bootrom code. >> >> Thanks for your patch! > > Thank you for looking into this! > > I am not going to reply to your comments on the other patches for now, as we need to find a solution for this particular patch we are all happy with first. > A change to this patch may impact the other patches as well. > >> > The purpose of this patch is to jump to the bootrom code in case of a >> > WDT triggered reset, and keep the SMP functionality untouched. >> > In order to tell if the code had been called due to the WDT overflowing >> > we need to inspect flag WOVF from register RWTCSRA, however for this >> > to work smoothly we need to make sure that RWDT clock is ON. >> > Since it's not wise to interfere with the clock configuration from >> > within this routine, a flag has been put in place >> > (shmobile_wdt_clock_status) so that the watchdog driver can tell >> > shmobile_boot_vector when the clock is ON, and therefore there is no >> > need for shmobile_boot_vector to mess up with the clock registers. >> > >> > Bit WOVF survives a watchdog triggered reset, and it is usually cleared >> > by the bootloader. Checking the MMU enable bit from register SCTLR >> > allows us to make the code a little bit more robust (just in case the >> > bit wasn't cleared up), as right after a reset the MMU is disabled, >> > and when Linux is running the MMU is enabled. Also, accessing RWTCSRA >> > physical address is safe when the MMU is down. >> >> Checking a hardware register is indeed a better solution than my original >> idea to let SMP bringup set a flag in RAM, as the former is less racy. > > Also, such a flag would not be accessible after the reset gets triggered. It would, if it's stored in e.g. ICRAM. >> However, as you can probably imagine, I don't like the >> shmobile_wdt_clock_status part ;-) > > Neither do I! :-D Good ;-) >> Isn't is sufficient to check the MMU enable bit? > > I am afraid it isn't, when bringing up SMP the cores will read the MMU flag as disabled, to make things worse at that precise point in time the rwdt clock is disabled. > If the system just restarted due to the watchdog, then when you read WOVF chances are you are going to read '1', hence the system will fail to bring up SMP. OK, so I was mislead by the MMU check. >> However, that would precludes uClinux (do we care?). > > The MMU will be constantly disabled in this case, wouldn't it? Therefore the reset vector will always proceed with the testing of variable "shmobile_wdt_clock_status", and it'll finally test WOVF only when it's safe to do so. If WOVF is set, then we still jump to the bootrom code. if WOVF is not set, then we jump to shmobile_boot_fn. Could you please elaborate your thoughts a little bit more? > >> Is there any other register/bit that's reset when the watchdog is >> triggered, and always set by Linux? > > Not that I know of, but you may know better ;-P > Any suggestion? Any chance WDTRSTCR.RWDT_RSTMSK is reinitialized to 1 on watchdog reset? Probably not, as the Hardware User's Manual says the register is initialized on power on reset caused by PRESET#. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org 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
Hello Geert, > Subject: Re: [RFC 01/37] ARM: shmobile: Add watchdog support > > Hi Fabrizio, > > On Fri, Jan 26, 2018 at 12:52 PM, Fabrizio Castro > <fabrizio.castro@bp.renesas.com> wrote: > >> Subject: Re: [RFC 01/37] ARM: shmobile: Add watchdog support > >> On Thu, Jan 25, 2018 at 7:02 PM, Fabrizio Castro > >> <fabrizio.castro@bp.renesas.com> wrote: > >> > On R-Car Gen2 and RZ/G1 platforms, we use the SBAR registers to make non > >> > boot CPUs run a routine designed to bring up SMP and deal with hot plug. > >> > The value contained in the SBAR registers is not initialized by a WDT > >> > triggered reset, which means that after a WDT triggered reset we jump > >> > to the SMP bring up routine, preventing the system from executing the > >> > bootrom code. > >> > >> Thanks for your patch! > > > > Thank you for looking into this! > > > > I am not going to reply to your comments on the other patches for now, as we need to find a solution for this particular patch we are > all happy with first. > > A change to this patch may impact the other patches as well. > > > >> > The purpose of this patch is to jump to the bootrom code in case of a > >> > WDT triggered reset, and keep the SMP functionality untouched. > >> > In order to tell if the code had been called due to the WDT overflowing > >> > we need to inspect flag WOVF from register RWTCSRA, however for this > >> > to work smoothly we need to make sure that RWDT clock is ON. > >> > Since it's not wise to interfere with the clock configuration from > >> > within this routine, a flag has been put in place > >> > (shmobile_wdt_clock_status) so that the watchdog driver can tell > >> > shmobile_boot_vector when the clock is ON, and therefore there is no > >> > need for shmobile_boot_vector to mess up with the clock registers. > >> > > >> > Bit WOVF survives a watchdog triggered reset, and it is usually cleared > >> > by the bootloader. Checking the MMU enable bit from register SCTLR > >> > allows us to make the code a little bit more robust (just in case the > >> > bit wasn't cleared up), as right after a reset the MMU is disabled, > >> > and when Linux is running the MMU is enabled. Also, accessing RWTCSRA > >> > physical address is safe when the MMU is down. > >> > >> Checking a hardware register is indeed a better solution than my original > >> idea to let SMP bringup set a flag in RAM, as the former is less racy. > > > > Also, such a flag would not be accessible after the reset gets triggered. > > It would, if it's stored in e.g. ICRAM. Yes, of course. It reminds me of shmobile_wdt_clock_status... :-D > > >> However, as you can probably imagine, I don't like the > >> shmobile_wdt_clock_status part ;-) > > > > Neither do I! :-D > > Good ;-) > > >> Isn't is sufficient to check the MMU enable bit? > > > > I am afraid it isn't, when bringing up SMP the cores will read the MMU flag as disabled, to make things worse at that precise point in > time the rwdt clock is disabled. > > If the system just restarted due to the watchdog, then when you read WOVF chances are you are going to read '1', hence the > system will fail to bring up SMP. > > OK, so I was mislead by the MMU check. > > >> However, that would precludes uClinux (do we care?). > > > > The MMU will be constantly disabled in this case, wouldn't it? Therefore the reset vector will always proceed with the testing of > variable "shmobile_wdt_clock_status", and it'll finally test WOVF only when it's safe to do so. If WOVF is set, then we still jump to the > bootrom code. if WOVF is not set, then we jump to shmobile_boot_fn. Could you please elaborate your thoughts a little bit more? > > > >> Is there any other register/bit that's reset when the watchdog is > >> triggered, and always set by Linux? > > > > Not that I know of, but you may know better ;-P > > Any suggestion? > > Any chance WDTRSTCR.RWDT_RSTMSK is reinitialized to 1 on watchdog reset? > Probably not, as the Hardware User's Manual says the register is > initialized on power on reset caused by PRESET#. I think its value is retained, as you pointed out. So basically, I still think testing WOVF is the best way to tell if we jumped into the reset vector because of a watchdog triggered reset, or because of SMP. We "just" need to guarantee we read from RWTCSRA when it's safe to do so. Can you think of any other alternative to the flag in ICRAM1 to achieve this safely? Thanks, Fab > > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org > > 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 Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered No. 04586709.
On R-Car Gen2 and RZ/G1 platforms, we use the SBAR registers to make non boot CPUs run a routine designed to bring up SMP and deal with hot plug. The value contained in the SBAR registers is not initialized by a WDT triggered reset, which means that after a WDT triggered reset we jump to the SMP bring up routine, preventing the system from executing the bootrom code. The purpose of this patch is to jump to the bootrom code in case of a WDT triggered reset, and keep the SMP functionality untouched. In order to tell if the code had been called due to the WDT overflowing we need to inspect flag WOVF from register RWTCSRA, however for this to work smoothly we need to make sure that RWDT clock is ON. Since it's not wise to interfere with the clock configuration from within this routine, a flag has been put in place (shmobile_wdt_clock_status) so that the watchdog driver can tell shmobile_boot_vector_gen2 when the clock is ON, and therefore there is no need for shmobile_boot_vector to mess up with the clock registers. Bit WOVF survives a watchdog triggered reset, and it is usually cleared by the bootloader. Checking the MMU enable bit from register SCTLR allows us to make the code a little bit more robust (just in case the bit wasn't cleared up), as right after a reset the MMU is disabled, and when Linux is running the MMU is enabled. Also, accessing RWTCSRA physical address is safe when the MMU is down. New function shmobile_boot_vector_gen2 isn't replacing shmobile_boot_vector for backward compatibility reasons. The kernel will install the best option (either shmobile_boot_vector or shmobile_boot_vector_gen2) to ICRAM1 after parsing the device tree. SMP bringup, CPU hot plug, and suspend to RAM work as normal. Since shmobile_boot_vector has become bigger, "reg" property of nodes compatible with "renesas,smp-sram" now need to be set to "<0 0x64>". Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/mach-shmobile/headsmp.S | 74 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S index 32e0bf6..4b14d4c 100644 --- a/arch/arm/mach-shmobile/headsmp.S +++ b/arch/arm/mach-shmobile/headsmp.S @@ -16,6 +16,13 @@ #include <asm/assembler.h> #include <asm/memory.h> +#define RWDT_CLOCK_ON 0xdeadbeef +#define RWDT_CLOCK_OFF 0x00000000 +#define SCTLR_MMU 0x01 +#define BOOTROM_ADDRESS 0xE6340000 +#define RWTCSRA_ADDRESS 0xE6020004 +#define RWTCSRA_WOVF 0x10 + /* * Reset vector for secondary CPUs. * This will be mapped at address 0 by SBAR register. @@ -37,6 +44,73 @@ shmobile_boot_fn: shmobile_boot_size: .long . - shmobile_boot_vector +#ifdef CONFIG_ARCH_RCAR_GEN2 +/* + * Reset vector for R-Car Gen2 and RZ/G1 secondary CPUs. + * This will be mapped at address 0 by SBAR register. + */ +ENTRY(shmobile_boot_vector_gen2) +/* + if (SCTLR_MMU == 1) + goto shmobile_smp_continue_gen2; +*/ + mrc p15, 0, r1, c1, c0, 0 @ r1 = SCTLR + and r0, r1, #SCTLR_MMU + cmp r0, #SCTLR_MMU + beq shmobile_smp_continue_gen2 + +/* + if (shmobile_wdt_clock_status != RWDT_CLOCK_ON) + goto shmobile_smp_continue_gen2; +*/ + ldr r0, #shmobile_wdt_clock_status + ldr r1, #clock_on + cmp r0, r1 + bne shmobile_smp_continue_gen2 + +/* + if (RWTCSRA_WOVF == 0) + goto shmobile_smp_continue_gen2; +*/ + ldr r0, rwtcsra + mov r1, #0 + ldrb r1, [r0] + and r0, r1, #RWTCSRA_WOVF + cmp r0, #RWTCSRA_WOVF + bne shmobile_smp_continue_gen2 + +/* + goto bootrom; +*/ + ldr r0, bootrom + bx r0 + +shmobile_smp_continue_gen2: + ldr r1, shmobile_boot_fn_gen2 + bx r1 + +ENDPROC(shmobile_boot_vector_gen2) + + .align 4 +rwtcsra: + .word RWTCSRA_ADDRESS +bootrom: + .word BOOTROM_ADDRESS +clock_on: + .word RWDT_CLOCK_ON + .globl shmobile_wdt_clock_status +shmobile_wdt_clock_status: + .word RWDT_CLOCK_OFF + + .align 2 + .globl shmobile_boot_fn_gen2 +shmobile_boot_fn_gen2: + .space 4 + .globl shmobile_boot_size_gen2 +shmobile_boot_size_gen2: + .long . - shmobile_boot_vector_gen2 +#endif /* CONFIG_ARCH_RCAR_GEN2 */ + /* * Per-CPU SMP boot function/argument selection code based on MPIDR */ -- 2.7.4
This patch exposes a function to set the value of variable "shmobile_wdt_clock_status" so that the watchdog driver may communicate critical information to the SMP bring up assembly routine. Also, the new code provided by this commit decides which version of the boot vector to install to ICRAM1, and that depends on the size of the memory region available for this purpose. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> --- arch/arm/mach-shmobile/common.h | 6 ++++++ arch/arm/mach-shmobile/platsmp-apmu.c | 1 + arch/arm/mach-shmobile/pm-rcar-gen2.c | 25 +++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index a8fa4f7..88d3c1b 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h @@ -7,6 +7,12 @@ extern void shmobile_init_delay(void); extern void shmobile_boot_vector(void); extern unsigned long shmobile_boot_fn; extern unsigned long shmobile_boot_size; +#ifdef CONFIG_ARCH_RCAR_GEN2 +extern void shmobile_boot_vector_gen2(void); +extern unsigned long shmobile_boot_fn_gen2; +extern unsigned long shmobile_boot_size_gen2; +extern unsigned long shmobile_wdt_clock_status; +#endif /* CONFIG_ARCH_RCAR_GEN2 */ extern void shmobile_smp_boot(void); extern void shmobile_smp_sleep(void); extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c index 4422b61..ba732ef 100644 --- a/arch/arm/mach-shmobile/platsmp-apmu.c +++ b/arch/arm/mach-shmobile/platsmp-apmu.c @@ -191,6 +191,7 @@ static void __init shmobile_smp_apmu_setup_boot(void) { /* install boot code shared by all CPUs */ shmobile_boot_fn = __pa_symbol(shmobile_smp_boot); + shmobile_boot_fn_gen2 = shmobile_boot_fn; } void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus, diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c index e5f215c..7158d05 100644 --- a/arch/arm/mach-shmobile/pm-rcar-gen2.c +++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c @@ -50,6 +50,18 @@ static inline u32 phys_to_sbar(phys_addr_t addr) #define SYSCIER 0x0c #define SYSCIMR 0x10 +static void __iomem *shmobile_boot_vector_gen2_start = NULL; +static unsigned long clock_status; + +void shmobile_set_wdt_clock_status(unsigned long value) +{ + if (!shmobile_boot_vector_gen2_start) + return; + memcpy_toio(shmobile_boot_vector_gen2_start + clock_status, + &value, sizeof(value)); +} +EXPORT_SYMBOL(shmobile_set_wdt_clock_status); + #if defined(CONFIG_SMP) static void __init rcar_gen2_sysc_init(u32 syscier) @@ -120,8 +132,17 @@ void __init rcar_gen2_pm_init(void) if (!p) return; - memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); - iounmap(p); + if (resource_size(&res) >= shmobile_boot_size_gen2) { + memcpy_toio(p, shmobile_boot_vector_gen2, + shmobile_boot_size_gen2); + shmobile_boot_vector_gen2_start = p; + clock_status = (&shmobile_wdt_clock_status - + (unsigned long *)shmobile_boot_vector_gen2) * + sizeof(shmobile_wdt_clock_status); + } else { + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); + } + /* setup reset vectors */ p = ioremap_nocache(RST, 0x63); -- 2.7.4
Hello Geert, >> Since shmobile_boot_vector has become bigger, "reg" property of nodes >> compatible with "renesas,smp-sram" now need to be set to "<0 0x64>". > This breaks backwards compatibility with old DTs declaring a too small > smp-sram area. If the area is too small, you should fallback to the old and > smaller code. would the v2s for patches 01/37 and 23/37 be ok with you to take care of that issue? Thanks, Fabrizio Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered No. 04586709. -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hello Sergei, thank you for your feedback. > Subject: Re: [RFC 10/37] soc: renesas: rcar-rst: Enable watchdog as reset trigger for Gen2 > > Hello! > > On 1/25/2018 9:02 PM, Fabrizio Castro wrote: > > > This patch allows for platform specific quirks as some of the SoC need > > further customization for the watchdog to work properly, like for R-Car > > Gen2 and for RZ/G. > > > > Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> > > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> > > --- > > drivers/soc/renesas/rcar-rst.c | 21 ++++++++++++++++++++- > > 1 file changed, 20 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c > > index f7a0d54..5f52aea 100644 > > --- a/drivers/soc/renesas/rcar-rst.c > > +++ b/drivers/soc/renesas/rcar-rst.c > > @@ -13,8 +13,18 @@ > > #include <linux/of_address.h> > > #include <linux/soc/renesas/rcar-rst.h> > > > > +#define WDTRSTCR_RESET0xA55A0002 > > +#define WDTRSTCR0x0054 > > + > > +static int gen2_configuration(void __iomem *base) > > +{ > > +iowrite32(WDTRSTCR_RESET, base + WDTRSTCR); > > +return 0; > > +} > > + > > struct rst_config { > > -unsigned int modemr;/* Mode Monitoring Register Offset */ > > +unsigned int modemr;/* Mode Monitoring Register Offset */ > > +int (*configure)(void *base);/* Platform specific configuration */ > > }; > > > > static const struct rst_config rcar_rst_gen1 __initconst = { > > @@ -23,6 +33,7 @@ static const struct rst_config rcar_rst_gen1 __initconst = { > > > > static const struct rst_config rcar_rst_gen2 __initconst = { > > .modemr = 0x60, > > +.configure = gen2_configuration, > > Why not call the method gen2_configure() then? Yeah, the name gen2_configuration isn't great! As you may have noticed already, Geert suggested rcar_rst_enable_wdt_reset. I am definitely going to change it (if I am keeping the function pointer at all!), expect to see another version of this patch in the next few days to address this. Thanks, Fab > > [...] > > MBR, Sergei Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered No. 04586709.
On Thu, Jan 25, 2018 at 06:02:56PM +0000, Fabrizio Castro wrote: > This commit extends the driver to add restart support by implementing > the restart callback to trigger the watchdog as quickly as possible. > > Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> > --- > drivers/watchdog/renesas_wdt.c | 19 +++++++++++++++++++ > 1 file changed, 19 insertions(+) > > diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c > index 831ef83..120ddac 100644 > --- a/drivers/watchdog/renesas_wdt.c > +++ b/drivers/watchdog/renesas_wdt.c > @@ -107,6 +107,24 @@ static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) > return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); > } > > +static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, > + void *data) > +{ > + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > + > + pm_runtime_get_sync(wdev->parent); > + > + rwdt_write(priv, 0x00, RWTCSRB); > + rwdt_write(priv, 0x00, RWTCSRA); > + rwdt_write(priv, 0xffff, RWTCNT); > + > + while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) > + cpu_relax(); Can this get stuck forever or should there be a timeout ? Guenter > + > + rwdt_write(priv, 0x80, RWTCSRA); > + return 0; > +} > + > static const struct watchdog_info rwdt_ident = { > .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, > .identity = "Renesas WDT Watchdog", > @@ -118,6 +136,7 @@ static const struct watchdog_ops rwdt_ops = { > .stop = rwdt_stop, > .ping = rwdt_init_timeout, > .get_timeleft = rwdt_get_timeleft, > + .restart = rwdt_restart, > }; > > static int rwdt_probe(struct platform_device *pdev) > -- > 2.7.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 25, 2018 at 06:02:58PM +0000, Fabrizio Castro wrote: > R-Car Gen2 (and RZ/G1) platforms need some tweaking for SMP and watchdog > to coexist nicely. > This new driver is based on top of Wolfram Sang's driver > (drivers/watchdog/renesas_wdt.c), and it contains the quirks necessary > for R-Car Gen2 and RZ/G1 to work properly and in harmony with the rest of > the system. In particular, the driver: > * expects the device clock to be ON all the time, > * "pauses" the watchdog operation during suspend, and > * "reassures" the SMP bringup function about the availability of the > watchdog registers. > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > --- > drivers/watchdog/Kconfig | 15 +- > drivers/watchdog/Makefile | 1 + > drivers/watchdog/renesas_wdt_gen2.c | 270 ++++++++++++++++++++++++++++++++++++ > drivers/watchdog/renesas_wdt_gen2.h | 22 +++ > 4 files changed, 306 insertions(+), 2 deletions(-) > create mode 100644 drivers/watchdog/renesas_wdt_gen2.c > create mode 100644 drivers/watchdog/renesas_wdt_gen2.h > > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig > index ca200d1..e580c72 100644 > --- a/drivers/watchdog/Kconfig > +++ b/drivers/watchdog/Kconfig > @@ -725,12 +725,23 @@ config ATLAS7_WATCHDOG > module will be called atlas7_wdt. > > config RENESAS_WDT > - tristate "Renesas WDT Watchdog" > + tristate "Renesas R-Car Gen3 WDT Watchdog" > depends on ARCH_RENESAS || COMPILE_TEST > select WATCHDOG_CORE > help > This driver adds watchdog support for the integrated watchdogs in the > - Renesas R-Car and other SH-Mobile SoCs (usually named RWDT or SWDT). > + Renesas R-Car Gen3 devices. > + > +config RENESAS_WDT_GEN2 > + tristate "Renesas R-Car Gen2 and RZ/G1 WDT Watchdog" > + depends on ARCH_RENESAS || COMPILE_TEST > + select WATCHDOG_CORE > + help > + This driver adds watchdog support for the integrated watchdogs in the > + Renesas R-Car Gen2 and RZ/G1 devices. > + > + To compile this driver as a module, choose M here: the > + module will be called renesas_wdt_gen2. > > config RENESAS_RZAWDT > tristate "Renesas RZ/A WDT Watchdog" > diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile > index 715a210..57ab810 100644 > --- a/drivers/watchdog/Makefile > +++ b/drivers/watchdog/Makefile > @@ -83,6 +83,7 @@ obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o > obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o > obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o > obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o > +obj-$(CONFIG_RENESAS_WDT_GEN2) += renesas_wdt_gen2.o > obj-$(CONFIG_RENESAS_RZAWDT) += rza_wdt.o > obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o > obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o > diff --git a/drivers/watchdog/renesas_wdt_gen2.c b/drivers/watchdog/renesas_wdt_gen2.c > new file mode 100644 > index 0000000..c841636 > --- /dev/null > +++ b/drivers/watchdog/renesas_wdt_gen2.c > @@ -0,0 +1,270 @@ > +/* > + * Watchdog driver for Renesas WDT watchdog > + * > + * Copyright (C) 2015-17 Wolfram Sang, Sang Engineering <wsa-jBu1N2QxHDJrcw3mvpCnnVaTQe2KTcn/@public.gmane.org> > + * Copyright (C) 2018 Renesas Electronics Corporation > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License version 2 as published by > + * the Free Software Foundation. Please use the SPDX identifier. > + */ > +#include <linux/bitops.h> > +#include <linux/clk.h> > +#include <linux/io.h> > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/platform_device.h> > +#include <linux/pm_runtime.h> > +#include <linux/watchdog.h> > +#include "renesas_wdt_gen2.h" > + > +#define RWTCNT 0 > +#define RWTCSRA 4 > +#define RWTCSRA_WOVF BIT(4) > +#define RWTCSRA_WRFLG BIT(5) > +#define RWTCSRA_TME BIT(7) > +#define RWTCSRB 8 > + > +#define RWDT_DEFAULT_TIMEOUT 60U > + > +/* > + * In probe, clk_rate is checked to be not more than 16 bit * biggest clock > + * divider (12 bits). d is only a factor to fully utilize the WDT counter and > + * will not exceed its 16 bits. Thus, no overflow, we stay below 32 bits. > + */ > +#define MUL_BY_CLKS_PER_SEC(p, d) \ > + DIV_ROUND_UP((d) * (p)->clk_rate, clk_divs[(p)->cks]) > + > +/* d is 16 bit, clk_divs 12 bit -> no 32 bit overflow */ > +#define DIV_BY_CLKS_PER_SEC(p, d) ((d) * clk_divs[(p)->cks] / (p)->clk_rate) > + > +static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024, 4096 }; > + > +static bool nowayout = WATCHDOG_NOWAYOUT; > +module_param(nowayout, bool, 0); > +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" > + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); > + > +struct rwdt_priv { > + void __iomem *base; > + struct watchdog_device wdev; > + unsigned long clk_rate; > + bool enabled; > + u8 cks; > +}; > + > +static void rwdt_write(struct rwdt_priv *priv, u32 val, unsigned int reg) > +{ > + if (reg == RWTCNT) > + val |= 0x5a5a0000; > + else > + val |= 0xa5a5a500; > + > + writel_relaxed(val, priv->base + reg); > +} > + > +static int rwdt_init_timeout(struct watchdog_device *wdev) > +{ > + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > + > + rwdt_write(priv, 65536 - MUL_BY_CLKS_PER_SEC(priv, wdev->timeout), > + RWTCNT); > + > + return 0; > +} > + > +static int rwdt_start(struct watchdog_device *wdev) > +{ > + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > + > + rwdt_write(priv, 0, RWTCSRB); > + rwdt_write(priv, priv->cks, RWTCSRA); > + rwdt_init_timeout(wdev); > + > + while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) > + cpu_relax(); > + Can this get stuck ? > + rwdt_write(priv, priv->cks | RWTCSRA_TME, RWTCSRA); > + > + return 0; > +} > + > +static int rwdt_stop(struct watchdog_device *wdev) > +{ > + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > + > + rwdt_write(priv, priv->cks, RWTCSRA); > + > + return 0; > +} > + > +static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) > +{ > + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > + u16 val = readw_relaxed(priv->base + RWTCNT); > + > + return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); > +} > + > +static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, > + void *data) > +{ > + struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > + > + rwdt_write(priv, 0x00, RWTCSRB); > + rwdt_write(priv, 0x00, RWTCSRA); > + rwdt_write(priv, 0xffff, RWTCNT); > + > + while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) > + cpu_relax(); > + > + rwdt_write(priv, 0x80, RWTCSRA); > + return 0; > +} > + > +static const struct watchdog_info rwdt_ident = { > + .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, > + .identity = "Renesas WDT Watchdog", > +}; > + > +static const struct watchdog_ops rwdt_ops = { > + .owner = THIS_MODULE, > + .start = rwdt_start, > + .stop = rwdt_stop, > + .ping = rwdt_init_timeout, > + .get_timeleft = rwdt_get_timeleft, > + .restart = rwdt_restart, > +}; > + > +static int rwdt_probe(struct platform_device *pdev) > +{ > + struct rwdt_priv *priv; > + struct resource *res; > + struct clk *clk; > + unsigned long clks_per_sec; > + int ret, i; > + > + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + priv->base = devm_ioremap_resource(&pdev->dev, res); > + if (IS_ERR(priv->base)) > + return PTR_ERR(priv->base); > + > + clk = devm_clk_get(&pdev->dev, NULL); > + if (IS_ERR(clk)) > + return PTR_ERR(clk); > + > + > + priv->clk_rate = clk_get_rate(clk); > + > + if (!priv->clk_rate) > + return -ENOENT; > + Odd line spacing. Please no double empty lines, and please no empty line after a function and before checking the return value. ENOENT is an odd return value. No such file or directory ? > + for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { > + clks_per_sec = priv->clk_rate / clk_divs[i]; > + if (clks_per_sec && clks_per_sec < 65536) { > + priv->cks = i; > + break; > + } > + } > + > + if (i < 0) { > + dev_err(&pdev->dev, "Can't find suitable clock divider\n"); > + return -ERANGE; Another odd return value. Math result not presentable ? > + } > + > + priv->wdev.info = &rwdt_ident, > + priv->wdev.ops = &rwdt_ops, > + priv->wdev.parent = &pdev->dev; > + priv->wdev.min_timeout = 1; > + priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536); > + priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT); > + > + platform_set_drvdata(pdev, priv); > + watchdog_set_drvdata(&priv->wdev, priv); > + watchdog_set_nowayout(&priv->wdev, nowayout); > + > + ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev); > + if (ret) > + dev_warn(&pdev->dev, > + "Specified timeout value invalid, using default\n"); > + shmobile_set_wdt_clock_status(RWDT_CLOCK_ON); > + > + ret = watchdog_register_device(&priv->wdev); Please consider using devm_watchdog_register_device(). > + return ret; > +} > + > +static int rwdt_remove(struct platform_device *pdev) > +{ > + struct rwdt_priv *priv = platform_get_drvdata(pdev); > + > + watchdog_unregister_device(&priv->wdev); > + > + return 0; > +} > + > +#ifdef CONFIG_PM > +static int rwdt_suspend(struct device *dev) > +{ > + struct platform_device *pdev; > + struct rwdt_priv *priv; > + u8 val; > + > + pdev = to_platform_device(dev); > + priv = platform_get_drvdata(pdev); > + val = readb_relaxed(priv->base + RWTCSRA); > + if (val & RWTCSRA_TME) { > + priv->enabled = true; > + rwdt_write(priv, val & ~RWTCSRA_TME, RWTCSRA); > + } else { > + priv->enabled = false; > + } This will require an explanation why you can't use watchdog_active() here and in the resume function. > + return 0; > +} > + > +static int rwdt_resume(struct device *dev) > +{ > + struct platform_device *pdev; > + struct rwdt_priv *priv; > + u8 val; > + > + pdev = to_platform_device(dev); > + priv = platform_get_drvdata(pdev); > + if (priv->enabled) { > + val = readb_relaxed(priv->base + RWTCSRA); > + rwdt_write(priv, val | RWTCSRA_TME, RWTCSRA); > + } > + return 0; > +} > + > +static const struct dev_pm_ops rwdt_pm = { > + .suspend = rwdt_suspend, > + .resume = rwdt_resume, Any reason for not using helper functions such as SET_SYSTEM_SLEEP_PM_OPS() or SIMPLE_DEV_PM_OPS() ? > +}; > +#endif > + > +static const struct of_device_id rwdt_ids[] = { > + { .compatible = "renesas,rcar-gen2-wdt", }, > + { /* sentinel */ } > +}; > +MODULE_DEVICE_TABLE(of, rwdt_ids); > + > +static struct platform_driver rwdt_driver = { > + .driver = { > + .name = "renesas_wdt_gen2", > + .of_match_table = rwdt_ids, > +#ifdef CONFIG_PM > + .pm = &rwdt_pm, > +#endif > + }, > + .probe = rwdt_probe, > + .remove = rwdt_remove, > +}; > +module_platform_driver(rwdt_driver); > + > +MODULE_DESCRIPTION("Renesas R-Car Gen2 Watchdog Driver"); > +MODULE_LICENSE("GPL v2"); > +MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org>"); > diff --git a/drivers/watchdog/renesas_wdt_gen2.h b/drivers/watchdog/renesas_wdt_gen2.h > new file mode 100644 > index 0000000..41b9e9c > --- /dev/null > +++ b/drivers/watchdog/renesas_wdt_gen2.h > @@ -0,0 +1,22 @@ > +/* > + * drivers/watchdog/renesas_wdt_gen2.h > + * > + * Copyright (C) 2018 Renesas Electronics Corporation > + * > + * R-Car Gen2 and RZ/G specific symbols > + * > + * 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 > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + */ > + > +#ifndef RENESAS_WDT_GEN2_H > +#define RENESAS_WDT_GEN2_H > + > +#define RWDT_CLOCK_ON 0xdeadbeef > +#define RWDT_CLOCK_OFF 0x00000000 > + > +extern void shmobile_set_wdt_clock_status(unsigned long value); Wrong file to declare this function. It is not defined in the watchdog driver. Same for the defines. > + > +#endif /* RENESAS_WDT_GEN2_H */ > -- > 2.7.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hello Guenter, thank you for your feedback. > Subject: Re: [RFC 22/37] watchdog: renesas_wdt: Add restart support > > On Thu, Jan 25, 2018 at 06:02:56PM +0000, Fabrizio Castro wrote: > > This commit extends the driver to add restart support by implementing > > the restart callback to trigger the watchdog as quickly as possible. > > > > Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> > > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> > > --- > > drivers/watchdog/renesas_wdt.c | 19 +++++++++++++++++++ > > 1 file changed, 19 insertions(+) > > > > diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c > > index 831ef83..120ddac 100644 > > --- a/drivers/watchdog/renesas_wdt.c > > +++ b/drivers/watchdog/renesas_wdt.c > > @@ -107,6 +107,24 @@ static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) > > return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); > > } > > > > +static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, > > +void *data) > > +{ > > +struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > > + > > +pm_runtime_get_sync(wdev->parent); > > + > > +rwdt_write(priv, 0x00, RWTCSRB); > > +rwdt_write(priv, 0x00, RWTCSRA); > > +rwdt_write(priv, 0xffff, RWTCNT); > > + > > +while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) > > +cpu_relax(); > > Can this get stuck forever or should there be a timeout ? This won't get stuck forever, the particular bit we are checking marks the period of time writing to register RWTCNT is prohibited due to synchronization from the previous write. It gets cleared eventually (quite quickly). Also, we use exactly the same logic for the "start" callback. Best regards, Fabrizio > > Guenter > > > + > > +rwdt_write(priv, 0x80, RWTCSRA); > > +return 0; > > +} > > + > > static const struct watchdog_info rwdt_ident = { > > .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, > > .identity = "Renesas WDT Watchdog", > > @@ -118,6 +136,7 @@ static const struct watchdog_ops rwdt_ops = { > > .stop = rwdt_stop, > > .ping = rwdt_init_timeout, > > .get_timeleft = rwdt_get_timeleft, > > +.restart = rwdt_restart, > > }; > > > > static int rwdt_probe(struct platform_device *pdev) > > -- > > 2.7.4 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in > > the body of a message to majordomo@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered No. 04586709.
Hello Guenter, thank you so much for your feedback. This driver is similar to the R-Car Gen3 watchdog driver (drivers/watchdog/renesas_wdt.c), at this point in time there is a discussion in progress about merging the functionality specific to R-Car Gen2 into the R-Car Gen3 driver, but this decision is stalled until we agree on something else that has in turn an impact on the driver implementation. I'll keep your comments in mind whatever we decide to do, but I am going to get back to you only after the decision has been made. Thanks, Fabrizio > Subject: Re: [RFC 24/37] watchdog: renesas_wdt_gen2: Add Gen2 specific driver > > On Thu, Jan 25, 2018 at 06:02:58PM +0000, Fabrizio Castro wrote: > > R-Car Gen2 (and RZ/G1) platforms need some tweaking for SMP and watchdog > > to coexist nicely. > > This new driver is based on top of Wolfram Sang's driver > > (drivers/watchdog/renesas_wdt.c), and it contains the quirks necessary > > for R-Car Gen2 and RZ/G1 to work properly and in harmony with the rest of > > the system. In particular, the driver: > > * expects the device clock to be ON all the time, > > * "pauses" the watchdog operation during suspend, and > > * "reassures" the SMP bringup function about the availability of the > > watchdog registers. > > > > Signed-off-by: Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> > > Signed-off-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram-+3GIUL1IS+U@public.gmane.orgsas.com> > > --- > > drivers/watchdog/Kconfig | 15 +- > > drivers/watchdog/Makefile | 1 + > > drivers/watchdog/renesas_wdt_gen2.c | 270 ++++++++++++++++++++++++++++++++++++ > > drivers/watchdog/renesas_wdt_gen2.h | 22 +++ > > 4 files changed, 306 insertions(+), 2 deletions(-) > > create mode 100644 drivers/watchdog/renesas_wdt_gen2.c > > create mode 100644 drivers/watchdog/renesas_wdt_gen2.h > > > > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig > > index ca200d1..e580c72 100644 > > --- a/drivers/watchdog/Kconfig > > +++ b/drivers/watchdog/Kconfig > > @@ -725,12 +725,23 @@ config ATLAS7_WATCHDOG > > module will be called atlas7_wdt. > > > > config RENESAS_WDT > > -tristate "Renesas WDT Watchdog" > > +tristate "Renesas R-Car Gen3 WDT Watchdog" > > depends on ARCH_RENESAS || COMPILE_TEST > > select WATCHDOG_CORE > > help > > This driver adds watchdog support for the integrated watchdogs in the > > - Renesas R-Car and other SH-Mobile SoCs (usually named RWDT or SWDT). > > + Renesas R-Car Gen3 devices. > > + > > +config RENESAS_WDT_GEN2 > > +tristate "Renesas R-Car Gen2 and RZ/G1 WDT Watchdog" > > +depends on ARCH_RENESAS || COMPILE_TEST > > +select WATCHDOG_CORE > > +help > > + This driver adds watchdog support for the integrated watchdogs in the > > + Renesas R-Car Gen2 and RZ/G1 devices. > > + > > + To compile this driver as a module, choose M here: the > > + module will be called renesas_wdt_gen2. > > > > config RENESAS_RZAWDT > > tristate "Renesas RZ/A WDT Watchdog" > > diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile > > index 715a210..57ab810 100644 > > --- a/drivers/watchdog/Makefile > > +++ b/drivers/watchdog/Makefile > > @@ -83,6 +83,7 @@ obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o > > obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o > > obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o > > obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o > > +obj-$(CONFIG_RENESAS_WDT_GEN2) += renesas_wdt_gen2.o > > obj-$(CONFIG_RENESAS_RZAWDT) += rza_wdt.o > > obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o > > obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o > > diff --git a/drivers/watchdog/renesas_wdt_gen2.c b/drivers/watchdog/renesas_wdt_gen2.c > > new file mode 100644 > > index 0000000..c841636 > > --- /dev/null > > +++ b/drivers/watchdog/renesas_wdt_gen2.c > > @@ -0,0 +1,270 @@ > > +/* > > + * Watchdog driver for Renesas WDT watchdog > > + * > > + * Copyright (C) 2015-17 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com> > > + * Copyright (C) 2018 Renesas Electronics Corporation > > + * > > + * This program is free software; you can redistribute it and/or modify it > > + * under the terms of the GNU General Public License version 2 as published by > > + * the Free Software Foundation. > > Please use the SPDX identifier. > > > + */ > > +#include <linux/bitops.h> > > +#include <linux/clk.h> > > +#include <linux/io.h> > > +#include <linux/kernel.h> > > +#include <linux/module.h> > > +#include <linux/of.h> > > +#include <linux/platform_device.h> > > +#include <linux/pm_runtime.h> > > +#include <linux/watchdog.h> > > +#include "renesas_wdt_gen2.h" > > + > > +#define RWTCNT0 > > +#define RWTCSRA4 > > +#define RWTCSRA_WOVFBIT(4) > > +#define RWTCSRA_WRFLGBIT(5) > > +#define RWTCSRA_TMEBIT(7) > > +#define RWTCSRB8 > > + > > +#define RWDT_DEFAULT_TIMEOUT60U > > + > > +/* > > + * In probe, clk_rate is checked to be not more than 16 bit * biggest clock > > + * divider (12 bits). d is only a factor to fully utilize the WDT counter and > > + * will not exceed its 16 bits. Thus, no overflow, we stay below 32 bits. > > + */ > > +#define MUL_BY_CLKS_PER_SEC(p, d) \ > > +DIV_ROUND_UP((d) * (p)->clk_rate, clk_divs[(p)->cks]) > > + > > +/* d is 16 bit, clk_divs 12 bit -> no 32 bit overflow */ > > +#define DIV_BY_CLKS_PER_SEC(p, d) ((d) * clk_divs[(p)->cks] / (p)->clk_rate) > > + > > +static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024, 4096 }; > > + > > +static bool nowayout = WATCHDOG_NOWAYOUT; > > +module_param(nowayout, bool, 0); > > +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" > > +__MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); > > + > > +struct rwdt_priv { > > +void __iomem *base; > > +struct watchdog_device wdev; > > +unsigned long clk_rate; > > +bool enabled; > > +u8 cks; > > +}; > > + > > +static void rwdt_write(struct rwdt_priv *priv, u32 val, unsigned int reg) > > +{ > > +if (reg == RWTCNT) > > +val |= 0x5a5a0000; > > +else > > +val |= 0xa5a5a500; > > + > > +writel_relaxed(val, priv->base + reg); > > +} > > + > > +static int rwdt_init_timeout(struct watchdog_device *wdev) > > +{ > > +struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > > + > > +rwdt_write(priv, 65536 - MUL_BY_CLKS_PER_SEC(priv, wdev->timeout), > > + RWTCNT); > > + > > +return 0; > > +} > > + > > +static int rwdt_start(struct watchdog_device *wdev) > > +{ > > +struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > > + > > +rwdt_write(priv, 0, RWTCSRB); > > +rwdt_write(priv, priv->cks, RWTCSRA); > > +rwdt_init_timeout(wdev); > > + > > +while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) > > +cpu_relax(); > > + > Can this get stuck ? > > > +rwdt_write(priv, priv->cks | RWTCSRA_TME, RWTCSRA); > > + > > +return 0; > > +} > > + > > +static int rwdt_stop(struct watchdog_device *wdev) > > +{ > > +struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > > + > > +rwdt_write(priv, priv->cks, RWTCSRA); > > + > > +return 0; > > +} > > + > > +static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) > > +{ > > +struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > > +u16 val = readw_relaxed(priv->base + RWTCNT); > > + > > +return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); > > +} > > + > > +static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, > > +void *data) > > +{ > > +struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > > + > > +rwdt_write(priv, 0x00, RWTCSRB); > > +rwdt_write(priv, 0x00, RWTCSRA); > > +rwdt_write(priv, 0xffff, RWTCNT); > > + > > +while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) > > +cpu_relax(); > > + > > +rwdt_write(priv, 0x80, RWTCSRA); > > +return 0; > > +} > > + > > +static const struct watchdog_info rwdt_ident = { > > +.options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, > > +.identity = "Renesas WDT Watchdog", > > +}; > > + > > +static const struct watchdog_ops rwdt_ops = { > > +.owner = THIS_MODULE, > > +.start = rwdt_start, > > +.stop = rwdt_stop, > > +.ping = rwdt_init_timeout, > > +.get_timeleft = rwdt_get_timeleft, > > +.restart = rwdt_restart, > > +}; > > + > > +static int rwdt_probe(struct platform_device *pdev) > > +{ > > +struct rwdt_priv *priv; > > +struct resource *res; > > +struct clk *clk; > > +unsigned long clks_per_sec; > > +int ret, i; > > + > > +priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); > > +if (!priv) > > +return -ENOMEM; > > +res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > +priv->base = devm_ioremap_resource(&pdev->dev, res); > > +if (IS_ERR(priv->base)) > > +return PTR_ERR(priv->base); > > + > > +clk = devm_clk_get(&pdev->dev, NULL); > > +if (IS_ERR(clk)) > > +return PTR_ERR(clk); > > + > > + > > +priv->clk_rate = clk_get_rate(clk); > > + > > +if (!priv->clk_rate) > > +return -ENOENT; > > + > Odd line spacing. Please no double empty lines, and please no > empty line after a function and before checking the return value. > > ENOENT is an odd return value. No such file or directory ? > > > +for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { > > +clks_per_sec = priv->clk_rate / clk_divs[i]; > > +if (clks_per_sec && clks_per_sec < 65536) { > > +priv->cks = i; > > +break; > > +} > > +} > > + > > +if (i < 0) { > > +dev_err(&pdev->dev, "Can't find suitable clock divider\n"); > > +return -ERANGE; > > Another odd return value. Math result not presentable ? > > > +} > > + > > +priv->wdev.info = &rwdt_ident, > > +priv->wdev.ops = &rwdt_ops, > > +priv->wdev.parent = &pdev->dev; > > +priv->wdev.min_timeout = 1; > > +priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536); > > +priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT); > > + > > +platform_set_drvdata(pdev, priv); > > +watchdog_set_drvdata(&priv->wdev, priv); > > +watchdog_set_nowayout(&priv->wdev, nowayout); > > + > > +ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev); > > +if (ret) > > +dev_warn(&pdev->dev, > > + "Specified timeout value invalid, using default\n"); > > +shmobile_set_wdt_clock_status(RWDT_CLOCK_ON); > > + > > +ret = watchdog_register_device(&priv->wdev); > > Please consider using devm_watchdog_register_device(). > > > +return ret; > > +} > > + > > +static int rwdt_remove(struct platform_device *pdev) > > +{ > > +struct rwdt_priv *priv = platform_get_drvdata(pdev); > > + > > +watchdog_unregister_device(&priv->wdev); > > + > > +return 0; > > +} > > + > > +#ifdef CONFIG_PM > > +static int rwdt_suspend(struct device *dev) > > +{ > > +struct platform_device *pdev; > > +struct rwdt_priv *priv; > > +u8 val; > > + > > +pdev = to_platform_device(dev); > > +priv = platform_get_drvdata(pdev); > > +val = readb_relaxed(priv->base + RWTCSRA); > > +if (val & RWTCSRA_TME) { > > +priv->enabled = true; > > +rwdt_write(priv, val & ~RWTCSRA_TME, RWTCSRA); > > +} else { > > +priv->enabled = false; > > +} > > This will require an explanation why you can't use watchdog_active() > here and in the resume function. > > > +return 0; > > +} > > + > > +static int rwdt_resume(struct device *dev) > > +{ > > +struct platform_device *pdev; > > +struct rwdt_priv *priv; > > +u8 val; > > + > > +pdev = to_platform_device(dev); > > +priv = platform_get_drvdata(pdev); > > +if (priv->enabled) { > > +val = readb_relaxed(priv->base + RWTCSRA); > > +rwdt_write(priv, val | RWTCSRA_TME, RWTCSRA); > > +} > > +return 0; > > +} > > + > > +static const struct dev_pm_ops rwdt_pm = { > > +.suspend = rwdt_suspend, > > +.resume = rwdt_resume, > > Any reason for not using helper functions such as SET_SYSTEM_SLEEP_PM_OPS() > or SIMPLE_DEV_PM_OPS() ? > > > +}; > > +#endif > > + > > +static const struct of_device_id rwdt_ids[] = { > > +{ .compatible = "renesas,rcar-gen2-wdt", }, > > +{ /* sentinel */ } > > +}; > > +MODULE_DEVICE_TABLE(of, rwdt_ids); > > + > > +static struct platform_driver rwdt_driver = { > > +.driver = { > > +.name = "renesas_wdt_gen2", > > +.of_match_table = rwdt_ids, > > +#ifdef CONFIG_PM > > +.pm = &rwdt_pm, > > +#endif > > +}, > > +.probe = rwdt_probe, > > +.remove = rwdt_remove, > > +}; > > +module_platform_driver(rwdt_driver); > > + > > +MODULE_DESCRIPTION("Renesas R-Car Gen2 Watchdog Driver"); > > +MODULE_LICENSE("GPL v2"); > > +MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org>"); > > diff --git a/drivers/watchdog/renesas_wdt_gen2.h b/drivers/watchdog/renesas_wdt_gen2.h > > new file mode 100644 > > index 0000000..41b9e9c > > --- /dev/null > > +++ b/drivers/watchdog/renesas_wdt_gen2.h > > @@ -0,0 +1,22 @@ > > +/* > > + * drivers/watchdog/renesas_wdt_gen2.h > > + * > > + * Copyright (C) 2018 Renesas Electronics Corporation > > + * > > + * R-Car Gen2 and RZ/G specific symbols > > + * > > + * 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 > > + * the Free Software Foundation; either version 2 of the License, or > > + * (at your option) any later version. > > + */ > > + > > +#ifndef RENESAS_WDT_GEN2_H > > +#define RENESAS_WDT_GEN2_H > > + > > +#define RWDT_CLOCK_ON0xdeadbeef > > +#define RWDT_CLOCK_OFF0x00000000 > > + > > +extern void shmobile_set_wdt_clock_status(unsigned long value); > > Wrong file to declare this function. It is not defined in the watchdog driver. > Same for the defines. > > > + > > +#endif /* RENESAS_WDT_GEN2_H */ > > -- > > 2.7.4 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in > > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered No. 04586709. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html