[PATCH v3 0/7] wdt: Add support for watchdogs on Kendryte K210

This series depends on https://patchwork.ozlabs.org/project/uboot/patch/20200901195548.542737-1-sea...
Changes in v3: - Note dependency on "time: Fix get_ticks being non-monotonic" - Add a few signed-off-bys which were sent for version 1
Changes in v2: - Fix fls being off-by-one when compared to log_2_n_round_up - Move watchdog enable to k210.dtsi as it does not depend on anything board-specific.
Sean Anderson (7): wdt: dw: Switch to using fls for log2 wdt: dw: Switch to if(CONFIG()) instead of using #if wdt: dw: Fix clock rate being off by 1000 wdt: dw: Enable the clock before using it wdt: dw: Free the clock on error riscv: Add watchdog bindings for the k210 riscv: Enable watchdog for the k210
arch/riscv/dts/k210.dtsi | 1 - board/sipeed/maix/Kconfig | 2 ++ drivers/watchdog/designware_wdt.c | 38 +++++++++++++++++++------------ 3 files changed, 26 insertions(+), 15 deletions(-)

log_2_n_round_up is only found in arm. fls performs the same job and is generic.
Signed-off-by: Sean Anderson seanga2@gmail.com ---
(no changes since v2)
Changes in v2: - Fix fls being off-by-one when compared to log_2_n_round_up
drivers/watchdog/designware_wdt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index 12f09a7a39..f25c8d9ab3 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -9,7 +9,6 @@ #include <reset.h> #include <wdt.h> #include <asm/io.h> -#include <asm/utils.h> #include <linux/bitops.h>
#define DW_WDT_CR 0x00 @@ -35,7 +34,7 @@ static int designware_wdt_settimeout(void __iomem *base, unsigned int clk_khz, signed int i;
/* calculate the timeout range value */ - i = log_2_n_round_up(timeout * clk_khz) - 16; + i = fls(timeout * clk_khz - 1) - 16; i = clamp(i, 0, 15);
writel(i | (i << 4), base + DW_WDT_TORR);

On Tue, 1 Sep 2020 at 14:08, Sean Anderson seanga2@gmail.com wrote:
log_2_n_round_up is only found in arm. fls performs the same job and is generic.
Signed-off-by: Sean Anderson seanga2@gmail.com
(no changes since v2)
Changes in v2:
- Fix fls being off-by-one when compared to log_2_n_round_up
drivers/watchdog/designware_wdt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

This is preferred over #if because the compiler can check syntax even if the feature is disabled. This cannot be used for CONFIG_CLK because CONFIG_DW_WDT_CLOCK_KHZ is not defined on all platforms.
Signed-off-by: Sean Anderson seanga2@gmail.com Reviewed-by: Heinrich Schuchardt xypron.glpk@gmx.de ---
(no changes since v1)
drivers/watchdog/designware_wdt.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index f25c8d9ab3..49cf861d46 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -136,17 +136,17 @@ static int designware_wdt_probe(struct udevice *dev) priv->clk_khz = CONFIG_DW_WDT_CLOCK_KHZ; #endif
-#if CONFIG_IS_ENABLED(DM_RESET) - struct reset_ctl_bulk resets; + if (CONFIG_IS_ENABLED(DM_RESET)) { + struct reset_ctl_bulk resets;
- ret = reset_get_bulk(dev, &resets); - if (ret) - return ret; + ret = reset_get_bulk(dev, &resets); + if (ret) + return ret;
- ret = reset_deassert_bulk(&resets); - if (ret) - return ret; -#endif + ret = reset_deassert_bulk(&resets); + if (ret) + return ret; + }
/* reset to disable the watchdog */ return designware_wdt_stop(dev);

The clock subsystem returns clock rates in Hz. We need to divide by 1000 so the rate is in kHz.
Fixes: cf89ef8d10f240554541c20b2e1bdcdd58d1d7e6 Signed-off-by: Sean Anderson seanga2@gmail.com Reviewed-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/watchdog/designware_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index 49cf861d46..41866fa01b 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -129,7 +129,7 @@ static int designware_wdt_probe(struct udevice *dev) if (ret) return ret;
- priv->clk_khz = clk_get_rate(&clk); + priv->clk_khz = clk_get_rate(&clk) / 1000; if (!priv->clk_khz) return -EINVAL; #else

The watchdog won't work if the clock isn't enabled.
Fixes: cf89ef8d10f240554541c20b2e1bdcdd58d1d7e6 Signed-off-by: Sean Anderson seanga2@gmail.com Reviewed-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/watchdog/designware_wdt.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index 41866fa01b..e6f5437056 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -129,6 +129,10 @@ static int designware_wdt_probe(struct udevice *dev) if (ret) return ret;
+ ret = clk_enable(&clk); + if (ret) + return ret; + priv->clk_khz = clk_get_rate(&clk) / 1000; if (!priv->clk_khz) return -EINVAL;

