[U-Boot] [PATCH 2/2] watchdog: designware: Convert to DM and DT probing
Ley Foon Tan
lftan.linux at gmail.com
Thu Oct 3 01:57:54 UTC 2019
On Thu, Oct 3, 2019 at 6:56 AM Marek Vasut <marex at denx.de> wrote:
>
> Convert the designware watchdog timer driver to DM and add DT probing
> support. Perform minor coding style clean up, like drop superfluous
> braces. These ought to be no functional change.
>
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Chin Liang See <chin.liang.see at intel.com>
> Cc: Dalon Westergreen <dwesterg at gmail.com>
> Cc: Dinh Nguyen <dinguyen at kernel.org>
> Cc: Ley Foon Tan <ley.foon.tan at intel.com>
> Cc: Simon Goldschmidt <simon.k.r.goldschmidt at gmail.com>
> Cc: Tien Fong Chee <tien.fong.chee at intel.com>
> ---
> configs/socfpga_stratix10_defconfig | 1 +
> configs/socfpga_vining_fpga_defconfig | 1 +
> drivers/watchdog/Kconfig | 14 ++--
> drivers/watchdog/designware_wdt.c | 97 +++++++++++++++++++--------
> 4 files changed, 77 insertions(+), 36 deletions(-)
>
> diff --git a/configs/socfpga_stratix10_defconfig b/configs/socfpga_stratix10_defconfig
> index 462082b67b..cc5f49a536 100644
> --- a/configs/socfpga_stratix10_defconfig
> +++ b/configs/socfpga_stratix10_defconfig
> @@ -56,4 +56,5 @@ CONFIG_USB=y
> CONFIG_DM_USB=y
> CONFIG_USB_DWC2=y
> CONFIG_USB_STORAGE=y
> +CONFIG_WDT=y
> CONFIG_DESIGNWARE_WATCHDOG=y
> diff --git a/configs/socfpga_vining_fpga_defconfig b/configs/socfpga_vining_fpga_defconfig
> index 03c43fa8b9..def7a3eca7 100644
> --- a/configs/socfpga_vining_fpga_defconfig
> +++ b/configs/socfpga_vining_fpga_defconfig
> @@ -91,4 +91,5 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0525
> CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
> CONFIG_USB_GADGET_DWC2_OTG=y
> CONFIG_USB_GADGET_DOWNLOAD=y
> +CONFIG_WDT=y
> CONFIG_DESIGNWARE_WATCHDOG=y
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 6fd9b0a177..ec34993664 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -36,13 +36,6 @@ config ULP_WATCHDOG
> help
> Say Y here to enable i.MX7ULP watchdog driver.
>
> -config DESIGNWARE_WATCHDOG
> - bool "Designware watchdog timer support"
> - select HW_WATCHDOG
CONFIG_HW_WATCHDOG is disabled now. Few areas of code in
arm/mach-socfpga/ still using this CONFIG and call to
hw_watchdog_init(). They need to remove too.
Do we need call to uclass_get_device(UCLASS_WDT, 0, &dev) in SPL to
probe watchdog and call to wdt_start() to start watchdog? Can't find
place that start watchdog.
> - help
> - Enable this to support Designware Watchdog Timer IP, present e.g.
> - on Altera SoCFPGA SoCs.
> -
> config WDT
> bool "Enable driver model for watchdog timer drivers"
> depends on DM
> @@ -54,6 +47,13 @@ config WDT
> What exactly happens when the timer expires is up to a particular
> device/driver.
>
> +config DESIGNWARE_WATCHDOG
> + bool "Designware watchdog timer support"
> + depends on WDT
> + help
> + Enable this to support Designware Watchdog Timer IP, present e.g.
> + on Altera SoCFPGA SoCs.
> +
> config WDT_ARMADA_37XX
> bool "Marvell Armada 37xx watchdog timer support"
> depends on WDT && ARMADA_3700
> diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c
> index c668567c66..f2b9175345 100644
> --- a/drivers/watchdog/designware_wdt.c
> +++ b/drivers/watchdog/designware_wdt.c
> @@ -4,7 +4,8 @@
> */
>
> #include <common.h>
> -#include <watchdog.h>
> +#include <dm.h>
> +#include <wdt.h>
> #include <asm/io.h>
> #include <asm/utils.h>
>
> @@ -17,57 +18,95 @@
> #define DW_WDT_CR_RMOD_VAL 0x00
> #define DW_WDT_CRR_RESTART_VAL 0x76
>
> +struct designware_wdt_priv {
> + void __iomem *base;
> +};
> +
> /*
> * Set the watchdog time interval.
> * Counter is 32 bit.
> */
> -static int designware_wdt_settimeout(unsigned int timeout)
> +static int designware_wdt_settimeout(struct udevice *dev, unsigned int timeout)
> {
> + struct designware_wdt_priv *priv = dev_get_priv(dev);
> signed int i;
>
> /* calculate the timeout range value */
> i = (log_2_n_round_up(timeout * CONFIG_DW_WDT_CLOCK_KHZ)) - 16;
> - if (i > 15)
> - i = 15;
> - if (i < 0)
> - i = 0;
> + i = clamp(i, 0, 15);
> +
> + writel(i | (i << 4), priv->base + DW_WDT_TORR);
>
> - writel((i | (i << 4)), (CONFIG_DW_WDT_BASE + DW_WDT_TORR));
> return 0;
> }
>
> -static void designware_wdt_enable(void)
> +static unsigned int designware_wdt_is_enabled(struct udevice *dev)
> {
> - writel(((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) |
> - (0x1 << DW_WDT_CR_EN_OFFSET)),
> - (CONFIG_DW_WDT_BASE + DW_WDT_CR));
> -}
> + struct designware_wdt_priv *priv = dev_get_priv(dev);
>
> -static unsigned int designware_wdt_is_enabled(void)
> -{
> - unsigned long val;
> - val = readl((CONFIG_DW_WDT_BASE + DW_WDT_CR));
> - return val & 0x1;
> + return readl(priv->base + DW_WDT_CR) & BIT(0);
> }
>
> -#if defined(CONFIG_HW_WATCHDOG)
> -void hw_watchdog_reset(void)
> +static int designware_wdt_reset(struct udevice *dev)
> {
> - if (designware_wdt_is_enabled())
> + struct designware_wdt_priv *priv = dev_get_priv(dev);
> +
> + if (designware_wdt_is_enabled(dev))
> /* restart the watchdog counter */
> - writel(DW_WDT_CRR_RESTART_VAL,
> - (CONFIG_DW_WDT_BASE + DW_WDT_CRR));
> + writel(DW_WDT_CRR_RESTART_VAL, priv->base + DW_WDT_CRR);
> +
> + return 0;
> }
>
> -void hw_watchdog_init(void)
> +static int designware_wdt_stop(struct udevice *dev)
> {
> /* reset to disable the watchdog */
> - hw_watchdog_reset();
> + designware_wdt_reset(dev);
Need to clear BIT(DW_WDT_CR_EN_OFFSET) in CR register to disable watchdog.
> + return 0;
> +}
> +
> +static int designware_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
> +{
> + struct designware_wdt_priv *priv = dev_get_priv(dev);
> +
> + designware_wdt_stop(dev);
> +
> /* set timer in miliseconds */
> - designware_wdt_settimeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
> - /* enable the watchdog */
> - designware_wdt_enable();
> + designware_wdt_settimeout(dev, timeout);
> +
> + writel((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) |
> + BIT(DW_WDT_CR_EN_OFFSET),
> + priv->base + DW_WDT_CR);
> +
> /* reset the watchdog */
> - hw_watchdog_reset();
> + designware_wdt_reset(dev);
Need move to before enable CR_EN bit if we add clear CR_EN bit in
designware_wdt_reset().
> + return 0;
> +}
> +
> +static int designware_wdt_probe(struct udevice *dev)
> +{
Need to de-assert reset for watchdog in probe using reset framework.
> + /* reset to disable the watchdog */
> + designware_wdt_reset(dev);
designware_wdt_reset() only reset watchdog counter, but doesn't
disable the watchdog.
Can change call to designware_wdt_stop() if _stop() add clear CR_EN bit.
> + return 0;
> }
> -#endif
> +
> +static const struct wdt_ops designware_wdt_ops = {
> + .start = designware_wdt_start,
> + .reset = designware_wdt_reset,
> + .stop = designware_wdt_stop,
> +};
> +
> +static const struct udevice_id designware_wdt_ids[] = {
> + { .compatible = "snps,dw-wdt"},
> + {}
> +};
> +
> +U_BOOT_DRIVER(designware_wdt) = {
> + .name = "designware_wdt",
> + .id = UCLASS_WDT,
> + .of_match = designware_wdt_ids,
> + .priv_auto_alloc_size = sizeof(struct designware_wdt_priv),
> + .probe = designware_wdt_probe,
> + .ops = &designware_wdt_ops,
> + .flags = DM_FLAG_PRE_RELOC,
> +};
> --
> 2.23.0
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
More information about the U-Boot
mailing list