linux/drivers/watchdog/hpwdt.c
<<
>>
Prefs
   1/*
   2 *      HP WatchDog Driver
   3 *      based on
   4 *
   5 *      SoftDog 0.05:   A Software Watchdog Device
   6 *
   7 *      (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
   8 *      Thomas Mingarelli <thomas.mingarelli@hp.com>
   9 *
  10 *      This program is free software; you can redistribute it and/or
  11 *      modify it under the terms of the GNU General Public License
  12 *      version 2 as published by the Free Software Foundation
  13 *
  14 */
  15
  16#include <linux/device.h>
  17#include <linux/fs.h>
  18#include <linux/init.h>
  19#include <linux/interrupt.h>
  20#include <linux/io.h>
  21#include <linux/irq.h>
  22#include <linux/nmi.h>
  23#include <linux/kernel.h>
  24#include <linux/miscdevice.h>
  25#include <linux/mm.h>
  26#include <linux/module.h>
  27#include <linux/kdebug.h>
  28#include <linux/moduleparam.h>
  29#include <linux/notifier.h>
  30#include <linux/pci.h>
  31#include <linux/pci_ids.h>
  32#include <linux/reboot.h>
  33#include <linux/sched.h>
  34#include <linux/timer.h>
  35#include <linux/types.h>
  36#include <linux/uaccess.h>
  37#include <linux/watchdog.h>
  38#include <linux/dmi.h>
  39#include <linux/efi.h>
  40#include <linux/string.h>
  41#include <linux/bootmem.h>
  42#include <linux/slab.h>
  43#include <asm/desc.h>
  44#include <asm/cacheflush.h>
  45
  46#define PCI_BIOS32_SD_VALUE             0x5F32335F      /* "_32_" */
  47#define CRU_BIOS_SIGNATURE_VALUE        0x55524324
  48#define PCI_BIOS32_PARAGRAPH_LEN        16
  49#define PCI_ROM_BASE1                   0x000F0000
  50#define ROM_SIZE                        0x10000
  51#define HPWDT_VERSION                   "1.1.1"
  52
  53struct bios32_service_dir {
  54        u32 signature;
  55        u32 entry_point;
  56        u8 revision;
  57        u8 length;
  58        u8 checksum;
  59        u8 reserved[5];
  60};
  61
  62/* type 212 */
  63struct smbios_cru64_info {
  64        u8 type;
  65        u8 byte_length;
  66        u16 handle;
  67        u32 signature;
  68        u64 physical_address;
  69        u32 double_length;
  70        u32 double_offset;
  71};
  72#define SMBIOS_CRU64_INFORMATION        212
  73
  74struct cmn_registers {
  75        union {
  76                struct {
  77                        u8 ral;
  78                        u8 rah;
  79                        u16 rea2;
  80                };
  81                u32 reax;
  82        } u1;
  83        union {
  84                struct {
  85                        u8 rbl;
  86                        u8 rbh;
  87                        u8 reb2l;
  88                        u8 reb2h;
  89                };
  90                u32 rebx;
  91        } u2;
  92        union {
  93                struct {
  94                        u8 rcl;
  95                        u8 rch;
  96                        u16 rec2;
  97                };
  98                u32 recx;
  99        } u3;
 100        union {
 101                struct {
 102                        u8 rdl;
 103                        u8 rdh;
 104                        u16 red2;
 105                };
 106                u32 redx;
 107        } u4;
 108
 109        u32 resi;
 110        u32 redi;
 111        u16 rds;
 112        u16 res;
 113        u32 reflags;
 114}  __attribute__((packed));
 115
 116#define DEFAULT_MARGIN  30
 117static unsigned int soft_margin = DEFAULT_MARGIN;       /* in seconds */
 118static unsigned int reload;                     /* the computed soft_margin */
 119static int nowayout = WATCHDOG_NOWAYOUT;
 120static char expect_release;
 121static unsigned long hpwdt_is_open;
 122static unsigned int allow_kdump;
 123static unsigned int hpwdt_nmi_sourcing;
 124static unsigned int priority;           /* hpwdt at end of die_notify list */
 125
 126static void __iomem *pci_mem_addr;              /* the PCI-memory address */
 127static unsigned long __iomem *hpwdt_timer_reg;
 128static unsigned long __iomem *hpwdt_timer_con;
 129
 130static DEFINE_SPINLOCK(rom_lock);
 131
 132static void *cru_rom_addr;
 133
 134static struct cmn_registers cmn_regs;
 135
 136static struct pci_device_id hpwdt_devices[] = {
 137        { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB203) },
 138        { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3306) },
 139        {0},                    /* terminate list */
 140};
 141MODULE_DEVICE_TABLE(pci, hpwdt_devices);
 142
 143extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
 144                                                unsigned long *pRomEntry);
 145
 146#ifndef CONFIG_X86_64
 147/* --32 Bit Bios------------------------------------------------------------ */
 148
 149#define HPWDT_ARCH      32
 150
 151asm(".text                          \n\t"
 152    ".align 4                       \n"
 153    "asminline_call:                \n\t"
 154    "pushl       %ebp               \n\t"
 155    "movl        %esp, %ebp         \n\t"
 156    "pusha                          \n\t"
 157    "pushf                          \n\t"
 158    "push        %es                \n\t"
 159    "push        %ds                \n\t"
 160    "pop         %es                \n\t"
 161    "movl        8(%ebp),%eax       \n\t"
 162    "movl        4(%eax),%ebx       \n\t"
 163    "movl        8(%eax),%ecx       \n\t"
 164    "movl        12(%eax),%edx      \n\t"
 165    "movl        16(%eax),%esi      \n\t"
 166    "movl        20(%eax),%edi      \n\t"
 167    "movl        (%eax),%eax        \n\t"
 168    "push        %cs                \n\t"
 169    "call        *12(%ebp)          \n\t"
 170    "pushf                          \n\t"
 171    "pushl       %eax               \n\t"
 172    "movl        8(%ebp),%eax       \n\t"
 173    "movl        %ebx,4(%eax)       \n\t"
 174    "movl        %ecx,8(%eax)       \n\t"
 175    "movl        %edx,12(%eax)      \n\t"
 176    "movl        %esi,16(%eax)      \n\t"
 177    "movl        %edi,20(%eax)      \n\t"
 178    "movw        %ds,24(%eax)       \n\t"
 179    "movw        %es,26(%eax)       \n\t"
 180    "popl        %ebx               \n\t"
 181    "movl        %ebx,(%eax)        \n\t"
 182    "popl        %ebx               \n\t"
 183    "movl        %ebx,28(%eax)      \n\t"
 184    "pop         %es                \n\t"
 185    "popf                           \n\t"
 186    "popa                           \n\t"
 187    "leave                          \n\t"
 188    "ret                            \n\t"
 189    ".previous");
 190
 191
 192/*
 193 *      cru_detect
 194 *
 195 *      Routine Description:
 196 *      This function uses the 32-bit BIOS Service Directory record to
 197 *      search for a $CRU record.
 198 *
 199 *      Return Value:
 200 *      0        :  SUCCESS
 201 *      <0       :  FAILURE
 202 */
 203static int __devinit cru_detect(unsigned long map_entry,
 204        unsigned long map_offset)
 205{
 206        void *bios32_map;
 207        unsigned long *bios32_entrypoint;
 208        unsigned long cru_physical_address;
 209        unsigned long cru_length;
 210        unsigned long physical_bios_base = 0;
 211        unsigned long physical_bios_offset = 0;
 212        int retval = -ENODEV;
 213
 214        bios32_map = ioremap(map_entry, (2 * PAGE_SIZE));
 215
 216        if (bios32_map == NULL)
 217                return -ENODEV;
 218
 219        bios32_entrypoint = bios32_map + map_offset;
 220
 221        cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;
 222
 223        asminline_call(&cmn_regs, bios32_entrypoint);
 224
 225        if (cmn_regs.u1.ral != 0) {
 226                printk(KERN_WARNING
 227                        "hpwdt: Call succeeded but with an error: 0x%x\n",
 228                        cmn_regs.u1.ral);
 229        } else {
 230                physical_bios_base = cmn_regs.u2.rebx;
 231                physical_bios_offset = cmn_regs.u4.redx;
 232                cru_length = cmn_regs.u3.recx;
 233                cru_physical_address =
 234                        physical_bios_base + physical_bios_offset;
 235
 236                /* If the values look OK, then map it in. */
 237                if ((physical_bios_base + physical_bios_offset)) {
 238                        cru_rom_addr =
 239                                ioremap(cru_physical_address, cru_length);
 240                        if (cru_rom_addr)
 241                                retval = 0;
 242                }
 243
 244                printk(KERN_DEBUG "hpwdt: CRU Base Address:   0x%lx\n",
 245                        physical_bios_base);
 246                printk(KERN_DEBUG "hpwdt: CRU Offset Address: 0x%lx\n",
 247                        physical_bios_offset);
 248                printk(KERN_DEBUG "hpwdt: CRU Length:         0x%lx\n",
 249                        cru_length);
 250                printk(KERN_DEBUG "hpwdt: CRU Mapped Address: 0x%x\n",
 251                        (unsigned int)&cru_rom_addr);
 252        }
 253        iounmap(bios32_map);
 254        return retval;
 255}
 256
 257/*
 258 *      bios_checksum
 259 */
 260static int __devinit bios_checksum(const char __iomem *ptr, int len)
 261{
 262        char sum = 0;
 263        int i;
 264
 265        /*
 266         * calculate checksum of size bytes. This should add up
 267         * to zero if we have a valid header.
 268         */
 269        for (i = 0; i < len; i++)
 270                sum += ptr[i];
 271
 272        return ((sum == 0) && (len > 0));
 273}
 274
 275/*
 276 *      bios32_present
 277 *
 278 *      Routine Description:
 279 *      This function finds the 32-bit BIOS Service Directory
 280 *
 281 *      Return Value:
 282 *      0        :  SUCCESS
 283 *      <0       :  FAILURE
 284 */
 285static int __devinit bios32_present(const char __iomem *p)
 286{
 287        struct bios32_service_dir *bios_32_ptr;
 288        int length;
 289        unsigned long map_entry, map_offset;
 290
 291        bios_32_ptr = (struct bios32_service_dir *) p;
 292
 293        /*
 294         * Search for signature by checking equal to the swizzled value
 295         * instead of calling another routine to perform a strcmp.
 296         */
 297        if (bios_32_ptr->signature == PCI_BIOS32_SD_VALUE) {
 298                length = bios_32_ptr->length * PCI_BIOS32_PARAGRAPH_LEN;
 299                if (bios_checksum(p, length)) {
 300                        /*
 301                         * According to the spec, we're looking for the
 302                         * first 4KB-aligned address below the entrypoint
 303                         * listed in the header. The Service Directory code
 304                         * is guaranteed to occupy no more than 2 4KB pages.
 305                         */
 306                        map_entry = bios_32_ptr->entry_point & ~(PAGE_SIZE - 1);
 307                        map_offset = bios_32_ptr->entry_point - map_entry;
 308
 309                        return cru_detect(map_entry, map_offset);
 310                }
 311        }
 312        return -ENODEV;
 313}
 314
 315static int __devinit detect_cru_service(void)
 316{
 317        char __iomem *p, *q;
 318        int rc = -1;
 319
 320        /*
 321         * Search from 0x0f0000 through 0x0fffff, inclusive.
 322         */
 323        p = ioremap(PCI_ROM_BASE1, ROM_SIZE);
 324        if (p == NULL)
 325                return -ENOMEM;
 326
 327        for (q = p; q < p + ROM_SIZE; q += 16) {
 328                rc = bios32_present(q);
 329                if (!rc)
 330                        break;
 331        }
 332        iounmap(p);
 333        return rc;
 334}
 335
 336#else
 337/* --64 Bit Bios------------------------------------------------------------ */
 338
 339#define HPWDT_ARCH      64
 340
 341asm(".text                      \n\t"
 342    ".align 4                   \n"
 343    "asminline_call:            \n\t"
 344    "pushq      %rbp            \n\t"
 345    "movq       %rsp, %rbp      \n\t"
 346    "pushq      %rax            \n\t"
 347    "pushq      %rbx            \n\t"
 348    "pushq      %rdx            \n\t"
 349    "pushq      %r12            \n\t"
 350    "pushq      %r9             \n\t"
 351    "movq       %rsi, %r12      \n\t"
 352    "movq       %rdi, %r9       \n\t"
 353    "movl       4(%r9),%ebx     \n\t"
 354    "movl       8(%r9),%ecx     \n\t"
 355    "movl       12(%r9),%edx    \n\t"
 356    "movl       16(%r9),%esi    \n\t"
 357    "movl       20(%r9),%edi    \n\t"
 358    "movl       (%r9),%eax      \n\t"
 359    "call       *%r12           \n\t"
 360    "pushfq                     \n\t"
 361    "popq        %r12           \n\t"
 362    "movl       %eax, (%r9)     \n\t"
 363    "movl       %ebx, 4(%r9)    \n\t"
 364    "movl       %ecx, 8(%r9)    \n\t"
 365    "movl       %edx, 12(%r9)   \n\t"
 366    "movl       %esi, 16(%r9)   \n\t"
 367    "movl       %edi, 20(%r9)   \n\t"
 368    "movq       %r12, %rax      \n\t"
 369    "movl       %eax, 28(%r9)   \n\t"
 370    "popq       %r9             \n\t"
 371    "popq       %r12            \n\t"
 372    "popq       %rdx            \n\t"
 373    "popq       %rbx            \n\t"
 374    "popq       %rax            \n\t"
 375    "leave                      \n\t"
 376    "ret                        \n\t"
 377    ".previous");
 378
 379/*
 380 *      dmi_find_cru
 381 *
 382 *      Routine Description:
 383 *      This function checks whether or not a SMBIOS/DMI record is
 384 *      the 64bit CRU info or not
 385 */
 386static void __devinit dmi_find_cru(const struct dmi_header *dm, void *dummy)
 387{
 388        struct smbios_cru64_info *smbios_cru64_ptr;
 389        unsigned long cru_physical_address;
 390
 391        if (dm->type == SMBIOS_CRU64_INFORMATION) {
 392                smbios_cru64_ptr = (struct smbios_cru64_info *) dm;
 393                if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) {
 394                        cru_physical_address =
 395                                smbios_cru64_ptr->physical_address +
 396                                smbios_cru64_ptr->double_offset;
 397                        cru_rom_addr = ioremap(cru_physical_address,
 398                                smbios_cru64_ptr->double_length);
 399                        set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK,
 400                                smbios_cru64_ptr->double_length >> PAGE_SHIFT);
 401                }
 402        }
 403}
 404
 405static int __devinit detect_cru_service(void)
 406{
 407        cru_rom_addr = NULL;
 408
 409        dmi_walk(dmi_find_cru, NULL);
 410
 411        /* if cru_rom_addr has been set then we found a CRU service */
 412        return ((cru_rom_addr != NULL) ? 0 : -ENODEV);
 413}
 414
 415/* ------------------------------------------------------------------------- */
 416
 417#endif
 418
 419/*
 420 *      Watchdog operations
 421 */
 422static void hpwdt_start(void)
 423{
 424        reload = (soft_margin * 1000) / 128;
 425        iowrite16(reload, hpwdt_timer_reg);
 426        iowrite16(0x85, hpwdt_timer_con);
 427}
 428
 429static void hpwdt_stop(void)
 430{
 431        unsigned long data;
 432
 433        data = ioread16(hpwdt_timer_con);
 434        data &= 0xFE;
 435        iowrite16(data, hpwdt_timer_con);
 436}
 437
 438static void hpwdt_ping(void)
 439{
 440        iowrite16(reload, hpwdt_timer_reg);
 441}
 442
 443static int hpwdt_change_timer(int new_margin)
 444{
 445        /* Arbitrary, can't find the card's limits */
 446        if (new_margin < 30 || new_margin > 600) {
 447                printk(KERN_WARNING
 448                        "hpwdt: New value passed in is invalid: %d seconds.\n",
 449                        new_margin);
 450                return -EINVAL;
 451        }
 452
 453        soft_margin = new_margin;
 454        printk(KERN_DEBUG
 455                "hpwdt: New timer passed in is %d seconds.\n",
 456                new_margin);
 457        reload = (soft_margin * 1000) / 128;
 458
 459        return 0;
 460}
 461
 462/*
 463 *      NMI Handler
 464 */
 465static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
 466                                void *data)
 467{
 468        unsigned long rom_pl;
 469        static int die_nmi_called;
 470
 471        if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI)
 472                return NOTIFY_OK;
 473
 474        if (hpwdt_nmi_sourcing) {
 475                spin_lock_irqsave(&rom_lock, rom_pl);
 476                if (!die_nmi_called)
 477                        asminline_call(&cmn_regs, cru_rom_addr);
 478                die_nmi_called = 1;
 479                spin_unlock_irqrestore(&rom_lock, rom_pl);
 480                if (cmn_regs.u1.ral == 0) {
 481                        printk(KERN_WARNING "hpwdt: An NMI occurred, "
 482                                "but unable to determine source.\n");
 483                } else {
 484                        if (allow_kdump)
 485                                hpwdt_stop();
 486                        panic("An NMI occurred, please see the Integrated "
 487                                "Management Log for details.\n");
 488                }
 489        }
 490        return NOTIFY_OK;
 491}
 492
 493/*
 494 *      /dev/watchdog handling
 495 */
 496static int hpwdt_open(struct inode *inode, struct file *file)
 497{
 498        /* /dev/watchdog can only be opened once */
 499        if (test_and_set_bit(0, &hpwdt_is_open))
 500                return -EBUSY;
 501
 502        /* Start the watchdog */
 503        hpwdt_start();
 504        hpwdt_ping();
 505
 506        return nonseekable_open(inode, file);
 507}
 508
 509static int hpwdt_release(struct inode *inode, struct file *file)
 510{
 511        /* Stop the watchdog */
 512        if (expect_release == 42) {
 513                hpwdt_stop();
 514        } else {
 515                printk(KERN_CRIT
 516                        "hpwdt: Unexpected close, not stopping watchdog!\n");
 517                hpwdt_ping();
 518        }
 519
 520        expect_release = 0;
 521
 522        /* /dev/watchdog is being closed, make sure it can be re-opened */
 523        clear_bit(0, &hpwdt_is_open);
 524
 525        return 0;
 526}
 527
 528static ssize_t hpwdt_write(struct file *file, const char __user *data,
 529        size_t len, loff_t *ppos)
 530{
 531        /* See if we got the magic character 'V' and reload the timer */
 532        if (len) {
 533                if (!nowayout) {
 534                        size_t i;
 535
 536                        /* note: just in case someone wrote the magic character
 537                         * five months ago... */
 538                        expect_release = 0;
 539
 540                        /* scan to see whether or not we got the magic char. */
 541                        for (i = 0; i != len; i++) {
 542                                char c;
 543                                if (get_user(c, data + i))
 544                                        return -EFAULT;
 545                                if (c == 'V')
 546                                        expect_release = 42;
 547                        }
 548                }
 549
 550                /* someone wrote to us, we should reload the timer */
 551                hpwdt_ping();
 552        }
 553
 554        return len;
 555}
 556
 557static struct watchdog_info ident = {
 558        .options = WDIOF_SETTIMEOUT |
 559                   WDIOF_KEEPALIVEPING |
 560                   WDIOF_MAGICCLOSE,
 561        .identity = "HP iLO2 HW Watchdog Timer",
 562};
 563
 564static long hpwdt_ioctl(struct file *file, unsigned int cmd,
 565        unsigned long arg)
 566{
 567        void __user *argp = (void __user *)arg;
 568        int __user *p = argp;
 569        int new_margin;
 570        int ret = -ENOTTY;
 571
 572        switch (cmd) {
 573        case WDIOC_GETSUPPORT:
 574                ret = 0;
 575                if (copy_to_user(argp, &ident, sizeof(ident)))
 576                        ret = -EFAULT;
 577                break;
 578
 579        case WDIOC_GETSTATUS:
 580        case WDIOC_GETBOOTSTATUS:
 581                ret = put_user(0, p);
 582                break;
 583
 584        case WDIOC_KEEPALIVE:
 585                hpwdt_ping();
 586                ret = 0;
 587                break;
 588
 589        case WDIOC_SETTIMEOUT:
 590                ret = get_user(new_margin, p);
 591                if (ret)
 592                        break;
 593
 594                ret = hpwdt_change_timer(new_margin);
 595                if (ret)
 596                        break;
 597
 598                hpwdt_ping();
 599                /* Fall */
 600        case WDIOC_GETTIMEOUT:
 601                ret = put_user(soft_margin, p);
 602                break;
 603        }
 604        return ret;
 605}
 606
 607/*
 608 *      Kernel interfaces
 609 */
 610static const struct file_operations hpwdt_fops = {
 611        .owner = THIS_MODULE,
 612        .llseek = no_llseek,
 613        .write = hpwdt_write,
 614        .unlocked_ioctl = hpwdt_ioctl,
 615        .open = hpwdt_open,
 616        .release = hpwdt_release,
 617};
 618
 619static struct miscdevice hpwdt_miscdev = {
 620        .minor = WATCHDOG_MINOR,
 621        .name = "watchdog",
 622        .fops = &hpwdt_fops,
 623};
 624
 625static struct notifier_block die_notifier = {
 626        .notifier_call = hpwdt_pretimeout,
 627        .priority = 0,
 628};
 629
 630/*
 631 *      Init & Exit
 632 */
 633
 634#ifdef ARCH_HAS_NMI_WATCHDOG
 635static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
 636{
 637        /*
 638         * If nmi_watchdog is turned off then we can turn on
 639         * our nmi sourcing capability.
 640         */
 641        if (!nmi_watchdog_active())
 642                hpwdt_nmi_sourcing = 1;
 643        else
 644                dev_warn(&dev->dev, "NMI sourcing is disabled. To enable this "
 645                        "functionality you must reboot with nmi_watchdog=0 "
 646                        "and load the hpwdt driver with priority=1.\n");
 647}
 648#else
 649static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
 650{
 651        dev_warn(&dev->dev, "NMI sourcing is disabled. "
 652                "Your kernel does not support a NMI Watchdog.\n");
 653}
 654#endif
 655
 656static int __devinit hpwdt_init_one(struct pci_dev *dev,
 657                                        const struct pci_device_id *ent)
 658{
 659        int retval;
 660
 661        /*
 662         * Check if we can do NMI sourcing or not
 663         */
 664        hpwdt_check_nmi_sourcing(dev);
 665
 666        /*
 667         * First let's find out if we are on an iLO2 server. We will
 668         * not run on a legacy ASM box.
 669         * So we only support the G5 ProLiant servers and higher.
 670         */
 671        if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) {
 672                dev_warn(&dev->dev,
 673                        "This server does not have an iLO2 ASIC.\n");
 674                return -ENODEV;
 675        }
 676
 677        if (pci_enable_device(dev)) {
 678                dev_warn(&dev->dev,
 679                        "Not possible to enable PCI Device: 0x%x:0x%x.\n",
 680                        ent->vendor, ent->device);
 681                return -ENODEV;
 682        }
 683
 684        pci_mem_addr = pci_iomap(dev, 1, 0x80);
 685        if (!pci_mem_addr) {
 686                dev_warn(&dev->dev,
 687                        "Unable to detect the iLO2 server memory.\n");
 688                retval = -ENOMEM;
 689                goto error_pci_iomap;
 690        }
 691        hpwdt_timer_reg = pci_mem_addr + 0x70;
 692        hpwdt_timer_con = pci_mem_addr + 0x72;
 693
 694        /* Make sure that we have a valid soft_margin */
 695        if (hpwdt_change_timer(soft_margin))
 696                hpwdt_change_timer(DEFAULT_MARGIN);
 697
 698        /*
 699         * We need to map the ROM to get the CRU service.
 700         * For 32 bit Operating Systems we need to go through the 32 Bit
 701         * BIOS Service Directory
 702         * For 64 bit Operating Systems we get that service through SMBIOS.
 703         */
 704        retval = detect_cru_service();
 705        if (retval < 0) {
 706                dev_warn(&dev->dev,
 707                        "Unable to detect the %d Bit CRU Service.\n",
 708                        HPWDT_ARCH);
 709                goto error_get_cru;
 710        }
 711
 712        /*
 713         * We know this is the only CRU call we need to make so lets keep as
 714         * few instructions as possible once the NMI comes in.
 715         */
 716        cmn_regs.u1.rah = 0x0D;
 717        cmn_regs.u1.ral = 0x02;
 718
 719        /*
 720         * If the priority is set to 1, then we will be put first on the
 721         * die notify list to handle a critical NMI. The default is to
 722         * be last so other users of the NMI signal can function.
 723         */
 724        if (priority)
 725                die_notifier.priority = 0x7FFFFFFF;
 726
 727        retval = register_die_notifier(&die_notifier);
 728        if (retval != 0) {
 729                dev_warn(&dev->dev,
 730                        "Unable to register a die notifier (err=%d).\n",
 731                        retval);
 732                goto error_die_notifier;
 733        }
 734
 735        retval = misc_register(&hpwdt_miscdev);
 736        if (retval < 0) {
 737                dev_warn(&dev->dev,
 738                        "Unable to register miscdev on minor=%d (err=%d).\n",
 739                        WATCHDOG_MINOR, retval);
 740                goto error_misc_register;
 741        }
 742
 743        printk(KERN_INFO
 744                "hp Watchdog Timer Driver: %s"
 745                ", timer margin: %d seconds (nowayout=%d)"
 746                ", allow kernel dump: %s (default = 0/OFF)"
 747                ", priority: %s (default = 0/LAST).\n",
 748                HPWDT_VERSION, soft_margin, nowayout,
 749                (allow_kdump == 0) ? "OFF" : "ON",
 750                (priority == 0) ? "LAST" : "FIRST");
 751
 752        return 0;
 753
 754error_misc_register:
 755        unregister_die_notifier(&die_notifier);
 756error_die_notifier:
 757        if (cru_rom_addr)
 758                iounmap(cru_rom_addr);
 759error_get_cru:
 760        pci_iounmap(dev, pci_mem_addr);
 761error_pci_iomap:
 762        pci_disable_device(dev);
 763        return retval;
 764}
 765
 766static void __devexit hpwdt_exit(struct pci_dev *dev)
 767{
 768        if (!nowayout)
 769                hpwdt_stop();
 770
 771        misc_deregister(&hpwdt_miscdev);
 772        unregister_die_notifier(&die_notifier);
 773
 774        if (cru_rom_addr)
 775                iounmap(cru_rom_addr);
 776        pci_iounmap(dev, pci_mem_addr);
 777        pci_disable_device(dev);
 778}
 779
 780static struct pci_driver hpwdt_driver = {
 781        .name = "hpwdt",
 782        .id_table = hpwdt_devices,
 783        .probe = hpwdt_init_one,
 784        .remove = __devexit_p(hpwdt_exit),
 785};
 786
 787static void __exit hpwdt_cleanup(void)
 788{
 789        pci_unregister_driver(&hpwdt_driver);
 790}
 791
 792static int __init hpwdt_init(void)
 793{
 794        return pci_register_driver(&hpwdt_driver);
 795}
 796
 797MODULE_AUTHOR("Tom Mingarelli");
 798MODULE_DESCRIPTION("hp watchdog driver");
 799MODULE_LICENSE("GPL");
 800MODULE_VERSION(HPWDT_VERSION);
 801MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
 802
 803module_param(soft_margin, int, 0);
 804MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds");
 805
 806module_param(allow_kdump, int, 0);
 807MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs");
 808
 809module_param(nowayout, int, 0);
 810MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
 811                __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 812
 813module_param(priority, int, 0);
 814MODULE_PARM_DESC(priority, "The hpwdt driver handles NMIs first or last"
 815                " (default = 0/Last)\n");
 816
 817module_init(hpwdt_init);
 818module_exit(hpwdt_cleanup);
 819