[PATCH] watchdog: Add MAX6370 watchdog timer driver

MAX6370 watchdog is available e.g. on Freescale P1/P2 RDB-PC boards.
Signed-off-by: Pali Rohár pali@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@kernel.org + +#include <common.h> +#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, +};

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@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@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@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

On Tuesday 03 May 2022 07:16:34 Stefan Roese wrote:
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@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@kernel.org
+#include <common.h>
AFAIK, it's not recommended any more to include "common.h" in general.
Hello! I checked that driver compiles without any errors/warnings also when common.h is removed. So it can be dropped.
Looks good, other than this:
Reviewed-by: Stefan Roese sr@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@denx.de

On Thursday 05 May 2022 11:36:09 Pali Rohár wrote:
On Tuesday 03 May 2022 07:16:34 Stefan Roese wrote:
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@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@kernel.org
+#include <common.h>
AFAIK, it's not recommended any more to include "common.h" in general.
Hello! I checked that driver compiles without any errors/warnings also when common.h is removed. So it can be dropped.
I have tested this driver on P2020 board. Together with P2020 board code workaround which I sent in separate patch, watchdog is working correctly https://patchwork.ozlabs.org/project/uboot/patch/20220501122314.32626-2-pali...
Looks good, other than this:
Reviewed-by: Stefan Roese sr@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@denx.de

On 05.05.22 19:15, Pali Rohár wrote:
On Thursday 05 May 2022 11:36:09 Pali Rohár wrote:
On Tuesday 03 May 2022 07:16:34 Stefan Roese wrote:
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@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@kernel.org
+#include <common.h>
AFAIK, it's not recommended any more to include "common.h" in general.
Hello! I checked that driver compiles without any errors/warnings also when common.h is removed. So it can be dropped.
I have tested this driver on P2020 board. Together with P2020 board code workaround which I sent in separate patch, watchdog is working correctly https://patchwork.ozlabs.org/project/uboot/patch/20220501122314.32626-2-pali...
Good. I'll send a pull request for the MAX6370 watchdog driver later today. I've removed including "common.h" here.
Thanks, Stefan
Looks good, other than this:
Reviewed-by: Stefan Roese sr@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@denx.de
Viele Grüße, Stefan Roese

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@kernel.org
Applied to u-boot-watchdog/master
Thanks, Stefan
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@kernel.org
+#include <common.h> +#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
participants (2)
-
Pali Rohár
-
Stefan Roese