[PATCH v5 3/5] watchdog: w83627hf_wdt: Move register offsets into driver data

From: Paul Louvel

Date: Tue Oct 20 2026 - 04:15:03 EST


Register offsets for the watchdog timer, control, and status registers
differ across Super I/O chip variants. Store them in the driver data
instead of global variables.

Signed-off-by: Paul Louvel <paul.louvel@xxxxxxxxxxx>
---
drivers/watchdog/w83627hf_wdt.c | 93 ++++++++++++++++++++++++++---------------
1 file changed, 59 insertions(+), 34 deletions(-)

diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index 96ea278e45c4..fc3703b38141 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -42,9 +42,6 @@
#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */

static int wdt_io;
-static int cr_wdt_timeout; /* WDT timeout register */
-static int cr_wdt_control; /* WDT control register */
-static int cr_wdt_csr; /* WDT control & status register */
static int wdt_cfg_enter = 0x87;/* key to unlock configuration space */
static int wdt_cfg_leave = 0xAA;/* key to lock configuration space */

@@ -130,9 +127,16 @@ MODULE_PARM_DESC(early_disable, "Disable watchdog at boot time (default=0)");
#define WDT_CTRL_RISING_EDGE_KBD_RESET BIT(2)
#define WDT_CTRL_MINUTE_MODE BIT(3)

+struct w83627hf_reg {
+ int control;
+ int timeout;
+ int csr;
+};
+
struct w83627hf_data {
struct watchdog_device wdd;
struct watchdog_info info;
+ const struct w83627hf_reg *reg;
};

static void superio_outb(int reg, int val)
@@ -171,6 +175,7 @@ static void superio_exit(void)

static int w83627hf_init(struct watchdog_device *wdog, enum chips chip)
{
+ struct w83627hf_data *data = watchdog_get_drvdata(wdog);
int ret;
unsigned char t;

@@ -210,10 +215,10 @@ static int w83627hf_init(struct watchdog_device *wdog, enum chips chip)
case w83627dhg_p:
t = superio_inb(0x2D) & ~0x01; /* PIN77 -> WDT0# */
superio_outb(0x2D, t); /* set GPIO5 to WDT0 */
- t = superio_inb(cr_wdt_control);
+ t = superio_inb(data->reg->control);
t |= 0x02; /* enable the WDTO# output low pulse
* to the KBRST# pin */
- superio_outb(cr_wdt_control, t);
+ superio_outb(data->reg->control, t);
break;
case w83637hf:
break;
@@ -242,46 +247,47 @@ static int w83627hf_init(struct watchdog_device *wdog, enum chips chip)
* Don't touch its configuration, and hope the BIOS
* does the right thing.
*/
- t = superio_inb(cr_wdt_control);
+ t = superio_inb(data->reg->control);
t |= 0x02; /* enable the WDTO# output low pulse
* to the KBRST# pin */
- superio_outb(cr_wdt_control, t);
+ superio_outb(data->reg->control, t);
break;
default:
break;
}

- t = superio_inb(cr_wdt_timeout);
+ t = superio_inb(data->reg->timeout);
if (t != 0) {
if (early_disable) {
pr_warn("Stopping previously enabled watchdog until userland kicks in\n");
- superio_outb(cr_wdt_timeout, 0);
+ superio_outb(data->reg->timeout, 0);
} else {
pr_info("Watchdog already running. Resetting timeout to %d sec\n",
wdog->timeout);
- superio_outb(cr_wdt_timeout, wdog->timeout);
+ superio_outb(data->reg->timeout, wdog->timeout);
set_bit(WDOG_HW_RUNNING, &wdog->status);
}
}

- t = superio_inb(cr_wdt_control) &
+ t = superio_inb(data->reg->control) &
~(WDT_CTRL_MINUTE_MODE | WDT_CTRL_RISING_EDGE_KBD_RESET);
- superio_outb(cr_wdt_control, t);
+ superio_outb(data->reg->control, t);

- t = superio_inb(cr_wdt_csr);
+ t = superio_inb(data->reg->csr);
if (t & WDT_CSR_STATUS)
wdog->bootstatus |= WDIOF_CARDRESET;

t &= ~(WDT_CSR_STATUS | WDT_CSR_KBD_INT_RESET | WDT_CSR_MOUSE_INT_RESET);
- superio_outb(cr_wdt_csr, t);
+ superio_outb(data->reg->csr, t);

superio_exit();

return 0;
}

