[PATCH] watchdog: i6300esb: do not stop an already running watchdog

From: Jan Kiszka

Date: Wed Sep 09 2026 - 07:24:23 EST


From: Jan Kiszka <jan.kiszka@xxxxxxxxxxx>

esb_initdevice() unconditionally disabled the WDT, stopping a
watchdog that firmware had left running instead of taking over its
care. Detect the enable bit in the lock register, set
WDOG_HW_RUNNING like the other watchdog drivers do, and simply
reset the timeout to the configured value.

Assisted-by: opencode:Qwen3.8-27B
Signed-off-by: Jan Kiszka <jan.kiszka@xxxxxxxxxxx>
---

Background to patch this: The i6300esb is the only watchdog model that
QEMU provides for non-x86 virt machines. It can serve there to test
complex system integrations. Patches to add a U-Boot driver were sent as
well:
https://lore.kernel.org/u-boot/cover.1788526864.git.jan.kiszka@xxxxxxxxxxx/

Background for this unusual as assistance: While crafting this with own
hands or using some cloud-hosted frontier model would have been much
quicker, I used this practical case to try out what could be done in the
background on my ordinary notebook already. Reviewing, testing (it
worked immediately) and a bit shortening was done by me, analysis and
patch fell out of the opencode after some half-day of thinking.

drivers/watchdog/i6300esb.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index a30835f547b3..13daafe05c43 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -264,13 +264,21 @@ static void esb_initdevice(struct esb_dev *edev)
*/
pci_write_config_word(edev->pdev, ESB_CONFIG_REG, 0x0003);

- /* Check that the WDT isn't already locked */
+ /* Check the current state of the WDT */
pci_read_config_byte(edev->pdev, ESB_LOCK_REG, &val1);
if (val1 & ESB_WDT_LOCK)
dev_warn(&edev->pdev->dev, "nowayout already set\n");

- /* Set the timer to watchdog mode and disable it for now */
- pci_write_config_byte(edev->pdev, ESB_LOCK_REG, 0x00);
+ if (val1 & ESB_WDT_ENABLE) {
+ /*
+ * The watchdog is already running, e.g. enabled by
+ * firmware. Do not stop it, just mark it as running.
+ */
+ set_bit(WDOG_HW_RUNNING, &edev->wdd.status);
+ } else {
+ /* Set the timer to watchdog mode and disable it for now */
+ pci_write_config_byte(edev->pdev, ESB_LOCK_REG, 0x00);
+ }

/* Check if the watchdog was previously triggered */
esb_unlock_registers(edev);
@@ -301,7 +309,10 @@ static int esb_probe(struct pci_dev *pdev,
if (!esb_getdevice(edev))
return -ENODEV;

- /* Initialize the watchdog and make sure it does not run */
+ /*
+ * Initialize the watchdog, keeping it running if it was already
+ * started, e.g. by firmware.
+ */
edev->wdd.info = &esb_info;
edev->wdd.ops = &esb_ops;
edev->wdd.min_timeout = ESB_HEARTBEAT_MIN;
--
2.47.3