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 42 #define WATCHDOG_NAME "w83627hf/thf/hg/dhg WDT" 43 #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ 44 45 static int wdt_io; 46 static int cr_wdt_timeout; /* WDT timeout register */ 47 static int cr_wdt_control; /* WDT control register */ 48 static int cr_wdt_csr; /* WDT control & status register */ 49 50 enum chips { w83627hf, w83627s, w83697hf, w83697ug, w83637hf, w83627thf, 51 w83687thf, w83627ehf, w83627dhg, w83627uhg, w83667hg, w83627dhg_p, 52 w83667hg_b, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793, 53 nct6795, nct6102 }; 54 55 static int timeout; /* in seconds */ 56 module_param(timeout, int, 0); 57 MODULE_PARM_DESC(timeout, 58 "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" 59 __MODULE_STRING(WATCHDOG_TIMEOUT) "."); 60 61 static bool nowayout = WATCHDOG_NOWAYOUT; 62 module_param(nowayout, bool, 0); 63 MODULE_PARM_DESC(nowayout, 64 "Watchdog cannot be stopped once started (default=" 65 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 66 67 static int early_disable; 68 module_param(early_disable, int, 0); 69 MODULE_PARM_DESC(early_disable, "Disable watchdog at boot time (default=0)"); 70 71 /* 72 * Kernel methods. 73 */ 74 75 #define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */ 76 #define WDT_EFIR (wdt_io+0) /* Extended Function Index Register 77 (same as EFER) */ 78 #define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ 79 80 #define W83627HF_LD_WDT 0x08 81 82 #define W83627HF_ID 0x52 83 #define W83627S_ID 0x59 84 #define W83697HF_ID 0x60 85 #define W83697UG_ID 0x68 86 #define W83637HF_ID 0x70 87 #define W83627THF_ID 0x82 88 #define W83687THF_ID 0x85 89 #define W83627EHF_ID 0x88 90 #define W83627DHG_ID 0xa0 91 #define W83627UHG_ID 0xa2 92 #define W83667HG_ID 0xa5 93 #define W83627DHG_P_ID 0xb0 94 #define W83667HG_B_ID 0xb3 95 #define NCT6775_ID 0xb4 96 #define NCT6776_ID 0xc3 97 #define NCT6102_ID 0xc4 98 #define NCT6779_ID 0xc5 99 #define NCT6791_ID 0xc8 100 #define NCT6792_ID 0xc9 101 #define NCT6793_ID 0xd1 102 #define NCT6795_ID 0xd3 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(0x87, WDT_EFER); /* Enter extended function mode */ 133 outb_p(0x87, 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(0xAA, 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 nct6102: 213 /* 214 * These chips have a fixed WDTO# output pin (W83627UHG), 215 * or support more than one WDTO# output pin. 216 * Don't touch its configuration, and hope the BIOS 217 * does the right thing. 218 */ 219 t = superio_inb(cr_wdt_control); 220 t |= 0x02; /* enable the WDTO# output low pulse 221 * to the KBRST# pin */ 222 superio_outb(cr_wdt_control, t); 223 break; 224 default: 225 break; 226 } 227 228 t = superio_inb(cr_wdt_timeout); 229 if (t != 0) { 230 if (early_disable) { 231 pr_warn("Stopping previously enabled watchdog until userland kicks in\n"); 232 superio_outb(cr_wdt_timeout, 0); 233 } else { 234 pr_info("Watchdog already running. Resetting timeout to %d sec\n", 235 wdog->timeout); 236 superio_outb(cr_wdt_timeout, wdog->timeout); 237 } 238 } 239 240 /* set second mode & disable keyboard turning off watchdog */ 241 t = superio_inb(cr_wdt_control) & ~0x0C; 242 superio_outb(cr_wdt_control, t); 243 244 /* reset trigger, disable keyboard & mouse turning off watchdog */ 245 t = superio_inb(cr_wdt_csr) & ~0xD0; 246 superio_outb(cr_wdt_csr, t); 247 248 superio_exit(); 249 250 return 0; 251 } 252 253 static int wdt_set_time(unsigned int timeout) 254 { 255 int ret; 256 257 ret = superio_enter(); 258 if (ret) 259 return ret; 260 261 superio_select(W83627HF_LD_WDT); 262 superio_outb(cr_wdt_timeout, timeout); 263 superio_exit(); 264 265 return 0; 266 } 267 268 static int wdt_start(struct watchdog_device *wdog) 269 { 270 return wdt_set_time(wdog->timeout); 271 } 272 273 static int wdt_stop(struct watchdog_device *wdog) 274 { 275 return wdt_set_time(0); 276 } 277 278 static int wdt_set_timeout(struct watchdog_device *wdog, unsigned int timeout) 279 { 280 wdog->timeout = timeout; 281 282 return 0; 283 } 284 285 static unsigned int wdt_get_time(struct watchdog_device *wdog) 286 { 287 unsigned int timeleft; 288 int ret; 289 290 ret = superio_enter(); 291 if (ret) 292 return 0; 293 294 superio_select(W83627HF_LD_WDT); 295 timeleft = superio_inb(cr_wdt_timeout); 296 superio_exit(); 297 298 return timeleft; 299 } 300 301 /* 302 * Kernel Interfaces 303 */ 304 305 static const struct watchdog_info wdt_info = { 306 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 307 .identity = "W83627HF Watchdog", 308 }; 309 310 static const struct watchdog_ops wdt_ops = { 311 .owner = THIS_MODULE, 312 .start = wdt_start, 313 .stop = wdt_stop, 314 .set_timeout = wdt_set_timeout, 315 .get_timeleft = wdt_get_time, 316 }; 317 318 static struct watchdog_device wdt_dev = { 319 .info = &wdt_info, 320 .ops = &wdt_ops, 321 .timeout = WATCHDOG_TIMEOUT, 322 .min_timeout = 1, 323 .max_timeout = 255, 324 }; 325 326 /* 327 * The WDT needs to learn about soft shutdowns in order to 328 * turn the timebomb registers off. 329 */ 330 331 static int wdt_find(int addr) 332 { 333 u8 val; 334 int ret; 335 336 cr_wdt_timeout = W83627HF_WDT_TIMEOUT; 337 cr_wdt_control = W83627HF_WDT_CONTROL; 338 cr_wdt_csr = W836X7HF_WDT_CSR; 339 340 ret = superio_enter(); 341 if (ret) 342 return ret; 343 superio_select(W83627HF_LD_WDT); 344 val = superio_inb(0x20); 345 switch (val) { 346 case W83627HF_ID: 347 ret = w83627hf; 348 break; 349 case W83627S_ID: 350 ret = w83627s; 351 break; 352 case W83697HF_ID: 353 ret = w83697hf; 354 cr_wdt_timeout = W83697HF_WDT_TIMEOUT; 355 cr_wdt_control = W83697HF_WDT_CONTROL; 356 break; 357 case W83697UG_ID: 358 ret = w83697ug; 359 cr_wdt_timeout = W83697HF_WDT_TIMEOUT; 360 cr_wdt_control = W83697HF_WDT_CONTROL; 361 break; 362 case W83637HF_ID: 363 ret = w83637hf; 364 break; 365 case W83627THF_ID: 366 ret = w83627thf; 367 break; 368 case W83687THF_ID: 369 ret = w83687thf; 370 break; 371 case W83627EHF_ID: 372 ret = w83627ehf; 373 break; 374 case W83627DHG_ID: 375 ret = w83627dhg; 376 break; 377 case W83627DHG_P_ID: 378 ret = w83627dhg_p; 379 break; 380 case W83627UHG_ID: 381 ret = w83627uhg; 382 break; 383 case W83667HG_ID: 384 ret = w83667hg; 385 break; 386 case W83667HG_B_ID: 387 ret = w83667hg_b; 388 break; 389 case NCT6775_ID: 390 ret = nct6775; 391 break; 392 case NCT6776_ID: 393 ret = nct6776; 394 break; 395 case NCT6779_ID: 396 ret = nct6779; 397 break; 398 case NCT6791_ID: 399 ret = nct6791; 400 break; 401 case NCT6792_ID: 402 ret = nct6792; 403 break; 404 case NCT6793_ID: 405 ret = nct6793; 406 break; 407 case NCT6795_ID: 408 ret = nct6795; 409 break; 410 case NCT6102_ID: 411 ret = nct6102; 412 cr_wdt_timeout = NCT6102D_WDT_TIMEOUT; 413 cr_wdt_control = NCT6102D_WDT_CONTROL; 414 cr_wdt_csr = NCT6102D_WDT_CSR; 415 break; 416 case 0xff: 417 ret = -ENODEV; 418 break; 419 default: 420 ret = -ENODEV; 421 pr_err("Unsupported chip ID: 0x%02x\n", val); 422 break; 423 } 424 superio_exit(); 425 return ret; 426 } 427 428 static int __init wdt_init(void) 429 { 430 int ret; 431 int chip; 432 static const char * const chip_name[] = { 433 "W83627HF", 434 "W83627S", 435 "W83697HF", 436 "W83697UG", 437 "W83637HF", 438 "W83627THF", 439 "W83687THF", 440 "W83627EHF", 441 "W83627DHG", 442 "W83627UHG", 443 "W83667HG", 444 "W83667DHG-P", 445 "W83667HG-B", 446 "NCT6775", 447 "NCT6776", 448 "NCT6779", 449 "NCT6791", 450 "NCT6792", 451 "NCT6793", 452 "NCT6795", 453 "NCT6102", 454 }; 455 456 wdt_io = 0x2e; 457 chip = wdt_find(0x2e); 458 if (chip < 0) { 459 wdt_io = 0x4e; 460 chip = wdt_find(0x4e); 461 if (chip < 0) 462 return chip; 463 } 464 465 pr_info("WDT driver for %s Super I/O chip initialising\n", 466 chip_name[chip]); 467 468 watchdog_init_timeout(&wdt_dev, timeout, NULL); 469 watchdog_set_nowayout(&wdt_dev, nowayout); 470 watchdog_stop_on_reboot(&wdt_dev); 471 472 ret = w83627hf_init(&wdt_dev, chip); 473 if (ret) { 474 pr_err("failed to initialize watchdog (err=%d)\n", ret); 475 return ret; 476 } 477 478 ret = watchdog_register_device(&wdt_dev); 479 if (ret) 480 return ret; 481 482 pr_info("initialized. timeout=%d sec (nowayout=%d)\n", 483 wdt_dev.timeout, nowayout); 484 485 return ret; 486 } 487 488 static void __exit wdt_exit(void) 489 { 490 watchdog_unregister_device(&wdt_dev); 491 } 492 493 module_init(wdt_init); 494 module_exit(wdt_exit); 495 496 MODULE_LICENSE("GPL"); 497 MODULE_AUTHOR("Pádraig Brady <P@draigBrady.com>"); 498 MODULE_DESCRIPTION("w83627hf/thf WDT driver"); 499