diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 688922fc4edb..afe14f530291 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1055,6 +1055,13 @@ config ADVANTECH_WDT
 	  feature. More information can be found at
 	  <https://www.advantech.com.tw/products/>
 
+config ADVANTECH_EC_WDT
+	tristate "Advantech Embedded Controller Watchdog Timer"
+	depends on X86
+	help
+	   	This driver supports Advantech products with ITE based Embedded Controller.
+ 		It does not support Advantech products with other ECs or without EC.
+
 config ALIM1535_WDT
 	tristate "ALi M1535 PMU Watchdog Timer"
 	depends on X86 && PCI
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index cdeb119e6e61..2768dc2348af 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -102,6 +102,7 @@ obj-$(CONFIG_SUNPLUS_WATCHDOG) += sunplus_wdt.o
 # X86 (i386 + ia64 + x86_64) Architecture
 obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
 obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
+obj-$(CONFIG_ADVANTECH_EC_WDT) += advantech_ec_wdt.o
 obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
 obj-$(CONFIG_EBC_C384_WDT) += ebc-c384_wdt.o
diff --git a/drivers/watchdog/advantech_ec_wdt.c b/drivers/watchdog/advantech_ec_wdt.c
new file mode 100644
index 000000000000..f3babaa918f7
--- /dev/null
+++ b/drivers/watchdog/advantech_ec_wdt.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *	Advantech Embedded Controller Watchdog Driver
+ *
+ *	This driver supports Advantech products with ITE based Embedded Controller.
+ *	It does not support Advantech products with other ECs or without EC.
+ *
+ *	This software is provided "as is" without warranty of any kind.
+ *
+ *	Copyright (C) 2022 Advantech Europe B.V.
+ *	<thomas.kastner@advantech.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/isa.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+#include <linux/spinlock.h>
+
+#define DRIVER_NAME		"advantech_ec_wdt"
+
+/* EC IO region */
+#define BASE_ADDR		0x299
+#define ADDR_EXTENT		2
+
+/* EC interface definitions */
+#define EC_ADDR_CMD		0x29A
+#define EC_ADDR_DATA		0x299
+#define EC_CMD_EC_PROBE		0x30
+#define EC_CMD_COMM		0x89
+#define EC_CMD_WDT_START	0x28
+#define EC_CMD_WDT_STOP		0x29
+#define EC_CMD_WDT_RESET	0x2A
+#define EC_DAT_EN_DLY_H		0x58
+#define EC_DAT_EN_DLY_L		0x59
+#define EC_DAT_RST_DLY_H	0x5E
+#define EC_DAT_RST_DLY_L	0x5F
+#define EC_MAGIC		0x95
+
+/* module parameters */
+#define MIN_TIME		1
+#define MAX_TIME		6000 /* 100 minutes */
+#define DEFAULT_TIME		60
+
+static unsigned int timeout = DEFAULT_TIME;
+module_param(timeout, uint, 0);
+MODULE_PARM_DESC(timeout,
+	"Default Watchdog timer setting ("
+	__MODULE_STRING(DEFAULT_TIME) "s)."
+	"The range is from " __MODULE_STRING(MIN_TIME)
+	" to " __MODULE_STRING(MAX_TIME) ".");
+
+static int adv_ec_wdt_ping(struct watchdog_device *wdd)
+{
+	pr_debug("%s: Strobing watchdog\n", __func__);
+
+	/* reset watchdog */
+	outb(EC_CMD_WDT_RESET, EC_ADDR_CMD);
+	usleep_range(10000, 11000);
+	return 0;
+}
+
+static int adv_ec_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
+{
+	unsigned int val;
+
+	/* scale time to EC 100 ms base */
+	val = t*10;
+
+	pr_debug("%s: Setting timeout value of %i\n", __func__, val);
+	/* reset enable delay, just in case it was set by BIOS etc. */
+	outb(EC_CMD_COMM, EC_ADDR_CMD);
+	usleep_range(10000, 11000);
+	outb(EC_DAT_EN_DLY_H, EC_ADDR_DATA);
+	usleep_range(10000, 11000);
+	outb(0, EC_ADDR_DATA);
+	usleep_range(10000, 11000);
+
+	outb(EC_CMD_COMM, EC_ADDR_CMD);
+	usleep_range(10000, 11000);
+	outb(EC_DAT_EN_DLY_L, EC_ADDR_DATA);
+	usleep_range(10000, 11000);
+	outb(0, EC_ADDR_DATA);
+	usleep_range(10000, 11000);
+
+	/* set reset delay */
+	outb(EC_CMD_COMM, EC_ADDR_CMD);
+	usleep_range(10000, 11000);
+	outb(EC_DAT_RST_DLY_H, EC_ADDR_DATA);
+	usleep_range(10000, 11000);
+	outb((val >> 8), EC_ADDR_DATA);
+	usleep_range(10000, 11000);
+
+	outb(EC_CMD_COMM, EC_ADDR_CMD);
+	usleep_range(10000, 11000);
+	outb(EC_DAT_RST_DLY_L, EC_ADDR_DATA);
+	usleep_range(10000, 11000);
+	outb((val & 0xFF), EC_ADDR_DATA);
+	usleep_range(10000, 11000);
+
+	wdd->timeout = t;
+	return 0;
+}
+
+
+static int adv_ec_probe(void)
+{
+	unsigned int val;
+
+	/* Check for magic byte */
+	outb(EC_CMD_EC_PROBE, EC_ADDR_CMD);
+	usleep_range(10000, 11000);
+	val = inb(EC_ADDR_DATA);
+
+	pr_debug("%s: probe result: %02X\n", __func__, val);
+
+	if (val == EC_MAGIC)
+		return 0;
+	else
+		return -ENODEV;
+}
+
+
+static int adv_ec_wdt_start(struct watchdog_device *wdd)
+{
+	adv_ec_wdt_set_timeout(wdd, wdd->timeout);
+
+	pr_debug("%s: Enabling watchdog timer\n", __func__);
+
+	/* Enable the watchdog timer */
+	outb(EC_CMD_WDT_START, EC_ADDR_CMD);
+	usleep_range(10000, 11000);
+
+	return 0;
+}
+
+static int adv_ec_wdt_stop(struct watchdog_device *wdd)
+{
+	pr_debug("%s: Disabling watchdog timer\n", __func__);
+
+	/* Disable the watchdog timer */
+	outb(EC_CMD_WDT_STOP, EC_ADDR_CMD);
+	usleep_range(10000, 11000);
+
+	return 0;
+}
+
+static const struct watchdog_info adv_ec_wdt_info = {
+	.identity =	DRIVER_NAME,
+	.options =	WDIOF_SETTIMEOUT |
+			WDIOF_MAGICCLOSE |
+			WDIOF_KEEPALIVEPING,
+};
+
+static const struct watchdog_ops adv_ec_wdt_ops = {
+	.owner =	THIS_MODULE,
+	.start =	adv_ec_wdt_start,
+	.stop =		adv_ec_wdt_stop,
+	.ping =		adv_ec_wdt_ping,
+	.set_timeout =	adv_ec_wdt_set_timeout,
+};
+
+static struct watchdog_device adv_ec_wdt_dev = {
+	.info =		&adv_ec_wdt_info,
+	.ops =		&adv_ec_wdt_ops,
+	.min_timeout =	MIN_TIME,
+	.max_timeout =	MAX_TIME,
+};
+
+static int adv_ec_wdt_probe(struct device *dev, unsigned int id)
+{
+	int ret;
+
+	if (!devm_request_region(dev, BASE_ADDR, ADDR_EXTENT, dev_name(dev))) {
+		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
+			BASE_ADDR, BASE_ADDR + ADDR_EXTENT);
+		return -EBUSY;
+	}
+
+	/* probe for EC */
+	ret = adv_ec_probe();
+	if (ret) {
+		dev_err(dev, "Error: cannot detect Advantech EC\n");
+		return -ENODEV;
+	}
+
+	adv_ec_wdt_dev.timeout = timeout;
+
+	ret = devm_watchdog_register_device(dev, &adv_ec_wdt_dev);
+
+	return ret;
+}
+
+static void adv_ec_wdt_remove(struct device *dev, unsigned int id)
+{
+	/* stop the watchdog */
+	adv_ec_wdt_stop(NULL);
+
+	/* watchdog_unregister() and release_region() are called automatically */
+
+	return;
+}
+
+static struct isa_driver adv_ec_wdt_driver = {
+	.probe		= adv_ec_wdt_probe,
+	.remove		= adv_ec_wdt_remove,
+	.driver		= {
+	.name		= DRIVER_NAME,
+	},
+};
+
+
+static int __init adv_ec_wdt_init(void)
+{
+	/* Check boot parameters to verify that their initial values */
+	/* are in range. */
+	if ((timeout < MIN_TIME) ||
+	    (timeout > MAX_TIME)) {
+		pr_err("Watchdog timer: value of timeout %d (dec) "
+		  "is out of range from %d to %d (dec)\n",
+		  timeout, MIN_TIME, MAX_TIME);
+		return -EINVAL;
+	}
+
+	return isa_register_driver(&adv_ec_wdt_driver, 1);
+}
+
+static void __exit adv_ec_wdt_exit(void)
+{
+	isa_unregister_driver(&adv_ec_wdt_driver);
+}
+
+module_init(adv_ec_wdt_init);
+module_exit(adv_ec_wdt_exit);
+
+MODULE_AUTHOR("Thomas Kastner <thomas.kastne@advantech.com>");
+MODULE_DESCRIPTION("Advantech Embedded Controller Watchdog Device Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("20221012");
+MODULE_ALIAS("isa:" DRIVER_NAME);
