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: softdog.c: enhancement to optionally invoke panic instead of reboot on timer expiry
  watchdog: fix nv_tco section mismatch
  watchdog: sp5100_tco.c: Check if firmware has set correct value in tcobase.
  watchdog: Convert release_resource to release_region/release_mem_region
  watchdog: s3c2410_wdt.c: Convert release_resource to release_region/release_mem_region
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 596ba60..51b5551 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -202,7 +202,6 @@
 static int __devinit davinci_wdt_probe(struct platform_device *pdev)
 {
 	int ret = 0, size;
-	struct resource *res;
 	struct device *dev = &pdev->dev;
 
 	wdt_clk = clk_get(dev, NULL);
@@ -216,31 +215,31 @@
 
 	dev_info(dev, "heartbeat %d sec\n", heartbeat);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
+	wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (wdt_mem == NULL) {
 		dev_err(dev, "failed to get memory region resource\n");
 		return -ENOENT;
 	}
 
-	size = resource_size(res);
-	wdt_mem = request_mem_region(res->start, size, pdev->name);
-
-	if (wdt_mem == NULL) {
+	size = resource_size(wdt_mem);
+	if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
 		dev_err(dev, "failed to get memory region\n");
 		return -ENOENT;
 	}
 
-	wdt_base = ioremap(res->start, size);
+	wdt_base = ioremap(wdt_mem->start, size);
 	if (!wdt_base) {
 		dev_err(dev, "failed to map memory region\n");
+		release_mem_region(wdt_mem->start, size);
+		wdt_mem = NULL;
 		return -ENOMEM;
 	}
 
 	ret = misc_register(&davinci_wdt_miscdev);
 	if (ret < 0) {
 		dev_err(dev, "cannot register misc device\n");
-		release_resource(wdt_mem);
-		kfree(wdt_mem);
+		release_mem_region(wdt_mem->start, size);
+		wdt_mem = NULL;
 	} else {
 		set_bit(WDT_DEVICE_INITED, &wdt_status);
 	}
@@ -253,8 +252,7 @@
 {
 	misc_deregister(&davinci_wdt_miscdev);
 	if (wdt_mem) {
-		release_resource(wdt_mem);
-		kfree(wdt_mem);
+		release_mem_region(wdt_mem->start, resource_size(wdt_mem));
 		wdt_mem = NULL;
 	}
 
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c
index 7a82ce5..73ba2fd 100644
--- a/drivers/watchdog/max63xx_wdt.c
+++ b/drivers/watchdog/max63xx_wdt.c
@@ -270,7 +270,6 @@
 {
 	int ret = 0;
 	int size;
-	struct resource *res;
 	struct device *dev = &pdev->dev;
 	struct max63xx_timeout *table;
 
@@ -294,21 +293,19 @@
 
 	max63xx_pdev = pdev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
+	wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (wdt_mem == NULL) {
 		dev_err(dev, "failed to get memory region resource\n");
 		return -ENOENT;
 	}
 
-	size = resource_size(res);
-	wdt_mem = request_mem_region(res->start, size, pdev->name);
-
-	if (wdt_mem == NULL) {
+	size = resource_size(wdt_mem);
+	if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
 		dev_err(dev, "failed to get memory region\n");
 		return -ENOENT;
 	}
 
-	wdt_base = ioremap(res->start, size);
+	wdt_base = ioremap(wdt_mem->start, size);
 	if (!wdt_base) {
 		dev_err(dev, "failed to map memory region\n");
 		ret = -ENOMEM;
@@ -326,8 +323,8 @@
 out_unmap:
 	iounmap(wdt_base);
 out_request:
-	release_resource(wdt_mem);
-	kfree(wdt_mem);
+	release_mem_region(wdt_mem->start, size);
+	wdt_mem = NULL;
 
 	return ret;
 }
@@ -336,8 +333,7 @@
 {
 	misc_deregister(&max63xx_wdt_miscdev);
 	if (wdt_mem) {
-		release_resource(wdt_mem);
-		kfree(wdt_mem);
+		release_mem_region(wdt_mem->start, resource_size(wdt_mem));
 		wdt_mem = NULL;
 	}
 
diff --git a/drivers/watchdog/nv_tco.c b/drivers/watchdog/nv_tco.c
index 267377a..afa78a5 100644
--- a/drivers/watchdog/nv_tco.c
+++ b/drivers/watchdog/nv_tco.c
@@ -302,7 +302,7 @@
  *	Init & exit routines
  */
 
-static unsigned char __init nv_tco_getdevice(void)
+static unsigned char __devinit nv_tco_getdevice(void)
 {
 	struct pci_dev *dev = NULL;
 	u32 val;
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index c7cf4cb..6149332 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -254,7 +254,6 @@
 static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
 {
 	int ret = 0, size;
-	struct resource *res;
 
 	if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
 		heartbeat = DEFAULT_HEARTBEAT;
@@ -262,42 +261,42 @@
 	printk(KERN_INFO MODULE_NAME
 		"PNX4008 Watchdog Timer: heartbeat %d sec\n", heartbeat);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
+	wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (wdt_mem == NULL) {
 		printk(KERN_INFO MODULE_NAME
 			"failed to get memory region resouce\n");
 		return -ENOENT;
 	}
 
-	size = resource_size(res);
-	wdt_mem = request_mem_region(res->start, size, pdev->name);
+	size = resource_size(wdt_mem);
 
-	if (wdt_mem == NULL) {
+	if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
 		printk(KERN_INFO MODULE_NAME "failed to get memory region\n");
 		return -ENOENT;
 	}
-	wdt_base = (void __iomem *)IO_ADDRESS(res->start);
+	wdt_base = (void __iomem *)IO_ADDRESS(wdt_mem->start);
 
 	wdt_clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(wdt_clk)) {
 		ret = PTR_ERR(wdt_clk);
-		release_resource(wdt_mem);
-		kfree(wdt_mem);
+		release_mem_region(wdt_mem->start, size);
+		wdt_mem = NULL;
 		goto out;
 	}
 
 	ret = clk_enable(wdt_clk);
 	if (ret) {
-		release_resource(wdt_mem);
-		kfree(wdt_mem);
+		release_mem_region(wdt_mem->start, size);
+		wdt_mem = NULL;
+		clk_put(wdt_clk);
 		goto out;
 	}
 
 	ret = misc_register(&pnx4008_wdt_miscdev);
 	if (ret < 0) {
 		printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
-		release_resource(wdt_mem);
-		kfree(wdt_mem);
+		release_mem_region(wdt_mem->start, size);
+		wdt_mem = NULL;
 		clk_disable(wdt_clk);
 		clk_put(wdt_clk);
 	} else {
@@ -320,8 +319,7 @@
 	clk_put(wdt_clk);
 
 	if (wdt_mem) {
-		release_resource(wdt_mem);
-		kfree(wdt_mem);
+		release_mem_region(wdt_mem->start, resource_size(wdt_mem));
 		wdt_mem = NULL;
 	}
 	return 0;
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 25b39bf..f7f5aa0 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -402,7 +402,6 @@
 
 static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
 {
-	struct resource *res;
 	struct device *dev;
 	unsigned int wtcon;
 	int started = 0;
@@ -416,20 +415,19 @@
 
 	/* get the memory region for the watchdog timer */
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
+	wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (wdt_mem == NULL) {
 		dev_err(dev, "no memory resource specified\n");
 		return -ENOENT;
 	}
 
-	size = resource_size(res);
-	wdt_mem = request_mem_region(res->start, size, pdev->name);
-	if (wdt_mem == NULL) {
+	size = resource_size(wdt_mem);
+	if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
 		dev_err(dev, "failed to get memory region\n");
 		return -EBUSY;
 	}
 
-	wdt_base = ioremap(res->start, size);
+	wdt_base = ioremap(wdt_mem->start, size);
 	if (wdt_base == NULL) {
 		dev_err(dev, "failed to ioremap() region\n");
 		ret = -EINVAL;
@@ -524,8 +522,8 @@
 	iounmap(wdt_base);
 
  err_req:
-	release_resource(wdt_mem);
-	kfree(wdt_mem);
+	release_mem_region(wdt_mem->start, size);
+	wdt_mem = NULL;
 
 	return ret;
 }
@@ -545,8 +543,7 @@
 
 	iounmap(wdt_base);
 
-	release_resource(wdt_mem);
-	kfree(wdt_mem);
+	release_mem_region(wdt_mem->start, resource_size(wdt_mem));
 	wdt_mem = NULL;
 	return 0;
 }
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c
index 100b114..bf16ffb 100644
--- a/drivers/watchdog/softdog.c
+++ b/drivers/watchdog/softdog.c
@@ -48,6 +48,7 @@
 #include <linux/init.h>
 #include <linux/jiffies.h>
 #include <linux/uaccess.h>
+#include <linux/kernel.h>
 
 #define PFX "SoftDog: "
 
@@ -75,6 +76,11 @@
 	"Softdog action, set to 1 to ignore reboots, 0 to reboot "
 					"(default depends on ONLY_TESTING)");
 
+static int soft_panic;
+module_param(soft_panic, int, 0);
+MODULE_PARM_DESC(soft_panic,
+	"Softdog action, set to 1 to panic, 0 to reboot (default=0)");
+
 /*
  *	Our timer
  */
@@ -98,7 +104,10 @@
 
 	if (soft_noboot)
 		printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n");
-	else {
+	else if (soft_panic) {
+		printk(KERN_CRIT PFX "Initiating panic.\n");
+		panic("Software Watchdog Timer expired.");
+	} else {
 		printk(KERN_CRIT PFX "Initiating system reboot.\n");
 		emergency_restart();
 		printk(KERN_CRIT PFX "Reboot didn't ?????\n");
@@ -267,7 +276,8 @@
 };
 
 static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.07 "
-	"initialized. soft_noboot=%d soft_margin=%d sec (nowayout= %d)\n";
+	"initialized. soft_noboot=%d soft_margin=%d sec soft_panic=%d "
+	"(nowayout= %d)\n";
 
 static int __init watchdog_init(void)
 {
@@ -298,7 +308,7 @@
 		return ret;
 	}
 
-	printk(banner, soft_noboot, soft_margin, nowayout);
+	printk(banner, soft_noboot, soft_margin, soft_panic, nowayout);
 
 	return 0;
 }
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
index 1bc4938..87e0527 100644
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -42,6 +42,7 @@
 #define PFX TCO_MODULE_NAME ": "
 
 /* internal variables */
+static u32 tcobase_phys;
 static void __iomem *tcobase;
 static unsigned int pm_iobase;
 static DEFINE_SPINLOCK(tco_lock);	/* Guards the hardware */
@@ -305,10 +306,18 @@
 	/* Low three bits of BASE0 are reserved. */
 	val = val << 8 | (inb(SP5100_IO_PM_DATA_REG) & 0xf8);
 
+	if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
+								"SP5100 TCO")) {
+		printk(KERN_ERR PFX "mmio address 0x%04x already in use\n",
+			val);
+		goto unreg_region;
+	}
+	tcobase_phys = val;
+
 	tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE);
 	if (tcobase == 0) {
 		printk(KERN_ERR PFX "failed to get tcobase address\n");
-		goto unreg_region;
+		goto unreg_mem_region;
 	}
 
 	/* Enable watchdog decode bit */
@@ -346,7 +355,8 @@
 	/* Done */
 	return 1;
 
-	iounmap(tcobase);
+unreg_mem_region:
+	release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
 unreg_region:
 	release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
 exit:
@@ -401,6 +411,7 @@
 
 exit:
 	iounmap(tcobase);
+	release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
 	release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
 	return ret;
 }
@@ -414,6 +425,7 @@
 	/* Deregister */
 	misc_deregister(&sp5100_tco_miscdev);
 	iounmap(tcobase);
+	release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
 	release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
 }