[U-Boot] [PATCH v1] arm: at91: wdt: Convert watchdog driver to dm

Convert the Watchdog driver for AT91SAM9x processors to support the driver model and device tree
Signed-off-by: Prasanthi Chellakumar prasanthi.chellakumar@microchip.com --- arch/arm/mach-at91/include/mach/at91_wdt.h | 12 +++- drivers/watchdog/Kconfig | 7 ++ drivers/watchdog/Makefile | 2 +- drivers/watchdog/at91sam9_wdt.c | 105 +++++++++++++++++++++-------- 4 files changed, 95 insertions(+), 31 deletions(-)
diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h index 99b0cc8..df9f131 100644 --- a/arch/arm/mach-at91/include/mach/at91_wdt.h +++ b/arch/arm/mach-at91/include/mach/at91_wdt.h @@ -4,7 +4,7 @@ * * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com * Copyright (C) 2007 Andrew Victor - * Copyright (C) 2007 Atmel Corporation. + * Copyright (C) 2018 Microchip Technology Inc. * * Watchdog Timer (WDT) - System peripherals regsters. * Based on AT91SAM9261 datasheet revision D. @@ -27,15 +27,21 @@ typedef struct at91_wdt {
#endif
+/* Watchdog Control Register */ +#define AT91_WDT_CR 0x00 #define AT91_WDT_CR_WDRSTT 1 #define AT91_WDT_CR_KEY 0xa5000000 /* KEY Password */
-#define AT91_WDT_MR_WDV(x) (x & 0xfff) +/* Watchdog Mode Register*/ +#define AT91_WDT_MR 0X04 +#define AT91_WDT_MR_WDV (0xfff << 0) +#define AT91_WDT_MR_SET_WDV(x) ((x) & AT91_WDT_MR_WDV) #define AT91_WDT_MR_WDFIEN 0x00001000 #define AT91_WDT_MR_WDRSTEN 0x00002000 #define AT91_WDT_MR_WDRPROC 0x00004000 #define AT91_WDT_MR_WDDIS 0x00008000 -#define AT91_WDT_MR_WDD(x) ((x & 0xfff) << 16) +#define AT91_WDT_MR_WDD (0xfff << 16) +#define AT91_WDT_MR_SET_WDD(x) (((x) << 16) & AT91_WDT_MR_WDD) #define AT91_WDT_MR_WDDBGHLT 0x10000000 #define AT91_WDT_MR_WDIDLEHLT 0x20000000
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index d545b3e..001a8d0 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -111,4 +111,11 @@ config XILINX_TB_WATCHDOG Select this to enable Xilinx Axi watchdog timer, which can be found on some Xilinx Microblaze Platforms.
+config WDT_AT91 + bool "AT91 watchdog timer support" + depends on WDT + help + Select this to enable Microchip watchdog timer, which can be found on + some AT91 devices. + endmenu diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index f405f51..3f4fd59 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -3,7 +3,7 @@ # (C) Copyright 2008 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-obj-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o +obj-$(CONFIG_WDT_AT91) += at91sam9_wdt.o obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 mx7 vf610)) obj-y += imx_watchdog.o diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index fca2849..d3f8fa6 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -2,7 +2,7 @@ /* * [origin: Linux kernel drivers/watchdog/at91sam9_wdt.c] * - * Watchdog driver for Atmel AT91SAM9x processors. + * Watchdog driver for AT91SAM9x processors. * * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com * Copyright (C) 2008 Renaud CERRATO r.cerrato@til-technologies.fr @@ -14,38 +14,47 @@ * write to this register. Inform Linux to it too */
-#include <common.h> -#include <watchdog.h> -#include <asm/arch/hardware.h> #include <asm/io.h> #include <asm/arch/at91_wdt.h> +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <wdt.h> + +DECLARE_GLOBAL_DATA_PTR;
/* * AT91SAM9 watchdog runs a 12bit counter @ 256Hz, * use this to convert a watchdog - * value from/to milliseconds. + * value from seconds. */ -#define ms_to_ticks(t) (((t << 8) / 1000) - 1) -#define ticks_to_ms(t) (((t + 1) * 1000) >> 8) +#define WDT_SEC2TICKS(s) (((s) << 8) - 1)
/* Hardware timeout in seconds */ -#if !defined(CONFIG_AT91_HW_WDT_TIMEOUT) -#define WDT_HW_TIMEOUT 2 -#else -#define WDT_HW_TIMEOUT CONFIG_AT91_HW_WDT_TIMEOUT -#endif +#define WDT_MAX_TIMEOUT 16 +#define WDT_MIN_TIMEOUT 0 + +struct at91_wdt_priv { + void __iomem *regs; + u32 regval; +};
/* * Set the watchdog time interval in 1/256Hz (write-once) * Counter is 12 bit. */ -static int at91_wdt_settimeout(unsigned int timeout) +static int at91_wdt_start(struct udevice *dev, u64 timeout_s, ulong flags) { - unsigned int reg; - at91_wdt_t *wd = (at91_wdt_t *) ATMEL_BASE_WDT; + struct at91_wdt_priv *priv = dev_get_priv(dev); + u32 timeout = WDT_SEC2TICKS(timeout_s); + + if (timeout_s > WDT_MAX_TIMEOUT || timeout_s < WDT_MIN_TIMEOUT) { + printf("Invalid watchdog counter value\n"); + return -1; + }
/* Check if disabled */ - if (readl(&wd->mr) & AT91_WDT_MR_WDDIS) { + if (readl(priv->regs + AT91_WDT_MR) & AT91_WDT_MR_WDDIS) { printf("sorry, watchdog is disabled\n"); return -1; } @@ -56,25 +65,67 @@ static int at91_wdt_settimeout(unsigned int timeout) * Since WDV is a 12-bit counter, the maximum period is * 4096 / 256 = 16 seconds. */ + priv->regval &= ~AT91_WDT_MR_WDV; + priv->regval &= ~AT91_WDT_MR_WDD; + priv->regval |= AT91_WDT_MR_SET_WDV(timeout); + priv->regval |= AT91_WDT_MR_SET_WDD(timeout); + priv->regval |= AT91_WDT_MR_WDDBGHLT; + priv->regval |= AT91_WDT_MR_WDIDLEHLT; + priv->regval |= AT91_WDT_MR_WDRSTEN;
- reg = AT91_WDT_MR_WDRSTEN /* causes watchdog reset */ - | AT91_WDT_MR_WDDBGHLT /* disabled in debug mode */ - | AT91_WDT_MR_WDD(0xfff) /* restart at any time */ - | AT91_WDT_MR_WDV(timeout); /* timer value */ + writel(priv->regval, priv->regs + AT91_WDT_MR);
- writel(reg, &wd->mr); + return 0; +} + +static int at91_wdt_stop(struct udevice *dev) +{ + struct at91_wdt_priv *priv = dev_get_priv(dev); + + /* Disable Watchdog Timer */ + priv->regval |= AT91_WDT_MR_WDDIS; + writel(priv->regval, priv->regs + AT91_WDT_MR);
return 0; }
-void hw_watchdog_reset(void) +static int at91_wdt_reset(struct udevice *dev) { - at91_wdt_t *wd = (at91_wdt_t *) ATMEL_BASE_WDT; - writel(AT91_WDT_CR_WDRSTT | AT91_WDT_CR_KEY, &wd->cr); + struct at91_wdt_priv *priv = dev_get_priv(dev); + + writel(AT91_WDT_CR_WDRSTT | AT91_WDT_CR_KEY, priv->regs + AT91_WDT_CR); + + return 0; }
-void hw_watchdog_init(void) +static const struct wdt_ops at91_wdt_ops = { + .start = at91_wdt_start, + .stop = at91_wdt_stop, + .reset = at91_wdt_reset, +}; + +static const struct udevice_id at91_wdt_ids[] = { + { .compatible = "atmel,at91sam9260-wdt" }, + {} +}; + +static int at91_wdt_probe(struct udevice *dev) { - /* 16 seconds timer, resets enabled */ - at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000)); + struct at91_wdt_priv *priv = dev_get_priv(dev); + + priv->regs = dev_remap_addr(dev); + if (!priv->regs) + return -EINVAL; + debug("%s: Probing wdt%u\n", __func__, dev->seq); + + return 0; } + +U_BOOT_DRIVER(at91_wdt) = { + .name = "at91_wdt", + .id = UCLASS_WDT, + .of_match = at91_wdt_ids, + .priv_auto_alloc_size = sizeof(struct at91_wdt_priv), + .ops = &at91_wdt_ops, + .probe = at91_wdt_probe, +};

