1 /* 2 * Industrial Computer Source WDT501 driver 3 * 4 * (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>, 5 * All Rights Reserved. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 10 * 2 of the License, or (at your option) any later version. 11 * 12 * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide 13 * warranty for any of this software. This material is provided 14 * "AS-IS" and at no charge. 15 * 16 * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk> 17 * 18 * Release 0.10. 19 * 20 * Fixes 21 * Dave Gregorich : Modularisation and minor bugs 22 * Alan Cox : Added the watchdog ioctl() stuff 23 * Alan Cox : Fixed the reboot problem (as noted by 24 * Matt Crocker). 25 * Alan Cox : Added wdt= boot option 26 * Alan Cox : Cleaned up copy/user stuff 27 * Tim Hockin : Added insmod parameters, comment 28 * cleanup, parameterized timeout 29 * Tigran Aivazian : Restructured wdt_init() to handle 30 * failures 31 * Joel Becker : Added WDIOC_GET/SETTIMEOUT 32 * Matt Domsch : Added nowayout module option 33 */ 34 35 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 36 37 #include <linux/interrupt.h> 38 #include <linux/module.h> 39 #include <linux/moduleparam.h> 40 #include <linux/types.h> 41 #include <linux/miscdevice.h> 42 #include <linux/watchdog.h> 43 #include <linux/fs.h> 44 #include <linux/ioport.h> 45 #include <linux/notifier.h> 46 #include <linux/reboot.h> 47 #include <linux/init.h> 48 #include <linux/io.h> 49 #include <linux/uaccess.h> 50 51 #include "wd501p.h" 52 53 static unsigned long wdt_is_open; 54 static char expect_close; 55 56 /* 57 * Module parameters 58 */ 59 60 #define WD_TIMO 60 /* Default heartbeat = 60 seconds */ 61 62 static int heartbeat = WD_TIMO; 63 static int wd_heartbeat; 64 module_param(heartbeat, int, 0); 65 MODULE_PARM_DESC(heartbeat, 66 "Watchdog heartbeat in seconds. (0 < heartbeat < 65536, default=" 67 __MODULE_STRING(WD_TIMO) ")"); 68 69 static bool nowayout = WATCHDOG_NOWAYOUT; 70 module_param(nowayout, bool, 0); 71 MODULE_PARM_DESC(nowayout, 72 "Watchdog cannot be stopped once started (default=" 73 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 74 75 /* You must set these - there is no sane way to probe for this board. */ 76 static int io = 0x240; 77 static int irq = 11; 78 79 static DEFINE_SPINLOCK(wdt_lock); 80 81 module_param_hw(io, int, ioport, 0); 82 MODULE_PARM_DESC(io, "WDT io port (default=0x240)"); 83 module_param_hw(irq, int, irq, 0); 84 MODULE_PARM_DESC(irq, "WDT irq (default=11)"); 85 86 /* Support for the Fan Tachometer on the WDT501-P */ 87 static int tachometer; 88 module_param(tachometer, int, 0); 89 MODULE_PARM_DESC(tachometer, 90 "WDT501-P Fan Tachometer support (0=disable, default=0)"); 91 92 static int type = 500; 93 module_param(type, int, 0); 94 MODULE_PARM_DESC(type, 95 "WDT501-P Card type (500 or 501, default=500)"); 96 97 /* 98 * Programming support 99 */ 100 101 static void wdt_ctr_mode(int ctr, int mode) 102 { 103 ctr <<= 6; 104 ctr |= 0x30; 105 ctr |= (mode << 1); 106 outb_p(ctr, WDT_CR); 107 } 108 109 static void wdt_ctr_load(int ctr, int val) 110 { 111 outb_p(val&0xFF, WDT_COUNT0+ctr); 112 outb_p(val>>8, WDT_COUNT0+ctr); 113 } 114 115 /** 116 * wdt_start: 117 * 118 * Start the watchdog driver. 119 */ 120 121 static int wdt_start(void) 122 { 123 unsigned long flags; 124 spin_lock_irqsave(&wdt_lock, flags); 125 inb_p(WDT_DC); /* Disable watchdog */ 126 wdt_ctr_mode(0, 3); /* Program CTR0 for Mode 3: 127 Square Wave Generator */ 128 wdt_ctr_mode(1, 2); /* Program CTR1 for Mode 2: 129 Rate Generator */ 130 wdt_ctr_mode(2, 0); /* Program CTR2 for Mode 0: 131 Pulse on Terminal Count */ 132 wdt_ctr_load(0, 8948); /* Count at 100Hz */ 133 wdt_ctr_load(1, wd_heartbeat); /* Heartbeat */ 134 wdt_ctr_load(2, 65535); /* Length of reset pulse */ 135 outb_p(0, WDT_DC); /* Enable watchdog */ 136 spin_unlock_irqrestore(&wdt_lock, flags); 137 return 0; 138 } 139 140 /** 141 * wdt_stop: 142 * 143 * Stop the watchdog driver. 144 */ 145 146 static int wdt_stop(void) 147 { 148 unsigned long flags; 149 spin_lock_irqsave(&wdt_lock, flags); 150 /* Turn the card off */ 151 inb_p(WDT_DC); /* Disable watchdog */ 152 wdt_ctr_load(2, 0); /* 0 length reset pulses now */ 153 spin_unlock_irqrestore(&wdt_lock, flags); 154 return 0; 155 } 156 157 /** 158 * wdt_ping: 159 * 160 * Reload counter one with the watchdog heartbeat. We don't bother 161 * reloading the cascade counter. 162 */ 163 164 static void wdt_ping(void) 165 { 166 unsigned long flags; 167 spin_lock_irqsave(&wdt_lock, flags); 168 /* Write a watchdog value */ 169 inb_p(WDT_DC); /* Disable watchdog */ 170 wdt_ctr_mode(1, 2); /* Re-Program CTR1 for Mode 2: 171 Rate Generator */ 172 wdt_ctr_load(1, wd_heartbeat); /* Heartbeat */ 173 outb_p(0, WDT_DC); /* Enable watchdog */ 174 spin_unlock_irqrestore(&wdt_lock, flags); 175 } 176 177 /** 178 * wdt_set_heartbeat: 179 * @t: the new heartbeat value that needs to be set. 180 * 181 * Set a new heartbeat value for the watchdog device. If the heartbeat 182 * value is incorrect we keep the old value and return -EINVAL. If 183 * successful we return 0. 184 */ 185 186 static int wdt_set_heartbeat(int t) 187 { 188 if (t < 1 || t > 65535) 189 return -EINVAL; 190 191 heartbeat = t; 192 wd_heartbeat = t * 100; 193 return 0; 194 } 195 196 /** 197 * wdt_get_status: 198 * 199 * Extract the status information from a WDT watchdog device. There are 200 * several board variants so we have to know which bits are valid. Some 201 * bits default to one and some to zero in order to be maximally painful. 202 * 203 * we then map the bits onto the status ioctl flags. 204 */ 205 206 static int wdt_get_status(void) 207 { 208 unsigned char new_status; 209 int status = 0; 210 unsigned long flags; 211 212 spin_lock_irqsave(&wdt_lock, flags); 213 new_status = inb_p(WDT_SR); 214 spin_unlock_irqrestore(&wdt_lock, flags); 215 216 if (new_status & WDC_SR_ISOI0) 217 status |= WDIOF_EXTERN1; 218 if (new_status & WDC_SR_ISII1) 219 status |= WDIOF_EXTERN2; 220 if (type == 501) { 221 if (!(new_status & WDC_SR_TGOOD)) 222 status |= WDIOF_OVERHEAT; 223 if (!(new_status & WDC_SR_PSUOVER)) 224 status |= WDIOF_POWEROVER; 225 if (!(new_status & WDC_SR_PSUUNDR)) 226 status |= WDIOF_POWERUNDER; 227 if (tachometer) { 228 if (!(new_status & WDC_SR_FANGOOD)) 229 status |= WDIOF_FANFAULT; 230 } 231 } 232 return status; 233 } 234 235 /** 236 * wdt_get_temperature: 237 * 238 * Reports the temperature in degrees Fahrenheit. The API is in 239 * farenheit. It was designed by an imperial measurement luddite. 240 */ 241 242 static int wdt_get_temperature(void) 243 { 244 unsigned short c; 245 unsigned long flags; 246 247 spin_lock_irqsave(&wdt_lock, flags); 248 c = inb_p(WDT_RT); 249 spin_unlock_irqrestore(&wdt_lock, flags); 250 return (c * 11 / 15) + 7; 251 } 252 253 static void wdt_decode_501(int status) 254 { 255 if (!(status & WDC_SR_TGOOD)) 256 pr_crit("Overheat alarm (%d)\n", inb_p(WDT_RT)); 257 if (!(status & WDC_SR_PSUOVER)) 258 pr_crit("PSU over voltage\n"); 259 if (!(status & WDC_SR_PSUUNDR)) 260 pr_crit("PSU under voltage\n"); 261 } 262 263 /** 264 * wdt_interrupt: 265 * @irq: Interrupt number 266 * @dev_id: Unused as we don't allow multiple devices. 267 * 268 * Handle an interrupt from the board. These are raised when the status 269 * map changes in what the board considers an interesting way. That means 270 * a failure condition occurring. 271 */ 272 273 static irqreturn_t wdt_interrupt(int irq, void *dev_id) 274 { 275 /* 276 * Read the status register see what is up and 277 * then printk it. 278 */ 279 unsigned char status; 280 281 spin_lock(&wdt_lock); 282 status = inb_p(WDT_SR); 283 284 pr_crit("WDT status %d\n", status); 285 286 if (type == 501) { 287 wdt_decode_501(status); 288 if (tachometer) { 289 if (!(status & WDC_SR_FANGOOD)) 290 pr_crit("Possible fan fault\n"); 291 } 292 } 293 if (!(status & WDC_SR_WCCR)) { 294 #ifdef SOFTWARE_REBOOT 295 #ifdef ONLY_TESTING 296 pr_crit("Would Reboot\n"); 297 #else 298 pr_crit("Initiating system reboot\n"); 299 emergency_restart(); 300 #endif 301 #else 302 pr_crit("Reset in 5ms\n"); 303 #endif 304 } 305 spin_unlock(&wdt_lock); 306 return IRQ_HANDLED; 307 } 308 309 310 /** 311 * wdt_write: 312 * @file: file handle to the watchdog 313 * @buf: buffer to write (unused as data does not matter here 314 * @count: count of bytes 315 * @ppos: pointer to the position to write. No seeks allowed 316 * 317 * A write to a watchdog device is defined as a keepalive signal. Any 318 * write of data will do, as we we don't define content meaning. 319 */ 320 321 static ssize_t wdt_write(struct file *file, const char __user *buf, 322 size_t count, loff_t *ppos) 323 { 324 if (count) { 325 if (!nowayout) { 326 size_t i; 327 328 /* In case it was set long ago */ 329 expect_close = 0; 330 331 for (i = 0; i != count; i++) { 332 char c; 333 if (get_user(c, buf + i)) 334 return -EFAULT; 335 if (c == 'V') 336 expect_close = 42; 337 } 338 } 339 wdt_ping(); 340 } 341 return count; 342 } 343 344 /** 345 * wdt_ioctl: 346 * @file: file handle to the device 347 * @cmd: watchdog command 348 * @arg: argument pointer 349 * 350 * The watchdog API defines a common set of functions for all watchdogs 351 * according to their available features. We only actually usefully support 352 * querying capabilities and current status. 353 */ 354 355 static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 356 { 357 void __user *argp = (void __user *)arg; 358 int __user *p = argp; 359 int new_heartbeat; 360 int status; 361 362 struct watchdog_info ident = { 363 .options = WDIOF_SETTIMEOUT| 364 WDIOF_MAGICCLOSE| 365 WDIOF_KEEPALIVEPING, 366 .firmware_version = 1, 367 .identity = "WDT500/501", 368 }; 369 370 /* Add options according to the card we have */ 371 ident.options |= (WDIOF_EXTERN1|WDIOF_EXTERN2); 372 if (type == 501) { 373 ident.options |= (WDIOF_OVERHEAT|WDIOF_POWERUNDER| 374 WDIOF_POWEROVER); 375 if (tachometer) 376 ident.options |= WDIOF_FANFAULT; 377 } 378 379 switch (cmd) { 380 case WDIOC_GETSUPPORT: 381 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 382 case WDIOC_GETSTATUS: 383 status = wdt_get_status(); 384 return put_user(status, p); 385 case WDIOC_GETBOOTSTATUS: 386 return put_user(0, p); 387 case WDIOC_KEEPALIVE: 388 wdt_ping(); 389 return 0; 390 case WDIOC_SETTIMEOUT: 391 if (get_user(new_heartbeat, p)) 392 return -EFAULT; 393 if (wdt_set_heartbeat(new_heartbeat)) 394 return -EINVAL; 395 wdt_ping(); 396 /* Fall */ 397 case WDIOC_GETTIMEOUT: 398 return put_user(heartbeat, p); 399 default: 400 return -ENOTTY; 401 } 402 } 403 404 /** 405 * wdt_open: 406 * @inode: inode of device 407 * @file: file handle to device 408 * 409 * The watchdog device has been opened. The watchdog device is single 410 * open and on opening we load the counters. Counter zero is a 100Hz 411 * cascade, into counter 1 which downcounts to reboot. When the counter 412 * triggers counter 2 downcounts the length of the reset pulse which 413 * set set to be as long as possible. 414 */ 415 416 static int wdt_open(struct inode *inode, struct file *file) 417 { 418 if (test_and_set_bit(0, &wdt_is_open)) 419 return -EBUSY; 420 /* 421 * Activate 422 */ 423 wdt_start(); 424 return stream_open(inode, file); 425 } 426 427 /** 428 * wdt_release: 429 * @inode: inode to board 430 * @file: file handle to board 431 * 432 * The watchdog has a configurable API. There is a religious dispute 433 * between people who want their watchdog to be able to shut down and 434 * those who want to be sure if the watchdog manager dies the machine 435 * reboots. In the former case we disable the counters, in the latter 436 * case you have to open it again very soon. 437 */ 438 439 static int wdt_release(struct inode *inode, struct file *file) 440 { 441 if (expect_close == 42) { 442 wdt_stop(); 443 clear_bit(0, &wdt_is_open); 444 } else { 445 pr_crit("WDT device closed unexpectedly. WDT will not stop!\n"); 446 wdt_ping(); 447 } 448 expect_close = 0; 449 return 0; 450 } 451 452 /** 453 * wdt_temp_read: 454 * @file: file handle to the watchdog board 455 * @buf: buffer to write 1 byte into 456 * @count: length of buffer 457 * @ptr: offset (no seek allowed) 458 * 459 * Temp_read reports the temperature in degrees Fahrenheit. The API is in 460 * farenheit. It was designed by an imperial measurement luddite. 461 */ 462 463 static ssize_t wdt_temp_read(struct file *file, char __user *buf, 464 size_t count, loff_t *ptr) 465 { 466 int temperature = wdt_get_temperature(); 467 468 if (copy_to_user(buf, &temperature, 1)) 469 return -EFAULT; 470 471 return 1; 472 } 473 474 /** 475 * wdt_temp_open: 476 * @inode: inode of device 477 * @file: file handle to device 478 * 479 * The temperature device has been opened. 480 */ 481 482 static int wdt_temp_open(struct inode *inode, struct file *file) 483 { 484 return stream_open(inode, file); 485 } 486 487 /** 488 * wdt_temp_release: 489 * @inode: inode to board 490 * @file: file handle to board 491 * 492 * The temperature device has been closed. 493 */ 494 495 static int wdt_temp_release(struct inode *inode, struct file *file) 496 { 497 return 0; 498 } 499 500 /** 501 * notify_sys: 502 * @this: our notifier block 503 * @code: the event being reported 504 * @unused: unused 505 * 506 * Our notifier is called on system shutdowns. We want to turn the card 507 * off at reboot otherwise the machine will reboot again during memory 508 * test or worse yet during the following fsck. This would suck, in fact 509 * trust me - if it happens it does suck. 510 */ 511 512 static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 513 void *unused) 514 { 515 if (code == SYS_DOWN || code == SYS_HALT) 516 wdt_stop(); 517 return NOTIFY_DONE; 518 } 519 520 /* 521 * Kernel Interfaces 522 */ 523 524 525 static const struct file_operations wdt_fops = { 526 .owner = THIS_MODULE, 527 .llseek = no_llseek, 528 .write = wdt_write, 529 .unlocked_ioctl = wdt_ioctl, 530 .open = wdt_open, 531 .release = wdt_release, 532 }; 533 534 static struct miscdevice wdt_miscdev = { 535 .minor = WATCHDOG_MINOR, 536 .name = "watchdog", 537 .fops = &wdt_fops, 538 }; 539 540 static const struct file_operations wdt_temp_fops = { 541 .owner = THIS_MODULE, 542 .llseek = no_llseek, 543 .read = wdt_temp_read, 544 .open = wdt_temp_open, 545 .release = wdt_temp_release, 546 }; 547 548 static struct miscdevice temp_miscdev = { 549 .minor = TEMP_MINOR, 550 .name = "temperature", 551 .fops = &wdt_temp_fops, 552 }; 553 554 /* 555 * The WDT card needs to learn about soft shutdowns in order to 556 * turn the timebomb registers off. 557 */ 558 559 static struct notifier_block wdt_notifier = { 560 .notifier_call = wdt_notify_sys, 561 }; 562 563 /** 564 * cleanup_module: 565 * 566 * Unload the watchdog. You cannot do this with any file handles open. 567 * If your watchdog is set to continue ticking on close and you unload 568 * it, well it keeps ticking. We won't get the interrupt but the board 569 * will not touch PC memory so all is fine. You just have to load a new 570 * module in 60 seconds or reboot. 571 */ 572 573 static void __exit wdt_exit(void) 574 { 575 misc_deregister(&wdt_miscdev); 576 if (type == 501) 577 misc_deregister(&temp_miscdev); 578 unregister_reboot_notifier(&wdt_notifier); 579 free_irq(irq, NULL); 580 release_region(io, 8); 581 } 582 583 /** 584 * wdt_init: 585 * 586 * Set up the WDT watchdog board. All we have to do is grab the 587 * resources we require and bitch if anyone beat us to them. 588 * The open() function will actually kick the board off. 589 */ 590 591 static int __init wdt_init(void) 592 { 593 int ret; 594 595 if (type != 500 && type != 501) { 596 pr_err("unknown card type '%d'\n", type); 597 return -ENODEV; 598 } 599 600 /* Check that the heartbeat value is within it's range; 601 if not reset to the default */ 602 if (wdt_set_heartbeat(heartbeat)) { 603 wdt_set_heartbeat(WD_TIMO); 604 pr_info("heartbeat value must be 0 < heartbeat < 65536, using %d\n", 605 WD_TIMO); 606 } 607 608 if (!request_region(io, 8, "wdt501p")) { 609 pr_err("I/O address 0x%04x already in use\n", io); 610 ret = -EBUSY; 611 goto out; 612 } 613 614 ret = request_irq(irq, wdt_interrupt, 0, "wdt501p", NULL); 615 if (ret) { 616 pr_err("IRQ %d is not free\n", irq); 617 goto outreg; 618 } 619 620 ret = register_reboot_notifier(&wdt_notifier); 621 if (ret) { 622 pr_err("cannot register reboot notifier (err=%d)\n", ret); 623 goto outirq; 624 } 625 626 if (type == 501) { 627 ret = misc_register(&temp_miscdev); 628 if (ret) { 629 pr_err("cannot register miscdev on minor=%d (err=%d)\n", 630 TEMP_MINOR, ret); 631 goto outrbt; 632 } 633 } 634 635 ret = misc_register(&wdt_miscdev); 636 if (ret) { 637 pr_err("cannot register miscdev on minor=%d (err=%d)\n", 638 WATCHDOG_MINOR, ret); 639 goto outmisc; 640 } 641 642 pr_info("WDT500/501-P driver 0.10 at 0x%04x (Interrupt %d). heartbeat=%d sec (nowayout=%d)\n", 643 io, irq, heartbeat, nowayout); 644 if (type == 501) 645 pr_info("Fan Tachometer is %s\n", 646 tachometer ? "Enabled" : "Disabled"); 647 return 0; 648 649 outmisc: 650 if (type == 501) 651 misc_deregister(&temp_miscdev); 652 outrbt: 653 unregister_reboot_notifier(&wdt_notifier); 654 outirq: 655 free_irq(irq, NULL); 656 outreg: 657 release_region(io, 8); 658 out: 659 return ret; 660 } 661 662 module_init(wdt_init); 663 module_exit(wdt_exit); 664 665 MODULE_AUTHOR("Alan Cox"); 666 MODULE_DESCRIPTION("Driver for ISA ICS watchdog cards (WDT500/501)"); 667 MODULE_LICENSE("GPL"); 668