[PATCH v2 6/8] watchdog: w83627hf_wdt: Store Super I/O unlocking sequence in platform data
Paul Louvel <[email protected]> Sun, 26 Jul 2026 20:44:33 +0200
| Newsgroups | org.kernel.vger.linux-watchdog,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Instead of using two global variable, store the unlocking sequence in the platform data. Signed-off-by: Paul Louvel <[email protected]> --- drivers/watchdog/w83627hf_wdt.c | 59 ++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index a067b8ea6b28..064a99db80ef 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c @@ -41,9 +41,6 @@ #define WATCHDOG_NAME "w83627hf/thf/hg/dhg WDT" #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ -static int wdt_cfg_enter = 0x87;/* key to unlock configuration space */ -static int wdt_cfg_leave = 0xAA;/* key to lock configuration space */ - enum chips { w83627hf, w83627s, w83697hf, w83697ug, w83637hf, w83627thf, w83687thf, w83627ehf, w83627dhg, w83627uhg, w83667hg, w83627dhg_p, w83667hg_b, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793, @@ -121,6 +118,11 @@ 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 wdt_pdata { + int siocfg_enter; + int siocfg_leave; +}; + struct w83627hf_data { struct watchdog_device wdd; struct watchdog_info info; @@ -130,6 +132,8 @@ struct w83627hf_data { int csr; } reg; int sioaddr; + int siocfg_enter; + int siocfg_leave; }; static void superio_outb(int base, int reg, int val) @@ -144,13 +148,13 @@ static inline int superio_inb(int base, int reg) return inb(base + 1); } -static int superio_enter(int base) +static int superio_enter(int base, int enter) { if (!request_muxed_region(base, 2, WATCHDOG_NAME)) return -EBUSY; - outb_p(wdt_cfg_enter, base); /* Enter extended function mode */ - outb_p(wdt_cfg_enter, base); /* Again according to manual */ + outb_p(enter, base); /* Enter extended function mode */ + outb_p(enter, base); /* Again according to manual */ return 0; } @@ -160,9 +164,9 @@ static void superio_select(int base, int ld) superio_outb(base, SIO_REG_LDSEL, ld); } -static void superio_exit(int base) +static void superio_exit(int base, int leave) { - outb_p(wdt_cfg_leave, base); /* Leave extended function mode */ + outb_p(leave, base); /* Leave extended function mode */ release_region(base, 2); } @@ -172,7 +176,7 @@ static int w83627hf_init(struct watchdog_device *wdog, enum chips chip) int ret; unsigned char t; - ret = superio_enter(data->sioaddr); + ret = superio_enter(data->sioaddr, data->siocfg_enter); if (ret) return ret; @@ -275,7 +279,7 @@ static int w83627hf_init(struct watchdog_device *wdog, enum chips chip) t &= ~(WDT_CSR_STATUS | WDT_CSR_KBD_INT_RESET | WDT_CSR_MOUSE_INT_RESET); superio_outb(data->sioaddr, data->reg.csr, t); - superio_exit(data->sioaddr); + superio_exit(data->sioaddr, data->siocfg_leave); return 0; } @@ -285,13 +289,13 @@ 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(data->sioaddr); + ret = superio_enter(data->sioaddr, data->siocfg_enter); if (ret) return ret; superio_select(data->sioaddr, W83627HF_LD_WDT); superio_outb(data->sioaddr, data->reg.timeout, timeout); - superio_exit(data->sioaddr); + superio_exit(data->sioaddr, data->siocfg_leave); return 0; } @@ -319,13 +323,13 @@ static unsigned int wdt_get_time(struct watchdog_device *wdog) unsigned int timeleft; int ret; - ret = superio_enter(data->sioaddr); + ret = superio_enter(data->sioaddr, data->siocfg_enter); if (ret) return 0; superio_select(data->sioaddr, W83627HF_LD_WDT); timeleft = superio_inb(data->sioaddr, data->reg.timeout); - superio_exit(data->sioaddr); + superio_exit(data->sioaddr, data->siocfg_leave); return timeleft; } @@ -347,12 +351,12 @@ static const struct watchdog_ops wdt_ops = { * turn the timebomb registers off. */ -static int wdt_find(int addr) +static int wdt_find(int addr, int enter, int leave) { u8 val; int ret; - ret = superio_enter(addr); + ret = superio_enter(addr, enter); if (ret) return ret; superio_select(addr, W83627HF_LD_WDT); @@ -439,13 +443,14 @@ static int wdt_find(int addr) pr_err("Unsupported chip ID: 0x%02x\n", val); break; } - superio_exit(addr); + superio_exit(addr, leave); return ret; } static int wdt_probe(struct platform_device *pdev) { const struct platform_device_id *id = platform_get_device_id(pdev); + const struct wdt_pdata *pdata = pdev->dev.platform_data; enum chips chip = id->driver_data; struct device *dev = &pdev->dev; struct watchdog_device *wdd; @@ -476,6 +481,8 @@ static int wdt_probe(struct platform_device *pdev) wdd->max_timeout = 255; data->sioaddr = res->start; + data->siocfg_enter = pdata->siocfg_enter; + data->siocfg_leave = pdata->siocfg_leave; data->reg.timeout = W83627HF_WDT_TIMEOUT; data->reg.control = W83627HF_WDT_CONTROL; data->reg.csr = W836X7HF_WDT_CSR; @@ -517,12 +524,16 @@ static int wdt_probe(struct platform_device *pdev) */ static int __init wdt_use_alt_key(const struct dmi_system_id *d) { - wdt_cfg_enter = 0x88; - wdt_cfg_leave = 0xBB; + struct wdt_pdata *pdata = d->driver_data; + + pdata->siocfg_enter = 0x88; + pdata->siocfg_leave = 0xBB; return 0; } +static struct wdt_pdata pdata; + static const struct dmi_system_id wdt_dmi_table[] __initconst = { { .matches = { @@ -532,6 +543,7 @@ static const struct dmi_system_id wdt_dmi_table[] __initconst = { DMI_EXACT_MATCH(DMI_BOARD_NAME, "SHARKBAY"), }, .callback = wdt_use_alt_key, + .driver_data = &pdata, }, {} }; @@ -581,14 +593,17 @@ static int __init wdt_init(void) int ret; int chip; + pdata.siocfg_enter = 0x87; + pdata.siocfg_leave = 0xAA; + /* Apply system-specific quirks */ dmi_check_system(wdt_dmi_table); sioaddr = SIO_REG_CONF_ADDR0; - chip = wdt_find(sioaddr); + chip = wdt_find(sioaddr, pdata.siocfg_enter, pdata.siocfg_leave); if (chip < 0) { sioaddr = SIO_REG_CONF_ADDR1; - chip = wdt_find(sioaddr); + chip = wdt_find(sioaddr, pdata.siocfg_enter, pdata.siocfg_leave); if (chip < 0) return chip; } @@ -604,7 +619,7 @@ static int __init wdt_init(void) wdt_pdev = platform_device_register_resndata(NULL, wdt_ids[chip].name, PLATFORM_DEVID_NONE, &res, - 1, NULL, 0); + 1, &pdata, sizeof(pdata)); if (IS_ERR(wdt_pdev)) { platform_driver_unregister(&wdt_driver); return PTR_ERR(wdt_pdev); -- 2.55.0