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