Merge git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog

* git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog:
watchdog: hpwdt (12/12): Make NMI decoding a compile-time option
watchdog: hpwdt (11/12): move NMI-decoding init and exit to seperate functions
watchdog: hpwdt (10/12): Use "decoding" instead of "sourcing"
watchdog: hpwdt (9/12): hpwdt_pretimeout reorganization
watchdog: hpwdt (8/12): implement WDIOC_GETTIMELEFT
watchdog: hpwdt (7/12): allow full range of timer values supported by hardware
watchdog: hpwdt (6/12): Introduce SECS_TO_TICKS() macro
watchdog: hpwdt (5/12): Make x86 assembly ifdef guard more strict
watchdog: hpwdt (4/12): Despecificate driver from iLO2
watchdog: hpwdt (3/12): Group NMI sourcing specific items together
watchdog: hpwdt (2/12): Group options that affect watchdog behavior together
watchdog: hpwdt (1/12): clean-up include-files.

+185 -138
+12 -7
drivers/watchdog/Kconfig
··· 574 be called it87_wdt. 575 576 config HP_WATCHDOG 577 - tristate "HP Proliant iLO 2 Hardware Watchdog Timer" 578 depends on X86 579 help 580 A software monitoring watchdog and NMI sourcing driver. This driver 581 - will detect lockups and provide stack trace. Also, when an NMI 582 - occurs this driver will make the necessary BIOS calls to log 583 - the cause of the NMI. This is a driver that will only load on a 584 - HP ProLiant system with a minimum of iLO2 support. 585 - To compile this driver as a module, choose M here: the 586 - module will be called hpwdt. 587 588 config SC1200_WDT 589 tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
··· 574 be called it87_wdt. 575 576 config HP_WATCHDOG 577 + tristate "HP Proliant iLO2+ Hardware Watchdog Timer" 578 depends on X86 579 help 580 A software monitoring watchdog and NMI sourcing driver. This driver 581 + will detect lockups and provide a stack trace. This is a driver that 582 + will only load on a HP ProLiant system with a minimum of iLO2 support. 583 + To compile this driver as a module, choose M here: the module will be 584 + called hpwdt. 585 + 586 + config HPWDT_NMI_DECODING 587 + bool "NMI decoding support for the HP ProLiant iLO2+ Hardware Watchdog Timer" 588 + depends on HP_WATCHDOG 589 + help 590 + When an NMI occurs this feature will make the necessary BIOS calls to 591 + log the cause of the NMI. 592 593 config SC1200_WDT 594 tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
+173 -131
drivers/watchdog/hpwdt.c
··· 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 <asm/desc.h> 43 #include <asm/cacheflush.h> 44 45 #define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ 46 #define CRU_BIOS_SIGNATURE_VALUE 0x55524324 47 #define PCI_BIOS32_PARAGRAPH_LEN 16 48 #define PCI_ROM_BASE1 0x000F0000 49 #define ROM_SIZE 0x10000 50 - #define HPWDT_VERSION "1.1.1" 51 52 struct bios32_service_dir { 53 u32 signature; ··· 129 u32 reflags; 130 } __attribute__((packed)); 131 132 - #define DEFAULT_MARGIN 30 133 - static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ 134 - static unsigned int reload; /* the computed soft_margin */ 135 - static int nowayout = WATCHDOG_NOWAYOUT; 136 - static char expect_release; 137 - static unsigned long hpwdt_is_open; 138 static unsigned int allow_kdump; 139 - static unsigned int hpwdt_nmi_sourcing; 140 static unsigned int priority; /* hpwdt at end of die_notify list */ 141 - 142 - static void __iomem *pci_mem_addr; /* the PCI-memory address */ 143 - static unsigned long __iomem *hpwdt_timer_reg; 144 - static unsigned long __iomem *hpwdt_timer_con; 145 - 146 static DEFINE_SPINLOCK(rom_lock); 147 - 148 static void *cru_rom_addr; 149 - 150 static struct cmn_registers cmn_regs; 151 - 152 - static struct pci_device_id hpwdt_devices[] = { 153 - { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB203) }, 154 - { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3306) }, 155 - {0}, /* terminate list */ 156 - }; 157 - MODULE_DEVICE_TABLE(pci, hpwdt_devices); 158 159 extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs, 160 unsigned long *pRomEntry); 161 162 - #ifndef CONFIG_X86_64 163 /* --32 Bit Bios------------------------------------------------------------ */ 164 165 #define HPWDT_ARCH 32 ··· 328 iounmap(p); 329 return rc; 330 } 331 - 332 - #else 333 /* --64 Bit Bios------------------------------------------------------------ */ 334 335 #define HPWDT_ARCH 64 ··· 408 /* if cru_rom_addr has been set then we found a CRU service */ 409 return ((cru_rom_addr != NULL) ? 0 : -ENODEV); 410 } 411 - 412 /* ------------------------------------------------------------------------- */ 413 - 414 - #endif 415 416 /* 417 * Watchdog operations 418 */ 419 static void hpwdt_start(void) 420 { 421 - reload = (soft_margin * 1000) / 128; 422 iowrite16(reload, hpwdt_timer_reg); 423 iowrite16(0x85, hpwdt_timer_con); 424 } ··· 438 439 static int hpwdt_change_timer(int new_margin) 440 { 441 - /* Arbitrary, can't find the card's limits */ 442 - if (new_margin < 5 || new_margin > 600) { 443 printk(KERN_WARNING 444 "hpwdt: New value passed in is invalid: %d seconds.\n", 445 new_margin); ··· 449 printk(KERN_DEBUG 450 "hpwdt: New timer passed in is %d seconds.\n", 451 new_margin); 452 - reload = (soft_margin * 1000) / 128; 453 454 return 0; 455 } 456 457 /* 458 * NMI Handler 459 */ ··· 470 static int die_nmi_called; 471 472 if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI) 473 - return NOTIFY_OK; 474 475 - if (hpwdt_nmi_sourcing) { 476 - spin_lock_irqsave(&rom_lock, rom_pl); 477 - if (!die_nmi_called) 478 - asminline_call(&cmn_regs, cru_rom_addr); 479 - die_nmi_called = 1; 480 - spin_unlock_irqrestore(&rom_lock, rom_pl); 481 - if (cmn_regs.u1.ral == 0) { 482 - printk(KERN_WARNING "hpwdt: An NMI occurred, " 483 - "but unable to determine source.\n"); 484 - } else { 485 - if (allow_kdump) 486 - hpwdt_stop(); 487 - panic("An NMI occurred, please see the Integrated " 488 - "Management Log for details.\n"); 489 - } 490 } 491 return NOTIFY_OK; 492 } 493 494 /* 495 * /dev/watchdog handling ··· 562 .options = WDIOF_SETTIMEOUT | 563 WDIOF_KEEPALIVEPING | 564 WDIOF_MAGICCLOSE, 565 - .identity = "HP iLO2 HW Watchdog Timer", 566 }; 567 568 static long hpwdt_ioctl(struct file *file, unsigned int cmd, ··· 604 case WDIOC_GETTIMEOUT: 605 ret = put_user(soft_margin, p); 606 break; 607 } 608 return ret; 609 } ··· 630 .fops = &hpwdt_fops, 631 }; 632 633 static struct notifier_block die_notifier = { 634 .notifier_call = hpwdt_pretimeout, 635 .priority = 0, 636 }; 637 638 /* 639 * Init & Exit 640 */ 641 642 #ifdef ARCH_HAS_NMI_WATCHDOG 643 - static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev) 644 { 645 /* 646 * If nmi_watchdog is turned off then we can turn on 647 - * our nmi sourcing capability. 648 */ 649 if (!nmi_watchdog_active()) 650 - hpwdt_nmi_sourcing = 1; 651 else 652 - dev_warn(&dev->dev, "NMI sourcing is disabled. To enable this " 653 "functionality you must reboot with nmi_watchdog=0 " 654 "and load the hpwdt driver with priority=1.\n"); 655 } 656 #else 657 - static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev) 658 { 659 - dev_warn(&dev->dev, "NMI sourcing is disabled. " 660 "Your kernel does not support a NMI Watchdog.\n"); 661 } 662 - #endif 663 664 - static int __devinit hpwdt_init_one(struct pci_dev *dev, 665 - const struct pci_device_id *ent) 666 { 667 int retval; 668 - 669 - /* 670 - * Check if we can do NMI sourcing or not 671 - */ 672 - hpwdt_check_nmi_sourcing(dev); 673 - 674 - /* 675 - * First let's find out if we are on an iLO2 server. We will 676 - * not run on a legacy ASM box. 677 - * So we only support the G5 ProLiant servers and higher. 678 - */ 679 - if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) { 680 - dev_warn(&dev->dev, 681 - "This server does not have an iLO2 ASIC.\n"); 682 - return -ENODEV; 683 - } 684 - 685 - if (pci_enable_device(dev)) { 686 - dev_warn(&dev->dev, 687 - "Not possible to enable PCI Device: 0x%x:0x%x.\n", 688 - ent->vendor, ent->device); 689 - return -ENODEV; 690 - } 691 - 692 - pci_mem_addr = pci_iomap(dev, 1, 0x80); 693 - if (!pci_mem_addr) { 694 - dev_warn(&dev->dev, 695 - "Unable to detect the iLO2 server memory.\n"); 696 - retval = -ENOMEM; 697 - goto error_pci_iomap; 698 - } 699 - hpwdt_timer_reg = pci_mem_addr + 0x70; 700 - hpwdt_timer_con = pci_mem_addr + 0x72; 701 - 702 - /* Make sure that we have a valid soft_margin */ 703 - if (hpwdt_change_timer(soft_margin)) 704 - hpwdt_change_timer(DEFAULT_MARGIN); 705 706 /* 707 * We need to map the ROM to get the CRU service. ··· 679 dev_warn(&dev->dev, 680 "Unable to detect the %d Bit CRU Service.\n", 681 HPWDT_ARCH); 682 - goto error_get_cru; 683 } 684 685 /* ··· 702 dev_warn(&dev->dev, 703 "Unable to register a die notifier (err=%d).\n", 704 retval); 705 - goto error_die_notifier; 706 } 707 708 retval = misc_register(&hpwdt_miscdev); 709 if (retval < 0) { ··· 791 goto error_misc_register; 792 } 793 794 - printk(KERN_INFO 795 - "hp Watchdog Timer Driver: %s" 796 - ", timer margin: %d seconds (nowayout=%d)" 797 - ", allow kernel dump: %s (default = 0/OFF)" 798 - ", priority: %s (default = 0/LAST).\n", 799 - HPWDT_VERSION, soft_margin, nowayout, 800 - (allow_kdump == 0) ? "OFF" : "ON", 801 - (priority == 0) ? "LAST" : "FIRST"); 802 - 803 return 0; 804 805 error_misc_register: 806 - unregister_die_notifier(&die_notifier); 807 - error_die_notifier: 808 - if (cru_rom_addr) 809 - iounmap(cru_rom_addr); 810 - error_get_cru: 811 pci_iounmap(dev, pci_mem_addr); 812 error_pci_iomap: 813 pci_disable_device(dev); ··· 811 hpwdt_stop(); 812 813 misc_deregister(&hpwdt_miscdev); 814 - unregister_die_notifier(&die_notifier); 815 - 816 - if (cru_rom_addr) 817 - iounmap(cru_rom_addr); 818 pci_iounmap(dev, pci_mem_addr); 819 pci_disable_device(dev); 820 } ··· 842 module_param(soft_margin, int, 0); 843 MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds"); 844 845 - module_param(allow_kdump, int, 0); 846 - MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs"); 847 - 848 module_param(nowayout, int, 0); 849 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 850 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 851 852 module_param(priority, int, 0); 853 MODULE_PARM_DESC(priority, "The hpwdt driver handles NMIs first or last" 854 " (default = 0/Last)\n"); 855 856 module_init(hpwdt_init); 857 module_exit(hpwdt_cleanup);
··· 16 #include <linux/device.h> 17 #include <linux/fs.h> 18 #include <linux/init.h> 19 #include <linux/io.h> 20 + #include <linux/bitops.h> 21 #include <linux/kernel.h> 22 #include <linux/miscdevice.h> 23 #include <linux/module.h> 24 #include <linux/moduleparam.h> 25 #include <linux/pci.h> 26 #include <linux/pci_ids.h> 27 #include <linux/types.h> 28 #include <linux/uaccess.h> 29 #include <linux/watchdog.h> 30 + #ifdef CONFIG_HPWDT_NMI_DECODING 31 #include <linux/dmi.h> 32 + #include <linux/spinlock.h> 33 + #include <linux/nmi.h> 34 + #include <linux/kdebug.h> 35 + #include <linux/notifier.h> 36 #include <asm/cacheflush.h> 37 + #endif /* CONFIG_HPWDT_NMI_DECODING */ 38 39 + #define HPWDT_VERSION "1.2.0" 40 + #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) 41 + #define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) 42 + #define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) 43 + #define DEFAULT_MARGIN 30 44 + 45 + static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ 46 + static unsigned int reload; /* the computed soft_margin */ 47 + static int nowayout = WATCHDOG_NOWAYOUT; 48 + static char expect_release; 49 + static unsigned long hpwdt_is_open; 50 + 51 + static void __iomem *pci_mem_addr; /* the PCI-memory address */ 52 + static unsigned long __iomem *hpwdt_timer_reg; 53 + static unsigned long __iomem *hpwdt_timer_con; 54 + 55 + static struct pci_device_id hpwdt_devices[] = { 56 + { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB203) }, /* iLO2 */ 57 + { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3306) }, /* iLO3 */ 58 + {0}, /* terminate list */ 59 + }; 60 + MODULE_DEVICE_TABLE(pci, hpwdt_devices); 61 + 62 + #ifdef CONFIG_HPWDT_NMI_DECODING 63 #define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ 64 #define CRU_BIOS_SIGNATURE_VALUE 0x55524324 65 #define PCI_BIOS32_PARAGRAPH_LEN 16 66 #define PCI_ROM_BASE1 0x000F0000 67 #define ROM_SIZE 0x10000 68 69 struct bios32_service_dir { 70 u32 signature; ··· 112 u32 reflags; 113 } __attribute__((packed)); 114 115 + static unsigned int hpwdt_nmi_decoding; 116 static unsigned int allow_kdump; 117 static unsigned int priority; /* hpwdt at end of die_notify list */ 118 static DEFINE_SPINLOCK(rom_lock); 119 static void *cru_rom_addr; 120 static struct cmn_registers cmn_regs; 121 122 extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs, 123 unsigned long *pRomEntry); 124 125 + #ifdef CONFIG_X86_32 126 /* --32 Bit Bios------------------------------------------------------------ */ 127 128 #define HPWDT_ARCH 32 ··· 331 iounmap(p); 332 return rc; 333 } 334 + /* ------------------------------------------------------------------------- */ 335 + #endif /* CONFIG_X86_32 */ 336 + #ifdef CONFIG_X86_64 337 /* --64 Bit Bios------------------------------------------------------------ */ 338 339 #define HPWDT_ARCH 64 ··· 410 /* if cru_rom_addr has been set then we found a CRU service */ 411 return ((cru_rom_addr != NULL) ? 0 : -ENODEV); 412 } 413 /* ------------------------------------------------------------------------- */ 414 + #endif /* CONFIG_X86_64 */ 415 + #endif /* CONFIG_HPWDT_NMI_DECODING */ 416 417 /* 418 * Watchdog operations 419 */ 420 static void hpwdt_start(void) 421 { 422 + reload = SECS_TO_TICKS(soft_margin); 423 iowrite16(reload, hpwdt_timer_reg); 424 iowrite16(0x85, hpwdt_timer_con); 425 } ··· 441 442 static int hpwdt_change_timer(int new_margin) 443 { 444 + if (new_margin < 1 || new_margin > HPWDT_MAX_TIMER) { 445 printk(KERN_WARNING 446 "hpwdt: New value passed in is invalid: %d seconds.\n", 447 new_margin); ··· 453 printk(KERN_DEBUG 454 "hpwdt: New timer passed in is %d seconds.\n", 455 new_margin); 456 + reload = SECS_TO_TICKS(soft_margin); 457 458 return 0; 459 } 460 461 + static int hpwdt_time_left(void) 462 + { 463 + return TICKS_TO_SECS(ioread16(hpwdt_timer_reg)); 464 + } 465 + 466 + #ifdef CONFIG_HPWDT_NMI_DECODING 467 /* 468 * NMI Handler 469 */ ··· 468 static int die_nmi_called; 469 470 if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI) 471 + goto out; 472 473 + if (!hpwdt_nmi_decoding) 474 + goto out; 475 + 476 + spin_lock_irqsave(&rom_lock, rom_pl); 477 + if (!die_nmi_called) 478 + asminline_call(&cmn_regs, cru_rom_addr); 479 + die_nmi_called = 1; 480 + spin_unlock_irqrestore(&rom_lock, rom_pl); 481 + if (cmn_regs.u1.ral == 0) { 482 + printk(KERN_WARNING "hpwdt: An NMI occurred, " 483 + "but unable to determine source.\n"); 484 + } else { 485 + if (allow_kdump) 486 + hpwdt_stop(); 487 + panic("An NMI occurred, please see the Integrated " 488 + "Management Log for details.\n"); 489 } 490 + out: 491 return NOTIFY_OK; 492 } 493 + #endif /* CONFIG_HPWDT_NMI_DECODING */ 494 495 /* 496 * /dev/watchdog handling ··· 557 .options = WDIOF_SETTIMEOUT | 558 WDIOF_KEEPALIVEPING | 559 WDIOF_MAGICCLOSE, 560 + .identity = "HP iLO2+ HW Watchdog Timer", 561 }; 562 563 static long hpwdt_ioctl(struct file *file, unsigned int cmd, ··· 599 case WDIOC_GETTIMEOUT: 600 ret = put_user(soft_margin, p); 601 break; 602 + 603 + case WDIOC_GETTIMELEFT: 604 + ret = put_user(hpwdt_time_left(), p); 605 + break; 606 } 607 return ret; 608 } ··· 621 .fops = &hpwdt_fops, 622 }; 623 624 + #ifdef CONFIG_HPWDT_NMI_DECODING 625 static struct notifier_block die_notifier = { 626 .notifier_call = hpwdt_pretimeout, 627 .priority = 0, 628 }; 629 + #endif /* CONFIG_HPWDT_NMI_DECODING */ 630 631 /* 632 * Init & Exit 633 */ 634 635 + #ifdef CONFIG_HPWDT_NMI_DECODING 636 #ifdef ARCH_HAS_NMI_WATCHDOG 637 + static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev) 638 { 639 /* 640 * If nmi_watchdog is turned off then we can turn on 641 + * our nmi decoding capability. 642 */ 643 if (!nmi_watchdog_active()) 644 + hpwdt_nmi_decoding = 1; 645 else 646 + dev_warn(&dev->dev, "NMI decoding is disabled. To enable this " 647 "functionality you must reboot with nmi_watchdog=0 " 648 "and load the hpwdt driver with priority=1.\n"); 649 } 650 #else 651 + static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev) 652 { 653 + dev_warn(&dev->dev, "NMI decoding is disabled. " 654 "Your kernel does not support a NMI Watchdog.\n"); 655 } 656 + #endif /* ARCH_HAS_NMI_WATCHDOG */ 657 658 + static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) 659 { 660 int retval; 661 662 /* 663 * We need to map the ROM to get the CRU service. ··· 705 dev_warn(&dev->dev, 706 "Unable to detect the %d Bit CRU Service.\n", 707 HPWDT_ARCH); 708 + return retval; 709 } 710 711 /* ··· 728 dev_warn(&dev->dev, 729 "Unable to register a die notifier (err=%d).\n", 730 retval); 731 + if (cru_rom_addr) 732 + iounmap(cru_rom_addr); 733 } 734 + 735 + dev_info(&dev->dev, 736 + "HP Watchdog Timer Driver: NMI decoding initialized" 737 + ", allow kernel dump: %s (default = 0/OFF)" 738 + ", priority: %s (default = 0/LAST).\n", 739 + (allow_kdump == 0) ? "OFF" : "ON", 740 + (priority == 0) ? "LAST" : "FIRST"); 741 + return 0; 742 + } 743 + 744 + static void __devexit hpwdt_exit_nmi_decoding(void) 745 + { 746 + unregister_die_notifier(&die_notifier); 747 + if (cru_rom_addr) 748 + iounmap(cru_rom_addr); 749 + } 750 + #else /* !CONFIG_HPWDT_NMI_DECODING */ 751 + static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev) 752 + { 753 + } 754 + 755 + static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) 756 + { 757 + return 0; 758 + } 759 + 760 + static void __devexit hpwdt_exit_nmi_decoding(void) 761 + { 762 + } 763 + #endif /* CONFIG_HPWDT_NMI_DECODING */ 764 + 765 + static int __devinit hpwdt_init_one(struct pci_dev *dev, 766 + const struct pci_device_id *ent) 767 + { 768 + int retval; 769 + 770 + /* 771 + * Check if we can do NMI decoding or not 772 + */ 773 + hpwdt_check_nmi_decoding(dev); 774 + 775 + /* 776 + * First let's find out if we are on an iLO2+ server. We will 777 + * not run on a legacy ASM box. 778 + * So we only support the G5 ProLiant servers and higher. 779 + */ 780 + if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) { 781 + dev_warn(&dev->dev, 782 + "This server does not have an iLO2+ ASIC.\n"); 783 + return -ENODEV; 784 + } 785 + 786 + if (pci_enable_device(dev)) { 787 + dev_warn(&dev->dev, 788 + "Not possible to enable PCI Device: 0x%x:0x%x.\n", 789 + ent->vendor, ent->device); 790 + return -ENODEV; 791 + } 792 + 793 + pci_mem_addr = pci_iomap(dev, 1, 0x80); 794 + if (!pci_mem_addr) { 795 + dev_warn(&dev->dev, 796 + "Unable to detect the iLO2+ server memory.\n"); 797 + retval = -ENOMEM; 798 + goto error_pci_iomap; 799 + } 800 + hpwdt_timer_reg = pci_mem_addr + 0x70; 801 + hpwdt_timer_con = pci_mem_addr + 0x72; 802 + 803 + /* Make sure that we have a valid soft_margin */ 804 + if (hpwdt_change_timer(soft_margin)) 805 + hpwdt_change_timer(DEFAULT_MARGIN); 806 + 807 + /* Initialize NMI Decoding functionality */ 808 + retval = hpwdt_init_nmi_decoding(dev); 809 + if (retval != 0) 810 + goto error_init_nmi_decoding; 811 812 retval = misc_register(&hpwdt_miscdev); 813 if (retval < 0) { ··· 739 goto error_misc_register; 740 } 741 742 + dev_info(&dev->dev, "HP Watchdog Timer Driver: %s" 743 + ", timer margin: %d seconds (nowayout=%d).\n", 744 + HPWDT_VERSION, soft_margin, nowayout); 745 return 0; 746 747 error_misc_register: 748 + hpwdt_exit_nmi_decoding(); 749 + error_init_nmi_decoding: 750 pci_iounmap(dev, pci_mem_addr); 751 error_pci_iomap: 752 pci_disable_device(dev); ··· 768 hpwdt_stop(); 769 770 misc_deregister(&hpwdt_miscdev); 771 + hpwdt_exit_nmi_decoding(); 772 pci_iounmap(dev, pci_mem_addr); 773 pci_disable_device(dev); 774 } ··· 802 module_param(soft_margin, int, 0); 803 MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds"); 804 805 module_param(nowayout, int, 0); 806 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 807 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 808 809 + #ifdef CONFIG_HPWDT_NMI_DECODING 810 + module_param(allow_kdump, int, 0); 811 + MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs"); 812 + 813 module_param(priority, int, 0); 814 MODULE_PARM_DESC(priority, "The hpwdt driver handles NMIs first or last" 815 " (default = 0/Last)\n"); 816 + #endif /* !CONFIG_HPWDT_NMI_DECODING */ 817 818 module_init(hpwdt_init); 819 module_exit(hpwdt_cleanup);