The clock subsystem requires that clk_free be called on clocks obtained via clk_get_*.
Signed-off-by: Sean Anderson seanga2@gmail.com Reviewed-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/watchdog/designware_wdt.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index e6f5437056..189d555f29 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -131,11 +131,13 @@ static int designware_wdt_probe(struct udevice *dev)
ret = clk_enable(&clk); if (ret) - return ret; + goto err;
priv->clk_khz = clk_get_rate(&clk) / 1000; - if (!priv->clk_khz) - return -EINVAL; + if (!priv->clk_khz) { + ret = -EINVAL; + goto err; + } #else priv->clk_khz = CONFIG_DW_WDT_CLOCK_KHZ; #endif @@ -145,15 +147,20 @@ static int designware_wdt_probe(struct udevice *dev)
ret = reset_get_bulk(dev, &resets); if (ret) - return ret; + goto err;
ret = reset_deassert_bulk(&resets); if (ret) - return ret; + goto err; }
/* reset to disable the watchdog */ return designware_wdt_stop(dev); + +err: + if (CONFIG_IS_ENABLED(CLK)) + clk_free(&clk); + return ret; }
static const struct wdt_ops designware_wdt_ops = {

On 9/1/20 4:07 PM, Sean Anderson wrote:
The clock subsystem requires that clk_free be called on clocks obtained via clk_get_*.
Signed-off-by: Sean Anderson seanga2@gmail.com Reviewed-by: Simon Glass sjg@chromium.org
(no changes since v1)
drivers/watchdog/designware_wdt.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index e6f5437056..189d555f29 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -131,11 +131,13 @@ static int designware_wdt_probe(struct udevice *dev)
ret = clk_enable(&clk); if (ret)
return ret;
goto err;
priv->clk_khz = clk_get_rate(&clk) / 1000;
- if (!priv->clk_khz)
return -EINVAL;
- if (!priv->clk_khz) {
ret = -EINVAL;
goto err;
- }
#else priv->clk_khz = CONFIG_DW_WDT_CLOCK_KHZ; #endif @@ -145,15 +147,20 @@ static int designware_wdt_probe(struct udevice *dev)
ret = reset_get_bulk(dev, &resets); if (ret)
return ret;
goto err;
ret = reset_deassert_bulk(&resets); if (ret)
return ret;
goto err;
}
/* reset to disable the watchdog */ return designware_wdt_stop(dev);
+err:
- if (CONFIG_IS_ENABLED(CLK))
This should be an #if. Found by running CI at
https://dev.azure.com/seanga2/u-boot/_build/results?buildId=26&view=logs...
Will be fixed in v4.
--Sean
clk_free(&clk);
- return ret;
}
static const struct wdt_ops designware_wdt_ops = {

This adds the necessary bindings. Most of them are already there.
Signed-off-by: Sean Anderson seanga2@gmail.com Acked-by: Rick Chen rick@andestech.com ---
(no changes since v2)
Changes in v2: - Move watchdog enable to k210.dtsi as it does not depend on anything board-specific.
arch/riscv/dts/k210.dtsi | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/riscv/dts/k210.dtsi b/arch/riscv/dts/k210.dtsi index 2546c7d4e0..f70318cb12 100644 --- a/arch/riscv/dts/k210.dtsi +++ b/arch/riscv/dts/k210.dtsi @@ -425,7 +425,6 @@ interrupts = <21>; clocks = <&sysclk K210_CLK_WDT0>; resets = <&sysrst K210_RST_WDT0>; - status = "disabled"; };
wdt1: watchdog@50410000 {

This enables the necessary config options.
Signed-off-by: Sean Anderson seanga2@gmail.com ---
Changes in v3: - Note dependency on "time: Fix get_ticks being non-monotonic" - Add a few signed-off-bys which were sent for version 1
board/sipeed/maix/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/board/sipeed/maix/Kconfig b/board/sipeed/maix/Kconfig index 0cdcd32adc..b9dac5a64e 100644 --- a/board/sipeed/maix/Kconfig +++ b/board/sipeed/maix/Kconfig @@ -44,4 +44,6 @@ config BOARD_SPECIFIC_OPTIONS imply RESET_SYSCON imply SYSRESET imply SYSRESET_SYSCON + imply WDT + imply DESIGNWARE_WATCHDOG endif

On Tue, 1 Sep 2020 at 14:08, Sean Anderson seanga2@gmail.com wrote:
This enables the necessary config options.
Signed-off-by: Sean Anderson seanga2@gmail.com
Changes in v3:
- Note dependency on "time: Fix get_ticks being non-monotonic"
- Add a few signed-off-bys which were sent for version 1
board/sipeed/maix/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

On 9/1/20 4:07 PM, Sean Anderson wrote:
This series depends on https://patchwork.ozlabs.org/project/uboot/patch/20200901195548.542737-1-sea...
A note for those following along at home: after further investigation, this series depends on [1]. It works with v1 of the above patch (as linked), but if one applies v2 [2], it will panic without [1].
[1] https://patchwork.ozlabs.org/project/uboot/list/?series=200642 [2] https://patchwork.ozlabs.org/project/uboot/list/?series=200645
Changes in v3:
- Note dependency on "time: Fix get_ticks being non-monotonic"
- Add a few signed-off-bys which were sent for version 1
Changes in v2:
- Fix fls being off-by-one when compared to log_2_n_round_up
- Move watchdog enable to k210.dtsi as it does not depend on anything board-specific.
Sean Anderson (7): wdt: dw: Switch to using fls for log2 wdt: dw: Switch to if(CONFIG()) instead of using #if wdt: dw: Fix clock rate being off by 1000 wdt: dw: Enable the clock before using it wdt: dw: Free the clock on error riscv: Add watchdog bindings for the k210 riscv: Enable watchdog for the k210
arch/riscv/dts/k210.dtsi | 1 - board/sipeed/maix/Kconfig | 2 ++ drivers/watchdog/designware_wdt.c | 38 +++++++++++++++++++------------ 3 files changed, 26 insertions(+), 15 deletions(-)
participants (2)
-
Sean Anderson
-
Simon Glass