1 /* 2 * W83977F Watchdog Timer Driver for Winbond W83977F I/O Chip 3 * 4 * (c) Copyright 2005 Jose Goncalves <jose.goncalves@inov.pt> 5 * 6 * Based on w83877f_wdt.c by Scott Jennings, 7 * and wdt977.c by Woody Suwalski 8 * 9 * ----------------------- 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation; either version 14 * 2 of the License, or (at your option) any later version. 15 * 16 */ 17 18 #include <linux/module.h> 19 #include <linux/moduleparam.h> 20 #include <linux/types.h> 21 #include <linux/kernel.h> 22 #include <linux/fs.h> 23 #include <linux/miscdevice.h> 24 #include <linux/init.h> 25 #include <linux/ioport.h> 26 #include <linux/watchdog.h> 27 #include <linux/notifier.h> 28 #include <linux/reboot.h> 29 30 #include <asm/io.h> 31 #include <asm/system.h> 32 #include <asm/uaccess.h> 33 34 #define WATCHDOG_VERSION "1.00" 35 #define WATCHDOG_NAME "W83977F WDT" 36 #define PFX WATCHDOG_NAME ": " 37 #define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n" 38 39 #define IO_INDEX_PORT 0x3F0 40 #define IO_DATA_PORT (IO_INDEX_PORT+1) 41 42 #define UNLOCK_DATA 0x87 43 #define LOCK_DATA 0xAA 44 #define DEVICE_REGISTER 0x07 45 46 #define DEFAULT_TIMEOUT 45 /* default timeout in seconds */ 47 48 static int timeout = DEFAULT_TIMEOUT; 49 static int timeoutW; /* timeout in watchdog counter units */ 50 static unsigned long timer_alive; 51 static int testmode; 52 static char expect_close; 53 static DEFINE_SPINLOCK(spinlock); 54 55 module_param(timeout, int, 0); 56 MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (15..7635), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); 57 module_param(testmode, int, 0); 58 MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0"); 59 60 static int nowayout = WATCHDOG_NOWAYOUT; 61 module_param(nowayout, int, 0); 62 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 63 64 /* 65 * Start the watchdog 66 */ 67 68 static int wdt_start(void) 69 { 70 unsigned long flags; 71 72 spin_lock_irqsave(&spinlock, flags); 73 74 /* Unlock the SuperIO chip */ 75 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 76 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 77 78 /* 79 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. 80 * F2 has the timeout in watchdog counter units. 81 * F3 is set to enable watchdog LED blink at timeout. 82 * F4 is used to just clear the TIMEOUT'ed state (bit 0). 83 */ 84 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 85 outb_p(0x08,IO_DATA_PORT); 86 outb_p(0xF2,IO_INDEX_PORT); 87 outb_p(timeoutW,IO_DATA_PORT); 88 outb_p(0xF3,IO_INDEX_PORT); 89 outb_p(0x08,IO_DATA_PORT); 90 outb_p(0xF4,IO_INDEX_PORT); 91 outb_p(0x00,IO_DATA_PORT); 92 93 /* Set device Aux2 active */ 94 outb_p(0x30,IO_INDEX_PORT); 95 outb_p(0x01,IO_DATA_PORT); 96 97 /* 98 * Select device Aux1 (dev=7) to set GP16 as the watchdog output 99 * (in reg E6) and GP13 as the watchdog LED output (in reg E3). 100 * Map GP16 at pin 119. 101 * In test mode watch the bit 0 on F4 to indicate "triggered" or 102 * check watchdog LED on SBC. 103 */ 104 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 105 outb_p(0x07,IO_DATA_PORT); 106 if (!testmode) 107 { 108 unsigned pin_map; 109 110 outb_p(0xE6,IO_INDEX_PORT); 111 outb_p(0x0A,IO_DATA_PORT); 112 outb_p(0x2C,IO_INDEX_PORT); 113 pin_map = inb_p(IO_DATA_PORT); 114 pin_map |= 0x10; 115 pin_map &= ~(0x20); 116 outb_p(0x2C,IO_INDEX_PORT); 117 outb_p(pin_map,IO_DATA_PORT); 118 } 119 outb_p(0xE3,IO_INDEX_PORT); 120 outb_p(0x08,IO_DATA_PORT); 121 122 /* Set device Aux1 active */ 123 outb_p(0x30,IO_INDEX_PORT); 124 outb_p(0x01,IO_DATA_PORT); 125 126 /* Lock the SuperIO chip */ 127 outb_p(LOCK_DATA,IO_INDEX_PORT); 128 129 spin_unlock_irqrestore(&spinlock, flags); 130 131 printk(KERN_INFO PFX "activated.\n"); 132 133 return 0; 134 } 135 136 /* 137 * Stop the watchdog 138 */ 139 140 static int wdt_stop(void) 141 { 142 unsigned long flags; 143 144 spin_lock_irqsave(&spinlock, flags); 145 146 /* Unlock the SuperIO chip */ 147 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 148 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 149 150 /* 151 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. 152 * F2 is reset to its default value (watchdog timer disabled). 153 * F3 is reset to its default state. 154 * F4 clears the TIMEOUT'ed state (bit 0) - back to default. 155 */ 156 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 157 outb_p(0x08,IO_DATA_PORT); 158 outb_p(0xF2,IO_INDEX_PORT); 159 outb_p(0xFF,IO_DATA_PORT); 160 outb_p(0xF3,IO_INDEX_PORT); 161 outb_p(0x00,IO_DATA_PORT); 162 outb_p(0xF4,IO_INDEX_PORT); 163 outb_p(0x00,IO_DATA_PORT); 164 outb_p(0xF2,IO_INDEX_PORT); 165 outb_p(0x00,IO_DATA_PORT); 166 167 /* 168 * Select device Aux1 (dev=7) to set GP16 (in reg E6) and 169 * Gp13 (in reg E3) as inputs. 170 */ 171 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 172 outb_p(0x07,IO_DATA_PORT); 173 if (!testmode) 174 { 175 outb_p(0xE6,IO_INDEX_PORT); 176 outb_p(0x01,IO_DATA_PORT); 177 } 178 outb_p(0xE3,IO_INDEX_PORT); 179 outb_p(0x01,IO_DATA_PORT); 180 181 /* Lock the SuperIO chip */ 182 outb_p(LOCK_DATA,IO_INDEX_PORT); 183 184 spin_unlock_irqrestore(&spinlock, flags); 185 186 printk(KERN_INFO PFX "shutdown.\n"); 187 188 return 0; 189 } 190 191 /* 192 * Send a keepalive ping to the watchdog 193 * This is done by simply re-writing the timeout to reg. 0xF2 194 */ 195 196 static int wdt_keepalive(void) 197 { 198 unsigned long flags; 199 200 spin_lock_irqsave(&spinlock, flags); 201 202 /* Unlock the SuperIO chip */ 203 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 204 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 205 206 /* Select device Aux2 (device=8) to kick watchdog reg F2 */ 207 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 208 outb_p(0x08,IO_DATA_PORT); 209 outb_p(0xF2,IO_INDEX_PORT); 210 outb_p(timeoutW,IO_DATA_PORT); 211 212 /* Lock the SuperIO chip */ 213 outb_p(LOCK_DATA,IO_INDEX_PORT); 214 215 spin_unlock_irqrestore(&spinlock, flags); 216 217 return 0; 218 } 219 220 /* 221 * Set the watchdog timeout value 222 */ 223 224 static int wdt_set_timeout(int t) 225 { 226 int tmrval; 227 228 /* 229 * Convert seconds to watchdog counter time units, rounding up. 230 * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup 231 * value. This information is supplied in the PCM-5335 manual and was 232 * checked by me on a real board. This is a bit strange because W83977f 233 * datasheet says counter unit is in minutes! 234 */ 235 if (t < 15) 236 return -EINVAL; 237 238 tmrval = ((t + 15) + 29) / 30; 239 240 if (tmrval > 255) 241 return -EINVAL; 242 243 /* 244 * timeout is the timeout in seconds, 245 * timeoutW is the timeout in watchdog counter units. 246 */ 247 timeoutW = tmrval; 248 timeout = (timeoutW * 30) - 15; 249 return 0; 250 } 251 252 /* 253 * Get the watchdog status 254 */ 255 256 static int wdt_get_status(int *status) 257 { 258 int new_status; 259 unsigned long flags; 260 261 spin_lock_irqsave(&spinlock, flags); 262 263 /* Unlock the SuperIO chip */ 264 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 265 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 266 267 /* Select device Aux2 (device=8) to read watchdog reg F4 */ 268 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 269 outb_p(0x08,IO_DATA_PORT); 270 outb_p(0xF4,IO_INDEX_PORT); 271 new_status = inb_p(IO_DATA_PORT); 272 273 /* Lock the SuperIO chip */ 274 outb_p(LOCK_DATA,IO_INDEX_PORT); 275 276 spin_unlock_irqrestore(&spinlock, flags); 277 278 *status = 0; 279 if (new_status & 1) 280 *status |= WDIOF_CARDRESET; 281 282 return 0; 283 } 284 285 286 /* 287 * /dev/watchdog handling 288 */ 289 290 static int wdt_open(struct inode *inode, struct file *file) 291 { 292 /* If the watchdog is alive we don't need to start it again */ 293 if( test_and_set_bit(0, &timer_alive) ) 294 return -EBUSY; 295 296 if (nowayout) 297 __module_get(THIS_MODULE); 298 299 wdt_start(); 300 return nonseekable_open(inode, file); 301 } 302 303 static int wdt_release(struct inode *inode, struct file *file) 304 { 305 /* 306 * Shut off the timer. 307 * Lock it in if it's a module and we set nowayout 308 */ 309 if (expect_close == 42) 310 { 311 wdt_stop(); 312 clear_bit(0, &timer_alive); 313 } else { 314 wdt_keepalive(); 315 printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); 316 } 317 expect_close = 0; 318 return 0; 319 } 320 321 /* 322 * wdt_write: 323 * @file: file handle to the watchdog 324 * @buf: buffer to write (unused as data does not matter here 325 * @count: count of bytes 326 * @ppos: pointer to the position to write. No seeks allowed 327 * 328 * A write to a watchdog device is defined as a keepalive signal. Any 329 * write of data will do, as we we don't define content meaning. 330 */ 331 332 static ssize_t wdt_write(struct file *file, const char __user *buf, 333 size_t count, loff_t *ppos) 334 { 335 /* See if we got the magic character 'V' and reload the timer */ 336 if(count) 337 { 338 if (!nowayout) 339 { 340 size_t ofs; 341 342 /* note: just in case someone wrote the magic character long ago */ 343 expect_close = 0; 344 345 /* scan to see whether or not we got the magic character */ 346 for(ofs = 0; ofs != count; ofs++) 347 { 348 char c; 349 if (get_user(c, buf + ofs)) 350 return -EFAULT; 351 if (c == 'V') { 352 expect_close = 42; 353 } 354 } 355 } 356 357 /* someone wrote to us, we should restart timer */ 358 wdt_keepalive(); 359 } 360 return count; 361 } 362 363 /* 364 * wdt_ioctl: 365 * @inode: inode of the device 366 * @file: file handle to the device 367 * @cmd: watchdog command 368 * @arg: argument pointer 369 * 370 * The watchdog API defines a common set of functions for all watchdogs 371 * according to their available features. 372 */ 373 374 static struct watchdog_info ident = { 375 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 376 .firmware_version = 1, 377 .identity = WATCHDOG_NAME, 378 }; 379 380 static int wdt_ioctl(struct inode *inode, struct file *file, 381 unsigned int cmd, unsigned long arg) 382 { 383 int status; 384 int new_options, retval = -EINVAL; 385 int new_timeout; 386 union { 387 struct watchdog_info __user *ident; 388 int __user *i; 389 } uarg; 390 391 uarg.i = (int __user *)arg; 392 393 switch(cmd) 394 { 395 default: 396 return -ENOTTY; 397 398 case WDIOC_GETSUPPORT: 399 return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; 400 401 case WDIOC_GETSTATUS: 402 wdt_get_status(&status); 403 return put_user(status, uarg.i); 404 405 case WDIOC_GETBOOTSTATUS: 406 return put_user(0, uarg.i); 407 408 case WDIOC_KEEPALIVE: 409 wdt_keepalive(); 410 return 0; 411 412 case WDIOC_SETOPTIONS: 413 if (get_user (new_options, uarg.i)) 414 return -EFAULT; 415 416 if (new_options & WDIOS_DISABLECARD) { 417 wdt_stop(); 418 retval = 0; 419 } 420 421 if (new_options & WDIOS_ENABLECARD) { 422 wdt_start(); 423 retval = 0; 424 } 425 426 return retval; 427 428 case WDIOC_SETTIMEOUT: 429 if (get_user(new_timeout, uarg.i)) 430 return -EFAULT; 431 432 if (wdt_set_timeout(new_timeout)) 433 return -EINVAL; 434 435 wdt_keepalive(); 436 /* Fall */ 437 438 case WDIOC_GETTIMEOUT: 439 return put_user(timeout, uarg.i); 440 441 } 442 } 443 444 static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 445 void *unused) 446 { 447 if (code==SYS_DOWN || code==SYS_HALT) 448 wdt_stop(); 449 return NOTIFY_DONE; 450 } 451 452 static const struct file_operations wdt_fops= 453 { 454 .owner = THIS_MODULE, 455 .llseek = no_llseek, 456 .write = wdt_write, 457 .ioctl = wdt_ioctl, 458 .open = wdt_open, 459 .release = wdt_release, 460 }; 461 462 static struct miscdevice wdt_miscdev= 463 { 464 .minor = WATCHDOG_MINOR, 465 .name = "watchdog", 466 .fops = &wdt_fops, 467 }; 468 469 static struct notifier_block wdt_notifier = { 470 .notifier_call = wdt_notify_sys, 471 }; 472 473 static int __init w83977f_wdt_init(void) 474 { 475 int rc; 476 477 printk(KERN_INFO PFX DRIVER_VERSION); 478 479 /* 480 * Check that the timeout value is within it's range ; 481 * if not reset to the default 482 */ 483 if (wdt_set_timeout(timeout)) { 484 wdt_set_timeout(DEFAULT_TIMEOUT); 485 printk(KERN_INFO PFX "timeout value must be 15<=timeout<=7635, using %d\n", 486 DEFAULT_TIMEOUT); 487 } 488 489 if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) 490 { 491 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 492 IO_INDEX_PORT); 493 rc = -EIO; 494 goto err_out; 495 } 496 497 rc = register_reboot_notifier(&wdt_notifier); 498 if (rc) 499 { 500 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 501 rc); 502 goto err_out_region; 503 } 504 505 rc = misc_register(&wdt_miscdev); 506 if (rc) 507 { 508 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 509 wdt_miscdev.minor, rc); 510 goto err_out_reboot; 511 } 512 513 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n", 514 timeout, nowayout, testmode); 515 516 return 0; 517 518 err_out_reboot: 519 unregister_reboot_notifier(&wdt_notifier); 520 err_out_region: 521 release_region(IO_INDEX_PORT,2); 522 err_out: 523 return rc; 524 } 525 526 static void __exit w83977f_wdt_exit(void) 527 { 528 wdt_stop(); 529 misc_deregister(&wdt_miscdev); 530 unregister_reboot_notifier(&wdt_notifier); 531 release_region(IO_INDEX_PORT,2); 532 } 533 534 module_init(w83977f_wdt_init); 535 module_exit(w83977f_wdt_exit); 536 537 MODULE_AUTHOR("Jose Goncalves <jose.goncalves@inov.pt>"); 538 MODULE_DESCRIPTION("Driver for watchdog timer in W83977F I/O chip"); 539 MODULE_LICENSE("GPL"); 540 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 541