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