Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.4-rc3 818 lines 21 kB view raw
1/*************************************************************************** 2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * 3 * Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com> * 4 * Copyright (C) 2010 Giel van Schijndel <me@mortis.eu> * 5 * * 6 * This program is free software; you can redistribute it and/or modify * 7 * it under the terms of the GNU General Public License as published by * 8 * the Free Software Foundation; either version 2 of the License, or * 9 * (at your option) any later version. * 10 * * 11 * This program is distributed in the hope that it will be useful, * 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 * GNU General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU General Public License * 17 * along with this program; if not, write to the * 18 * Free Software Foundation, Inc., * 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 20 ***************************************************************************/ 21 22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 23 24#include <linux/err.h> 25#include <linux/fs.h> 26#include <linux/init.h> 27#include <linux/io.h> 28#include <linux/ioport.h> 29#include <linux/miscdevice.h> 30#include <linux/module.h> 31#include <linux/mutex.h> 32#include <linux/notifier.h> 33#include <linux/reboot.h> 34#include <linux/uaccess.h> 35#include <linux/watchdog.h> 36 37#define DRVNAME "f71808e_wdt" 38 39#define SIO_F71808FG_LD_WDT 0x07 /* Watchdog timer logical device */ 40#define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ 41#define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ 42 43#define SIO_REG_LDSEL 0x07 /* Logical device select */ 44#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ 45#define SIO_REG_DEVREV 0x22 /* Device revision */ 46#define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ 47#define SIO_REG_ROM_ADDR_SEL 0x27 /* ROM address select */ 48#define SIO_REG_MFUNCT1 0x29 /* Multi function select 1 */ 49#define SIO_REG_MFUNCT2 0x2a /* Multi function select 2 */ 50#define SIO_REG_MFUNCT3 0x2b /* Multi function select 3 */ 51#define SIO_REG_ENABLE 0x30 /* Logical device enable */ 52#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 53 54#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ 55#define SIO_F71808_ID 0x0901 /* Chipset ID */ 56#define SIO_F71858_ID 0x0507 /* Chipset ID */ 57#define SIO_F71862_ID 0x0601 /* Chipset ID */ 58#define SIO_F71869_ID 0x0814 /* Chipset ID */ 59#define SIO_F71882_ID 0x0541 /* Chipset ID */ 60#define SIO_F71889_ID 0x0723 /* Chipset ID */ 61 62#define F71808FG_REG_WDO_CONF 0xf0 63#define F71808FG_REG_WDT_CONF 0xf5 64#define F71808FG_REG_WD_TIME 0xf6 65 66#define F71808FG_FLAG_WDOUT_EN 7 67 68#define F71808FG_FLAG_WDTMOUT_STS 5 69#define F71808FG_FLAG_WD_EN 5 70#define F71808FG_FLAG_WD_PULSE 4 71#define F71808FG_FLAG_WD_UNIT 3 72 73/* Default values */ 74#define WATCHDOG_TIMEOUT 60 /* 1 minute default timeout */ 75#define WATCHDOG_MAX_TIMEOUT (60 * 255) 76#define WATCHDOG_PULSE_WIDTH 125 /* 125 ms, default pulse width for 77 watchdog signal */ 78#define WATCHDOG_F71862FG_PIN 63 /* default watchdog reset output 79 pin number 63 */ 80 81static unsigned short force_id; 82module_param(force_id, ushort, 0); 83MODULE_PARM_DESC(force_id, "Override the detected device ID"); 84 85static const int max_timeout = WATCHDOG_MAX_TIMEOUT; 86static int timeout = WATCHDOG_TIMEOUT; /* default timeout in seconds */ 87module_param(timeout, int, 0); 88MODULE_PARM_DESC(timeout, 89 "Watchdog timeout in seconds. 1<= timeout <=" 90 __MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default=" 91 __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 92 93static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH; 94module_param(pulse_width, uint, 0); 95MODULE_PARM_DESC(pulse_width, 96 "Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms" 97 " (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")"); 98 99static unsigned int f71862fg_pin = WATCHDOG_F71862FG_PIN; 100module_param(f71862fg_pin, uint, 0); 101MODULE_PARM_DESC(f71862fg_pin, 102 "Watchdog f71862fg reset output pin configuration. Choose pin 56 or 63" 103 " (default=" __MODULE_STRING(WATCHDOG_F71862FG_PIN)")"); 104 105static bool nowayout = WATCHDOG_NOWAYOUT; 106module_param(nowayout, bool, 0444); 107MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); 108 109static unsigned int start_withtimeout; 110module_param(start_withtimeout, uint, 0); 111MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with" 112 " given initial timeout. Zero (default) disables this feature."); 113 114enum chips { f71808fg, f71858fg, f71862fg, f71869, f71882fg, f71889fg }; 115 116static const char *f71808e_names[] = { 117 "f71808fg", 118 "f71858fg", 119 "f71862fg", 120 "f71869", 121 "f71882fg", 122 "f71889fg", 123}; 124 125/* Super-I/O Function prototypes */ 126static inline int superio_inb(int base, int reg); 127static inline int superio_inw(int base, int reg); 128static inline void superio_outb(int base, int reg, u8 val); 129static inline void superio_set_bit(int base, int reg, int bit); 130static inline void superio_clear_bit(int base, int reg, int bit); 131static inline int superio_enter(int base); 132static inline void superio_select(int base, int ld); 133static inline void superio_exit(int base); 134 135struct watchdog_data { 136 unsigned short sioaddr; 137 enum chips type; 138 unsigned long opened; 139 struct mutex lock; 140 char expect_close; 141 struct watchdog_info ident; 142 143 unsigned short timeout; 144 u8 timer_val; /* content for the wd_time register */ 145 char minutes_mode; 146 u8 pulse_val; /* pulse width flag */ 147 char pulse_mode; /* enable pulse output mode? */ 148 char caused_reboot; /* last reboot was by the watchdog */ 149}; 150 151static struct watchdog_data watchdog = { 152 .lock = __MUTEX_INITIALIZER(watchdog.lock), 153}; 154 155/* Super I/O functions */ 156static inline int superio_inb(int base, int reg) 157{ 158 outb(reg, base); 159 return inb(base + 1); 160} 161 162static int superio_inw(int base, int reg) 163{ 164 int val; 165 val = superio_inb(base, reg) << 8; 166 val |= superio_inb(base, reg + 1); 167 return val; 168} 169 170static inline void superio_outb(int base, int reg, u8 val) 171{ 172 outb(reg, base); 173 outb(val, base + 1); 174} 175 176static inline void superio_set_bit(int base, int reg, int bit) 177{ 178 unsigned long val = superio_inb(base, reg); 179 __set_bit(bit, &val); 180 superio_outb(base, reg, val); 181} 182 183static inline void superio_clear_bit(int base, int reg, int bit) 184{ 185 unsigned long val = superio_inb(base, reg); 186 __clear_bit(bit, &val); 187 superio_outb(base, reg, val); 188} 189 190static inline int superio_enter(int base) 191{ 192 /* Don't step on other drivers' I/O space by accident */ 193 if (!request_muxed_region(base, 2, DRVNAME)) { 194 pr_err("I/O address 0x%04x already in use\n", (int)base); 195 return -EBUSY; 196 } 197 198 /* according to the datasheet the key must be send twice! */ 199 outb(SIO_UNLOCK_KEY, base); 200 outb(SIO_UNLOCK_KEY, base); 201 202 return 0; 203} 204 205static inline void superio_select(int base, int ld) 206{ 207 outb(SIO_REG_LDSEL, base); 208 outb(ld, base + 1); 209} 210 211static inline void superio_exit(int base) 212{ 213 outb(SIO_LOCK_KEY, base); 214 release_region(base, 2); 215} 216 217static int watchdog_set_timeout(int timeout) 218{ 219 if (timeout <= 0 220 || timeout > max_timeout) { 221 pr_err("watchdog timeout out of range\n"); 222 return -EINVAL; 223 } 224 225 mutex_lock(&watchdog.lock); 226 227 watchdog.timeout = timeout; 228 if (timeout > 0xff) { 229 watchdog.timer_val = DIV_ROUND_UP(timeout, 60); 230 watchdog.minutes_mode = true; 231 } else { 232 watchdog.timer_val = timeout; 233 watchdog.minutes_mode = false; 234 } 235 236 mutex_unlock(&watchdog.lock); 237 238 return 0; 239} 240 241static int watchdog_set_pulse_width(unsigned int pw) 242{ 243 int err = 0; 244 245 mutex_lock(&watchdog.lock); 246 247 if (pw <= 1) { 248 watchdog.pulse_val = 0; 249 } else if (pw <= 25) { 250 watchdog.pulse_val = 1; 251 } else if (pw <= 125) { 252 watchdog.pulse_val = 2; 253 } else if (pw <= 5000) { 254 watchdog.pulse_val = 3; 255 } else { 256 pr_err("pulse width out of range\n"); 257 err = -EINVAL; 258 goto exit_unlock; 259 } 260 261 watchdog.pulse_mode = pw; 262 263exit_unlock: 264 mutex_unlock(&watchdog.lock); 265 return err; 266} 267 268static int watchdog_keepalive(void) 269{ 270 int err = 0; 271 272 mutex_lock(&watchdog.lock); 273 err = superio_enter(watchdog.sioaddr); 274 if (err) 275 goto exit_unlock; 276 superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT); 277 278 if (watchdog.minutes_mode) 279 /* select minutes for timer units */ 280 superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF, 281 F71808FG_FLAG_WD_UNIT); 282 else 283 /* select seconds for timer units */ 284 superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF, 285 F71808FG_FLAG_WD_UNIT); 286 287 /* Set timer value */ 288 superio_outb(watchdog.sioaddr, F71808FG_REG_WD_TIME, 289 watchdog.timer_val); 290 291 superio_exit(watchdog.sioaddr); 292 293exit_unlock: 294 mutex_unlock(&watchdog.lock); 295 return err; 296} 297 298static int f71862fg_pin_configure(unsigned short ioaddr) 299{ 300 /* When ioaddr is non-zero the calling function has to take care of 301 mutex handling and superio preparation! */ 302 303 if (f71862fg_pin == 63) { 304 if (ioaddr) { 305 /* SPI must be disabled first to use this pin! */ 306 superio_clear_bit(ioaddr, SIO_REG_ROM_ADDR_SEL, 6); 307 superio_set_bit(ioaddr, SIO_REG_MFUNCT3, 4); 308 } 309 } else if (f71862fg_pin == 56) { 310 if (ioaddr) 311 superio_set_bit(ioaddr, SIO_REG_MFUNCT1, 1); 312 } else { 313 pr_err("Invalid argument f71862fg_pin=%d\n", f71862fg_pin); 314 return -EINVAL; 315 } 316 return 0; 317} 318 319static int watchdog_start(void) 320{ 321 /* Make sure we don't die as soon as the watchdog is enabled below */ 322 int err = watchdog_keepalive(); 323 if (err) 324 return err; 325 326 mutex_lock(&watchdog.lock); 327 err = superio_enter(watchdog.sioaddr); 328 if (err) 329 goto exit_unlock; 330 superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT); 331 332 /* Watchdog pin configuration */ 333 switch (watchdog.type) { 334 case f71808fg: 335 /* Set pin 21 to GPIO23/WDTRST#, then to WDTRST# */ 336 superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT2, 3); 337 superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT3, 3); 338 break; 339 340 case f71862fg: 341 err = f71862fg_pin_configure(watchdog.sioaddr); 342 if (err) 343 goto exit_superio; 344 break; 345 346 case f71869: 347 /* GPIO14 --> WDTRST# */ 348 superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT1, 4); 349 break; 350 351 case f71882fg: 352 /* Set pin 56 to WDTRST# */ 353 superio_set_bit(watchdog.sioaddr, SIO_REG_MFUNCT1, 1); 354 break; 355 356 case f71889fg: 357 /* set pin 40 to WDTRST# */ 358 superio_outb(watchdog.sioaddr, SIO_REG_MFUNCT3, 359 superio_inb(watchdog.sioaddr, SIO_REG_MFUNCT3) & 0xcf); 360 break; 361 362 default: 363 /* 364 * 'default' label to shut up the compiler and catch 365 * programmer errors 366 */ 367 err = -ENODEV; 368 goto exit_superio; 369 } 370 371 superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT); 372 superio_set_bit(watchdog.sioaddr, SIO_REG_ENABLE, 0); 373 superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDO_CONF, 374 F71808FG_FLAG_WDOUT_EN); 375 376 superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF, 377 F71808FG_FLAG_WD_EN); 378 379 if (watchdog.pulse_mode) { 380 /* Select "pulse" output mode with given duration */ 381 u8 wdt_conf = superio_inb(watchdog.sioaddr, 382 F71808FG_REG_WDT_CONF); 383 384 /* Set WD_PSWIDTH bits (1:0) */ 385 wdt_conf = (wdt_conf & 0xfc) | (watchdog.pulse_val & 0x03); 386 /* Set WD_PULSE to "pulse" mode */ 387 wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE); 388 389 superio_outb(watchdog.sioaddr, F71808FG_REG_WDT_CONF, 390 wdt_conf); 391 } else { 392 /* Select "level" output mode */ 393 superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF, 394 F71808FG_FLAG_WD_PULSE); 395 } 396 397exit_superio: 398 superio_exit(watchdog.sioaddr); 399exit_unlock: 400 mutex_unlock(&watchdog.lock); 401 402 return err; 403} 404 405static int watchdog_stop(void) 406{ 407 int err = 0; 408 409 mutex_lock(&watchdog.lock); 410 err = superio_enter(watchdog.sioaddr); 411 if (err) 412 goto exit_unlock; 413 superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT); 414 415 superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF, 416 F71808FG_FLAG_WD_EN); 417 418 superio_exit(watchdog.sioaddr); 419 420exit_unlock: 421 mutex_unlock(&watchdog.lock); 422 423 return err; 424} 425 426static int watchdog_get_status(void) 427{ 428 int status = 0; 429 430 mutex_lock(&watchdog.lock); 431 status = (watchdog.caused_reboot) ? WDIOF_CARDRESET : 0; 432 mutex_unlock(&watchdog.lock); 433 434 return status; 435} 436 437static bool watchdog_is_running(void) 438{ 439 /* 440 * if we fail to determine the watchdog's status assume it to be 441 * running to be on the safe side 442 */ 443 bool is_running = true; 444 445 mutex_lock(&watchdog.lock); 446 if (superio_enter(watchdog.sioaddr)) 447 goto exit_unlock; 448 superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT); 449 450 is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0)) 451 && (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF) 452 & F71808FG_FLAG_WD_EN); 453 454 superio_exit(watchdog.sioaddr); 455 456exit_unlock: 457 mutex_unlock(&watchdog.lock); 458 return is_running; 459} 460 461/* /dev/watchdog api */ 462 463static int watchdog_open(struct inode *inode, struct file *file) 464{ 465 int err; 466 467 /* If the watchdog is alive we don't need to start it again */ 468 if (test_and_set_bit(0, &watchdog.opened)) 469 return -EBUSY; 470 471 err = watchdog_start(); 472 if (err) { 473 clear_bit(0, &watchdog.opened); 474 return err; 475 } 476 477 if (nowayout) 478 __module_get(THIS_MODULE); 479 480 watchdog.expect_close = 0; 481 return nonseekable_open(inode, file); 482} 483 484static int watchdog_release(struct inode *inode, struct file *file) 485{ 486 clear_bit(0, &watchdog.opened); 487 488 if (!watchdog.expect_close) { 489 watchdog_keepalive(); 490 pr_crit("Unexpected close, not stopping watchdog!\n"); 491 } else if (!nowayout) { 492 watchdog_stop(); 493 } 494 return 0; 495} 496 497/* 498 * watchdog_write: 499 * @file: file handle to the watchdog 500 * @buf: buffer to write 501 * @count: count of bytes 502 * @ppos: pointer to the position to write. No seeks allowed 503 * 504 * A write to a watchdog device is defined as a keepalive signal. Any 505 * write of data will do, as we we don't define content meaning. 506 */ 507 508static ssize_t watchdog_write(struct file *file, const char __user *buf, 509 size_t count, loff_t *ppos) 510{ 511 if (count) { 512 if (!nowayout) { 513 size_t i; 514 515 /* In case it was set long ago */ 516 bool expect_close = false; 517 518 for (i = 0; i != count; i++) { 519 char c; 520 if (get_user(c, buf + i)) 521 return -EFAULT; 522 expect_close = (c == 'V'); 523 } 524 525 /* Properly order writes across fork()ed processes */ 526 mutex_lock(&watchdog.lock); 527 watchdog.expect_close = expect_close; 528 mutex_unlock(&watchdog.lock); 529 } 530 531 /* someone wrote to us, we should restart timer */ 532 watchdog_keepalive(); 533 } 534 return count; 535} 536 537/* 538 * watchdog_ioctl: 539 * @inode: inode of the device 540 * @file: file handle to the device 541 * @cmd: watchdog command 542 * @arg: argument pointer 543 * 544 * The watchdog API defines a common set of functions for all watchdogs 545 * according to their available features. 546 */ 547static long watchdog_ioctl(struct file *file, unsigned int cmd, 548 unsigned long arg) 549{ 550 int status; 551 int new_options; 552 int new_timeout; 553 union { 554 struct watchdog_info __user *ident; 555 int __user *i; 556 } uarg; 557 558 uarg.i = (int __user *)arg; 559 560 switch (cmd) { 561 case WDIOC_GETSUPPORT: 562 return copy_to_user(uarg.ident, &watchdog.ident, 563 sizeof(watchdog.ident)) ? -EFAULT : 0; 564 565 case WDIOC_GETSTATUS: 566 status = watchdog_get_status(); 567 if (status < 0) 568 return status; 569 return put_user(status, uarg.i); 570 571 case WDIOC_GETBOOTSTATUS: 572 return put_user(0, uarg.i); 573 574 case WDIOC_SETOPTIONS: 575 if (get_user(new_options, uarg.i)) 576 return -EFAULT; 577 578 if (new_options & WDIOS_DISABLECARD) 579 watchdog_stop(); 580 581 if (new_options & WDIOS_ENABLECARD) 582 return watchdog_start(); 583 584 585 case WDIOC_KEEPALIVE: 586 watchdog_keepalive(); 587 return 0; 588 589 case WDIOC_SETTIMEOUT: 590 if (get_user(new_timeout, uarg.i)) 591 return -EFAULT; 592 593 if (watchdog_set_timeout(new_timeout)) 594 return -EINVAL; 595 596 watchdog_keepalive(); 597 /* Fall */ 598 599 case WDIOC_GETTIMEOUT: 600 return put_user(watchdog.timeout, uarg.i); 601 602 default: 603 return -ENOTTY; 604 605 } 606} 607 608static int watchdog_notify_sys(struct notifier_block *this, unsigned long code, 609 void *unused) 610{ 611 if (code == SYS_DOWN || code == SYS_HALT) 612 watchdog_stop(); 613 return NOTIFY_DONE; 614} 615 616static const struct file_operations watchdog_fops = { 617 .owner = THIS_MODULE, 618 .llseek = no_llseek, 619 .open = watchdog_open, 620 .release = watchdog_release, 621 .write = watchdog_write, 622 .unlocked_ioctl = watchdog_ioctl, 623}; 624 625static struct miscdevice watchdog_miscdev = { 626 .minor = WATCHDOG_MINOR, 627 .name = "watchdog", 628 .fops = &watchdog_fops, 629}; 630 631static struct notifier_block watchdog_notifier = { 632 .notifier_call = watchdog_notify_sys, 633}; 634 635static int __init watchdog_init(int sioaddr) 636{ 637 int wdt_conf, err = 0; 638 639 /* No need to lock watchdog.lock here because no entry points 640 * into the module have been registered yet. 641 */ 642 watchdog.sioaddr = sioaddr; 643 watchdog.ident.options = WDIOC_SETTIMEOUT 644 | WDIOF_MAGICCLOSE 645 | WDIOF_KEEPALIVEPING; 646 647 snprintf(watchdog.ident.identity, 648 sizeof(watchdog.ident.identity), "%s watchdog", 649 f71808e_names[watchdog.type]); 650 651 err = superio_enter(sioaddr); 652 if (err) 653 return err; 654 superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT); 655 656 wdt_conf = superio_inb(sioaddr, F71808FG_REG_WDT_CONF); 657 watchdog.caused_reboot = wdt_conf & F71808FG_FLAG_WDTMOUT_STS; 658 659 superio_exit(sioaddr); 660 661 err = watchdog_set_timeout(timeout); 662 if (err) 663 return err; 664 err = watchdog_set_pulse_width(pulse_width); 665 if (err) 666 return err; 667 668 err = register_reboot_notifier(&watchdog_notifier); 669 if (err) 670 return err; 671 672 err = misc_register(&watchdog_miscdev); 673 if (err) { 674 pr_err("cannot register miscdev on minor=%d\n", 675 watchdog_miscdev.minor); 676 goto exit_reboot; 677 } 678 679 if (start_withtimeout) { 680 if (start_withtimeout <= 0 681 || start_withtimeout > max_timeout) { 682 pr_err("starting timeout out of range\n"); 683 err = -EINVAL; 684 goto exit_miscdev; 685 } 686 687 err = watchdog_start(); 688 if (err) { 689 pr_err("cannot start watchdog timer\n"); 690 goto exit_miscdev; 691 } 692 693 mutex_lock(&watchdog.lock); 694 err = superio_enter(sioaddr); 695 if (err) 696 goto exit_unlock; 697 superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT); 698 699 if (start_withtimeout > 0xff) { 700 /* select minutes for timer units */ 701 superio_set_bit(sioaddr, F71808FG_REG_WDT_CONF, 702 F71808FG_FLAG_WD_UNIT); 703 superio_outb(sioaddr, F71808FG_REG_WD_TIME, 704 DIV_ROUND_UP(start_withtimeout, 60)); 705 } else { 706 /* select seconds for timer units */ 707 superio_clear_bit(sioaddr, F71808FG_REG_WDT_CONF, 708 F71808FG_FLAG_WD_UNIT); 709 superio_outb(sioaddr, F71808FG_REG_WD_TIME, 710 start_withtimeout); 711 } 712 713 superio_exit(sioaddr); 714 mutex_unlock(&watchdog.lock); 715 716 if (nowayout) 717 __module_get(THIS_MODULE); 718 719 pr_info("watchdog started with initial timeout of %u sec\n", 720 start_withtimeout); 721 } 722 723 return 0; 724 725exit_unlock: 726 mutex_unlock(&watchdog.lock); 727exit_miscdev: 728 misc_deregister(&watchdog_miscdev); 729exit_reboot: 730 unregister_reboot_notifier(&watchdog_notifier); 731 732 return err; 733} 734 735static int __init f71808e_find(int sioaddr) 736{ 737 u16 devid; 738 int err = superio_enter(sioaddr); 739 if (err) 740 return err; 741 742 devid = superio_inw(sioaddr, SIO_REG_MANID); 743 if (devid != SIO_FINTEK_ID) { 744 pr_debug("Not a Fintek device\n"); 745 err = -ENODEV; 746 goto exit; 747 } 748 749 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); 750 switch (devid) { 751 case SIO_F71808_ID: 752 watchdog.type = f71808fg; 753 break; 754 case SIO_F71862_ID: 755 watchdog.type = f71862fg; 756 err = f71862fg_pin_configure(0); /* validate module parameter */ 757 break; 758 case SIO_F71869_ID: 759 watchdog.type = f71869; 760 break; 761 case SIO_F71882_ID: 762 watchdog.type = f71882fg; 763 break; 764 case SIO_F71889_ID: 765 watchdog.type = f71889fg; 766 break; 767 case SIO_F71858_ID: 768 /* Confirmed (by datasheet) not to have a watchdog. */ 769 err = -ENODEV; 770 goto exit; 771 default: 772 pr_info("Unrecognized Fintek device: %04x\n", 773 (unsigned int)devid); 774 err = -ENODEV; 775 goto exit; 776 } 777 778 pr_info("Found %s watchdog chip, revision %d\n", 779 f71808e_names[watchdog.type], 780 (int)superio_inb(sioaddr, SIO_REG_DEVREV)); 781exit: 782 superio_exit(sioaddr); 783 return err; 784} 785 786static int __init f71808e_init(void) 787{ 788 static const unsigned short addrs[] = { 0x2e, 0x4e }; 789 int err = -ENODEV; 790 int i; 791 792 for (i = 0; i < ARRAY_SIZE(addrs); i++) { 793 err = f71808e_find(addrs[i]); 794 if (err == 0) 795 break; 796 } 797 if (i == ARRAY_SIZE(addrs)) 798 return err; 799 800 return watchdog_init(addrs[i]); 801} 802 803static void __exit f71808e_exit(void) 804{ 805 if (watchdog_is_running()) { 806 pr_warn("Watchdog timer still running, stopping it\n"); 807 watchdog_stop(); 808 } 809 misc_deregister(&watchdog_miscdev); 810 unregister_reboot_notifier(&watchdog_notifier); 811} 812 813MODULE_DESCRIPTION("F71808E Watchdog Driver"); 814MODULE_AUTHOR("Giel van Schijndel <me@mortis.eu>"); 815MODULE_LICENSE("GPL"); 816 817module_init(f71808e_init); 818module_exit(f71808e_exit);