[PATCH 1/7] wdt: dw: Switch to using fls for log2

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 ---
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..5684acefd2 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) - 16; i = clamp(i, 0, 15);
writel(i | (i << 4), base + DW_WDT_TORR);

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 ---
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 5684acefd2..1d46382f67 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);

On 8/5/20 9:14 PM, Sean Anderson wrote:
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

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 ---
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 1d46382f67..c7a0c896b8 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

On Wed, 5 Aug 2020 at 13:14, Sean Anderson seanga2@gmail.com wrote:
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
drivers/watchdog/designware_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org

The watchdog won't work if the clock isn't enabled.
Fixes: cf89ef8d10f240554541c20b2e1bdcdd58d1d7e6 Signed-off-by: Sean Anderson seanga2@gmail.com ---
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 c7a0c896b8..70c863dc9c 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;

On Wed, 5 Aug 2020 at 13:14, Sean Anderson seanga2@gmail.com wrote:
The watchdog won't work if the clock isn't enabled.
Fixes: cf89ef8d10f240554541c20b2e1bdcdd58d1d7e6 Signed-off-by: Sean Anderson seanga2@gmail.com
drivers/watchdog/designware_wdt.c | 4 ++++ 1 file changed, 4 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

The clock subsystem requires that clk_free be called on clocks obtained via clk_get_*.
Signed-off-by: Sean Anderson seanga2@gmail.com ---
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 70c863dc9c..dc5b3f377f 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 Wed, 5 Aug 2020 at 13:14, Sean Anderson seanga2@gmail.com wrote:
The clock subsystem requires that clk_free be called on clocks obtained via clk_get_*.
Signed-off-by: Sean Anderson seanga2@gmail.com
drivers/watchdog/designware_wdt.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

This adds the necessary bindings. Most of them are already there.
Signed-off-by: Sean Anderson seanga2@gmail.com ---
arch/riscv/dts/k210-maix-bit.dts | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/riscv/dts/k210-maix-bit.dts b/arch/riscv/dts/k210-maix-bit.dts index 5b32c5fd5f..331742068d 100644 --- a/arch/riscv/dts/k210-maix-bit.dts +++ b/arch/riscv/dts/k210-maix-bit.dts @@ -45,3 +45,7 @@ &i2s0 { #sound-dai-cells = <1>; }; + +&wdt0 { + status = "okay"; +};

This enables the necessary config options.
Signed-off-by: Sean Anderson seanga2@gmail.com ---
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 8/5/20 9:14 PM, Sean Anderson 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
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..5684acefd2 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) - 16;
The two functions create different results:
generic_fls(15) = 4, log_2_n_round_up(15) = 4 generic_fls(16) = 5, log_2_n_round_up(16) = 4 generic_fls(17) = 5, log_2_n_round_up(17) = 5
Please, describe the effect of your change in the commit message.
Best regards
Heinrich
i = clamp(i, 0, 15);
writel(i | (i << 4), base + DW_WDT_TORR);

On 8/5/20 5:06 PM, Heinrich Schuchardt wrote:
On 8/5/20 9:14 PM, Sean Anderson 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
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..5684acefd2 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) - 16;
The two functions create different results:
generic_fls(15) = 4, log_2_n_round_up(15) = 4 generic_fls(16) = 5, log_2_n_round_up(16) = 4 generic_fls(17) = 5, log_2_n_round_up(17) = 5
Please, describe the effect of your change in the commit message.
Hm, then perhaps this should be
i = fls(timeout * clk_khz - 1) - 16;
--Sean
participants (4)
-
Heinrich Schuchardt
-
Heinrich Schuchardt
-
Sean Anderson
-
Simon Glass