On Thu, Jul 26, 2018 at 02:56:27PM -0700, Prasanthi Chellakumar wrote:
Convert the Watchdog driver for AT91SAM9x processors to support the driver model and device tree
Signed-off-by: Prasanthi Chellakumar prasanthi.chellakumar@microchip.com
arch/arm/mach-at91/include/mach/at91_wdt.h | 12 +++- drivers/watchdog/Kconfig | 7 ++ drivers/watchdog/Makefile | 2 +- drivers/watchdog/at91sam9_wdt.c | 105 +++++++++++++++++++++-------- 4 files changed, 95 insertions(+), 31 deletions(-)
Thanks for doing the conversion. It's fine to rename the config option to match the rest of the WDT drivers but you need to update all of the existing users now too, thanks!

On 08/10/2018 07:53 AM, Tom Rini wrote:
On Thu, Jul 26, 2018 at 02:56:27PM -0700, Prasanthi Chellakumar wrote:
Convert the Watchdog driver for AT91SAM9x processors to support the driver model and device tree
Signed-off-by: Prasanthi Chellakumar prasanthi.chellakumar@microchip.com
arch/arm/mach-at91/include/mach/at91_wdt.h | 12 +++- drivers/watchdog/Kconfig | 7 ++ drivers/watchdog/Makefile | 2 +- drivers/watchdog/at91sam9_wdt.c | 105 +++++++++++++++++++++-------- 4 files changed, 95 insertions(+), 31 deletions(-)
Thanks for doing the conversion. It's fine to rename the config option to match the rest of the WDT drivers but you need to update all of the existing users now too, thanks!
Noted. Thanks for reviewing.
Prasanthi
participants (3)
-
Prasanthi Chellakumar
-
Prasanthi.Chellakumar
-
Tom Rini