aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/watchdog/hpwdt.txt84
-rw-r--r--drivers/watchdog/alim7101_wdt.c15
-rw-r--r--drivers/watchdog/ar7_wdt.c3
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c3
-rw-r--r--drivers/watchdog/at91sam9_wdt.c3
-rw-r--r--drivers/watchdog/bfin_wdt.c14
-rw-r--r--drivers/watchdog/cpwd.c6
-rw-r--r--drivers/watchdog/davinci_wdt.c6
-rw-r--r--drivers/watchdog/hpwdt.c59
-rw-r--r--drivers/watchdog/iTCO_vendor_support.c88
-rw-r--r--drivers/watchdog/iTCO_wdt.c36
-rw-r--r--drivers/watchdog/indydog.c4
-rw-r--r--drivers/watchdog/it8712f_wdt.c3
-rw-r--r--drivers/watchdog/ks8695_wdt.c4
-rw-r--r--drivers/watchdog/machzwd.c9
-rw-r--r--drivers/watchdog/mpcore_wdt.c7
-rw-r--r--drivers/watchdog/mtx-1_wdt.c6
-rw-r--r--drivers/watchdog/pnx4008_wdt.c6
-rw-r--r--drivers/watchdog/rdc321x_wdt.c4
-rw-r--r--drivers/watchdog/rm9k_wdt.c6
-rw-r--r--drivers/watchdog/s3c2410_wdt.c32
-rw-r--r--drivers/watchdog/sb_wdog.c9
-rw-r--r--drivers/watchdog/sbc60xxwdt.c5
-rw-r--r--drivers/watchdog/sbc8360.c4
-rw-r--r--drivers/watchdog/sbc_epx_c3.c12
-rw-r--r--drivers/watchdog/scx200_wdt.c7
-rw-r--r--drivers/watchdog/shwdt.c4
-rw-r--r--drivers/watchdog/softdog.c7
-rw-r--r--drivers/watchdog/w83697hf_wdt.c3
-rw-r--r--drivers/watchdog/wdrtas.c7
30 files changed, 335 insertions, 121 deletions
diff --git a/Documentation/watchdog/hpwdt.txt b/Documentation/watchdog/hpwdt.txt
new file mode 100644
index 000000000000..127839e53043
--- /dev/null
+++ b/Documentation/watchdog/hpwdt.txt
@@ -0,0 +1,84 @@
1Last reviewed: 06/02/2009
2
3 HP iLO2 NMI Watchdog Driver
4 NMI sourcing for iLO2 based ProLiant Servers
5 Documentation and Driver by
6 Thomas Mingarelli <thomas.mingarelli@hp.com>
7
8 The HP iLO2 NMI Watchdog driver is a kernel module that provides basic
9 watchdog functionality and the added benefit of NMI sourcing. Both the
10 watchdog functionality and the NMI sourcing capability need to be enabled
11 by the user. Remember that the two modes are not dependant on one another.
12 A user can have the NMI sourcing without the watchdog timer and vice-versa.
13
14 Watchdog functionality is enabled like any other common watchdog driver. That
15 is, an application needs to be started that kicks off the watchdog timer. A
16 basic application exists in the Documentation/watchdog/src directory called
17 watchdog-test.c. Simply compile the C file and kick it off. If the system
18 gets into a bad state and hangs, the HP ProLiant iLO 2 timer register will
19 not be updated in a timely fashion and a hardware system reset (also known as
20 an Automatic Server Recovery (ASR)) event will occur.
21
22 The hpwdt driver also has three (3) module parameters. They are the following:
23
24 soft_margin - allows the user to set the watchdog timer value
25 allow_kdump - allows the user to save off a kernel dump image after an NMI
26 nowayout - basic watchdog parameter that does not allow the timer to
27 be restarted or an impending ASR to be escaped.
28
29 NOTE: More information about watchdog drivers in general, including the ioctl
30 interface to /dev/watchdog can be found in
31 Documentation/watchdog/watchdog-api.txt and Documentation/IPMI.txt.
32
33 The NMI sourcing capability is disabled when the driver discovers that the
34 nmi_watchdog is turned on (nmi_watchdog = 1). This is due to the inability to
35 distinguish between "NMI Watchdog Ticks" and "HW generated NMI events" in the
36 Linux kernel. What this means is that the hpwdt nmi handler code is called
37 each time the NMI signal fires off. This could amount to several thousands of
38 NMIs in a matter of seconds. If a user sees the Linux kernel's "dazed and
39 confused" message in the logs or if the system gets into a hung state, then
40 the user should reboot with nmi_watchdog=0.
41
42 1. If the kernel has not been booted with nmi_watchdog turned off then
43 edit /boot/grub/menu.lst and place the nmi_watchdog=0 at the end of the
44 currently booting kernel line.
45 2. reboot the sever
46
47 Now, the hpwdt can successfully receive and source the NMI and provide a log
48 message that details the reason for the NMI (as determined by the HP BIOS).
49
50 Below is a list of NMIs the HP BIOS understands along with the associated
51 code (reason):
52
53 No source found 00h
54
55 Uncorrectable Memory Error 01h
56
57 ASR NMI 1Bh
58
59 PCI Parity Error 20h
60
61 NMI Button Press 27h
62
63 SB_BUS_NMI 28h
64
65 ILO Doorbell NMI 29h
66
67 ILO IOP NMI 2Ah
68
69 ILO Watchdog NMI 2Bh
70
71 Proc Throt NMI 2Ch
72
73 Front Side Bus NMI 2Dh
74
75 PCI Express Error 2Fh
76
77 DMA controller NMI 30h
78
79 Hypertransport/CSI Error 31h
80
81
82
83 -- Tom Mingarelli
84 (thomas.mingarelli@hp.com)
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 90f98df5f106..f90afdb1b255 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -322,7 +322,8 @@ static int wdt_notify_sys(struct notifier_block *this,
322 * watchdog on reboot with no heartbeat 322 * watchdog on reboot with no heartbeat
323 */ 323 */
324 wdt_change(WDT_ENABLE); 324 wdt_change(WDT_ENABLE);
325 printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); 325 printk(KERN_INFO PFX "Watchdog timer is now enabled "
326 "with no heartbeat - should reboot in ~1 second.\n");
326 } 327 }
327 return NOTIFY_DONE; 328 return NOTIFY_DONE;
328} 329}
@@ -374,12 +375,17 @@ static int __init alim7101_wdt_init(void)
374 pci_dev_put(ali1543_south); 375 pci_dev_put(ali1543_south);
375 if ((tmp & 0x1e) == 0x00) { 376 if ((tmp & 0x1e) == 0x00) {
376 if (!use_gpio) { 377 if (!use_gpio) {
377 printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); 378 printk(KERN_INFO PFX
379 "Detected old alim7101 revision 'a1d'. "
380 "If this is a cobalt board, set the 'use_gpio' "
381 "module parameter.\n");
378 goto err_out; 382 goto err_out;
379 } 383 }
380 nowayout = 1; 384 nowayout = 1;
381 } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { 385 } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) {
382 printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); 386 printk(KERN_INFO PFX
387 "ALi 1543 South-Bridge does not have the correct "
388 "revision number (???1001?) - WDT not set\n");
383 goto err_out; 389 goto err_out;
384 } 390 }
385 391
@@ -409,7 +415,8 @@ static int __init alim7101_wdt_init(void)
409 if (nowayout) 415 if (nowayout)
410 __module_get(THIS_MODULE); 416 __module_get(THIS_MODULE);
411 417
412 printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", 418 printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. "
419 "timeout=%d sec (nowayout=%d)\n",
413 timeout, nowayout); 420 timeout, nowayout);
414 return 0; 421 return 0;
415 422
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index 55dcbfe2bb72..3fe9742c23ca 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -246,7 +246,8 @@ static long ar7_wdt_ioctl(struct file *file,
246 static struct watchdog_info ident = { 246 static struct watchdog_info ident = {
247 .identity = LONGNAME, 247 .identity = LONGNAME,
248 .firmware_version = 1, 248 .firmware_version = 1,
249 .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING), 249 .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
250 WDIOF_MAGICCLOSE),
250 }; 251 };
251 int new_margin; 252 int new_margin;
252 253
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index 29e52c237a3b..b185dafe1494 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -268,7 +268,8 @@ static int __init at91_wdt_init(void)
268 if not reset to the default */ 268 if not reset to the default */
269 if (at91_wdt_settimeout(wdt_time)) { 269 if (at91_wdt_settimeout(wdt_time)) {
270 at91_wdt_settimeout(WDT_DEFAULT_TIME); 270 at91_wdt_settimeout(WDT_DEFAULT_TIME);
271 pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); 271 pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256"
272 ", using %d\n", wdt_time);
272 } 273 }
273 274
274 return platform_driver_register(&at91wdt_driver); 275 return platform_driver_register(&at91wdt_driver);
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 435b0573fb0a..eac26021e8da 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -156,7 +156,8 @@ static int at91_wdt_settimeout(unsigned int timeout)
156 156
157static const struct watchdog_info at91_wdt_info = { 157static const struct watchdog_info at91_wdt_info = {
158 .identity = DRV_NAME, 158 .identity = DRV_NAME,
159 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 159 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
160 WDIOF_MAGICCLOSE,
160}; 161};
161 162
162/* 163/*
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index 067a57cb3f82..c7b3f9df2317 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -27,10 +27,15 @@
27#include <linux/uaccess.h> 27#include <linux/uaccess.h>
28#include <asm/blackfin.h> 28#include <asm/blackfin.h>
29 29
30#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) 30#define stamp(fmt, args...) \
31 pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
31#define stampit() stamp("here i am") 32#define stampit() stamp("here i am")
32#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) 33#define pr_devinit(fmt, args...) \
33#define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); }) 34 ({ static const __devinitconst char __fmt[] = fmt; \
35 printk(__fmt, ## args); })
36#define pr_init(fmt, args...) \
37 ({ static const __initconst char __fmt[] = fmt; \
38 printk(__fmt, ## args); })
34 39
35#define WATCHDOG_NAME "bfin-wdt" 40#define WATCHDOG_NAME "bfin-wdt"
36#define PFX WATCHDOG_NAME ": " 41#define PFX WATCHDOG_NAME ": "
@@ -476,7 +481,8 @@ static int __init bfin_wdt_init(void)
476 return ret; 481 return ret;
477 } 482 }
478 483
479 bfin_wdt_device = platform_device_register_simple(WATCHDOG_NAME, -1, NULL, 0); 484 bfin_wdt_device = platform_device_register_simple(WATCHDOG_NAME,
485 -1, NULL, 0);
480 if (IS_ERR(bfin_wdt_device)) { 486 if (IS_ERR(bfin_wdt_device)) {
481 pr_init(KERN_ERR PFX "unable to register device\n"); 487 pr_init(KERN_ERR PFX "unable to register device\n");
482 platform_driver_unregister(&bfin_wdt_driver); 488 platform_driver_unregister(&bfin_wdt_driver);
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 41070e4771a0..081f2955419e 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -154,9 +154,9 @@ static struct cpwd *cpwd_device;
154 154
155static struct timer_list cpwd_timer; 155static struct timer_list cpwd_timer;
156 156
157static int wd0_timeout = 0; 157static int wd0_timeout;
158static int wd1_timeout = 0; 158static int wd1_timeout;
159static int wd2_timeout = 0; 159static int wd2_timeout;
160 160
161module_param(wd0_timeout, int, 0); 161module_param(wd0_timeout, int, 0);
162MODULE_PARM_DESC(wd0_timeout, "Default watchdog0 timeout in 1/10secs"); 162MODULE_PARM_DESC(wd0_timeout, "Default watchdog0 timeout in 1/10secs");
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index c51d0b0ea0c4..83e22e7ea4a2 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -193,7 +193,7 @@ static struct miscdevice davinci_wdt_miscdev = {
193 .fops = &davinci_wdt_fops, 193 .fops = &davinci_wdt_fops,
194}; 194};
195 195
196static int davinci_wdt_probe(struct platform_device *pdev) 196static int __devinit davinci_wdt_probe(struct platform_device *pdev)
197{ 197{
198 int ret = 0, size; 198 int ret = 0, size;
199 struct resource *res; 199 struct resource *res;
@@ -237,7 +237,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
237 return ret; 237 return ret;
238} 238}
239 239
240static int davinci_wdt_remove(struct platform_device *pdev) 240static int __devexit davinci_wdt_remove(struct platform_device *pdev)
241{ 241{
242 misc_deregister(&davinci_wdt_miscdev); 242 misc_deregister(&davinci_wdt_miscdev);
243 if (wdt_mem) { 243 if (wdt_mem) {
@@ -254,7 +254,7 @@ static struct platform_driver platform_wdt_driver = {
254 .owner = THIS_MODULE, 254 .owner = THIS_MODULE,
255 }, 255 },
256 .probe = davinci_wdt_probe, 256 .probe = davinci_wdt_probe,
257 .remove = davinci_wdt_remove, 257 .remove = __devexit_p(davinci_wdt_remove),
258}; 258};
259 259
260static int __init davinci_wdt_init(void) 260static int __init davinci_wdt_init(void)
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.
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
index d3c0f6de5523..5133bca5ccbe 100644
--- a/drivers/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
@@ -19,7 +19,7 @@
19 19
20/* Module and version information */ 20/* Module and version information */
21#define DRV_NAME "iTCO_vendor_support" 21#define DRV_NAME "iTCO_vendor_support"
22#define DRV_VERSION "1.03" 22#define DRV_VERSION "1.04"
23#define PFX DRV_NAME ": " 23#define PFX DRV_NAME ": "
24 24
25/* Includes */ 25/* Includes */
@@ -35,20 +35,23 @@
35#include "iTCO_vendor.h" 35#include "iTCO_vendor.h"
36 36
37/* iTCO defines */ 37/* iTCO defines */
38#define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */ 38#define SMI_EN (acpibase + 0x30) /* SMI Control and Enable Register */
39#define TCOBASE acpibase + 0x60 /* TCO base address */ 39#define TCOBASE (acpibase + 0x60) /* TCO base address */
40#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ 40#define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */
41 41
42/* List of vendor support modes */ 42/* List of vendor support modes */
43/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ 43/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */
44#define SUPERMICRO_OLD_BOARD 1 44#define SUPERMICRO_OLD_BOARD 1
45/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */ 45/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */
46#define SUPERMICRO_NEW_BOARD 2 46#define SUPERMICRO_NEW_BOARD 2
47/* Broken BIOS */
48#define BROKEN_BIOS 911
47 49
48static int vendorsupport; 50static int vendorsupport;
49module_param(vendorsupport, int, 0); 51module_param(vendorsupport, int, 0);
50MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=" 52MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default="
51 "0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+"); 53 "0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+, "
54 "911=Broken SMI BIOS");
52 55
53/* 56/*
54 * Vendor Specific Support 57 * Vendor Specific Support
@@ -243,25 +246,92 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat)
243} 246}
244 247
245/* 248/*
249 * Vendor Support: 911
250 * Board: Some Intel ICHx based motherboards
251 * iTCO chipset: ICH7+
252 *
253 * Some Intel motherboards have a broken BIOS implementation: i.e.
254 * the SMI handler clear's the TIMEOUT bit in the TC01_STS register
255 * and does not reload the time. Thus the TCO watchdog does not reboot
256 * the system.
257 *
258 * These are the conclusions of Andriy Gapon <avg@icyb.net.ua> after
259 * debugging: the SMI handler is quite simple - it tests value in
260 * TCO1_CNT against 0x800, i.e. checks TCO_TMR_HLT. If the bit is set
261 * the handler goes into an infinite loop, apparently to allow the
262 * second timeout and reboot. Otherwise it simply clears TIMEOUT bit
263 * in TCO1_STS and that's it.
264 * So the logic seems to be reversed, because it is hard to see how
265 * TIMEOUT can get set to 1 and SMI generated when TCO_TMR_HLT is set
266 * (other than a transitional effect).
267 *
268 * The only fix found to get the motherboard(s) to reboot is to put
269 * the glb_smi_en bit to 0. This is a dirty hack that bypasses the
270 * broken code by disabling Global SMI.
271 *
272 * WARNING: globally disabling SMI could possibly lead to dramatic
273 * problems, especially on laptops! I.e. various ACPI things where
274 * SMI is used for communication between OS and firmware.
275 *
276 * Don't use this fix if you don't need to!!!
277 */
278
279static void broken_bios_start(unsigned long acpibase)
280{
281 unsigned long val32;
282
283 val32 = inl(SMI_EN);
284 /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI#
285 Bit 0: GBL_SMI_EN -> 0 = No SMI# will be generated by ICH. */
286 val32 &= 0xffffdffe;
287 outl(val32, SMI_EN);
288}
289
290static void broken_bios_stop(unsigned long acpibase)
291{
292 unsigned long val32;
293
294 val32 = inl(SMI_EN);
295 /* Bit 13: TCO_EN -> 1 = Enables TCO logic generating an SMI#
296 Bit 0: GBL_SMI_EN -> 1 = Turn global SMI on again. */
297 val32 |= 0x00002001;
298 outl(val32, SMI_EN);
299}
300
301/*
246 * Generic Support Functions 302 * Generic Support Functions
247 */ 303 */
248 304
249void iTCO_vendor_pre_start(unsigned long acpibase, 305void iTCO_vendor_pre_start(unsigned long acpibase,
250 unsigned int heartbeat) 306 unsigned int heartbeat)
251{ 307{
252 if (vendorsupport == SUPERMICRO_OLD_BOARD) 308 switch (vendorsupport) {
309 case SUPERMICRO_OLD_BOARD:
253 supermicro_old_pre_start(acpibase); 310 supermicro_old_pre_start(acpibase);
254 else if (vendorsupport == SUPERMICRO_NEW_BOARD) 311 break;
312 case SUPERMICRO_NEW_BOARD:
255 supermicro_new_pre_start(heartbeat); 313 supermicro_new_pre_start(heartbeat);
314 break;
315 case BROKEN_BIOS:
316 broken_bios_start(acpibase);
317 break;
318 }
256} 319}
257EXPORT_SYMBOL(iTCO_vendor_pre_start); 320EXPORT_SYMBOL(iTCO_vendor_pre_start);
258 321
259void iTCO_vendor_pre_stop(unsigned long acpibase) 322void iTCO_vendor_pre_stop(unsigned long acpibase)
260{ 323{
261 if (vendorsupport == SUPERMICRO_OLD_BOARD) 324 switch (vendorsupport) {
325 case SUPERMICRO_OLD_BOARD:
262 supermicro_old_pre_stop(acpibase); 326 supermicro_old_pre_stop(acpibase);
263 else if (vendorsupport == SUPERMICRO_NEW_BOARD) 327 break;
328 case SUPERMICRO_NEW_BOARD:
264 supermicro_new_pre_stop(); 329 supermicro_new_pre_stop();
330 break;
331 case BROKEN_BIOS:
332 broken_bios_stop(acpibase);
333 break;
334 }
265} 335}
266EXPORT_SYMBOL(iTCO_vendor_pre_stop); 336EXPORT_SYMBOL(iTCO_vendor_pre_stop);
267 337
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 648250b998c4..6a51edde6ea7 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -236,19 +236,19 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
236 236
237/* Address definitions for the TCO */ 237/* Address definitions for the TCO */
238/* TCO base address */ 238/* TCO base address */
239#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 239#define TCOBASE (iTCO_wdt_private.ACPIBASE + 0x60)
240/* SMI Control and Enable Register */ 240/* SMI Control and Enable Register */
241#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 241#define SMI_EN (iTCO_wdt_private.ACPIBASE + 0x30)
242 242
243#define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */ 243#define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */
244#define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ 244#define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */
245#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ 245#define TCO_DAT_IN (TCOBASE + 0x02) /* TCO Data In Register */
246#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ 246#define TCO_DAT_OUT (TCOBASE + 0x03) /* TCO Data Out Register */
247#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ 247#define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */
248#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ 248#define TCO2_STS (TCOBASE + 0x06) /* TCO2 Status Register */
249#define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */ 249#define TCO1_CNT (TCOBASE + 0x08) /* TCO1 Control Register */
250#define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */ 250#define TCO2_CNT (TCOBASE + 0x0a) /* TCO2 Control Register */
251#define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */ 251#define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */
252 252
253/* internal variables */ 253/* internal variables */
254static unsigned long is_active; 254static unsigned long is_active;
@@ -666,6 +666,11 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
666 GCS = RCBA + ICH6_GCS(0x3410). */ 666 GCS = RCBA + ICH6_GCS(0x3410). */
667 if (iTCO_wdt_private.iTCO_version == 2) { 667 if (iTCO_wdt_private.iTCO_version == 2) {
668 pci_read_config_dword(pdev, 0xf0, &base_address); 668 pci_read_config_dword(pdev, 0xf0, &base_address);
669 if ((base_address & 1) == 0) {
670 printk(KERN_ERR PFX "RCBA is disabled by harddware\n");
671 ret = -ENODEV;
672 goto out;
673 }
669 RCBA = base_address & 0xffffc000; 674 RCBA = base_address & 0xffffc000;
670 iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4); 675 iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4);
671 } 676 }
@@ -675,7 +680,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
675 printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " 680 printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, "
676 "reboot disabled by hardware\n"); 681 "reboot disabled by hardware\n");
677 ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ 682 ret = -ENODEV; /* Cannot reset NO_REBOOT bit */
678 goto out; 683 goto out_unmap;
679 } 684 }
680 685
681 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ 686 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */
@@ -686,7 +691,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
686 printk(KERN_ERR PFX 691 printk(KERN_ERR PFX
687 "I/O address 0x%04lx already in use\n", SMI_EN); 692 "I/O address 0x%04lx already in use\n", SMI_EN);
688 ret = -EIO; 693 ret = -EIO;
689 goto out; 694 goto out_unmap;
690 } 695 }
691 /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ 696 /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
692 val32 = inl(SMI_EN); 697 val32 = inl(SMI_EN);
@@ -742,9 +747,10 @@ unreg_region:
742 release_region(TCOBASE, 0x20); 747 release_region(TCOBASE, 0x20);
743unreg_smi_en: 748unreg_smi_en:
744 release_region(SMI_EN, 4); 749 release_region(SMI_EN, 4);
745out: 750out_unmap:
746 if (iTCO_wdt_private.iTCO_version == 2) 751 if (iTCO_wdt_private.iTCO_version == 2)
747 iounmap(iTCO_wdt_private.gcs); 752 iounmap(iTCO_wdt_private.gcs);
753out:
748 pci_dev_put(iTCO_wdt_private.pdev); 754 pci_dev_put(iTCO_wdt_private.pdev);
749 iTCO_wdt_private.ACPIBASE = 0; 755 iTCO_wdt_private.ACPIBASE = 0;
750 return ret; 756 return ret;
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c
index 0f761db9a27c..bea8a124a559 100644
--- a/drivers/watchdog/indydog.c
+++ b/drivers/watchdog/indydog.c
@@ -83,7 +83,6 @@ static int indydog_open(struct inode *inode, struct file *file)
83 indydog_start(); 83 indydog_start();
84 indydog_ping(); 84 indydog_ping();
85 85
86 indydog_alive = 1;
87 printk(KERN_INFO "Started watchdog timer.\n"); 86 printk(KERN_INFO "Started watchdog timer.\n");
88 87
89 return nonseekable_open(inode, file); 88 return nonseekable_open(inode, file);
@@ -113,8 +112,7 @@ static long indydog_ioctl(struct file *file, unsigned int cmd,
113{ 112{
114 int options, retval = -EINVAL; 113 int options, retval = -EINVAL;
115 static struct watchdog_info ident = { 114 static struct watchdog_info ident = {
116 .options = WDIOF_KEEPALIVEPING | 115 .options = WDIOF_KEEPALIVEPING,
117 WDIOF_MAGICCLOSE,
118 .firmware_version = 0, 116 .firmware_version = 0,
119 .identity = "Hardware Watchdog for SGI IP22", 117 .identity = "Hardware Watchdog for SGI IP22",
120 }; 118 };
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
index 2270ee07c01b..daed48ded7fe 100644
--- a/drivers/watchdog/it8712f_wdt.c
+++ b/drivers/watchdog/it8712f_wdt.c
@@ -239,7 +239,8 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
239 static struct watchdog_info ident = { 239 static struct watchdog_info ident = {
240 .identity = "IT8712F Watchdog", 240 .identity = "IT8712F Watchdog",
241 .firmware_version = 1, 241 .firmware_version = 1,
242 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 242 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
243 WDIOF_MAGICCLOSE,
243 }; 244 };
244 int value; 245 int value;
245 246
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index ae3832110acb..00b03eb43bf0 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -293,8 +293,8 @@ static int __init ks8695_wdt_init(void)
293 if not reset to the default */ 293 if not reset to the default */
294 if (ks8695_wdt_settimeout(wdt_time)) { 294 if (ks8695_wdt_settimeout(wdt_time)) {
295 ks8695_wdt_settimeout(WDT_DEFAULT_TIME); 295 ks8695_wdt_settimeout(WDT_DEFAULT_TIME);
296 pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n", 296 pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i"
297 wdt_time, WDT_MAX_TIME); 297 ", using %d\n", wdt_time, WDT_MAX_TIME);
298 } 298 }
299 return platform_driver_register(&ks8695wdt_driver); 299 return platform_driver_register(&ks8695wdt_driver);
300} 300}
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
index 2dfc27559bf7..b6b3f59ab446 100644
--- a/drivers/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
@@ -118,7 +118,8 @@ static struct watchdog_info zf_info = {
118 */ 118 */
119static int action; 119static int action;
120module_param(action, int, 0); 120module_param(action, int, 0);
121MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI"); 121MODULE_PARM_DESC(action, "after watchdog resets, generate: "
122 "0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI");
122 123
123static void zf_ping(unsigned long data); 124static void zf_ping(unsigned long data);
124 125
@@ -142,7 +143,8 @@ static unsigned long next_heartbeat;
142#ifndef ZF_DEBUG 143#ifndef ZF_DEBUG
143# define dprintk(format, args...) 144# define dprintk(format, args...)
144#else 145#else
145# define dprintk(format, args...) printk(KERN_DEBUG PFX ":%s:%d: " format, __func__, __LINE__ , ## args) 146# define dprintk(format, args...) printk(KERN_DEBUG PFX
147 ":%s:%d: " format, __func__, __LINE__ , ## args)
146#endif 148#endif
147 149
148 150
@@ -340,7 +342,8 @@ static int zf_close(struct inode *inode, struct file *file)
340 zf_timer_off(); 342 zf_timer_off();
341 else { 343 else {
342 del_timer(&zf_timer); 344 del_timer(&zf_timer);
343 printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n"); 345 printk(KERN_ERR PFX ": device file closed unexpectedly. "
346 "Will not stop the WDT!\n");
344 } 347 }
345 clear_bit(0, &zf_is_open); 348 clear_bit(0, &zf_is_open);
346 zf_expect_close = 0; 349 zf_expect_close = 0;
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 1512ab8b175b..83fa34b214b4 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -61,7 +61,9 @@ MODULE_PARM_DESC(nowayout,
61#define ONLY_TESTING 0 61#define ONLY_TESTING 0
62static int mpcore_noboot = ONLY_TESTING; 62static int mpcore_noboot = ONLY_TESTING;
63module_param(mpcore_noboot, int, 0); 63module_param(mpcore_noboot, int, 0);
64MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, set to 1 to ignore reboots, 0 to reboot (default=" __MODULE_STRING(ONLY_TESTING) ")"); 64MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, "
65 "set to 1 to ignore reboots, 0 to reboot (default="
66 __MODULE_STRING(ONLY_TESTING) ")");
65 67
66/* 68/*
67 * This is the interrupt handler. Note that we only use this 69 * This is the interrupt handler. Note that we only use this
@@ -416,7 +418,8 @@ static struct platform_driver mpcore_wdt_driver = {
416 }, 418 },
417}; 419};
418 420
419static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. mpcore_noboot=%d mpcore_margin=%d sec (nowayout= %d)\n"; 421static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. "
422 "mpcore_noboot=%d mpcore_margin=%d sec (nowayout= %d)\n";
420 423
421static int __init mpcore_wdt_init(void) 424static int __init mpcore_wdt_init(void)
422{ 425{
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
index 539b6f6ba7f1..08e8a6ab74e1 100644
--- a/drivers/watchdog/mtx-1_wdt.c
+++ b/drivers/watchdog/mtx-1_wdt.c
@@ -206,7 +206,7 @@ static struct miscdevice mtx1_wdt_misc = {
206}; 206};
207 207
208 208
209static int mtx1_wdt_probe(struct platform_device *pdev) 209static int __devinit mtx1_wdt_probe(struct platform_device *pdev)
210{ 210{
211 int ret; 211 int ret;
212 212
@@ -229,7 +229,7 @@ static int mtx1_wdt_probe(struct platform_device *pdev)
229 return 0; 229 return 0;
230} 230}
231 231
232static int mtx1_wdt_remove(struct platform_device *pdev) 232static int __devexit mtx1_wdt_remove(struct platform_device *pdev)
233{ 233{
234 /* FIXME: do we need to lock this test ? */ 234 /* FIXME: do we need to lock this test ? */
235 if (mtx1_wdt_device.queue) { 235 if (mtx1_wdt_device.queue) {
@@ -242,7 +242,7 @@ static int mtx1_wdt_remove(struct platform_device *pdev)
242 242
243static struct platform_driver mtx1_wdt = { 243static struct platform_driver mtx1_wdt = {
244 .probe = mtx1_wdt_probe, 244 .probe = mtx1_wdt_probe,
245 .remove = mtx1_wdt_remove, 245 .remove = __devexit_p(mtx1_wdt_remove),
246 .driver.name = "mtx1-wdt", 246 .driver.name = "mtx1-wdt",
247 .driver.owner = THIS_MODULE, 247 .driver.owner = THIS_MODULE,
248}; 248};
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 64135195f827..f24d04132eda 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -246,7 +246,7 @@ static struct miscdevice pnx4008_wdt_miscdev = {
246 .fops = &pnx4008_wdt_fops, 246 .fops = &pnx4008_wdt_fops,
247}; 247};
248 248
249static int pnx4008_wdt_probe(struct platform_device *pdev) 249static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
250{ 250{
251 int ret = 0, size; 251 int ret = 0, size;
252 struct resource *res; 252 struct resource *res;
@@ -299,7 +299,7 @@ out:
299 return ret; 299 return ret;
300} 300}
301 301
302static int pnx4008_wdt_remove(struct platform_device *pdev) 302static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
303{ 303{
304 misc_deregister(&pnx4008_wdt_miscdev); 304 misc_deregister(&pnx4008_wdt_miscdev);
305 if (wdt_clk) { 305 if (wdt_clk) {
@@ -321,7 +321,7 @@ static struct platform_driver platform_wdt_driver = {
321 .owner = THIS_MODULE, 321 .owner = THIS_MODULE,
322 }, 322 },
323 .probe = pnx4008_wdt_probe, 323 .probe = pnx4008_wdt_probe,
324 .remove = pnx4008_wdt_remove, 324 .remove = __devexit_p(pnx4008_wdt_remove),
325}; 325};
326 326
327static int __init pnx4008_wdt_init(void) 327static int __init pnx4008_wdt_init(void)
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 36e221beedcd..4976bfd1fce6 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -245,7 +245,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
245 return 0; 245 return 0;
246} 246}
247 247
248static int rdc321x_wdt_remove(struct platform_device *pdev) 248static int __devexit rdc321x_wdt_remove(struct platform_device *pdev)
249{ 249{
250 if (rdc321x_wdt_device.queue) { 250 if (rdc321x_wdt_device.queue) {
251 rdc321x_wdt_device.queue = 0; 251 rdc321x_wdt_device.queue = 0;
@@ -259,7 +259,7 @@ static int rdc321x_wdt_remove(struct platform_device *pdev)
259 259
260static struct platform_driver rdc321x_wdt_driver = { 260static struct platform_driver rdc321x_wdt_driver = {
261 .probe = rdc321x_wdt_probe, 261 .probe = rdc321x_wdt_probe,
262 .remove = rdc321x_wdt_remove, 262 .remove = __devexit_p(rdc321x_wdt_remove),
263 .driver = { 263 .driver = {
264 .owner = THIS_MODULE, 264 .owner = THIS_MODULE,
265 .name = "rdc321x-wdt", 265 .name = "rdc321x-wdt",
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
index cce1982a1b58..2e4442642262 100644
--- a/drivers/watchdog/rm9k_wdt.c
+++ b/drivers/watchdog/rm9k_wdt.c
@@ -345,8 +345,8 @@ static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv,
345 return platform_get_resource_byname(pdv, type, buf); 345 return platform_get_resource_byname(pdv, type, buf);
346} 346}
347 347
348/* No hotplugging on the platform bus - use __init */ 348/* No hotplugging on the platform bus - use __devinit */
349static int __init wdt_gpi_probe(struct platform_device *pdv) 349static int __devinit wdt_gpi_probe(struct platform_device *pdv)
350{ 350{
351 int res; 351 int res;
352 const struct resource 352 const struct resource
@@ -373,7 +373,7 @@ static int __init wdt_gpi_probe(struct platform_device *pdv)
373 return res; 373 return res;
374} 374}
375 375
376static int __exit wdt_gpi_remove(struct platform_device *dev) 376static int __devexit wdt_gpi_remove(struct platform_device *dev)
377{ 377{
378 int res; 378 int res;
379 379
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index e31925ee8346..b57ac6b49147 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -68,15 +68,10 @@ MODULE_PARM_DESC(tmr_atboot,
68 __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT)); 68 __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT));
69MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 69MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
70 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 70 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
71MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)"); 71MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, "
72 "0 to reboot (default depends on ONLY_TESTING)");
72MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug, (default 0)"); 73MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug, (default 0)");
73 74
74
75typedef enum close_state {
76 CLOSE_STATE_NOT,
77 CLOSE_STATE_ALLOW = 0x4021
78} close_state_t;
79
80static unsigned long open_lock; 75static unsigned long open_lock;
81static struct device *wdt_dev; /* platform device attached to */ 76static struct device *wdt_dev; /* platform device attached to */
82static struct resource *wdt_mem; 77static struct resource *wdt_mem;
@@ -84,7 +79,7 @@ static struct resource *wdt_irq;
84static struct clk *wdt_clock; 79static struct clk *wdt_clock;
85static void __iomem *wdt_base; 80static void __iomem *wdt_base;
86static unsigned int wdt_count; 81static unsigned int wdt_count;
87static close_state_t allow_close; 82static char expect_close;
88static DEFINE_SPINLOCK(wdt_lock); 83static DEFINE_SPINLOCK(wdt_lock);
89 84
90/* watchdog control routines */ 85/* watchdog control routines */
@@ -211,7 +206,7 @@ static int s3c2410wdt_open(struct inode *inode, struct file *file)
211 if (nowayout) 206 if (nowayout)
212 __module_get(THIS_MODULE); 207 __module_get(THIS_MODULE);
213 208
214 allow_close = CLOSE_STATE_NOT; 209 expect_close = 0;
215 210
216 /* start the timer */ 211 /* start the timer */
217 s3c2410wdt_start(); 212 s3c2410wdt_start();
@@ -225,13 +220,13 @@ static int s3c2410wdt_release(struct inode *inode, struct file *file)
225 * Lock it in if it's a module and we set nowayout 220 * Lock it in if it's a module and we set nowayout
226 */ 221 */
227 222
228 if (allow_close == CLOSE_STATE_ALLOW) 223 if (expect_close == 42)
229 s3c2410wdt_stop(); 224 s3c2410wdt_stop();
230 else { 225 else {
231 dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n"); 226 dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n");
232 s3c2410wdt_keepalive(); 227 s3c2410wdt_keepalive();
233 } 228 }
234 allow_close = CLOSE_STATE_NOT; 229 expect_close = 0;
235 clear_bit(0, &open_lock); 230 clear_bit(0, &open_lock);
236 return 0; 231 return 0;
237} 232}
@@ -247,7 +242,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
247 size_t i; 242 size_t i;
248 243
249 /* In case it was set long ago */ 244 /* In case it was set long ago */
250 allow_close = CLOSE_STATE_NOT; 245 expect_close = 0;
251 246
252 for (i = 0; i != len; i++) { 247 for (i = 0; i != len; i++) {
253 char c; 248 char c;
@@ -255,7 +250,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
255 if (get_user(c, data + i)) 250 if (get_user(c, data + i))
256 return -EFAULT; 251 return -EFAULT;
257 if (c == 'V') 252 if (c == 'V')
258 allow_close = CLOSE_STATE_ALLOW; 253 expect_close = 42;
259 } 254 }
260 } 255 }
261 s3c2410wdt_keepalive(); 256 s3c2410wdt_keepalive();
@@ -263,7 +258,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
263 return len; 258 return len;
264} 259}
265 260
266#define OPTIONS WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE 261#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
267 262
268static const struct watchdog_info s3c2410_wdt_ident = { 263static const struct watchdog_info s3c2410_wdt_ident = {
269 .options = OPTIONS, 264 .options = OPTIONS,
@@ -331,7 +326,7 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param)
331} 326}
332/* device interface */ 327/* device interface */
333 328
334static int s3c2410wdt_probe(struct platform_device *pdev) 329static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
335{ 330{
336 struct resource *res; 331 struct resource *res;
337 struct device *dev; 332 struct device *dev;
@@ -404,7 +399,8 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
404 "tmr_margin value out of range, default %d used\n", 399 "tmr_margin value out of range, default %d used\n",
405 CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); 400 CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);
406 else 401 else
407 dev_info(dev, "default timer value is out of range, cannot start\n"); 402 dev_info(dev, "default timer value is out of range, "
403 "cannot start\n");
408 } 404 }
409 405
410 ret = misc_register(&s3c2410wdt_miscdev); 406 ret = misc_register(&s3c2410wdt_miscdev);
@@ -453,7 +449,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
453 return ret; 449 return ret;
454} 450}
455 451
456static int s3c2410wdt_remove(struct platform_device *dev) 452static int __devexit s3c2410wdt_remove(struct platform_device *dev)
457{ 453{
458 release_resource(wdt_mem); 454 release_resource(wdt_mem);
459 kfree(wdt_mem); 455 kfree(wdt_mem);
@@ -515,7 +511,7 @@ static int s3c2410wdt_resume(struct platform_device *dev)
515 511
516static struct platform_driver s3c2410wdt_driver = { 512static struct platform_driver s3c2410wdt_driver = {
517 .probe = s3c2410wdt_probe, 513 .probe = s3c2410wdt_probe,
518 .remove = s3c2410wdt_remove, 514 .remove = __devexit_p(s3c2410wdt_remove),
519 .shutdown = s3c2410wdt_shutdown, 515 .shutdown = s3c2410wdt_shutdown,
520 .suspend = s3c2410wdt_suspend, 516 .suspend = s3c2410wdt_suspend,
521 .resume = s3c2410wdt_resume, 517 .resume = s3c2410wdt_resume,
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
index 38f5831c9291..9748eed73196 100644
--- a/drivers/watchdog/sb_wdog.c
+++ b/drivers/watchdog/sb_wdog.c
@@ -93,7 +93,7 @@ static int expect_close;
93 93
94static const struct watchdog_info ident = { 94static const struct watchdog_info ident = {
95 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | 95 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT |
96 WDIOF_KEEPALIVEPING, 96 WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
97 .identity = "SiByte Watchdog", 97 .identity = "SiByte Watchdog",
98}; 98};
99 99
@@ -269,9 +269,10 @@ irqreturn_t sbwdog_interrupt(int irq, void *addr)
269 * if it's the second watchdog timer, it's for those users 269 * if it's the second watchdog timer, it's for those users
270 */ 270 */
271 if (wd_cfg_reg == user_dog) 271 if (wd_cfg_reg == user_dog)
272 printk(KERN_CRIT 272 printk(KERN_CRIT "%s in danger of initiating system reset "
273 "%s in danger of initiating system reset in %ld.%01ld seconds\n", 273 "in %ld.%01ld seconds\n",
274 ident.identity, wd_init / 1000000, (wd_init / 100000) % 10); 274 ident.identity,
275 wd_init / 1000000, (wd_init / 100000) % 10);
275 else 276 else
276 cfg |= 1; 277 cfg |= 1;
277 278
diff --git a/drivers/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c
index d1c390c7155c..626d0e8e56c3 100644
--- a/drivers/watchdog/sbc60xxwdt.c
+++ b/drivers/watchdog/sbc60xxwdt.c
@@ -372,8 +372,9 @@ static int __init sbc60xxwdt_init(void)
372 wdt_miscdev.minor, rc); 372 wdt_miscdev.minor, rc);
373 goto err_out_reboot; 373 goto err_out_reboot;
374 } 374 }
375 printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n", 375 printk(KERN_INFO PFX
376 timeout, nowayout); 376 "WDT driver for 60XX single board computer initialised. "
377 "timeout=%d sec (nowayout=%d)\n", timeout, nowayout);
377 378
378 return 0; 379 return 0;
379 380
diff --git a/drivers/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c
index b6e6799ec45d..68e2e2d6f73d 100644
--- a/drivers/watchdog/sbc8360.c
+++ b/drivers/watchdog/sbc8360.c
@@ -280,8 +280,8 @@ static int sbc8360_close(struct inode *inode, struct file *file)
280 if (expect_close == 42) 280 if (expect_close == 42)
281 sbc8360_stop(); 281 sbc8360_stop();
282 else 282 else
283 printk(KERN_CRIT PFX 283 printk(KERN_CRIT PFX "SBC8360 device closed unexpectedly. "
284 "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n"); 284 "SBC8360 will not stop!\n");
285 285
286 clear_bit(0, &sbc8360_is_open); 286 clear_bit(0, &sbc8360_is_open);
287 expect_close = 0; 287 expect_close = 0;
diff --git a/drivers/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c
index e467ddcf796a..28f1214457bd 100644
--- a/drivers/watchdog/sbc_epx_c3.c
+++ b/drivers/watchdog/sbc_epx_c3.c
@@ -107,8 +107,7 @@ static long epx_c3_ioctl(struct file *file, unsigned int cmd,
107 int options, retval = -EINVAL; 107 int options, retval = -EINVAL;
108 int __user *argp = (void __user *)arg; 108 int __user *argp = (void __user *)arg;
109 static const struct watchdog_info ident = { 109 static const struct watchdog_info ident = {
110 .options = WDIOF_KEEPALIVEPING | 110 .options = WDIOF_KEEPALIVEPING,
111 WDIOF_MAGICCLOSE,
112 .firmware_version = 0, 111 .firmware_version = 0,
113 .identity = "Winsystems EPX-C3 H/W Watchdog", 112 .identity = "Winsystems EPX-C3 H/W Watchdog",
114 }; 113 };
@@ -174,8 +173,8 @@ static struct notifier_block epx_c3_notifier = {
174 .notifier_call = epx_c3_notify_sys, 173 .notifier_call = epx_c3_notify_sys,
175}; 174};
176 175
177static const char banner[] __initdata = 176static const char banner[] __initdata = KERN_INFO PFX
178 KERN_INFO PFX "Hardware Watchdog Timer for Winsystems EPX-C3 SBC: 0.1\n"; 177 "Hardware Watchdog Timer for Winsystems EPX-C3 SBC: 0.1\n";
179 178
180static int __init watchdog_init(void) 179static int __init watchdog_init(void)
181{ 180{
@@ -219,6 +218,9 @@ module_init(watchdog_init);
219module_exit(watchdog_exit); 218module_exit(watchdog_exit);
220 219
221MODULE_AUTHOR("Calin A. Culianu <calin@ajvar.org>"); 220MODULE_AUTHOR("Calin A. Culianu <calin@ajvar.org>");
222MODULE_DESCRIPTION("Hardware Watchdog Device for Winsystems EPX-C3 SBC. Note that there is no way to probe for this device -- so only use it if you are *sure* you are runnning on this specific SBC system from Winsystems! It writes to IO ports 0x1ee and 0x1ef!"); 221MODULE_DESCRIPTION("Hardware Watchdog Device for Winsystems EPX-C3 SBC. "
222 "Note that there is no way to probe for this device -- "
223 "so only use it if you are *sure* you are runnning on this specific "
224 "SBC system from Winsystems! It writes to IO ports 0x1ee and 0x1ef!");
223MODULE_LICENSE("GPL"); 225MODULE_LICENSE("GPL");
224MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 226MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/scx200_wdt.c b/drivers/watchdog/scx200_wdt.c
index 9e19a10a5bb9..e67b76c0526c 100644
--- a/drivers/watchdog/scx200_wdt.c
+++ b/drivers/watchdog/scx200_wdt.c
@@ -108,7 +108,9 @@ static int scx200_wdt_open(struct inode *inode, struct file *file)
108static int scx200_wdt_release(struct inode *inode, struct file *file) 108static int scx200_wdt_release(struct inode *inode, struct file *file)
109{ 109{
110 if (expect_close != 42) 110 if (expect_close != 42)
111 printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n"); 111 printk(KERN_WARNING NAME
112 ": watchdog device closed unexpectedly, "
113 "will not disable the watchdog timer\n");
112 else if (!nowayout) 114 else if (!nowayout)
113 scx200_wdt_disable(); 115 scx200_wdt_disable();
114 expect_close = 0; 116 expect_close = 0;
@@ -163,7 +165,8 @@ static long scx200_wdt_ioctl(struct file *file, unsigned int cmd,
163 static const struct watchdog_info ident = { 165 static const struct watchdog_info ident = {
164 .identity = "NatSemi SCx200 Watchdog", 166 .identity = "NatSemi SCx200 Watchdog",
165 .firmware_version = 1, 167 .firmware_version = 1,
166 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 168 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
169 WDIOF_MAGICCLOSE,
167 }; 170 };
168 int new_margin; 171 int new_margin;
169 172
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index cdc7138be301..a03f84e5ee1f 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -494,7 +494,9 @@ MODULE_LICENSE("GPL");
494MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 494MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
495 495
496module_param(clock_division_ratio, int, 0); 496module_param(clock_division_ratio, int, 0);
497MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")"); 497MODULE_PARM_DESC(clock_division_ratio,
498 "Clock division ratio. Valid ranges are from 0x5 (1.31ms) "
499 "to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")");
498 500
499module_param(heartbeat, int, 0); 501module_param(heartbeat, int, 0);
500MODULE_PARM_DESC(heartbeat, 502MODULE_PARM_DESC(heartbeat,
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c
index ebcc9cea5e99..833f49f43d43 100644
--- a/drivers/watchdog/softdog.c
+++ b/drivers/watchdog/softdog.c
@@ -71,7 +71,9 @@ static int soft_noboot = 0;
71#endif /* ONLY_TESTING */ 71#endif /* ONLY_TESTING */
72 72
73module_param(soft_noboot, int, 0); 73module_param(soft_noboot, int, 0);
74MODULE_PARM_DESC(soft_noboot, "Softdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)"); 74MODULE_PARM_DESC(soft_noboot,
75 "Softdog action, set to 1 to ignore reboots, 0 to reboot "
76 "(default depends on ONLY_TESTING)");
75 77
76/* 78/*
77 * Our timer 79 * Our timer
@@ -264,7 +266,8 @@ static struct notifier_block softdog_notifier = {
264 .notifier_call = softdog_notify_sys, 266 .notifier_call = softdog_notify_sys,
265}; 267};
266 268
267static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.07 initialized. soft_noboot=%d soft_margin=%d sec (nowayout= %d)\n"; 269static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.07 "
270 "initialized. soft_noboot=%d soft_margin=%d sec (nowayout= %d)\n";
268 271
269static int __init watchdog_init(void) 272static int __init watchdog_init(void)
270{ 273{
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c
index a9c7f352fcbf..af08972de506 100644
--- a/drivers/watchdog/w83697hf_wdt.c
+++ b/drivers/watchdog/w83697hf_wdt.c
@@ -413,7 +413,8 @@ static int __init wdt_init(void)
413 w83697hf_init(); 413 w83697hf_init();
414 if (early_disable) { 414 if (early_disable) {
415 if (wdt_running()) 415 if (wdt_running())
416 printk(KERN_WARNING PFX "Stopping previously enabled watchdog until userland kicks in\n"); 416 printk(KERN_WARNING PFX "Stopping previously enabled "
417 "watchdog until userland kicks in\n");
417 wdt_disable(); 418 wdt_disable();
418 } 419 }
419 420
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index a38fa4907c92..a4fe7a38d9b0 100644
--- a/drivers/watchdog/wdrtas.c
+++ b/drivers/watchdog/wdrtas.c
@@ -49,12 +49,7 @@ MODULE_LICENSE("GPL");
49MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 49MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
50MODULE_ALIAS_MISCDEV(TEMP_MINOR); 50MODULE_ALIAS_MISCDEV(TEMP_MINOR);
51 51
52#ifdef CONFIG_WATCHDOG_NOWAYOUT 52static int wdrtas_nowayout = WATCHDOG_NOWAYOUT;
53static int wdrtas_nowayout = 1;
54#else
55static int wdrtas_nowayout = 0;
56#endif
57
58static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); 53static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0);
59static char wdrtas_expect_close; 54static char wdrtas_expect_close;
60 55