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