[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