[WATCHDOG] hpwdt: Add NMI priority option

Add a priority option so that the user can choose if we do the NMI
first or last.

Signed-off-by: Thomas Mingarelli <thomas.mingarelli@hp.com>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>

diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index c0b9169..a6c5674 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -120,7 +120,8 @@
 static char expect_release;
 static unsigned long hpwdt_is_open;
 static unsigned int allow_kdump;
-static int hpwdt_nmi_sourcing;
+static unsigned int hpwdt_nmi_sourcing;
+static unsigned int priority;		/* hpwdt at end of die_notify list */
 
 static void __iomem *pci_mem_addr;		/* the PCI-memory address */
 static unsigned long __iomem *hpwdt_timer_reg;
@@ -623,7 +624,7 @@
 
 static struct notifier_block die_notifier = {
 	.notifier_call = hpwdt_pretimeout,
-	.priority = 0x7FFFFFFF,
+	.priority = 0,
 };
 
 /*
@@ -641,7 +642,8 @@
 		hpwdt_nmi_sourcing = 1;
 	else
 		dev_warn(&dev->dev, "NMI sourcing is disabled. To enable this "
-			"functionality you must reboot with nmi_watchdog=0.\n");
+			"functionality you must reboot with nmi_watchdog=0 "
+			"and load the hpwdt driver with priority=1.\n");
 }
 #else
 static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
@@ -714,6 +716,14 @@
 	cmn_regs.u1.rah = 0x0D;
 	cmn_regs.u1.ral = 0x02;
 
+	/*
+	 * If the priority is set to 1, then we will be put first on the
+	 * die notify list to handle a critical NMI. The default is to
+	 * be last so other users of the NMI signal can function.
+	 */
+	if (priority)
+		die_notifier.priority = 0x7FFFFFFF;
+
 	retval = register_die_notifier(&die_notifier);
 	if (retval != 0) {
 		dev_warn(&dev->dev,
@@ -733,9 +743,11 @@
 	printk(KERN_INFO
 		"hp Watchdog Timer Driver: %s"
 		", timer margin: %d seconds (nowayout=%d)"
-		", allow kernel dump: %s (default = 0/OFF).\n",
+		", allow kernel dump: %s (default = 0/OFF)"
+		", priority: %s (default = 0/LAST).\n",
 		HPWDT_VERSION, soft_margin, nowayout,
-		(allow_kdump == 0) ? "OFF" : "ON");
+		(allow_kdump == 0) ? "OFF" : "ON",
+		(priority == 0) ? "LAST" : "FIRST");
 
 	return 0;
 
@@ -798,5 +810,9 @@
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
 		__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
+module_param(priority, int, 0);
+MODULE_PARM_DESC(priority, "The hpwdt driver handles NMIs first or last"
+		" (default = 0/Last)\n");
+
 module_init(hpwdt_init);
 module_exit(hpwdt_cleanup);