1 /* 2 * Watchdog Timer Driver 3 * for ITE IT87xx Environment Control - Low Pin Count Input / Output 4 * 5 * (c) Copyright 2007 Oliver Schuster <olivers137@aol.com> 6 * 7 * Based on softdog.c by Alan Cox, 8 * 83977f_wdt.c by Jose Goncalves, 9 * it87.c by Chris Gauthron, Jean Delvare 10 * 11 * Data-sheets: Publicly available at the ITE website 12 * http://www.ite.com.tw/ 13 * 14 * Support of the watchdog timers, which are available on 15 * IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726 16 * and IT8728. 17 * 18 * This program is free software; you can redistribute it and/or 19 * modify it under the terms of the GNU General Public License 20 * as published by the Free Software Foundation; either version 21 * 2 of the License, or (at your option) any later version. 22 * 23 * This program is distributed in the hope that it will be useful, 24 * but WITHOUT ANY WARRANTY; without even the implied warranty of 25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 * GNU General Public License for more details. 27 * 28 * You should have received a copy of the GNU General Public License 29 * along with this program; if not, write to the Free Software 30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 31 */ 32 33 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 34 35 #include <linux/module.h> 36 #include <linux/moduleparam.h> 37 #include <linux/types.h> 38 #include <linux/kernel.h> 39 #include <linux/fs.h> 40 #include <linux/miscdevice.h> 41 #include <linux/init.h> 42 #include <linux/ioport.h> 43 #include <linux/watchdog.h> 44 #include <linux/notifier.h> 45 #include <linux/reboot.h> 46 #include <linux/uaccess.h> 47 #include <linux/io.h> 48 49 50 #define WATCHDOG_VERSION "1.14" 51 #define WATCHDOG_NAME "IT87 WDT" 52 #define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n" 53 #define WD_MAGIC 'V' 54 55 /* Defaults for Module Parameter */ 56 #define DEFAULT_NOGAMEPORT 0 57 #define DEFAULT_NOCIR 0 58 #define DEFAULT_EXCLUSIVE 1 59 #define DEFAULT_TIMEOUT 60 60 #define DEFAULT_TESTMODE 0 61 #define DEFAULT_NOWAYOUT WATCHDOG_NOWAYOUT 62 63 /* IO Ports */ 64 #define REG 0x2e 65 #define VAL 0x2f 66 67 /* Logical device Numbers LDN */ 68 #define GPIO 0x07 69 #define GAMEPORT 0x09 70 #define CIR 0x0a 71 72 /* Configuration Registers and Functions */ 73 #define LDNREG 0x07 74 #define CHIPID 0x20 75 #define CHIPREV 0x22 76 #define ACTREG 0x30 77 #define BASEREG 0x60 78 79 /* Chip Id numbers */ 80 #define NO_DEV_ID 0xffff 81 #define IT8702_ID 0x8702 82 #define IT8705_ID 0x8705 83 #define IT8712_ID 0x8712 84 #define IT8716_ID 0x8716 85 #define IT8718_ID 0x8718 86 #define IT8720_ID 0x8720 87 #define IT8721_ID 0x8721 88 #define IT8726_ID 0x8726 /* the data sheet suggest wrongly 0x8716 */ 89 #define IT8728_ID 0x8728 90 91 /* GPIO Configuration Registers LDN=0x07 */ 92 #define WDTCTRL 0x71 93 #define WDTCFG 0x72 94 #define WDTVALLSB 0x73 95 #define WDTVALMSB 0x74 96 97 /* GPIO Bits WDTCTRL */ 98 #define WDT_CIRINT 0x80 99 #define WDT_MOUSEINT 0x40 100 #define WDT_KYBINT 0x20 101 #define WDT_GAMEPORT 0x10 /* not in it8718, it8720, it8721, it8728 */ 102 #define WDT_FORCE 0x02 103 #define WDT_ZERO 0x01 104 105 /* GPIO Bits WDTCFG */ 106 #define WDT_TOV1 0x80 107 #define WDT_KRST 0x40 108 #define WDT_TOVE 0x20 109 #define WDT_PWROK 0x10 /* not in it8721 */ 110 #define WDT_INT_MASK 0x0f 111 112 /* CIR Configuration Register LDN=0x0a */ 113 #define CIR_ILS 0x70 114 115 /* The default Base address is not always available, we use this */ 116 #define CIR_BASE 0x0208 117 118 /* CIR Controller */ 119 #define CIR_DR(b) (b) 120 #define CIR_IER(b) (b + 1) 121 #define CIR_RCR(b) (b + 2) 122 #define CIR_TCR1(b) (b + 3) 123 #define CIR_TCR2(b) (b + 4) 124 #define CIR_TSR(b) (b + 5) 125 #define CIR_RSR(b) (b + 6) 126 #define CIR_BDLR(b) (b + 5) 127 #define CIR_BDHR(b) (b + 6) 128 #define CIR_IIR(b) (b + 7) 129 130 /* Default Base address of Game port */ 131 #define GP_BASE_DEFAULT 0x0201 132 133 /* wdt_status */ 134 #define WDTS_TIMER_RUN 0 135 #define WDTS_DEV_OPEN 1 136 #define WDTS_KEEPALIVE 2 137 #define WDTS_LOCKED 3 138 #define WDTS_USE_GP 4 139 #define WDTS_EXPECTED 5 140 #define WDTS_USE_CIR 6 141 142 static unsigned int base, gpact, ciract, max_units, chip_type; 143 static unsigned long wdt_status; 144 145 static int nogameport = DEFAULT_NOGAMEPORT; 146 static int nocir = DEFAULT_NOCIR; 147 static int exclusive = DEFAULT_EXCLUSIVE; 148 static int timeout = DEFAULT_TIMEOUT; 149 static int testmode = DEFAULT_TESTMODE; 150 static bool nowayout = DEFAULT_NOWAYOUT; 151 152 module_param(nogameport, int, 0); 153 MODULE_PARM_DESC(nogameport, "Forbid the activation of game port, default=" 154 __MODULE_STRING(DEFAULT_NOGAMEPORT)); 155 module_param(nocir, int, 0); 156 MODULE_PARM_DESC(nocir, "Forbid the use of Consumer IR interrupts to reset timer, default=" 157 __MODULE_STRING(DEFAULT_NOCIR)); 158 module_param(exclusive, int, 0); 159 MODULE_PARM_DESC(exclusive, "Watchdog exclusive device open, default=" 160 __MODULE_STRING(DEFAULT_EXCLUSIVE)); 161 module_param(timeout, int, 0); 162 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, default=" 163 __MODULE_STRING(DEFAULT_TIMEOUT)); 164 module_param(testmode, int, 0); 165 MODULE_PARM_DESC(testmode, "Watchdog test mode (1 = no reboot), default=" 166 __MODULE_STRING(DEFAULT_TESTMODE)); 167 module_param(nowayout, bool, 0); 168 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started, default=" 169 __MODULE_STRING(WATCHDOG_NOWAYOUT)); 170 171 /* Superio Chip */ 172 173 static inline int superio_enter(void) 174 { 175 /* 176 * Try to reserve REG and REG + 1 for exclusive access. 177 */ 178 if (!request_muxed_region(REG, 2, WATCHDOG_NAME)) 179 return -EBUSY; 180 181 outb(0x87, REG); 182 outb(0x01, REG); 183 outb(0x55, REG); 184 outb(0x55, REG); 185 return 0; 186 } 187 188 static inline void superio_exit(void) 189 { 190 outb(0x02, REG); 191 outb(0x02, VAL); 192 release_region(REG, 2); 193 } 194 195 static inline void superio_select(int ldn) 196 { 197 outb(LDNREG, REG); 198 outb(ldn, VAL); 199 } 200 201 static inline int superio_inb(int reg) 202 { 203 outb(reg, REG); 204 return inb(VAL); 205 } 206 207 static inline void superio_outb(int val, int reg) 208 { 209 outb(reg, REG); 210 outb(val, VAL); 211 } 212 213 static inline int superio_inw(int reg) 214 { 215 int val; 216 outb(reg++, REG); 217 val = inb(VAL) << 8; 218 outb(reg, REG); 219 val |= inb(VAL); 220 return val; 221 } 222 223 static inline void superio_outw(int val, int reg) 224 { 225 outb(reg++, REG); 226 outb(val >> 8, VAL); 227 outb(reg, REG); 228 outb(val, VAL); 229 } 230 231 /* Internal function, should be called after superio_select(GPIO) */ 232 static void wdt_update_timeout(void) 233 { 234 unsigned char cfg = WDT_KRST; 235 int tm = timeout; 236 237 if (testmode) 238 cfg = 0; 239 240 if (tm <= max_units) 241 cfg |= WDT_TOV1; 242 else 243 tm /= 60; 244 245 if (chip_type != IT8721_ID) 246 cfg |= WDT_PWROK; 247 248 superio_outb(cfg, WDTCFG); 249 superio_outb(tm, WDTVALLSB); 250 if (max_units > 255) 251 superio_outb(tm>>8, WDTVALMSB); 252 } 253 254 static int wdt_round_time(int t) 255 { 256 t += 59; 257 t -= t % 60; 258 return t; 259 } 260 261 /* watchdog timer handling */ 262 263 static void wdt_keepalive(void) 264 { 265 if (test_bit(WDTS_USE_GP, &wdt_status)) 266 inb(base); 267 else if (test_bit(WDTS_USE_CIR, &wdt_status)) 268 /* The timer reloads with around 5 msec delay */ 269 outb(0x55, CIR_DR(base)); 270 else { 271 if (superio_enter()) 272 return; 273 274 superio_select(GPIO); 275 wdt_update_timeout(); 276 superio_exit(); 277 } 278 set_bit(WDTS_KEEPALIVE, &wdt_status); 279 } 280 281 static int wdt_start(void) 282 { 283 int ret = superio_enter(); 284 if (ret) 285 return ret; 286 287 superio_select(GPIO); 288 if (test_bit(WDTS_USE_GP, &wdt_status)) 289 superio_outb(WDT_GAMEPORT, WDTCTRL); 290 else if (test_bit(WDTS_USE_CIR, &wdt_status)) 291 superio_outb(WDT_CIRINT, WDTCTRL); 292 wdt_update_timeout(); 293 294 superio_exit(); 295 296 return 0; 297 } 298 299 static int wdt_stop(void) 300 { 301 int ret = superio_enter(); 302 if (ret) 303 return ret; 304 305 superio_select(GPIO); 306 superio_outb(0x00, WDTCTRL); 307 superio_outb(WDT_TOV1, WDTCFG); 308 superio_outb(0x00, WDTVALLSB); 309 if (max_units > 255) 310 superio_outb(0x00, WDTVALMSB); 311 312 superio_exit(); 313 return 0; 314 } 315 316 /** 317 * wdt_set_timeout - set a new timeout value with watchdog ioctl 318 * @t: timeout value in seconds 319 * 320 * The hardware device has a 8 or 16 bit watchdog timer (depends on 321 * chip version) that can be configured to count seconds or minutes. 322 * 323 * Used within WDIOC_SETTIMEOUT watchdog device ioctl. 324 */ 325 326 static int wdt_set_timeout(int t) 327 { 328 if (t < 1 || t > max_units * 60) 329 return -EINVAL; 330 331 if (t > max_units) 332 timeout = wdt_round_time(t); 333 else 334 timeout = t; 335 336 if (test_bit(WDTS_TIMER_RUN, &wdt_status)) { 337 int ret = superio_enter(); 338 if (ret) 339 return ret; 340 341 superio_select(GPIO); 342 wdt_update_timeout(); 343 superio_exit(); 344 } 345 return 0; 346 } 347 348 /** 349 * wdt_get_status - determines the status supported by watchdog ioctl 350 * @status: status returned to user space 351 * 352 * The status bit of the device does not allow to distinguish 353 * between a regular system reset and a watchdog forced reset. 354 * But, in test mode it is useful, so it is supported through 355 * WDIOC_GETSTATUS watchdog ioctl. Additionally the driver 356 * reports the keepalive signal and the acception of the magic. 357 * 358 * Used within WDIOC_GETSTATUS watchdog device ioctl. 359 */ 360 361 static int wdt_get_status(int *status) 362 { 363 *status = 0; 364 if (testmode) { 365 int ret = superio_enter(); 366 if (ret) 367 return ret; 368 369 superio_select(GPIO); 370 if (superio_inb(WDTCTRL) & WDT_ZERO) { 371 superio_outb(0x00, WDTCTRL); 372 clear_bit(WDTS_TIMER_RUN, &wdt_status); 373 *status |= WDIOF_CARDRESET; 374 } 375 376 superio_exit(); 377 } 378 if (test_and_clear_bit(WDTS_KEEPALIVE, &wdt_status)) 379 *status |= WDIOF_KEEPALIVEPING; 380 if (test_bit(WDTS_EXPECTED, &wdt_status)) 381 *status |= WDIOF_MAGICCLOSE; 382 return 0; 383 } 384 385 /* /dev/watchdog handling */ 386 387 /** 388 * wdt_open - watchdog file_operations .open 389 * @inode: inode of the device 390 * @file: file handle to the device 391 * 392 * The watchdog timer starts by opening the device. 393 * 394 * Used within the file operation of the watchdog device. 395 */ 396 397 static int wdt_open(struct inode *inode, struct file *file) 398 { 399 if (exclusive && test_and_set_bit(WDTS_DEV_OPEN, &wdt_status)) 400 return -EBUSY; 401 if (!test_and_set_bit(WDTS_TIMER_RUN, &wdt_status)) { 402 int ret; 403 if (nowayout && !test_and_set_bit(WDTS_LOCKED, &wdt_status)) 404 __module_get(THIS_MODULE); 405 406 ret = wdt_start(); 407 if (ret) { 408 clear_bit(WDTS_LOCKED, &wdt_status); 409 clear_bit(WDTS_TIMER_RUN, &wdt_status); 410 clear_bit(WDTS_DEV_OPEN, &wdt_status); 411 return ret; 412 } 413 } 414 return nonseekable_open(inode, file); 415 } 416 417 /** 418 * wdt_release - watchdog file_operations .release 419 * @inode: inode of the device 420 * @file: file handle to the device 421 * 422 * Closing the watchdog device either stops the watchdog timer 423 * or in the case, that nowayout is set or the magic character 424 * wasn't written, a critical warning about an running watchdog 425 * timer is given. 426 * 427 * Used within the file operation of the watchdog device. 428 */ 429 430 static int wdt_release(struct inode *inode, struct file *file) 431 { 432 if (test_bit(WDTS_TIMER_RUN, &wdt_status)) { 433 if (test_and_clear_bit(WDTS_EXPECTED, &wdt_status)) { 434 int ret = wdt_stop(); 435 if (ret) { 436 /* 437 * Stop failed. Just keep the watchdog alive 438 * and hope nothing bad happens. 439 */ 440 set_bit(WDTS_EXPECTED, &wdt_status); 441 wdt_keepalive(); 442 return ret; 443 } 444 clear_bit(WDTS_TIMER_RUN, &wdt_status); 445 } else { 446 wdt_keepalive(); 447 pr_crit("unexpected close, not stopping watchdog!\n"); 448 } 449 } 450 clear_bit(WDTS_DEV_OPEN, &wdt_status); 451 return 0; 452 } 453 454 /** 455 * wdt_write - watchdog file_operations .write 456 * @file: file handle to the watchdog 457 * @buf: buffer to write 458 * @count: count of bytes 459 * @ppos: pointer to the position to write. No seeks allowed 460 * 461 * A write to a watchdog device is defined as a keepalive signal. Any 462 * write of data will do, as we don't define content meaning. 463 * 464 * Used within the file operation of the watchdog device. 465 */ 466 467 static ssize_t wdt_write(struct file *file, const char __user *buf, 468 size_t count, loff_t *ppos) 469 { 470 if (count) { 471 clear_bit(WDTS_EXPECTED, &wdt_status); 472 wdt_keepalive(); 473 } 474 if (!nowayout) { 475 size_t ofs; 476 477 /* note: just in case someone wrote the magic character long ago */ 478 for (ofs = 0; ofs != count; ofs++) { 479 char c; 480 if (get_user(c, buf + ofs)) 481 return -EFAULT; 482 if (c == WD_MAGIC) 483 set_bit(WDTS_EXPECTED, &wdt_status); 484 } 485 } 486 return count; 487 } 488 489 static const struct watchdog_info ident = { 490 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 491 .firmware_version = 1, 492 .identity = WATCHDOG_NAME, 493 }; 494 495 /** 496 * wdt_ioctl - watchdog file_operations .unlocked_ioctl 497 * @file: file handle to the device 498 * @cmd: watchdog command 499 * @arg: argument pointer 500 * 501 * The watchdog API defines a common set of functions for all watchdogs 502 * according to their available features. 503 * 504 * Used within the file operation of the watchdog device. 505 */ 506 507 static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 508 { 509 int rc = 0, status, new_options, new_timeout; 510 union { 511 struct watchdog_info __user *ident; 512 int __user *i; 513 } uarg; 514 515 uarg.i = (int __user *)arg; 516 517 switch (cmd) { 518 case WDIOC_GETSUPPORT: 519 return copy_to_user(uarg.ident, 520 &ident, sizeof(ident)) ? -EFAULT : 0; 521 522 case WDIOC_GETSTATUS: 523 rc = wdt_get_status(&status); 524 if (rc) 525 return rc; 526 return put_user(status, uarg.i); 527 528 case WDIOC_GETBOOTSTATUS: 529 return put_user(0, uarg.i); 530 531 case WDIOC_KEEPALIVE: 532 wdt_keepalive(); 533 return 0; 534 535 case WDIOC_SETOPTIONS: 536 if (get_user(new_options, uarg.i)) 537 return -EFAULT; 538 539 switch (new_options) { 540 case WDIOS_DISABLECARD: 541 if (test_bit(WDTS_TIMER_RUN, &wdt_status)) { 542 rc = wdt_stop(); 543 if (rc) 544 return rc; 545 } 546 clear_bit(WDTS_TIMER_RUN, &wdt_status); 547 return 0; 548 549 case WDIOS_ENABLECARD: 550 if (!test_and_set_bit(WDTS_TIMER_RUN, &wdt_status)) { 551 rc = wdt_start(); 552 if (rc) { 553 clear_bit(WDTS_TIMER_RUN, &wdt_status); 554 return rc; 555 } 556 } 557 return 0; 558 559 default: 560 return -EFAULT; 561 } 562 563 case WDIOC_SETTIMEOUT: 564 if (get_user(new_timeout, uarg.i)) 565 return -EFAULT; 566 rc = wdt_set_timeout(new_timeout); 567 case WDIOC_GETTIMEOUT: 568 if (put_user(timeout, uarg.i)) 569 return -EFAULT; 570 return rc; 571 572 default: 573 return -ENOTTY; 574 } 575 } 576 577 static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 578 void *unused) 579 { 580 if (code == SYS_DOWN || code == SYS_HALT) 581 wdt_stop(); 582 return NOTIFY_DONE; 583 } 584 585 static const struct file_operations wdt_fops = { 586 .owner = THIS_MODULE, 587 .llseek = no_llseek, 588 .write = wdt_write, 589 .unlocked_ioctl = wdt_ioctl, 590 .open = wdt_open, 591 .release = wdt_release, 592 }; 593 594 static struct miscdevice wdt_miscdev = { 595 .minor = WATCHDOG_MINOR, 596 .name = "watchdog", 597 .fops = &wdt_fops, 598 }; 599 600 static struct notifier_block wdt_notifier = { 601 .notifier_call = wdt_notify_sys, 602 }; 603 604 static int __init it87_wdt_init(void) 605 { 606 int rc = 0; 607 int try_gameport = !nogameport; 608 u8 chip_rev; 609 int gp_rreq_fail = 0; 610 611 wdt_status = 0; 612 613 rc = superio_enter(); 614 if (rc) 615 return rc; 616 617 chip_type = superio_inw(CHIPID); 618 chip_rev = superio_inb(CHIPREV) & 0x0f; 619 superio_exit(); 620 621 switch (chip_type) { 622 case IT8702_ID: 623 max_units = 255; 624 break; 625 case IT8712_ID: 626 max_units = (chip_rev < 8) ? 255 : 65535; 627 break; 628 case IT8716_ID: 629 case IT8726_ID: 630 max_units = 65535; 631 break; 632 case IT8718_ID: 633 case IT8720_ID: 634 case IT8721_ID: 635 case IT8728_ID: 636 max_units = 65535; 637 try_gameport = 0; 638 break; 639 case IT8705_ID: 640 pr_err("Unsupported Chip found, Chip %04x Revision %02x\n", 641 chip_type, chip_rev); 642 return -ENODEV; 643 case NO_DEV_ID: 644 pr_err("no device\n"); 645 return -ENODEV; 646 default: 647 pr_err("Unknown Chip found, Chip %04x Revision %04x\n", 648 chip_type, chip_rev); 649 return -ENODEV; 650 } 651 652 rc = superio_enter(); 653 if (rc) 654 return rc; 655 656 superio_select(GPIO); 657 superio_outb(WDT_TOV1, WDTCFG); 658 superio_outb(0x00, WDTCTRL); 659 660 /* First try to get Gameport support */ 661 if (try_gameport) { 662 superio_select(GAMEPORT); 663 base = superio_inw(BASEREG); 664 if (!base) { 665 base = GP_BASE_DEFAULT; 666 superio_outw(base, BASEREG); 667 } 668 gpact = superio_inb(ACTREG); 669 superio_outb(0x01, ACTREG); 670 if (request_region(base, 1, WATCHDOG_NAME)) 671 set_bit(WDTS_USE_GP, &wdt_status); 672 else 673 gp_rreq_fail = 1; 674 } 675 676 /* If we haven't Gameport support, try to get CIR support */ 677 if (!nocir && !test_bit(WDTS_USE_GP, &wdt_status)) { 678 if (!request_region(CIR_BASE, 8, WATCHDOG_NAME)) { 679 if (gp_rreq_fail) 680 pr_err("I/O Address 0x%04x and 0x%04x already in use\n", 681 base, CIR_BASE); 682 else 683 pr_err("I/O Address 0x%04x already in use\n", 684 CIR_BASE); 685 rc = -EIO; 686 goto err_out; 687 } 688 base = CIR_BASE; 689 690 superio_select(CIR); 691 superio_outw(base, BASEREG); 692 superio_outb(0x00, CIR_ILS); 693 ciract = superio_inb(ACTREG); 694 superio_outb(0x01, ACTREG); 695 if (gp_rreq_fail) { 696 superio_select(GAMEPORT); 697 superio_outb(gpact, ACTREG); 698 } 699 set_bit(WDTS_USE_CIR, &wdt_status); 700 } 701 702 if (timeout < 1 || timeout > max_units * 60) { 703 timeout = DEFAULT_TIMEOUT; 704 pr_warn("Timeout value out of range, use default %d sec\n", 705 DEFAULT_TIMEOUT); 706 } 707 708 if (timeout > max_units) 709 timeout = wdt_round_time(timeout); 710 711 rc = register_reboot_notifier(&wdt_notifier); 712 if (rc) { 713 pr_err("Cannot register reboot notifier (err=%d)\n", rc); 714 goto err_out_region; 715 } 716 717 rc = misc_register(&wdt_miscdev); 718 if (rc) { 719 pr_err("Cannot register miscdev on minor=%d (err=%d)\n", 720 wdt_miscdev.minor, rc); 721 goto err_out_reboot; 722 } 723 724 /* Initialize CIR to use it as keepalive source */ 725 if (test_bit(WDTS_USE_CIR, &wdt_status)) { 726 outb(0x00, CIR_RCR(base)); 727 outb(0xc0, CIR_TCR1(base)); 728 outb(0x5c, CIR_TCR2(base)); 729 outb(0x10, CIR_IER(base)); 730 outb(0x00, CIR_BDHR(base)); 731 outb(0x01, CIR_BDLR(base)); 732 outb(0x09, CIR_IER(base)); 733 } 734 735 pr_info("Chip IT%04x revision %d initialized. timeout=%d sec (nowayout=%d testmode=%d exclusive=%d nogameport=%d nocir=%d)\n", 736 chip_type, chip_rev, timeout, 737 nowayout, testmode, exclusive, nogameport, nocir); 738 739 superio_exit(); 740 return 0; 741 742 err_out_reboot: 743 unregister_reboot_notifier(&wdt_notifier); 744 err_out_region: 745 if (test_bit(WDTS_USE_GP, &wdt_status)) 746 release_region(base, 1); 747 else if (test_bit(WDTS_USE_CIR, &wdt_status)) { 748 release_region(base, 8); 749 superio_select(CIR); 750 superio_outb(ciract, ACTREG); 751 } 752 err_out: 753 if (try_gameport) { 754 superio_select(GAMEPORT); 755 superio_outb(gpact, ACTREG); 756 } 757 758 superio_exit(); 759 return rc; 760 } 761 762 static void __exit it87_wdt_exit(void) 763 { 764 if (superio_enter() == 0) { 765 superio_select(GPIO); 766 superio_outb(0x00, WDTCTRL); 767 superio_outb(0x00, WDTCFG); 768 superio_outb(0x00, WDTVALLSB); 769 if (max_units > 255) 770 superio_outb(0x00, WDTVALMSB); 771 if (test_bit(WDTS_USE_GP, &wdt_status)) { 772 superio_select(GAMEPORT); 773 superio_outb(gpact, ACTREG); 774 } else if (test_bit(WDTS_USE_CIR, &wdt_status)) { 775 superio_select(CIR); 776 superio_outb(ciract, ACTREG); 777 } 778 superio_exit(); 779 } 780 781 misc_deregister(&wdt_miscdev); 782 unregister_reboot_notifier(&wdt_notifier); 783 784 if (test_bit(WDTS_USE_GP, &wdt_status)) 785 release_region(base, 1); 786 else if (test_bit(WDTS_USE_CIR, &wdt_status)) 787 release_region(base, 8); 788 } 789 790 module_init(it87_wdt_init); 791 module_exit(it87_wdt_exit); 792 793 MODULE_AUTHOR("Oliver Schuster"); 794 MODULE_DESCRIPTION("Hardware Watchdog Device Driver for IT87xx EC-LPC I/O"); 795 MODULE_LICENSE("GPL"); 796