[PATCH] watchdog: Add MAX6370 watchdog timer driver

Stefan Roese sr at denx.de
Tue May 3 07:16:34 CEST 2022


On 02.05.22 18:41, Pali Rohár wrote:
> MAX6370 watchdog is available e.g. on Freescale P1/P2 RDB-PC boards.
> 
> Signed-off-by: Pali Rohár <pali at kernel.org>
> ---
>   drivers/watchdog/Kconfig       |   7 ++
>   drivers/watchdog/Makefile      |   1 +
>   drivers/watchdog/max6370_wdt.c | 119 +++++++++++++++++++++++++++++++++
>   3 files changed, 127 insertions(+)
>   create mode 100644 drivers/watchdog/max6370_wdt.c
> 
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index f90f0ca02bce..1801698ac512 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -167,6 +167,13 @@ config WDT_GPIO
>   	  doc/device-tree-bindings/watchdog/gpio-wdt.txt for
>   	  information on how to describe the watchdog in device tree.
>   
> +config WDT_MAX6370
> +	bool "MAX6370 watchdog timer support"
> +	depends on WDT
> +	select DM_GPIO
> +	help
> +	  Select this to enable max6370 watchdog timer.
> +
>   config WDT_MPC8xx
>   	bool "MPC8xx watchdog timer support"
>   	depends on WDT && MPC8xx
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index a35bd559f51b..f999e4126b4f 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -27,6 +27,7 @@ obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o
>   obj-$(CONFIG_WDT_ORION) += orion_wdt.o
>   obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
>   obj-$(CONFIG_WDT_GPIO) += gpio_wdt.o
> +obj-$(CONFIG_WDT_MAX6370) += max6370_wdt.o
>   obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
>   obj-$(CONFIG_WDT_MT7620) += mt7620_wdt.o
>   obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
> diff --git a/drivers/watchdog/max6370_wdt.c b/drivers/watchdog/max6370_wdt.c
> new file mode 100644
> index 000000000000..556c6a4b6d6b
> --- /dev/null
> +++ b/drivers/watchdog/max6370_wdt.c
> @@ -0,0 +1,119 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +// (C) 2022 Pali Rohár <pali at kernel.org>
> +
> +#include <common.h>

AFAIK, it's not recommended any more to include "common.h" in general.

Looks good, other than this:

Reviewed-by: Stefan Roese <sr at denx.de>

Thanks,
Stefan

> +#include <asm/io.h>
> +#include <asm-generic/gpio.h>
> +#include <dm.h>
> +#include <linux/delay.h>
> +#include <wdt.h>
> +
> +#define MAX6370_SET_MASK	0x7
> +#define MAX6370_SET_1MS		0x0
> +#define MAX6370_SET_10MS	0x1
> +#define MAX6370_SET_30MS	0x2
> +#define MAX6370_SET_DISABLE	0x3
> +#define MAX6370_SET_100MS	0x4
> +#define MAX6370_SET_1S		0x5
> +#define MAX6370_SET_10S		0x6
> +#define MAX6370_SET_60S		0x7
> +
> +#define MAX6370_WDI		0x8
> +
> +struct max6370_wdt {
> +	void __iomem *reg;
> +	struct gpio_desc gpio_wdi;
> +};
> +
> +static int max6370_wdt_start(struct udevice *dev, u64 ms, ulong flags)
> +{
> +	struct max6370_wdt *wdt = dev_get_priv(dev);
> +	u8 val;
> +
> +	val = readb(wdt->reg);
> +	val &= ~MAX6370_SET_MASK;
> +
> +	if (ms <= 1)
> +		val |= MAX6370_SET_1MS;
> +	else if (ms <= 10)
> +		val |= MAX6370_SET_10MS;
> +	else if (ms <= 30)
> +		val |= MAX6370_SET_30MS;
> +	else if (ms <= 100)
> +		val |= MAX6370_SET_100MS;
> +	else if (ms <= 1000)
> +		val |= MAX6370_SET_1S;
> +	else if (ms <= 10000)
> +		val |= MAX6370_SET_10S;
> +	else
> +		val |= MAX6370_SET_60S;
> +
> +	writeb(val, wdt->reg);
> +
> +	return 0;
> +}
> +
> +static int max6370_wdt_stop(struct udevice *dev)
> +{
> +	struct max6370_wdt *wdt = dev_get_priv(dev);
> +	u8 val;
> +
> +	val = readb(wdt->reg);
> +	val &= ~MAX6370_SET_MASK;
> +	val |= MAX6370_SET_DISABLE;
> +	writeb(val, wdt->reg);
> +
> +	return 0;
> +}
> +
> +static int max6370_wdt_reset(struct udevice *dev)
> +{
> +	struct max6370_wdt *wdt = dev_get_priv(dev);
> +	u8 val;
> +
> +	if (dm_gpio_is_valid(&wdt->gpio_wdi)) {
> +		dm_gpio_set_value(&wdt->gpio_wdi, 1);
> +		udelay(1);
> +		dm_gpio_set_value(&wdt->gpio_wdi, 0);
> +	} else {
> +		val = readb(wdt->reg);
> +		writeb(val | MAX6370_WDI, wdt->reg);
> +		writeb(val & ~MAX6370_WDI, wdt->reg);
> +	}
> +
> +	return 0;
> +}
> +
> +static int max6370_wdt_probe(struct udevice *dev)
> +{
> +	struct max6370_wdt *wdt = dev_get_priv(dev);
> +
> +	wdt->reg = dev_read_addr_ptr(dev);
> +	if (!wdt->reg)
> +		return -EINVAL;
> +
> +	/* WDI gpio is optional */
> +	gpio_request_by_name(dev, "gpios", 0, &wdt->gpio_wdi, GPIOD_IS_OUT);
> +
> +	return 0;
> +}
> +
> +static const struct wdt_ops max6370_wdt_ops = {
> +	.start = max6370_wdt_start,
> +	.stop = max6370_wdt_stop,
> +	.reset = max6370_wdt_reset,
> +};
> +
> +static const struct udevice_id max6370_wdt_ids[] = {
> +	{ .compatible = "maxim,max6370" },
> +	{}
> +};
> +
> +U_BOOT_DRIVER(max6370_wdt) = {
> +	.name = "max6370_wdt",
> +	.id = UCLASS_WDT,
> +	.of_match = max6370_wdt_ids,
> +	.probe = max6370_wdt_probe,
> +	.priv_auto = sizeof(struct max6370_wdt),
> +	.ops = &max6370_wdt_ops,
> +};

Viele Grüße,
Stefan Roese

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de


More information about the U-Boot mailing list