[PATCH v2] watchdog: ftwdt010: return a previously deleted driver now ported to DM

The ftwdt010 watchdog driver was deleted by commit 11232139e399 ("nds32: Remove the architecture")
Return it to the codebase in a DM compatible form. Enable it in sandbox_defconfig to test compilability. Another platform using ftwdt010 will be submitted later.
Signed-off-by: Sergei Antonov saproj@gmail.com Reviewed-by: Stefan Roese sr@denx.de ---
v2: * "imply WATCHDOG" in Kconfig like other watchdog drivers do * (by Stefan Roese) make .compatible string the same as in Linux driver
configs/sandbox_defconfig | 1 + drivers/watchdog/Kconfig | 7 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/ftwdt010_wdt.c | 132 ++++++++++++++++++++++++++++++++ include/faraday/ftwdt010_wdt.h | 3 - 5 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 drivers/watchdog/ftwdt010_wdt.c
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index cbace259f8..1025aa9fe9 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -322,6 +322,7 @@ CONFIG_WDT=y CONFIG_WDT_GPIO=y CONFIG_WDT_SANDBOX=y CONFIG_WDT_ALARM_SANDBOX=y +CONFIG_WDT_FTWDT010=y CONFIG_FS_CBFS=y CONFIG_FS_CRAMFS=y CONFIG_ADDR_MAP=y diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index b5ac8f7f50..8f78df509a 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -359,4 +359,11 @@ config SPL_WDT Enable driver model for watchdog timer in SPL. This is similar to CONFIG_WDT in U-Boot.
+config WDT_FTWDT010 + bool "Faraday Technology ftwdt010 watchdog timer support" + depends on WDT + imply WATCHDOG + help + Faraday Technology ftwdt010 watchdog is an architecture independent + watchdog. It is usually used in SoC chip design. endmenu diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 446d961d7d..fffa338bef 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_WDT_BOOKE) += booke_wdt.o obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o obj-$(CONFIG_WDT_ORION) += orion_wdt.o obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o +obj-$(CONFIG_WDT_FTWDT010) += ftwdt010_wdt.o obj-$(CONFIG_WDT_GPIO) += gpio_wdt.o obj-$(CONFIG_WDT_MAX6370) += max6370_wdt.o obj-$(CONFIG_WDT_MESON_GXBB) += meson_gxbb_wdt.o diff --git a/drivers/watchdog/ftwdt010_wdt.c b/drivers/watchdog/ftwdt010_wdt.c new file mode 100644 index 0000000000..a6b33b1720 --- /dev/null +++ b/drivers/watchdog/ftwdt010_wdt.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Watchdog driver for the FTWDT010 Watch Dog Driver + * + * (c) Copyright 2004 Faraday Technology Corp. (www.faraday-tech.com) + * Based on sa1100_wdt.c by Oleg Drokin green@crimea.edu + * Based on SoftDog driver by Alan Cox alan@redhat.com + * + * Copyright (C) 2011 Andes Technology Corporation + * Macpaul Lin, Andes Technology Corporation macpaul@andestech.com + * + * 27/11/2004 Initial release, Faraday. + * 12/01/2011 Port to u-boot, Macpaul Lin. + * 22/08/2022 Port to DM + */ + +#include <common.h> +#include <dm.h> +#include <wdt.h> +#include <log.h> +#include <asm/io.h> +#include <faraday/ftwdt010_wdt.h> + +struct ftwdt010_wdt_priv { + struct ftwdt010_wdt __iomem *regs; +}; + +/* + * Set the watchdog time interval. + * Counter is 32 bit. + */ +static int ftwdt010_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) +{ + struct ftwdt010_wdt_priv *priv = dev_get_priv(dev); + struct ftwdt010_wdt *wd = priv->regs; + unsigned int reg; + + debug("Activating WDT %llu ms\n", timeout_ms); + + /* Check if disabled */ + if (readl(&wd->wdcr) & ~FTWDT010_WDCR_ENABLE) { + printf("sorry, watchdog is disabled\n"); + return -1; + } + + /* + * In a 66MHz system, + * if you set WDLOAD as 0x03EF1480 (66000000) + * the reset timer is 1 second. + */ + reg = FTWDT010_WDLOAD(timeout_ms * FTWDT010_TIMEOUT_FACTOR); + + writel(reg, &wd->wdload); + + return 0; +} + +static int ftwdt010_wdt_reset(struct udevice *dev) +{ + struct ftwdt010_wdt_priv *priv = dev_get_priv(dev); + struct ftwdt010_wdt *wd = priv->regs; + + /* clear control register */ + writel(0, &wd->wdcr); + + /* Write Magic number */ + writel(FTWDT010_WDRESTART_MAGIC, &wd->wdrestart); + + /* Enable WDT */ + writel((FTWDT010_WDCR_RST | FTWDT010_WDCR_ENABLE), &wd->wdcr); + + return 0; +} + +static int ftwdt010_wdt_stop(struct udevice *dev) +{ + struct ftwdt010_wdt_priv *priv = dev_get_priv(dev); + struct ftwdt010_wdt *wd = priv->regs; + + debug("Deactivating WDT..\n"); + + /* + * It was defined with CONFIG_WATCHDOG_NOWAYOUT in Linux + * + * Shut off the timer. + * Lock it in if it's a module and we defined ...NOWAYOUT + */ + writel(0, &wd->wdcr); + return 0; +} + +static int ftwdt010_wdt_expire_now(struct udevice *dev, ulong flags) +{ + struct ftwdt010_wdt_priv *priv = dev_get_priv(dev); + struct ftwdt010_wdt *wd = priv->regs; + + debug("Expiring WDT..\n"); + writel(FTWDT010_WDLOAD(0), &wd->wdload); + return ftwdt010_wdt_reset(dev); +} + +static int ftwdt010_wdt_probe(struct udevice *dev) +{ + struct ftwdt010_wdt_priv *priv = dev_get_priv(dev); + + priv->regs = dev_read_addr_ptr(dev); + if (!priv->regs) + return -EINVAL; + + return 0; +} + +static const struct wdt_ops ftwdt010_wdt_ops = { + .start = ftwdt010_wdt_start, + .reset = ftwdt010_wdt_reset, + .stop = ftwdt010_wdt_stop, + .expire_now = ftwdt010_wdt_expire_now, +}; + +static const struct udevice_id ftwdt010_wdt_ids[] = { + { .compatible = "faraday,ftwdt010" }, + {} +}; + +U_BOOT_DRIVER(ftwdt010_wdt) = { + .name = "ftwdt010_wdt", + .id = UCLASS_WDT, + .of_match = ftwdt010_wdt_ids, + .ops = &ftwdt010_wdt_ops, + .probe = ftwdt010_wdt_probe, + .priv_auto = sizeof(struct ftwdt010_wdt_priv), +}; diff --git a/include/faraday/ftwdt010_wdt.h b/include/faraday/ftwdt010_wdt.h index 804907d645..d4c11e39a0 100644 --- a/include/faraday/ftwdt010_wdt.h +++ b/include/faraday/ftwdt010_wdt.h @@ -89,7 +89,4 @@ struct ftwdt010_wdt { */ #define FTWDT010_TIMEOUT_FACTOR (get_board_sys_clk() / 1000) /* 1 ms */
-void ftwdt010_wdt_reset(void); -void ftwdt010_wdt_disable(void); - #endif /* __FTWDT010_H */

