linux/drivers/watchdog/wdt_pci.c
<<
>>
Prefs
   1/*
   2 *      Industrial Computer Source PCI-WDT500/501 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 cleanup
  28 *                                      Parameterized timeout
  29 *              JP Nollmann     :       Added support for PCI wdt501p
  30 *              Alan Cox        :       Split ISA and PCI cards into two drivers
  31 *              Jeff Garzik     :       PCI cleanups
  32 *              Tigran Aivazian :       Restructured wdtpci_init_one() to handle
  33 *                                      failures
  34 *              Joel Becker     :       Added WDIOC_GET/SETTIMEOUT
  35 *              Zwane Mwaikambo :       Magic char closing, locking changes,
  36 *                                      cleanups
  37 *              Matt Domsch     :       nowayout module option
  38 */
  39
  40#include <linux/interrupt.h>
  41#include <linux/module.h>
  42#include <linux/moduleparam.h>
  43#include <linux/types.h>
  44#include <linux/miscdevice.h>
  45#include <linux/watchdog.h>
  46#include <linux/ioport.h>
  47#include <linux/delay.h>
  48#include <linux/notifier.h>
  49#include <linux/reboot.h>
  50#include <linux/init.h>
  51#include <linux/fs.h>
  52#include <linux/pci.h>
  53#include <linux/io.h>
  54#include <linux/uaccess.h>
  55
  56#include <asm/system.h>
  57
  58#define WDT_IS_PCI
  59#include "wd501p.h"
  60
  61#define PFX "wdt_pci: "
  62
  63/*
  64 * Until Access I/O gets their application for a PCI vendor ID approved,
  65 * I don't think that it's appropriate to move these constants into the
  66 * regular pci_ids.h file. -- JPN 2000/01/18
  67 */
  68
  69#ifndef PCI_VENDOR_ID_ACCESSIO
  70#define PCI_VENDOR_ID_ACCESSIO 0x494f
  71#endif
  72#ifndef PCI_DEVICE_ID_WDG_CSM
  73#define PCI_DEVICE_ID_WDG_CSM 0x22c0
  74#endif
  75
  76/* We can only use 1 card due to the /dev/watchdog restriction */
  77static int dev_count;
  78
  79static unsigned long open_lock;
  80static DEFINE_SPINLOCK(wdtpci_lock);
  81static char expect_close;
  82
  83static int io;
  84static int irq;
  85
  86/* Default timeout */
  87#define WD_TIMO 60                      /* Default heartbeat = 60 seconds */
  88
  89static int heartbeat = WD_TIMO;
  90static int wd_heartbeat;
  91module_param(heartbeat, int, 0);
  92MODULE_PARM_DESC(heartbeat,
  93                "Watchdog heartbeat in seconds. (0<heartbeat<65536, default="
  94                                __MODULE_STRING(WD_TIMO) ")");
  95
  96static int nowayout = WATCHDOG_NOWAYOUT;
  97module_param(nowayout, int, 0);
  98MODULE_PARM_DESC(nowayout,
  99                "Watchdog cannot be stopped once started (default="
 100                                __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 101
 102#ifdef CONFIG_WDT_501_PCI
 103/* Support for the Fan Tachometer on the PCI-WDT501 */
 104static int tachometer;
 105
 106module_param(tachometer, int, 0);
 107MODULE_PARM_DESC(tachometer,
 108        "PCI-WDT501 Fan Tachometer support (0=disable, default=0)");
 109#endif /* CONFIG_WDT_501_PCI */
 110
 111/*
 112 *      Programming support
 113 */
 114
 115static void wdtpci_ctr_mode(int ctr, int mode)
 116{
 117        ctr <<= 6;
 118        ctr |= 0x30;
 119        ctr |= (mode << 1);
 120        outb(ctr, WDT_CR);
 121        udelay(8);
 122}
 123
 124static void wdtpci_ctr_load(int ctr, int val)
 125{
 126        outb(val & 0xFF, WDT_COUNT0 + ctr);
 127        udelay(8);
 128        outb(val >> 8, WDT_COUNT0 + ctr);
 129        udelay(8);
 130}
 131
 132/**
 133 *      wdtpci_start:
 134 *
 135 *      Start the watchdog driver.
 136 */
 137
 138static int wdtpci_start(void)
 139{
 140        unsigned long flags;
 141
 142        spin_lock_irqsave(&wdtpci_lock, flags);
 143
 144        /*
 145         * "pet" the watchdog, as Access says.
 146         * This resets the clock outputs.
 147         */
 148        inb(WDT_DC);                    /* Disable watchdog */
 149        udelay(8);
 150        wdtpci_ctr_mode(2, 0);          /* Program CTR2 for Mode 0:
 151                                                Pulse on Terminal Count */
 152        outb(0, WDT_DC);                /* Enable watchdog */
 153        udelay(8);
 154        inb(WDT_DC);                    /* Disable watchdog */
 155        udelay(8);
 156        outb(0, WDT_CLOCK);             /* 2.0833MHz clock */
 157        udelay(8);
 158        inb(WDT_BUZZER);                /* disable */
 159        udelay(8);
 160        inb(WDT_OPTONOTRST);            /* disable */
 161        udelay(8);
 162        inb(WDT_OPTORST);               /* disable */
 163        udelay(8);
 164        inb(WDT_PROGOUT);               /* disable */
 165        udelay(8);
 166        wdtpci_ctr_mode(0, 3);          /* Program CTR0 for Mode 3:
 167                                                Square Wave Generator */
 168        wdtpci_ctr_mode(1, 2);          /* Program CTR1 for Mode 2:
 169                                                Rate Generator */
 170        wdtpci_ctr_mode(2, 1);          /* Program CTR2 for Mode 1:
 171                                                Retriggerable One-Shot */
 172        wdtpci_ctr_load(0, 20833);      /* count at 100Hz */
 173        wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */
 174        /* DO NOT LOAD CTR2 on PCI card! -- JPN */
 175        outb(0, WDT_DC);                /* Enable watchdog */
 176        udelay(8);
 177
 178        spin_unlock_irqrestore(&wdtpci_lock, flags);
 179        return 0;
 180}
 181
 182/**
 183 *      wdtpci_stop:
 184 *
 185 *      Stop the watchdog driver.
 186 */
 187
 188static int wdtpci_stop(void)
 189{
 190        unsigned long flags;
 191
 192        /* Turn the card off */
 193        spin_lock_irqsave(&wdtpci_lock, flags);
 194        inb(WDT_DC);                    /* Disable watchdog */
 195        udelay(8);
 196        wdtpci_ctr_load(2, 0);          /* 0 length reset pulses now */
 197        spin_unlock_irqrestore(&wdtpci_lock, flags);
 198        return 0;
 199}
 200
 201/**
 202 *      wdtpci_ping:
 203 *
 204 *      Reload counter one with the watchdog heartbeat. We don't bother
 205 *      reloading the cascade counter.
 206 */
 207
 208static int wdtpci_ping(void)
 209{
 210        unsigned long flags;
 211
 212        spin_lock_irqsave(&wdtpci_lock, flags);
 213        /* Write a watchdog value */
 214        inb(WDT_DC);                    /* Disable watchdog */
 215        udelay(8);
 216        wdtpci_ctr_mode(1, 2);          /* Re-Program CTR1 for Mode 2:
 217                                                        Rate Generator */
 218        wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */
 219        outb(0, WDT_DC);                /* Enable watchdog */
 220        udelay(8);
 221        spin_unlock_irqrestore(&wdtpci_lock, flags);
 222        return 0;
 223}
 224
 225/**
 226 *      wdtpci_set_heartbeat:
 227 *      @t:             the new heartbeat value that needs to be set.
 228 *
 229 *      Set a new heartbeat value for the watchdog device. If the heartbeat
 230 *      value is incorrect we keep the old value and return -EINVAL.
 231 *      If successful we return 0.
 232 */
 233static int wdtpci_set_heartbeat(int t)
 234{
 235        /* Arbitrary, can't find the card's limits */
 236        if (t < 1 || t > 65535)
 237                return -EINVAL;
 238
 239        heartbeat = t;
 240        wd_heartbeat = t * 100;
 241        return 0;
 242}
 243
 244/**
 245 *      wdtpci_get_status:
 246 *      @status:                the new status.
 247 *
 248 *      Extract the status information from a WDT watchdog device. There are
 249 *      several board variants so we have to know which bits are valid. Some
 250 *      bits default to one and some to zero in order to be maximally painful.
 251 *
 252 *      we then map the bits onto the status ioctl flags.
 253 */
 254
 255static int wdtpci_get_status(int *status)
 256{
 257        unsigned char new_status;
 258        unsigned long flags;
 259
 260        spin_lock_irqsave(&wdtpci_lock, flags);
 261        new_status = inb(WDT_SR);
 262        spin_unlock_irqrestore(&wdtpci_lock, flags);
 263
 264        *status = 0;
 265        if (new_status & WDC_SR_ISOI0)
 266                *status |= WDIOF_EXTERN1;
 267        if (new_status & WDC_SR_ISII1)
 268                *status |= WDIOF_EXTERN2;
 269#ifdef CONFIG_WDT_501_PCI
 270        if (!(new_status & WDC_SR_TGOOD))
 271                *status |= WDIOF_OVERHEAT;
 272        if (!(new_status & WDC_SR_PSUOVER))
 273                *status |= WDIOF_POWEROVER;
 274        if (!(new_status & WDC_SR_PSUUNDR))
 275                *status |= WDIOF_POWERUNDER;
 276        if (tachometer) {
 277                if (!(new_status & WDC_SR_FANGOOD))
 278                        *status |= WDIOF_FANFAULT;
 279        }
 280#endif /* CONFIG_WDT_501_PCI */
 281        return 0;
 282}
 283
 284#ifdef CONFIG_WDT_501_PCI
 285/**
 286 *      wdtpci_get_temperature:
 287 *
 288 *      Reports the temperature in degrees Fahrenheit. The API is in
 289 *      farenheit. It was designed by an imperial measurement luddite.
 290 */
 291
 292static int wdtpci_get_temperature(int *temperature)
 293{
 294        unsigned short c;
 295        unsigned long flags;
 296        spin_lock_irqsave(&wdtpci_lock, flags);
 297        c = inb(WDT_RT);
 298        udelay(8);
 299        spin_unlock_irqrestore(&wdtpci_lock, flags);
 300        *temperature = (c * 11 / 15) + 7;
 301        return 0;
 302}
 303#endif /* CONFIG_WDT_501_PCI */
 304
 305/**
 306 *      wdtpci_interrupt:
 307 *      @irq:           Interrupt number
 308 *      @dev_id:        Unused as we don't allow multiple devices.
 309 *
 310 *      Handle an interrupt from the board. These are raised when the status
 311 *      map changes in what the board considers an interesting way. That means
 312 *      a failure condition occurring.
 313 */
 314
 315static irqreturn_t wdtpci_interrupt(int irq, void *dev_id)
 316{
 317        /*
 318         *      Read the status register see what is up and
 319         *      then printk it.
 320         */
 321        unsigned char status;
 322
 323        spin_lock(&wdtpci_lock);
 324
 325        status = inb(WDT_SR);
 326        udelay(8);
 327
 328        printk(KERN_CRIT PFX "status %d\n", status);
 329
 330#ifdef CONFIG_WDT_501_PCI
 331        if (!(status & WDC_SR_TGOOD)) {
 332                u8 alarm = inb(WDT_RT);
 333                printk(KERN_CRIT PFX "Overheat alarm.(%d)\n", alarm);
 334                udelay(8);
 335        }
 336        if (!(status & WDC_SR_PSUOVER))
 337                printk(KERN_CRIT PFX "PSU over voltage.\n");
 338        if (!(status & WDC_SR_PSUUNDR))
 339                printk(KERN_CRIT PFX "PSU under voltage.\n");
 340        if (tachometer) {
 341                if (!(status & WDC_SR_FANGOOD))
 342                        printk(KERN_CRIT PFX "Possible fan fault.\n");
 343        }
 344#endif /* CONFIG_WDT_501_PCI */
 345        if (!(status&WDC_SR_WCCR)) {
 346#ifdef SOFTWARE_REBOOT
 347#ifdef ONLY_TESTING
 348                printk(KERN_CRIT PFX "Would Reboot.\n");
 349#else
 350                printk(KERN_CRIT PFX "Initiating system reboot.\n");
 351                emergency_restart(NULL);
 352#endif
 353#else
 354                printk(KERN_CRIT PFX "Reset in 5ms.\n");
 355#endif
 356        }
 357        spin_unlock(&wdtpci_lock);
 358        return IRQ_HANDLED;
 359}
 360
 361
 362/**
 363 *      wdtpci_write:
 364 *      @file: file handle to the watchdog
 365 *      @buf: buffer to write (unused as data does not matter here
 366 *      @count: count of bytes
 367 *      @ppos: pointer to the position to write. No seeks allowed
 368 *
 369 *      A write to a watchdog device is defined as a keepalive signal. Any
 370 *      write of data will do, as we we don't define content meaning.
 371 */
 372
 373static ssize_t wdtpci_write(struct file *file, const char __user *buf,
 374                                        size_t count, loff_t *ppos)
 375{
 376        if (count) {
 377                if (!nowayout) {
 378                        size_t i;
 379
 380                        expect_close = 0;
 381
 382                        for (i = 0; i != count; i++) {
 383                                char c;
 384                                if (get_user(c, buf + i))
 385                                        return -EFAULT;
 386                                if (c == 'V')
 387                                        expect_close = 42;
 388                        }
 389                }
 390                wdtpci_ping();
 391        }
 392        return count;
 393}
 394
 395/**
 396 *      wdtpci_ioctl:
 397 *      @file: file handle to the device
 398 *      @cmd: watchdog command
 399 *      @arg: argument pointer
 400 *
 401 *      The watchdog API defines a common set of functions for all watchdogs
 402 *      according to their available features. We only actually usefully support
 403 *      querying capabilities and current status.
 404 */
 405
 406static long wdtpci_ioctl(struct file *file, unsigned int cmd,
 407                                                        unsigned long arg)
 408{
 409        int new_heartbeat;
 410        int status;
 411        void __user *argp = (void __user *)arg;
 412        int __user *p = argp;
 413
 414        static struct watchdog_info ident = {
 415                .options =              WDIOF_SETTIMEOUT|
 416                                        WDIOF_MAGICCLOSE|
 417                                        WDIOF_KEEPALIVEPING,
 418                .firmware_version =     1,
 419                .identity =             "PCI-WDT500/501",
 420        };
 421
 422        /* Add options according to the card we have */
 423        ident.options |= (WDIOF_EXTERN1|WDIOF_EXTERN2);
 424#ifdef CONFIG_WDT_501_PCI
 425        ident.options |= (WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER);
 426        if (tachometer)
 427                ident.options |= WDIOF_FANFAULT;
 428#endif /* CONFIG_WDT_501_PCI */
 429
 430        switch (cmd) {
 431        case WDIOC_GETSUPPORT:
 432                return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
 433        case WDIOC_GETSTATUS:
 434                wdtpci_get_status(&status);
 435                return put_user(status, p);
 436        case WDIOC_GETBOOTSTATUS:
 437                return put_user(0, p);
 438        case WDIOC_KEEPALIVE:
 439                wdtpci_ping();
 440                return 0;
 441        case WDIOC_SETTIMEOUT:
 442                if (get_user(new_heartbeat, p))
 443                        return -EFAULT;
 444                if (wdtpci_set_heartbeat(new_heartbeat))
 445                        return -EINVAL;
 446                wdtpci_ping();
 447                /* Fall */
 448        case WDIOC_GETTIMEOUT:
 449                return put_user(heartbeat, p);
 450        default:
 451                return -ENOTTY;
 452        }
 453}
 454
 455/**
 456 *      wdtpci_open:
 457 *      @inode: inode of device
 458 *      @file: file handle to device
 459 *
 460 *      The watchdog device has been opened. The watchdog device is single
 461 *      open and on opening we load the counters. Counter zero is a 100Hz
 462 *      cascade, into counter 1 which downcounts to reboot. When the counter
 463 *      triggers counter 2 downcounts the length of the reset pulse which
 464 *      set set to be as long as possible.
 465 */
 466
 467static int wdtpci_open(struct inode *inode, struct file *file)
 468{
 469        if (test_and_set_bit(0, &open_lock))
 470                return -EBUSY;
 471
 472        if (nowayout)
 473                __module_get(THIS_MODULE);
 474        /*
 475         *      Activate
 476         */
 477        wdtpci_start();
 478        return nonseekable_open(inode, file);
 479}
 480
 481/**
 482 *      wdtpci_release:
 483 *      @inode: inode to board
 484 *      @file: file handle to board
 485 *
 486 *      The watchdog has a configurable API. There is a religious dispute
 487 *      between people who want their watchdog to be able to shut down and
 488 *      those who want to be sure if the watchdog manager dies the machine
 489 *      reboots. In the former case we disable the counters, in the latter
 490 *      case you have to open it again very soon.
 491 */
 492
 493static int wdtpci_release(struct inode *inode, struct file *file)
 494{
 495        if (expect_close == 42) {
 496                wdtpci_stop();
 497        } else {
 498                printk(KERN_CRIT PFX "Unexpected close, not stopping timer!");
 499                wdtpci_ping();
 500        }
 501        expect_close = 0;
 502        clear_bit(0, &open_lock);
 503        return 0;
 504}
 505
 506#ifdef CONFIG_WDT_501_PCI
 507/**
 508 *      wdtpci_temp_read:
 509 *      @file: file handle to the watchdog board
 510 *      @buf: buffer to write 1 byte into
 511 *      @count: length of buffer
 512 *      @ptr: offset (no seek allowed)
 513 *
 514 *      Read reports the temperature in degrees Fahrenheit. The API is in
 515 *      fahrenheit. It was designed by an imperial measurement luddite.
 516 */
 517
 518static ssize_t wdtpci_temp_read(struct file *file, char __user *buf,
 519                                                size_t count, loff_t *ptr)
 520{
 521        int temperature;
 522
 523        if (wdtpci_get_temperature(&temperature))
 524                return -EFAULT;
 525
 526        if (copy_to_user(buf, &temperature, 1))
 527                return -EFAULT;
 528
 529        return 1;
 530}
 531
 532/**
 533 *      wdtpci_temp_open:
 534 *      @inode: inode of device
 535 *      @file: file handle to device
 536 *
 537 *      The temperature device has been opened.
 538 */
 539
 540static int wdtpci_temp_open(struct inode *inode, struct file *file)
 541{
 542        return nonseekable_open(inode, file);
 543}
 544
 545/**
 546 *      wdtpci_temp_release:
 547 *      @inode: inode to board
 548 *      @file: file handle to board
 549 *
 550 *      The temperature device has been closed.
 551 */
 552
 553static int wdtpci_temp_release(struct inode *inode, struct file *file)
 554{
 555        return 0;
 556}
 557#endif /* CONFIG_WDT_501_PCI */
 558
 559/**
 560 *      notify_sys:
 561 *      @this: our notifier block
 562 *      @code: the event being reported
 563 *      @unused: unused
 564 *
 565 *      Our notifier is called on system shutdowns. We want to turn the card
 566 *      off at reboot otherwise the machine will reboot again during memory
 567 *      test or worse yet during the following fsck. This would suck, in fact
 568 *      trust me - if it happens it does suck.
 569 */
 570
 571static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
 572                                                        void *unused)
 573{
 574        if (code == SYS_DOWN || code == SYS_HALT)
 575                wdtpci_stop();
 576        return NOTIFY_DONE;
 577}
 578
 579/*
 580 *      Kernel Interfaces
 581 */
 582
 583
 584static const struct file_operations wdtpci_fops = {
 585        .owner          = THIS_MODULE,
 586        .llseek         = no_llseek,
 587        .write          = wdtpci_write,
 588        .unlocked_ioctl = wdtpci_ioctl,
 589        .open           = wdtpci_open,
 590        .release        = wdtpci_release,
 591};
 592
 593static struct miscdevice wdtpci_miscdev = {
 594        .minor  = WATCHDOG_MINOR,
 595        .name   = "watchdog",
 596        .fops   = &wdtpci_fops,
 597};
 598
 599#ifdef CONFIG_WDT_501_PCI
 600static const struct file_operations wdtpci_temp_fops = {
 601        .owner          = THIS_MODULE,
 602        .llseek         = no_llseek,
 603        .read           = wdtpci_temp_read,
 604        .open           = wdtpci_temp_open,
 605        .release        = wdtpci_temp_release,
 606};
 607
 608static struct miscdevice temp_miscdev = {
 609        .minor  = TEMP_MINOR,
 610        .name   = "temperature",
 611        .fops   = &wdtpci_temp_fops,
 612};
 613#endif /* CONFIG_WDT_501_PCI */
 614
 615/*
 616 *      The WDT card needs to learn about soft shutdowns in order to
 617 *      turn the timebomb registers off.
 618 */
 619
 620static struct notifier_block wdtpci_notifier = {
 621        .notifier_call = wdtpci_notify_sys,
 622};
 623
 624
 625static int __devinit wdtpci_init_one(struct pci_dev *dev,
 626                                        const struct pci_device_id *ent)
 627{
 628        int ret = -EIO;
 629
 630        dev_count++;
 631        if (dev_count > 1) {
 632                printk(KERN_ERR PFX "This driver only supports one device\n");
 633                return -ENODEV;
 634        }
 635
 636        if (pci_enable_device(dev)) {
 637                printk(KERN_ERR PFX "Not possible to enable PCI Device\n");
 638                return -ENODEV;
 639        }
 640
 641        if (pci_resource_start(dev, 2) == 0x0000) {
 642                printk(KERN_ERR PFX "No I/O-Address for card detected\n");
 643                ret = -ENODEV;
 644                goto out_pci;
 645        }
 646
 647        irq = dev->irq;
 648        io = pci_resource_start(dev, 2);
 649
 650        if (request_region(io, 16, "wdt_pci") == NULL) {
 651                printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", io);
 652                goto out_pci;
 653        }
 654
 655        if (request_irq(irq, wdtpci_interrupt, IRQF_DISABLED | IRQF_SHARED,
 656                         "wdt_pci", &wdtpci_miscdev)) {
 657                printk(KERN_ERR PFX "IRQ %d is not free\n", irq);
 658                goto out_reg;
 659        }
 660
 661        printk(KERN_INFO
 662         "PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%04x (Interrupt %d)\n",
 663                                                                io, irq);
 664
 665        /* Check that the heartbeat value is within its range;
 666           if not reset to the default */
 667        if (wdtpci_set_heartbeat(heartbeat)) {
 668                wdtpci_set_heartbeat(WD_TIMO);
 669                printk(KERN_INFO PFX
 670                  "heartbeat value must be 0 < heartbeat < 65536, using %d\n",
 671                                                                WD_TIMO);
 672        }
 673
 674        ret = register_reboot_notifier(&wdtpci_notifier);
 675        if (ret) {
 676                printk(KERN_ERR PFX
 677                        "cannot register reboot notifier (err=%d)\n", ret);
 678                goto out_irq;
 679        }
 680
 681#ifdef CONFIG_WDT_501_PCI
 682        ret = misc_register(&temp_miscdev);
 683        if (ret) {
 684                printk(KERN_ERR PFX
 685                        "cannot register miscdev on minor=%d (err=%d)\n",
 686                                        TEMP_MINOR, ret);
 687                goto out_rbt;
 688        }
 689#endif /* CONFIG_WDT_501_PCI */
 690
 691        ret = misc_register(&wdtpci_miscdev);
 692        if (ret) {
 693                printk(KERN_ERR PFX
 694                        "cannot register miscdev on minor=%d (err=%d)\n",
 695                                                WATCHDOG_MINOR, ret);
 696                goto out_misc;
 697        }
 698
 699        printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
 700                heartbeat, nowayout);
 701#ifdef CONFIG_WDT_501_PCI
 702        printk(KERN_INFO "wdt: Fan Tachometer is %s\n",
 703                                (tachometer ? "Enabled" : "Disabled"));
 704#endif /* CONFIG_WDT_501_PCI */
 705
 706        ret = 0;
 707out:
 708        return ret;
 709
 710out_misc:
 711#ifdef CONFIG_WDT_501_PCI
 712        misc_deregister(&temp_miscdev);
 713out_rbt:
 714#endif /* CONFIG_WDT_501_PCI */
 715        unregister_reboot_notifier(&wdtpci_notifier);
 716out_irq:
 717        free_irq(irq, &wdtpci_miscdev);
 718out_reg:
 719        release_region(io, 16);
 720out_pci:
 721        pci_disable_device(dev);
 722        goto out;
 723}
 724
 725
 726static void __devexit wdtpci_remove_one(struct pci_dev *pdev)
 727{
 728        /* here we assume only one device will ever have
 729         * been picked up and registered by probe function */
 730        misc_deregister(&wdtpci_miscdev);
 731#ifdef CONFIG_WDT_501_PCI
 732        misc_deregister(&temp_miscdev);
 733#endif /* CONFIG_WDT_501_PCI */
 734        unregister_reboot_notifier(&wdtpci_notifier);
 735        free_irq(irq, &wdtpci_miscdev);
 736        release_region(io, 16);
 737        pci_disable_device(pdev);
 738        dev_count--;
 739}
 740
 741
 742static struct pci_device_id wdtpci_pci_tbl[] = {
 743        {
 744                .vendor    = PCI_VENDOR_ID_ACCESSIO,
 745                .device    = PCI_DEVICE_ID_WDG_CSM,
 746                .subvendor = PCI_ANY_ID,
 747                .subdevice = PCI_ANY_ID,
 748        },
 749        { 0, }, /* terminate list */
 750};
 751MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl);
 752
 753
 754static struct pci_driver wdtpci_driver = {
 755        .name           = "wdt_pci",
 756        .id_table       = wdtpci_pci_tbl,
 757        .probe          = wdtpci_init_one,
 758        .remove         = __devexit_p(wdtpci_remove_one),
 759};
 760
 761
 762/**
 763 *      wdtpci_cleanup:
 764 *
 765 *      Unload the watchdog. You cannot do this with any file handles open.
 766 *      If your watchdog is set to continue ticking on close and you unload
 767 *      it, well it keeps ticking. We won't get the interrupt but the board
 768 *      will not touch PC memory so all is fine. You just have to load a new
 769 *      module in xx seconds or reboot.
 770 */
 771
 772static void __exit wdtpci_cleanup(void)
 773{
 774        pci_unregister_driver(&wdtpci_driver);
 775}
 776
 777
 778/**
 779 *      wdtpci_init:
 780 *
 781 *      Set up the WDT watchdog board. All we have to do is grab the
 782 *      resources we require and bitch if anyone beat us to them.
 783 *      The open() function will actually kick the board off.
 784 */
 785
 786static int __init wdtpci_init(void)
 787{
 788        return pci_register_driver(&wdtpci_driver);
 789}
 790
 791
 792module_init(wdtpci_init);
 793module_exit(wdtpci_cleanup);
 794
 795MODULE_AUTHOR("JP Nollmann, Alan Cox");
 796MODULE_DESCRIPTION("Driver for the ICS PCI-WDT500/501 watchdog cards");
 797MODULE_LICENSE("GPL");
 798MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
 799MODULE_ALIAS_MISCDEV(TEMP_MINOR);
 800