1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * w83627hf/thf WDT driver 4 * 5 * (c) Copyright 2013 Guenter Roeck 6 * converted to watchdog infrastructure 7 * 8 * (c) Copyright 2007 Vlad Drukker <vlad@storewiz.com> 9 * added support for W83627THF. 10 * 11 * (c) Copyright 2003,2007 Pádraig Brady <P@draigBrady.com> 12 * 13 * Based on advantechwdt.c which is based on wdt.c. 14 * Original copyright messages: 15 * 16 * (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl> 17 * 18 * (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>, 19 * All Rights Reserved. 20 * 21 * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide 22 * warranty for any of this software. This material is provided 23 * "AS-IS" and at no charge. 24 * 25 * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk> 26 */ 27 28 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 29 30 #include <linux/module.h> 31 #include <linux/moduleparam.h> 32 #include <linux/types.h> 33 #include <linux/watchdog.h> 34 #include <linux/ioport.h> 35 #include <linux/init.h> 36 #include <linux/io.h> 37 #include <linux/dmi.h> 38 39 #define WATCHDOG_NAME "w83627hf/thf/hg/dhg WDT" 40 #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ 41 42 static int wdt_io; 43 static int cr_wdt_timeout; /* WDT timeout register */ 44 static int cr_wdt_control; /* WDT control register */ 45 static int cr_wdt_csr; /* WDT control & status register */ 46 static int wdt_cfg_enter = 0x87;/* key to unlock configuration space */ 47 static int wdt_cfg_leave = 0xAA;/* key to lock configuration space */ 48 49 enum chips { w83627hf, w83627s, w83697hf, w83697ug, w83637hf, w83627thf, 50 w83687thf, w83627ehf, w83627dhg, w83627uhg, w83667hg, w83627dhg_p, 51 w83667hg_b, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793, 52 nct6795, nct6796, nct6102 }; 53 54 static int timeout; /* in seconds */ 55 module_param(timeout, int, 0); 56 MODULE_PARM_DESC(timeout, 57 "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" 58 __MODULE_STRING(WATCHDOG_TIMEOUT) "."); 59 60 static bool nowayout = WATCHDOG_NOWAYOUT; 61 module_param(nowayout, bool, 0); 62 MODULE_PARM_DESC(nowayout, 63 "Watchdog cannot be stopped once started (default=" 64 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 65 66 static int early_disable; 67 module_param(early_disable, int, 0); 68 MODULE_PARM_DESC(early_disable, "Disable watchdog at boot time (default=0)"); 69 70 /* 71 * Kernel methods. 72 */ 73 74 #define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */ 75 #define WDT_EFIR (wdt_io+0) /* Extended Function Index Register 76 (same as EFER) */ 77 #define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ 78 79 #define W83627HF_LD_WDT 0x08 80 81 #define W83627HF_ID 0x52 82 #define W83627S_ID 0x59 83 #define W83697HF_ID 0x60 84 #define W83697UG_ID 0x68 85 #define W83637HF_ID 0x70 86 #define W83627THF_ID 0x82 87 #define W83687THF_ID 0x85 88 #define W83627EHF_ID 0x88 89 #define W83627DHG_ID 0xa0 90 #define W83627UHG_ID 0xa2 91 #define W83667HG_ID 0xa5 92 #define W83627DHG_P_ID 0xb0 93 #define W83667HG_B_ID 0xb3 94 #define NCT6775_ID 0xb4 95 #define NCT6776_ID 0xc3 96 #define NCT6102_ID 0xc4 97 #define NCT6779_ID 0xc5 98 #define NCT6791_ID 0xc8 99 #define NCT6792_ID 0xc9 100 #define NCT6793_ID 0xd1 101 #define NCT6795_ID 0xd3 102 #define NCT6796_ID 0xd4 /* also NCT9697D, NCT9698D */ 103 104 #define W83627HF_WDT_TIMEOUT 0xf6 105 #define W83697HF_WDT_TIMEOUT 0xf4 106 #define NCT6102D_WDT_TIMEOUT 0xf1 107 108 #define W83627HF_WDT_CONTROL 0xf5 109 #define W83697HF_WDT_CONTROL 0xf3 110 #define NCT6102D_WDT_CONTROL 0xf0 111 112 #define W836X7HF_WDT_CSR 0xf7 113 #define NCT6102D_WDT_CSR 0xf2 114 115 static void superio_outb(int reg, int val) 116 { 117 outb(reg, WDT_EFER); 118 outb(val, WDT_EFDR); 119 } 120 121 static inline int superio_inb(int reg) 122 { 123 outb(reg, WDT_EFER); 124 return inb(WDT_EFDR); 125 } 126 127 static int superio_enter(void) 128 { 129 if (!request_muxed_region(wdt_io, 2, WATCHDOG_NAME)) 130 return -EBUSY; 131 132 outb_p(wdt_cfg_enter, WDT_EFER); /* Enter extended function mode */ 133 outb_p(wdt_cfg_enter, WDT_EFER); /* Again according to manual */ 134 135 return 0; 136 } 137 138 static void superio_select(int ld) 139 { 140 superio_outb(0x07, ld); 141 } 142 143 static void superio_exit(void) 144 { 145 outb_p(wdt_cfg_leave, WDT_EFER); /* Leave extended function mode */ 146 release_region(wdt_io, 2); 147 } 148 149 static int w83627hf_init(struct watchdog_device *wdog, enum chips chip) 150 { 151 int ret; 152 unsigned char t; 153 154 ret = superio_enter(); 155 if (ret) 156 return ret; 157 158 superio_select(W83627HF_LD_WDT); 159 160 /* set CR30 bit 0 to activate GPIO2 */ 161 t = superio_inb(0x30); 162 if (!(t & 0x01)) 163 superio_outb(0x30, t | 0x01); 164 165 switch (chip) { 166 case w83627hf: 167 case w83627s: 168 t = superio_inb(0x2B) & ~0x10; 169 superio_outb(0x2B, t); /* set GPIO24 to WDT0 */ 170 break; 171 case w83697hf: 172 /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ 173 t = superio_inb(0x29) & ~0x60; 174 t |= 0x20; 175 superio_outb(0x29, t); 176 break; 177 case w83697ug: 178 /* Set pin 118 to WDTO# mode */ 179 t = superio_inb(0x2b) & ~0x04; 180 superio_outb(0x2b, t); 181 break; 182 case w83627thf: 183 t = (superio_inb(0x2B) & ~0x08) | 0x04; 184 superio_outb(0x2B, t); /* set GPIO3 to WDT0 */ 185 break; 186 case w83627dhg: 187 case w83627dhg_p: 188 t = superio_inb(0x2D) & ~0x01; /* PIN77 -> WDT0# */ 189 superio_outb(0x2D, t); /* set GPIO5 to WDT0 */ 190 t = superio_inb(cr_wdt_control); 191 t |= 0x02; /* enable the WDTO# output low pulse 192 * to the KBRST# pin */ 193 superio_outb(cr_wdt_control, t); 194 break; 195 case w83637hf: 196 break; 197 case w83687thf: 198 t = superio_inb(0x2C) & ~0x80; /* PIN47 -> WDT0# */ 199 superio_outb(0x2C, t); 200 break; 201 case w83627ehf: 202 case w83627uhg: 203 case w83667hg: 204 case w83667hg_b: 205 case nct6775: 206 case nct6776: 207 case nct6779: 208 case nct6791: 209 case nct6792: 210 case nct6793: 211 case nct6795: 212 case nct6796: 213 case nct6102: 214 /* 215 * These chips have a fixed WDTO# output pin (W83627UHG), 216 * or support more than one WDTO# output pin. 217 * Don't touch its configuration, and hope the BIOS 218 * does the right thing. 219 */ 220 t = superio_inb(cr_wdt_control); 221 t |= 0x02; /* enable the WDTO# output low pulse 222 * to the KBRST# pin */ 223 superio_outb(cr_wdt_control, t); 224 break; 225 default: 226 break; 227 } 228 229 t = superio_inb(cr_wdt_timeout); 230 if (t != 0) { 231 if (early_disable) { 232 pr_warn("Stopping previously enabled watchdog until userland kicks in\n"); 233 superio_outb(cr_wdt_timeout, 0); 234 } else { 235 pr_info("Watchdog already running. Resetting timeout to %d sec\n", 236 wdog->timeout); 237 superio_outb(cr_wdt_timeout, wdog->timeout); 238 } 239 } 240 241 /* set second mode & disable keyboard turning off watchdog */ 242 t = superio_inb(cr_wdt_control) & ~0x0C; 243 superio_outb(cr_wdt_control, t); 244 245 /* reset trigger, disable keyboard & mouse turning off watchdog */ 246 t = superio_inb(cr_wdt_csr) & ~0xD0; 247 superio_outb(cr_wdt_csr, t); 248 249 superio_exit(); 250 251 return 0; 252 } 253 254 static int wdt_set_time(unsigned int timeout) 255 { 256 int ret; 257 258 ret = superio_enter(); 259 if (ret) 260 return ret; 261 262 superio_select(W83627HF_LD_WDT); 263 superio_outb(cr_wdt_timeout, timeout); 264 superio_exit(); 265 266 return 0; 267 } 268 269 static int wdt_start(struct watchdog_device *wdog) 270 { 271 return wdt_set_time(wdog->timeout); 272 } 273 274 static int wdt_stop(struct watchdog_device *wdog) 275 { 276 return wdt_set_time(0); 277 } 278 279 static int wdt_set_timeout(struct watchdog_device *wdog, unsigned int timeout) 280 { 281 wdog->timeout = timeout; 282 283 return 0; 284 } 285 286 static unsigned int wdt_get_time(struct watchdog_device *wdog) 287 { 288 unsigned int timeleft; 289 int ret; 290 291 ret = superio_enter(); 292 if (ret) 293 return 0; 294 295 superio_select(W83627HF_LD_WDT); 296 timeleft = superio_inb(cr_wdt_timeout); 297 superio_exit(); 298 299 return timeleft; 300 } 301 302 /* 303 * Kernel Interfaces 304 */ 305 306 static const struct watchdog_info wdt_info = { 307 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 308 .identity = "W83627HF Watchdog", 309 }; 310 311 static const struct watchdog_ops wdt_ops = { 312 .owner = THIS_MODULE, 313 .start = wdt_start, 314 .stop = wdt_stop, 315 .set_timeout = wdt_set_timeout, 316 .get_timeleft = wdt_get_time, 317 }; 318 319 static struct watchdog_device wdt_dev = { 320 .info = &wdt_info, 321 .ops = &wdt_ops, 322 .timeout = WATCHDOG_TIMEOUT, 323 .min_timeout = 1, 324 .max_timeout = 255, 325 }; 326 327 /* 328 * The WDT needs to learn about soft shutdowns in order to 329 * turn the timebomb registers off. 330 */ 331 332 static int wdt_find(int addr) 333 { 334 u8 val; 335 int ret; 336 337 cr_wdt_timeout = W83627HF_WDT_TIMEOUT; 338 cr_wdt_control = W83627HF_WDT_CONTROL; 339 cr_wdt_csr = W836X7HF_WDT_CSR; 340 341 ret = superio_enter(); 342 if (ret) 343 return ret; 344 superio_select(W83627HF_LD_WDT); 345 val = superio_inb(0x20); 346 switch (val) { 347 case W83627HF_ID: 348 ret = w83627hf; 349 break; 350 case W83627S_ID: 351 ret = w83627s; 352 break; 353 case W83697HF_ID: 354 ret = w83697hf; 355 cr_wdt_timeout = W83697HF_WDT_TIMEOUT; 356 cr_wdt_control = W83697HF_WDT_CONTROL; 357 break; 358 case W83697UG_ID: 359 ret = w83697ug; 360 cr_wdt_timeout = W83697HF_WDT_TIMEOUT; 361 cr_wdt_control = W83697HF_WDT_CONTROL; 362 break; 363 case W83637HF_ID: 364 ret = w83637hf; 365 break; 366 case W83627THF_ID: 367 ret = w83627thf; 368 break; 369 case W83687THF_ID: 370 ret = w83687thf; 371 break; 372 case W83627EHF_ID: 373 ret = w83627ehf; 374 break; 375 case W83627DHG_ID: 376 ret = w83627dhg; 377 break; 378 case W83627DHG_P_ID: 379 ret = w83627dhg_p; 380 break; 381 case W83627UHG_ID: 382 ret = w83627uhg; 383 break; 384 case W83667HG_ID: 385 ret = w83667hg; 386 break; 387 case W83667HG_B_ID: 388 ret = w83667hg_b; 389 break; 390 case NCT6775_ID: 391 ret = nct6775; 392 break; 393 case NCT6776_ID: 394 ret = nct6776; 395 break; 396 case NCT6779_ID: 397 ret = nct6779; 398 break; 399 case NCT6791_ID: 400 ret = nct6791; 401 break; 402 case NCT6792_ID: 403 ret = nct6792; 404 break; 405 case NCT6793_ID: 406 ret = nct6793; 407 break; 408 case NCT6795_ID: 409 ret = nct6795; 410 break; 411 case NCT6796_ID: 412 ret = nct6796; 413 break; 414 case NCT6102_ID: 415 ret = nct6102; 416 cr_wdt_timeout = NCT6102D_WDT_TIMEOUT; 417 cr_wdt_control = NCT6102D_WDT_CONTROL; 418 cr_wdt_csr = NCT6102D_WDT_CSR; 419 break; 420 case 0xff: 421 ret = -ENODEV; 422 break; 423 default: 424 ret = -ENODEV; 425 pr_err("Unsupported chip ID: 0x%02x\n", val); 426 break; 427 } 428 superio_exit(); 429 return ret; 430 } 431 432 /* 433 * On some systems, the NCT6791D comes with a companion chip and the 434 * watchdog function is in this companion chip. We must use a different 435 * unlocking sequence to access the companion chip. 436 */ 437 static int __init wdt_use_alt_key(const struct dmi_system_id *d) 438 { 439 wdt_cfg_enter = 0x88; 440 wdt_cfg_leave = 0xBB; 441 442 return 0; 443 } 444 445 static const struct dmi_system_id wdt_dmi_table[] __initconst = { 446 { 447 .matches = { 448 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "INVES"), 449 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CTS"), 450 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "INVES"), 451 DMI_EXACT_MATCH(DMI_BOARD_NAME, "SHARKBAY"), 452 }, 453 .callback = wdt_use_alt_key, 454 }, 455 {} 456 }; 457 458 static int __init wdt_init(void) 459 { 460 int ret; 461 int chip; 462 static const char * const chip_name[] = { 463 "W83627HF", 464 "W83627S", 465 "W83697HF", 466 "W83697UG", 467 "W83637HF", 468 "W83627THF", 469 "W83687THF", 470 "W83627EHF", 471 "W83627DHG", 472 "W83627UHG", 473 "W83667HG", 474 "W83667DHG-P", 475 "W83667HG-B", 476 "NCT6775", 477 "NCT6776", 478 "NCT6779", 479 "NCT6791", 480 "NCT6792", 481 "NCT6793", 482 "NCT6795", 483 "NCT6796", 484 "NCT6102", 485 }; 486 487 /* Apply system-specific quirks */ 488 dmi_check_system(wdt_dmi_table); 489 490 wdt_io = 0x2e; 491 chip = wdt_find(0x2e); 492 if (chip < 0) { 493 wdt_io = 0x4e; 494 chip = wdt_find(0x4e); 495 if (chip < 0) 496 return chip; 497 } 498 499 pr_info("WDT driver for %s Super I/O chip initialising\n", 500 chip_name[chip]); 501 502 watchdog_init_timeout(&wdt_dev, timeout, NULL); 503 watchdog_set_nowayout(&wdt_dev, nowayout); 504 watchdog_stop_on_reboot(&wdt_dev); 505 506 ret = w83627hf_init(&wdt_dev, chip); 507 if (ret) { 508 pr_err("failed to initialize watchdog (err=%d)\n", ret); 509 return ret; 510 } 511 512 ret = watchdog_register_device(&wdt_dev); 513 if (ret) 514 return ret; 515 516 pr_info("initialized. timeout=%d sec (nowayout=%d)\n", 517 wdt_dev.timeout, nowayout); 518 519 return ret; 520 } 521 522 static void __exit wdt_exit(void) 523 { 524 watchdog_unregister_device(&wdt_dev); 525 } 526 527 module_init(wdt_init); 528 module_exit(wdt_exit); 529 530 MODULE_LICENSE("GPL"); 531 MODULE_AUTHOR("Pádraig Brady <P@draigBrady.com>"); 532 MODULE_DESCRIPTION("w83627hf/thf WDT driver"); 533