On 4/12/23 13:01, Sergei Antonov wrote:
The ftwdt010 watchdog driver was deleted by commit 11232139e399 ("nds32: Remove the architecture")
Return it to the codebase in a DM compatible form. Enable it in sandbox_defconfig to test compilability. Another platform using ftwdt010 will be submitted later.
Signed-off-by: Sergei Antonov saproj@gmail.com Reviewed-by: Stefan Roese sr@denx.de
Applied to u-boot-watchdog/master
Thanks, Stefan
v2:
"imply WATCHDOG" in Kconfig like other watchdog drivers do
(by Stefan Roese) make .compatible string the same as in Linux driver
configs/sandbox_defconfig | 1 + drivers/watchdog/Kconfig | 7 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/ftwdt010_wdt.c | 132 ++++++++++++++++++++++++++++++++ include/faraday/ftwdt010_wdt.h | 3 - 5 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 drivers/watchdog/ftwdt010_wdt.c
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index cbace259f8..1025aa9fe9 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -322,6 +322,7 @@ CONFIG_WDT=y CONFIG_WDT_GPIO=y CONFIG_WDT_SANDBOX=y CONFIG_WDT_ALARM_SANDBOX=y +CONFIG_WDT_FTWDT010=y CONFIG_FS_CBFS=y CONFIG_FS_CRAMFS=y CONFIG_ADDR_MAP=y diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index b5ac8f7f50..8f78df509a 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -359,4 +359,11 @@ config SPL_WDT Enable driver model for watchdog timer in SPL. This is similar to CONFIG_WDT in U-Boot.
+config WDT_FTWDT010
- bool "Faraday Technology ftwdt010 watchdog timer support"
- depends on WDT
- imply WATCHDOG
- help
Faraday Technology ftwdt010 watchdog is an architecture independent
endmenuwatchdog. It is usually used in SoC chip design.
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 446d961d7d..fffa338bef 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_WDT_BOOKE) += booke_wdt.o obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o obj-$(CONFIG_WDT_ORION) += orion_wdt.o obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o +obj-$(CONFIG_WDT_FTWDT010) += ftwdt010_wdt.o obj-$(CONFIG_WDT_GPIO) += gpio_wdt.o obj-$(CONFIG_WDT_MAX6370) += max6370_wdt.o obj-$(CONFIG_WDT_MESON_GXBB) += meson_gxbb_wdt.o diff --git a/drivers/watchdog/ftwdt010_wdt.c b/drivers/watchdog/ftwdt010_wdt.c new file mode 100644 index 0000000000..a6b33b1720 --- /dev/null +++ b/drivers/watchdog/ftwdt010_wdt.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Watchdog driver for the FTWDT010 Watch Dog Driver
- (c) Copyright 2004 Faraday Technology Corp. (www.faraday-tech.com)
- Based on sa1100_wdt.c by Oleg Drokin green@crimea.edu
- Based on SoftDog driver by Alan Cox alan@redhat.com
- Copyright (C) 2011 Andes Technology Corporation
- Macpaul Lin, Andes Technology Corporation macpaul@andestech.com
- 27/11/2004 Initial release, Faraday.
- 12/01/2011 Port to u-boot, Macpaul Lin.
- 22/08/2022 Port to DM
- */
+#include <common.h> +#include <dm.h> +#include <wdt.h> +#include <log.h> +#include <asm/io.h> +#include <faraday/ftwdt010_wdt.h>
+struct ftwdt010_wdt_priv {
- struct ftwdt010_wdt __iomem *regs;
+};
+/*
- Set the watchdog time interval.
- Counter is 32 bit.
- */
+static int ftwdt010_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) +{
- struct ftwdt010_wdt_priv *priv = dev_get_priv(dev);
- struct ftwdt010_wdt *wd = priv->regs;
- unsigned int reg;
- debug("Activating WDT %llu ms\n", timeout_ms);
- /* Check if disabled */
- if (readl(&wd->wdcr) & ~FTWDT010_WDCR_ENABLE) {
printf("sorry, watchdog is disabled\n");
return -1;
- }
- /*
* In a 66MHz system,
* if you set WDLOAD as 0x03EF1480 (66000000)
* the reset timer is 1 second.
*/
- reg = FTWDT010_WDLOAD(timeout_ms * FTWDT010_TIMEOUT_FACTOR);
- writel(reg, &wd->wdload);
- return 0;
+}
+static int ftwdt010_wdt_reset(struct udevice *dev) +{
- struct ftwdt010_wdt_priv *priv = dev_get_priv(dev);
- struct ftwdt010_wdt *wd = priv->regs;
- /* clear control register */
- writel(0, &wd->wdcr);
- /* Write Magic number */
- writel(FTWDT010_WDRESTART_MAGIC, &wd->wdrestart);
- /* Enable WDT */
- writel((FTWDT010_WDCR_RST | FTWDT010_WDCR_ENABLE), &wd->wdcr);
- return 0;
+}
+static int ftwdt010_wdt_stop(struct udevice *dev) +{
- struct ftwdt010_wdt_priv *priv = dev_get_priv(dev);
- struct ftwdt010_wdt *wd = priv->regs;
- debug("Deactivating WDT..\n");
- /*
* It was defined with CONFIG_WATCHDOG_NOWAYOUT in Linux
*
* Shut off the timer.
* Lock it in if it's a module and we defined ...NOWAYOUT
*/
- writel(0, &wd->wdcr);
- return 0;
+}
+static int ftwdt010_wdt_expire_now(struct udevice *dev, ulong flags) +{
- struct ftwdt010_wdt_priv *priv = dev_get_priv(dev);
- struct ftwdt010_wdt *wd = priv->regs;
- debug("Expiring WDT..\n");
- writel(FTWDT010_WDLOAD(0), &wd->wdload);
- return ftwdt010_wdt_reset(dev);
+}
+static int ftwdt010_wdt_probe(struct udevice *dev) +{
- struct ftwdt010_wdt_priv *priv = dev_get_priv(dev);
- priv->regs = dev_read_addr_ptr(dev);
- if (!priv->regs)
return -EINVAL;
- return 0;
+}
+static const struct wdt_ops ftwdt010_wdt_ops = {
- .start = ftwdt010_wdt_start,
- .reset = ftwdt010_wdt_reset,
- .stop = ftwdt010_wdt_stop,
- .expire_now = ftwdt010_wdt_expire_now,
+};
+static const struct udevice_id ftwdt010_wdt_ids[] = {
- { .compatible = "faraday,ftwdt010" },
- {}
+};
+U_BOOT_DRIVER(ftwdt010_wdt) = {
- .name = "ftwdt010_wdt",
- .id = UCLASS_WDT,
- .of_match = ftwdt010_wdt_ids,
- .ops = &ftwdt010_wdt_ops,
- .probe = ftwdt010_wdt_probe,
- .priv_auto = sizeof(struct ftwdt010_wdt_priv),
+}; diff --git a/include/faraday/ftwdt010_wdt.h b/include/faraday/ftwdt010_wdt.h index 804907d645..d4c11e39a0 100644 --- a/include/faraday/ftwdt010_wdt.h +++ b/include/faraday/ftwdt010_wdt.h @@ -89,7 +89,4 @@ struct ftwdt010_wdt { */ #define FTWDT010_TIMEOUT_FACTOR (get_board_sys_clk() / 1000) /* 1 ms */
-void ftwdt010_wdt_reset(void); -void ftwdt010_wdt_disable(void);
- #endif /* __FTWDT010_H */
Viele Grüße, Stefan Roese
participants (2)
-
Sergei Antonov
-
Stefan Roese