aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/hpwdt.c
diff options
context:
space:
mode:
authorThomas Mingarelli <thomas.mingarelli@hp.com>2009-06-04 15:50:45 -0400
committerWim Van Sebroeck <wim@iguana.be>2009-06-18 03:32:06 -0400
commit47bece87b14b866872b52ff04d469832e4936756 (patch)
tree812f6e1856cb322f1246a761a46ef20295b4689b /drivers/watchdog/hpwdt.c
parent55e8ddecec6a9dbe35a99d03cc4189fd7c56e600 (diff)
[WATCHDOG] hpwdt: Add NMI sourcing
Add NMI sourcing functionality (Can only be active if nmi_watchdog is inactive). Signed-off-by: Thomas Mingarelli <thomas.mingarelli@hp.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog/hpwdt.c')
-rw-r--r--drivers/watchdog/hpwdt.c59
1 files changed, 44 insertions, 15 deletions
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 3137361ccbfe..c0b9169ba5d5 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -19,6 +19,7 @@
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/nmi.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
23#include <linux/miscdevice.h> 24#include <linux/miscdevice.h>
24#include <linux/mm.h> 25#include <linux/mm.h>
@@ -47,7 +48,7 @@
47#define PCI_BIOS32_PARAGRAPH_LEN 16 48#define PCI_BIOS32_PARAGRAPH_LEN 16
48#define PCI_ROM_BASE1 0x000F0000 49#define PCI_ROM_BASE1 0x000F0000
49#define ROM_SIZE 0x10000 50#define ROM_SIZE 0x10000
50#define HPWDT_VERSION "1.01" 51#define HPWDT_VERSION "1.1.1"
51 52
52struct bios32_service_dir { 53struct bios32_service_dir {
53 u32 signature; 54 u32 signature;
@@ -119,6 +120,7 @@ static int nowayout = WATCHDOG_NOWAYOUT;
119static char expect_release; 120static char expect_release;
120static unsigned long hpwdt_is_open; 121static unsigned long hpwdt_is_open;
121static unsigned int allow_kdump; 122static unsigned int allow_kdump;
123static int hpwdt_nmi_sourcing;
122 124
123static void __iomem *pci_mem_addr; /* the PCI-memory address */ 125static void __iomem *pci_mem_addr; /* the PCI-memory address */
124static unsigned long __iomem *hpwdt_timer_reg; 126static unsigned long __iomem *hpwdt_timer_reg;
@@ -468,21 +470,22 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
468 if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI) 470 if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI)
469 return NOTIFY_OK; 471 return NOTIFY_OK;
470 472
471 spin_lock_irqsave(&rom_lock, rom_pl); 473 if (hpwdt_nmi_sourcing) {
472 if (!die_nmi_called) 474 spin_lock_irqsave(&rom_lock, rom_pl);
473 asminline_call(&cmn_regs, cru_rom_addr); 475 if (!die_nmi_called)
474 die_nmi_called = 1; 476 asminline_call(&cmn_regs, cru_rom_addr);
475 spin_unlock_irqrestore(&rom_lock, rom_pl); 477 die_nmi_called = 1;
476 if (cmn_regs.u1.ral == 0) { 478 spin_unlock_irqrestore(&rom_lock, rom_pl);
477 printk(KERN_WARNING "hpwdt: An NMI occurred, " 479 if (cmn_regs.u1.ral == 0) {
478 "but unable to determine source.\n"); 480 printk(KERN_WARNING "hpwdt: An NMI occurred, "
479 } else { 481 "but unable to determine source.\n");
480 if (allow_kdump) 482 } else {
481 hpwdt_stop(); 483 if (allow_kdump)
482 panic("An NMI occurred, please see the Integrated " 484 hpwdt_stop();
483 "Management Log for details.\n"); 485 panic("An NMI occurred, please see the Integrated "
486 "Management Log for details.\n");
487 }
484 } 488 }
485
486 return NOTIFY_OK; 489 return NOTIFY_OK;
487} 490}
488 491
@@ -627,12 +630,38 @@ static struct notifier_block die_notifier = {
627 * Init & Exit 630 * Init & Exit
628 */ 631 */
629 632
633#ifdef ARCH_HAS_NMI_WATCHDOG
634static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
635{
636 /*
637 * If nmi_watchdog is turned off then we can turn on
638 * our nmi sourcing capability.
639 */
640 if (!nmi_watchdog_active())
641 hpwdt_nmi_sourcing = 1;
642 else
643 dev_warn(&dev->dev, "NMI sourcing is disabled. To enable this "
644 "functionality you must reboot with nmi_watchdog=0.\n");
645}
646#else
647static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
648{
649 dev_warn(&dev->dev, "NMI sourcing is disabled. "
650 "Your kernel does not support a NMI Watchdog.\n");
651}
652#endif
653
630static int __devinit hpwdt_init_one(struct pci_dev *dev, 654static int __devinit hpwdt_init_one(struct pci_dev *dev,
631 const struct pci_device_id *ent) 655 const struct pci_device_id *ent)
632{ 656{
633 int retval; 657 int retval;
634 658
635 /* 659 /*
660 * Check if we can do NMI sourcing or not
661 */
662 hpwdt_check_nmi_sourcing(dev);
663
664 /*
636 * First let's find out if we are on an iLO2 server. We will 665 * First let's find out if we are on an iLO2 server. We will
637 * not run on a legacy ASM box. 666 * not run on a legacy ASM box.
638 * So we only support the G5 ProLiant servers and higher. 667 * So we only support the G5 ProLiant servers and higher.