[PATCH v2 5/5] watchdog: aaeon: Add watchdog driver for SRG-IMX8PL MCU
From: Thomas Perrot (Schneider Electric) <hidden>
Date: 2026-01-23 09:55:06
Also in:
imx, linux-devicetree, linux-gpio, linux-watchdog, lkml
Subsystem:
the rest, watchdog device drivers · Maintainers:
Linus Torvalds, Wim Van Sebroeck, Guenter Roeck
Add watchdog driver for the Aaeon SRG-IMX8PL embedded controller. This driver provides system monitoring and recovery capabilities through the MCU's watchdog timer. The watchdog supports start, stop, and ping operations with a maximum hardware heartbeat of 25 seconds and a default timeout of 240 seconds. The driver assumes the watchdog is already running at probe time, as the MCU typically enables it by default. Co-developed-by: Jérémie Dautheribes (Schneider Electric) <redacted> Signed-off-by: Jérémie Dautheribes (Schneider Electric) <redacted> Signed-off-by: Thomas Perrot (Schneider Electric) <redacted> --- MAINTAINERS | 1 + drivers/watchdog/Kconfig | 10 ++++ drivers/watchdog/Makefile | 1 + drivers/watchdog/aaeon_mcu_wdt.c | 110 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 28dd964cdf69bdcaec3eb82d6df851a2bad47415..66cc4a5dcbe0977e6baee6d3b5e6023dcc06847b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS@@ -193,6 +193,7 @@ S: Maintained F: Documentation/devicetree/bindings/mfd/aaeon,srg-imx8pl-mcu.yaml F: drivers/gpio/gpio-aaeon-mcu.c F: drivers/mfd/aaeon-mcu.c +F: drivers/watchdog/aaeon_mcu_wdt.c F: include/linux/mfd/aaeon-mcu.h AAEON UPBOARD FPGA MFD DRIVER
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index d3b9df7d466b0b7215ee87b3040811d44ee53d2a..1bd4a7bee303e5e2508f540dc2c16e9e19ed18b0 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig@@ -168,6 +168,16 @@ config SOFT_WATCHDOG_PRETIMEOUT watchdog. Be aware that governors might affect the watchdog because it is purely software, e.g. the panic governor will stall it! +config AAEON_MCU_WATCHDOG + tristate "Aaeon MCU Watchdog" + depends on MFD_AAEON_MCU + select WATCHDOG_CORE + help + Select this option to enable watchdog timer support for the Aaeon + SRG-IMX8PL onboard microcontroller (MCU). This driver provides + watchdog functionality through the MCU, allowing system monitoring + and automatic recovery from system hangs. + config BD957XMUF_WATCHDOG tristate "ROHM BD9576MUF and BD9573MUF PMIC Watchdog" depends on MFD_ROHM_BD957XMUF
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index ba52099b125398a32f80dad23317e223cc4af028..2deec425d3eafb6b208e061fda9f216f4baa8ecc 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile@@ -37,6 +37,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o # ALPHA Architecture # ARM Architecture +obj-$(CONFIG_AAEON_MCU_WATCHDOG) += aaeon_mcu_wdt.o obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o obj-$(CONFIG_ARM_SBSA_WATCHDOG) += sbsa_gwdt.o obj-$(CONFIG_ARMADA_37XX_WATCHDOG) += armada_37xx_wdt.o
diff --git a/drivers/watchdog/aaeon_mcu_wdt.c b/drivers/watchdog/aaeon_mcu_wdt.c
new file mode 100644
index 0000000000000000000000000000000000000000..99be3ce327f44063fce6ba77a7d4efcba34361df
--- /dev/null
+++ b/drivers/watchdog/aaeon_mcu_wdt.c@@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Aaeon MCU Watchdog driver + * + * Copyright (C) 2025 Bootlin + * Author: Jérémie Dautheribes <jeremie.dautheribes@bootlin.com> + * Author: Thomas Perrot <thomas.perrot@bootlin.com> + */ + +#include <linux/mfd/aaeon-mcu.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/watchdog.h> + +#define AAEON_MCU_CONTROL_WDT 0x63 +#define AAEON_MCU_PING_WDT 0x73 + +#define AAEON_MCU_WDT_TIMEOUT 240 +#define AAEON_MCU_WDT_HEARTBEAT_MS 25000 + +struct aaeon_mcu_wdt { + struct watchdog_device wdt; + struct device *dev; +}; + +static int aaeon_mcu_wdt_cmd(struct device *dev, u8 opcode, u8 arg) +{ + u8 cmd[3] = { opcode, arg, 0x00 }; + u8 rsp; + + return aaeon_mcu_i2c_xfer(dev, cmd, sizeof(cmd), &rsp, sizeof(rsp)); +} + +static int aaeon_mcu_wdt_start(struct watchdog_device *wdt) +{ + struct aaeon_mcu_wdt *data = watchdog_get_drvdata(wdt); + + return aaeon_mcu_wdt_cmd(data->dev, AAEON_MCU_CONTROL_WDT, 0x01); +} + +static int aaeon_mcu_wdt_stop(struct watchdog_device *wdt) +{ + struct aaeon_mcu_wdt *data = watchdog_get_drvdata(wdt); + + return aaeon_mcu_wdt_cmd(data->dev, AAEON_MCU_CONTROL_WDT, 0x00); +} + +static int aaeon_mcu_wdt_ping(struct watchdog_device *wdt) +{ + struct aaeon_mcu_wdt *data = watchdog_get_drvdata(wdt); + + return aaeon_mcu_wdt_cmd(data->dev, AAEON_MCU_PING_WDT, 0x00); +} + +static const struct watchdog_info aaeon_mcu_wdt_info = { + .identity = "Aaeon MCU Watchdog", + .options = WDIOF_KEEPALIVEPING +}; + +static const struct watchdog_ops aaeon_mcu_wdt_ops = { + .owner = THIS_MODULE, + .start = aaeon_mcu_wdt_start, + .stop = aaeon_mcu_wdt_stop, + .ping = aaeon_mcu_wdt_ping, +}; + +static int aaeon_mcu_wdt_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct watchdog_device *wdt; + struct aaeon_mcu_wdt *data; + int ret; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->dev = dev->parent; + + wdt = &data->wdt; + wdt->parent = dev; + wdt->info = &aaeon_mcu_wdt_info; + wdt->ops = &aaeon_mcu_wdt_ops; + wdt->timeout = AAEON_MCU_WDT_TIMEOUT; + wdt->max_hw_heartbeat_ms = AAEON_MCU_WDT_HEARTBEAT_MS; + + watchdog_set_drvdata(wdt, data); + platform_set_drvdata(pdev, data); + + ret = aaeon_mcu_wdt_start(wdt); + if (ret) + return ret; + + set_bit(WDOG_HW_RUNNING, &wdt->status); + + return devm_watchdog_register_device(dev, wdt); +} + +static struct platform_driver aaeon_mcu_wdt_driver = { + .driver = { + .name = "aaeon-mcu-wdt", + }, + .probe = aaeon_mcu_wdt_probe, +}; + +module_platform_driver(aaeon_mcu_wdt_driver); + +MODULE_DESCRIPTION("Aaeon MCU Watchdog Driver"); +MODULE_AUTHOR("Jérémie Dautheribes <jeremie.dautheribes@bootlin.com>"); +MODULE_LICENSE("GPL");
--
2.52.0