-static int wdt_set_time(unsigned int timeout)
+static int wdt_set_time(struct watchdog_device *wdog, unsigned int timeout)
{
+ struct w83627hf_data *data = watchdog_get_drvdata(wdog);
int ret;

ret = superio_enter();
@@ -289,7 +295,7 @@ static int wdt_set_time(unsigned int timeout)
return ret;

superio_select(W83627HF_LD_WDT);
- superio_outb(cr_wdt_timeout, timeout);
+ superio_outb(data->reg->timeout, timeout);
superio_exit();

return 0;
@@ -297,12 +303,12 @@ static int wdt_set_time(unsigned int timeout)

static int wdt_start(struct watchdog_device *wdog)
{
- return wdt_set_time(wdog->timeout);
+ return wdt_set_time(wdog, wdog->timeout);
}

static int wdt_stop(struct watchdog_device *wdog)
{
- return wdt_set_time(0);
+ return wdt_set_time(wdog, 0);
}

static int wdt_set_timeout(struct watchdog_device *wdog, unsigned int timeout)
@@ -314,6 +320,7 @@ static int wdt_set_timeout(struct watchdog_device *wdog, unsigned int timeout)

static unsigned int wdt_get_time(struct watchdog_device *wdog)
{
+ struct w83627hf_data *data = watchdog_get_drvdata(wdog);
unsigned int timeleft;
int ret;

@@ -322,7 +329,7 @@ static unsigned int wdt_get_time(struct watchdog_device *wdog)
return 0;

superio_select(W83627HF_LD_WDT);
- timeleft = superio_inb(cr_wdt_timeout);
+ timeleft = superio_inb(data->reg->timeout);
superio_exit();

return timeleft;
@@ -350,10 +357,6 @@ static int wdt_find(int addr)
u8 val;
int ret;

- cr_wdt_timeout = W83627HF_WDT_TIMEOUT;
- cr_wdt_control = W83627HF_WDT_CONTROL;
- cr_wdt_csr = W836X7HF_WDT_CSR;
-
ret = superio_enter();
if (ret)
return ret;
@@ -368,13 +371,9 @@ static int wdt_find(int addr)
break;
case W83697HF_ID:
ret = w83697hf;
- cr_wdt_timeout = W83697HF_WDT_TIMEOUT;
- cr_wdt_control = W83697HF_WDT_CONTROL;
break;
case W83697UG_ID:
ret = w83697ug;
- cr_wdt_timeout = W83697HF_WDT_TIMEOUT;
- cr_wdt_control = W83697HF_WDT_CONTROL;
break;
case W83637HF_ID:
ret = w83637hf;
@@ -429,9 +428,6 @@ static int wdt_find(int addr)
break;
case NCT6102_ID:
ret = nct6102;
- cr_wdt_timeout = NCT6102D_WDT_TIMEOUT;
- cr_wdt_control = NCT6102D_WDT_CONTROL;
- cr_wdt_csr = NCT6102D_WDT_CSR;
break;
case NCT6116_ID:
val = superio_inb(SIO_REG_DEVID + 1);
@@ -439,10 +435,6 @@ static int wdt_find(int addr)
ret = nct6126;
else
ret = nct6116;
-
- cr_wdt_timeout = NCT6102D_WDT_TIMEOUT;
- cr_wdt_control = NCT6102D_WDT_CONTROL;
- cr_wdt_csr = NCT6102D_WDT_CSR;
break;
case 0xff:
ret = -ENODEV;
@@ -456,6 +448,24 @@ static int wdt_find(int addr)
return ret;
}

+static const struct w83627hf_reg w83627hf_default_regs = {
+ .timeout = W83627HF_WDT_TIMEOUT,
+ .control = W83627HF_WDT_CONTROL,
+ .csr = W836X7HF_WDT_CSR
+};
+
+static const struct w83627hf_reg w83627hf_nct61xx_regs = {
+ .timeout = NCT6102D_WDT_TIMEOUT,
+ .control = NCT6102D_WDT_CONTROL,
+ .csr = NCT6102D_WDT_CSR
+};
+
+static const struct w83627hf_reg w83627hf_w83697xx_regs = {
+ .timeout = W83697HF_WDT_TIMEOUT,
+ .control = W83697HF_WDT_CONTROL,
+ .csr = W836X7HF_WDT_CSR
+};
+
static int wdt_probe(struct platform_device *pdev)
{
const struct platform_device_id *id = platform_get_device_id(pdev);
@@ -489,6 +499,21 @@ static int wdt_probe(struct platform_device *pdev)
wdd->min_timeout = 1;
wdd->max_timeout = 255;

+ switch (chip) {
+ case nct6102:
+ case nct6116:
+ case nct6126:
+ data->reg = &w83627hf_nct61xx_regs;
+ break;
+ case w83697hf:
+ case w83697ug:
+ data->reg = &w83627hf_w83697xx_regs;
+ break;
+ default:
+ data->reg = &w83627hf_default_regs;
+ break;
+ }
+
watchdog_set_drvdata(wdd, data);
watchdog_init_timeout(wdd, timeout, NULL);
watchdog_set_nowayout(wdd, nowayout);

--
2.56.0