Commit 9e3e4b1d authored by Linus Torvalds's avatar Linus Torvalds

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: Add NMI sourcing
  [WATCHDOG] iTCO_wdt: Fix ICH7+ reboot issue.
  [WATCHDOG] iTCO_wdt: fix memory corruption when RCBA is disabled by hardware
  [WATCHDOG] Correct WDIOF_MAGICCLOSE flag
  [WATCHDOG] move platform probe and remove function to devinit and devexit
  [WATCHDOG] Some more general cleanup
  [WATCHDOG] iTCO_wdt: Cleanup code
parents dcce284a 47bece87
Last reviewed: 06/02/2009
HP iLO2 NMI Watchdog Driver
NMI sourcing for iLO2 based ProLiant Servers
Documentation and Driver by
Thomas Mingarelli <thomas.mingarelli@hp.com>
The HP iLO2 NMI Watchdog driver is a kernel module that provides basic
watchdog functionality and the added benefit of NMI sourcing. Both the
watchdog functionality and the NMI sourcing capability need to be enabled
by the user. Remember that the two modes are not dependant on one another.
A user can have the NMI sourcing without the watchdog timer and vice-versa.
Watchdog functionality is enabled like any other common watchdog driver. That
is, an application needs to be started that kicks off the watchdog timer. A
basic application exists in the Documentation/watchdog/src directory called
watchdog-test.c. Simply compile the C file and kick it off. If the system
gets into a bad state and hangs, the HP ProLiant iLO 2 timer register will
not be updated in a timely fashion and a hardware system reset (also known as
an Automatic Server Recovery (ASR)) event will occur.
The hpwdt driver also has three (3) module parameters. They are the following:
soft_margin - allows the user to set the watchdog timer value
allow_kdump - allows the user to save off a kernel dump image after an NMI
nowayout - basic watchdog parameter that does not allow the timer to
be restarted or an impending ASR to be escaped.
NOTE: More information about watchdog drivers in general, including the ioctl
interface to /dev/watchdog can be found in
Documentation/watchdog/watchdog-api.txt and Documentation/IPMI.txt.
The NMI sourcing capability is disabled when the driver discovers that the
nmi_watchdog is turned on (nmi_watchdog = 1). This is due to the inability to
distinguish between "NMI Watchdog Ticks" and "HW generated NMI events" in the
Linux kernel. What this means is that the hpwdt nmi handler code is called
each time the NMI signal fires off. This could amount to several thousands of
NMIs in a matter of seconds. If a user sees the Linux kernel's "dazed and
confused" message in the logs or if the system gets into a hung state, then
the user should reboot with nmi_watchdog=0.
1. If the kernel has not been booted with nmi_watchdog turned off then
edit /boot/grub/menu.lst and place the nmi_watchdog=0 at the end of the
currently booting kernel line.
2. reboot the sever
Now, the hpwdt can successfully receive and source the NMI and provide a log
message that details the reason for the NMI (as determined by the HP BIOS).
Below is a list of NMIs the HP BIOS understands along with the associated
code (reason):
No source found 00h
Uncorrectable Memory Error 01h
ASR NMI 1Bh
PCI Parity Error 20h
NMI Button Press 27h
SB_BUS_NMI 28h
ILO Doorbell NMI 29h
ILO IOP NMI 2Ah
ILO Watchdog NMI 2Bh
Proc Throt NMI 2Ch
Front Side Bus NMI 2Dh
PCI Express Error 2Fh
DMA controller NMI 30h
Hypertransport/CSI Error 31h
-- Tom Mingarelli
(thomas.mingarelli@hp.com)
...@@ -322,7 +322,8 @@ static int wdt_notify_sys(struct notifier_block *this, ...@@ -322,7 +322,8 @@ static int wdt_notify_sys(struct notifier_block *this,
* watchdog on reboot with no heartbeat * watchdog on reboot with no heartbeat
*/ */
wdt_change(WDT_ENABLE); wdt_change(WDT_ENABLE);
printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); printk(KERN_INFO PFX "Watchdog timer is now enabled "
"with no heartbeat - should reboot in ~1 second.\n");
} }
return NOTIFY_DONE; return NOTIFY_DONE;
} }
...@@ -374,12 +375,17 @@ static int __init alim7101_wdt_init(void) ...@@ -374,12 +375,17 @@ static int __init alim7101_wdt_init(void)
pci_dev_put(ali1543_south); pci_dev_put(ali1543_south);
if ((tmp & 0x1e) == 0x00) { if ((tmp & 0x1e) == 0x00) {
if (!use_gpio) { if (!use_gpio) {
printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); printk(KERN_INFO PFX
"Detected old alim7101 revision 'a1d'. "
"If this is a cobalt board, set the 'use_gpio' "
"module parameter.\n");
goto err_out; goto err_out;
} }
nowayout = 1; nowayout = 1;
} else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) {
printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); printk(KERN_INFO PFX
"ALi 1543 South-Bridge does not have the correct "
"revision number (???1001?) - WDT not set\n");
goto err_out; goto err_out;
} }
...@@ -409,7 +415,8 @@ static int __init alim7101_wdt_init(void) ...@@ -409,7 +415,8 @@ static int __init alim7101_wdt_init(void)
if (nowayout) if (nowayout)
__module_get(THIS_MODULE); __module_get(THIS_MODULE);
printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. "
"timeout=%d sec (nowayout=%d)\n",
timeout, nowayout); timeout, nowayout);
return 0; return 0;
......
...@@ -246,7 +246,8 @@ static long ar7_wdt_ioctl(struct file *file, ...@@ -246,7 +246,8 @@ static long ar7_wdt_ioctl(struct file *file,
static struct watchdog_info ident = { static struct watchdog_info ident = {
.identity = LONGNAME, .identity = LONGNAME,
.firmware_version = 1, .firmware_version = 1,
.options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING), .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE),
}; };
int new_margin; int new_margin;
......
...@@ -268,7 +268,8 @@ static int __init at91_wdt_init(void) ...@@ -268,7 +268,8 @@ static int __init at91_wdt_init(void)
if not reset to the default */ if not reset to the default */
if (at91_wdt_settimeout(wdt_time)) { if (at91_wdt_settimeout(wdt_time)) {
at91_wdt_settimeout(WDT_DEFAULT_TIME); at91_wdt_settimeout(WDT_DEFAULT_TIME);
pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256"
", using %d\n", wdt_time);
} }
return platform_driver_register(&at91wdt_driver); return platform_driver_register(&at91wdt_driver);
......
...@@ -156,7 +156,8 @@ static int at91_wdt_settimeout(unsigned int timeout) ...@@ -156,7 +156,8 @@ static int at91_wdt_settimeout(unsigned int timeout)
static const struct watchdog_info at91_wdt_info = { static const struct watchdog_info at91_wdt_info = {
.identity = DRV_NAME, .identity = DRV_NAME,
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
}; };
/* /*
......
...@@ -27,10 +27,15 @@ ...@@ -27,10 +27,15 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/blackfin.h> #include <asm/blackfin.h>
#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) #define stamp(fmt, args...) \
pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
#define stampit() stamp("here i am") #define stampit() stamp("here i am")
#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) #define pr_devinit(fmt, args...) \
#define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); }) ({ static const __devinitconst char __fmt[] = fmt; \
printk(__fmt, ## args); })
#define pr_init(fmt, args...) \
({ static const __initconst char __fmt[] = fmt; \
printk(__fmt, ## args); })
#define WATCHDOG_NAME "bfin-wdt" #define WATCHDOG_NAME "bfin-wdt"
#define PFX WATCHDOG_NAME ": " #define PFX WATCHDOG_NAME ": "
...@@ -476,7 +481,8 @@ static int __init bfin_wdt_init(void) ...@@ -476,7 +481,8 @@ static int __init bfin_wdt_init(void)
return ret; return ret;
} }
bfin_wdt_device = platform_device_register_simple(WATCHDOG_NAME, -1, NULL, 0); bfin_wdt_device = platform_device_register_simple(WATCHDOG_NAME,
-1, NULL, 0);
if (IS_ERR(bfin_wdt_device)) { if (IS_ERR(bfin_wdt_device)) {
pr_init(KERN_ERR PFX "unable to register device\n"); pr_init(KERN_ERR PFX "unable to register device\n");
platform_driver_unregister(&bfin_wdt_driver); platform_driver_unregister(&bfin_wdt_driver);
......
...@@ -154,9 +154,9 @@ static struct cpwd *cpwd_device; ...@@ -154,9 +154,9 @@ static struct cpwd *cpwd_device;
static struct timer_list cpwd_timer; static struct timer_list cpwd_timer;
static int wd0_timeout = 0; static int wd0_timeout;
static int wd1_timeout = 0; static int wd1_timeout;
static int wd2_timeout = 0; static int wd2_timeout;
module_param(wd0_timeout, int, 0); module_param(wd0_timeout, int, 0);
MODULE_PARM_DESC(wd0_timeout, "Default watchdog0 timeout in 1/10secs"); MODULE_PARM_DESC(wd0_timeout, "Default watchdog0 timeout in 1/10secs");
......
...@@ -193,7 +193,7 @@ static struct miscdevice davinci_wdt_miscdev = { ...@@ -193,7 +193,7 @@ static struct miscdevice davinci_wdt_miscdev = {
.fops = &davinci_wdt_fops, .fops = &davinci_wdt_fops,
}; };
static int davinci_wdt_probe(struct platform_device *pdev) static int __devinit davinci_wdt_probe(struct platform_device *pdev)
{ {
int ret = 0, size; int ret = 0, size;
struct resource *res; struct resource *res;
...@@ -237,7 +237,7 @@ static int davinci_wdt_probe(struct platform_device *pdev) ...@@ -237,7 +237,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
return ret; return ret;
} }
static int davinci_wdt_remove(struct platform_device *pdev) static int __devexit davinci_wdt_remove(struct platform_device *pdev)
{ {
misc_deregister(&davinci_wdt_miscdev); misc_deregister(&davinci_wdt_miscdev);
if (wdt_mem) { if (wdt_mem) {
...@@ -254,7 +254,7 @@ static struct platform_driver platform_wdt_driver = { ...@@ -254,7 +254,7 @@ static struct platform_driver platform_wdt_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = davinci_wdt_probe, .probe = davinci_wdt_probe,
.remove = davinci_wdt_remove, .remove = __devexit_p(davinci_wdt_remove),
}; };
static int __init davinci_wdt_init(void) static int __init davinci_wdt_init(void)
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/nmi.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/mm.h> #include <linux/mm.h>
...@@ -47,7 +48,7 @@ ...@@ -47,7 +48,7 @@
#define PCI_BIOS32_PARAGRAPH_LEN 16 #define PCI_BIOS32_PARAGRAPH_LEN 16
#define PCI_ROM_BASE1 0x000F0000 #define PCI_ROM_BASE1 0x000F0000
#define ROM_SIZE 0x10000 #define ROM_SIZE 0x10000
#define HPWDT_VERSION "1.01" #define HPWDT_VERSION "1.1.1"
struct bios32_service_dir { struct bios32_service_dir {
u32 signature; u32 signature;
...@@ -119,6 +120,7 @@ static int nowayout = WATCHDOG_NOWAYOUT; ...@@ -119,6 +120,7 @@ static int nowayout = WATCHDOG_NOWAYOUT;
static char expect_release; static char expect_release;
static unsigned long hpwdt_is_open; static unsigned long hpwdt_is_open;
static unsigned int allow_kdump; static unsigned int allow_kdump;
static int hpwdt_nmi_sourcing;
static void __iomem *pci_mem_addr; /* the PCI-memory address */ static void __iomem *pci_mem_addr; /* the PCI-memory address */
static unsigned long __iomem *hpwdt_timer_reg; static unsigned long __iomem *hpwdt_timer_reg;
...@@ -468,21 +470,22 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason, ...@@ -468,21 +470,22 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI) if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI)
return NOTIFY_OK; return NOTIFY_OK;
spin_lock_irqsave(&rom_lock, rom_pl); if (hpwdt_nmi_sourcing) {
if (!die_nmi_called) spin_lock_irqsave(&rom_lock, rom_pl);
asminline_call(&cmn_regs, cru_rom_addr); if (!die_nmi_called)
die_nmi_called = 1; asminline_call(&cmn_regs, cru_rom_addr);
spin_unlock_irqrestore(&rom_lock, rom_pl); die_nmi_called = 1;
if (cmn_regs.u1.ral == 0) { spin_unlock_irqrestore(&rom_lock, rom_pl);
printk(KERN_WARNING "hpwdt: An NMI occurred, " if (cmn_regs.u1.ral == 0) {
"but unable to determine source.\n"); printk(KERN_WARNING "hpwdt: An NMI occurred, "
} else { "but unable to determine source.\n");
if (allow_kdump) } else {
hpwdt_stop(); if (allow_kdump)
panic("An NMI occurred, please see the Integrated " hpwdt_stop();
"Management Log for details.\n"); panic("An NMI occurred, please see the Integrated "
"Management Log for details.\n");
}
} }
return NOTIFY_OK; return NOTIFY_OK;
} }
...@@ -627,11 +630,37 @@ static struct notifier_block die_notifier = { ...@@ -627,11 +630,37 @@ static struct notifier_block die_notifier = {
* Init & Exit * Init & Exit
*/ */
#ifdef ARCH_HAS_NMI_WATCHDOG
static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
{
/*
* If nmi_watchdog is turned off then we can turn on
* our nmi sourcing capability.
*/
if (!nmi_watchdog_active())
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");
}
#else
static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
{
dev_warn(&dev->dev, "NMI sourcing is disabled. "
"Your kernel does not support a NMI Watchdog.\n");
}
#endif
static int __devinit hpwdt_init_one(struct pci_dev *dev, static int __devinit hpwdt_init_one(struct pci_dev *dev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
int retval; int retval;
/*
* Check if we can do NMI sourcing or not
*/
hpwdt_check_nmi_sourcing(dev);
/* /*
* First let's find out if we are on an iLO2 server. We will * First let's find out if we are on an iLO2 server. We will
* not run on a legacy ASM box. * not run on a legacy ASM box.
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
/* Module and version information */ /* Module and version information */
#define DRV_NAME "iTCO_vendor_support" #define DRV_NAME "iTCO_vendor_support"
#define DRV_VERSION "1.03" #define DRV_VERSION "1.04"
#define PFX DRV_NAME ": " #define PFX DRV_NAME ": "
/* Includes */ /* Includes */
...@@ -35,20 +35,23 @@ ...@@ -35,20 +35,23 @@
#include "iTCO_vendor.h" #include "iTCO_vendor.h"
/* iTCO defines */ /* iTCO defines */
#define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */ #define SMI_EN (acpibase + 0x30) /* SMI Control and Enable Register */
#define TCOBASE acpibase + 0x60 /* TCO base address */ #define TCOBASE (acpibase + 0x60) /* TCO base address */
#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ #define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */
/* List of vendor support modes */ /* List of vendor support modes */
/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */
#define SUPERMICRO_OLD_BOARD 1 #define SUPERMICRO_OLD_BOARD 1
/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */ /* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */
#define SUPERMICRO_NEW_BOARD 2 #define SUPERMICRO_NEW_BOARD 2
/* Broken BIOS */
#define BROKEN_BIOS 911
static int vendorsupport; static int vendorsupport;
module_param(vendorsupport, int, 0); module_param(vendorsupport, int, 0);
MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=" MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default="
"0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+"); "0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+, "
"911=Broken SMI BIOS");
/* /*
* Vendor Specific Support * Vendor Specific Support
...@@ -242,6 +245,59 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat) ...@@ -242,6 +245,59 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat)
supermicro_new_lock_watchdog(); supermicro_new_lock_watchdog();
} }
/*
* Vendor Support: 911
* Board: Some Intel ICHx based motherboards
* iTCO chipset: ICH7+
*
* Some Intel motherboards have a broken BIOS implementation: i.e.
* the SMI handler clear's the TIMEOUT bit in the TC01_STS register
* and does not reload the time. Thus the TCO watchdog does not reboot
* the system.
*
* These are the conclusions of Andriy Gapon <avg@icyb.net.ua> after
* debugging: the SMI handler is quite simple - it tests value in
* TCO1_CNT against 0x800, i.e. checks TCO_TMR_HLT. If the bit is set
* the handler goes into an infinite loop, apparently to allow the
* second timeout and reboot. Otherwise it simply clears TIMEOUT bit
* in TCO1_STS and that's it.
* So the logic seems to be reversed, because it is hard to see how
* TIMEOUT can get set to 1 and SMI generated when TCO_TMR_HLT is set
* (other than a transitional effect).
*
* The only fix found to get the motherboard(s) to reboot is to put
* the glb_smi_en bit to 0. This is a dirty hack that bypasses the
* broken code by disabling Global SMI.
*
* WARNING: globally disabling SMI could possibly lead to dramatic
* problems, especially on laptops! I.e. various ACPI things where
* SMI is used for communication between OS and firmware.
*
* Don't use this fix if you don't need to!!!
*/
static void broken_bios_start(unsigned long acpibase)
{
unsigned long val32;
val32 = inl(SMI_EN);
/* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI#
Bit 0: GBL_SMI_EN -> 0 = No SMI# will be generated by ICH. */
val32 &= 0xffffdffe;
outl(val32, SMI_EN);
}
static void broken_bios_stop(unsigned long acpibase)
{
unsigned long val32;
val32 = inl(SMI_EN);
/* Bit 13: TCO_EN -> 1 = Enables TCO logic generating an SMI#
Bit 0: GBL_SMI_EN -> 1 = Turn global SMI on again. */
val32 |= 0x00002001;
outl(val32, SMI_EN);
}
/* /*
* Generic Support Functions * Generic Support Functions
*/ */
...@@ -249,19 +305,33 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat) ...@@ -249,19 +305,33 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat)
void iTCO_vendor_pre_start(unsigned long acpibase, void iTCO_vendor_pre_start(unsigned long acpibase,
unsigned int heartbeat) unsigned int heartbeat)
{ {
if (vendorsupport == SUPERMICRO_OLD_BOARD) switch (vendorsupport) {
case SUPERMICRO_OLD_BOARD:
supermicro_old_pre_start(acpibase); supermicro_old_pre_start(acpibase);
else if (vendorsupport == SUPERMICRO_NEW_BOARD) break;
case SUPERMICRO_NEW_BOARD:
supermicro_new_pre_start(heartbeat); supermicro_new_pre_start(heartbeat);
break;
case BROKEN_BIOS:
broken_bios_start(acpibase);
break;
}
} }
EXPORT_SYMBOL(iTCO_vendor_pre_start); EXPORT_SYMBOL(iTCO_vendor_pre_start);
void iTCO_vendor_pre_stop(unsigned long acpibase) void iTCO_vendor_pre_stop(unsigned long acpibase)
{ {
if (vendorsupport == SUPERMICRO_OLD_BOARD) switch (vendorsupport) {
case SUPERMICRO_OLD_BOARD:
supermicro_old_pre_stop(acpibase); supermicro_old_pre_stop(acpibase);
else if (vendorsupport == SUPERMICRO_NEW_BOARD) break;
case SUPERMICRO_NEW_BOARD:
supermicro_new_pre_stop(); supermicro_new_pre_stop();
break;
case BROKEN_BIOS:
broken_bios_stop(acpibase);
break;
}
} }
EXPORT_SYMBOL(iTCO_vendor_pre_stop); EXPORT_SYMBOL(iTCO_vendor_pre_stop);
......
...@@ -236,19 +236,19 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); ...@@ -236,19 +236,19 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
/* Address definitions for the TCO */ /* Address definitions for the TCO */
/* TCO base address */ /* TCO base address */
#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 #define TCOBASE (iTCO_wdt_private.ACPIBASE + 0x60)
/* SMI Control and Enable Register */ /* SMI Control and Enable Register */
#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 #define SMI_EN (iTCO_wdt_private.ACPIBASE + 0x30)
#define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */ #define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */
#define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ #define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */
#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ #define TCO_DAT_IN (TCOBASE + 0x02) /* TCO Data In Register */
#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ #define TCO_DAT_OUT (TCOBASE + 0x03) /* TCO Data Out Register */
#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ #define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */
#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ #define TCO2_STS (TCOBASE + 0x06) /* TCO2 Status Register */
#define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */ #define TCO1_CNT (TCOBASE + 0x08) /* TCO1 Control Register */
#define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */ #define TCO2_CNT (TCOBASE + 0x0a) /* TCO2 Control Register */
#define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */ #define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */
/* internal variables */ /* internal variables */
static unsigned long is_active; static unsigned long is_active;
...@@ -666,6 +666,11 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, ...@@ -666,6 +666,11 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
GCS = RCBA + ICH6_GCS(0x3410). */ GCS = RCBA + ICH6_GCS(0x3410). */
if (iTCO_wdt_private.iTCO_version == 2) { if (iTCO_wdt_private.iTCO_version == 2) {
pci_read_config_dword(pdev, 0xf0, &base_address); pci_read_config_dword(pdev, 0xf0, &base_address);
if ((base_address & 1) == 0) {
printk(KERN_ERR PFX "RCBA is disabled by harddware\n");
ret = -ENODEV;
goto out;
}
RCBA = base_address & 0xffffc000; RCBA = base_address & 0xffffc000;
iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4); iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4);
} }
...@@ -675,7 +680,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, ...@@ -675,7 +680,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, "
"reboot disabled by hardware\n"); "reboot disabled by hardware\n");
ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ ret = -ENODEV; /* Cannot reset NO_REBOOT bit */
goto out; goto out_unmap;
} }
/* Set the NO_REBOOT bit to prevent later reboots, just for sure */ /* 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,7 +691,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
printk(KERN_ERR PFX printk(KERN_ERR PFX
"I/O address 0x%04lx already in use\n", SMI_EN); "I/O address 0x%04lx already in use\n", SMI_EN);
ret = -EIO; ret = -EIO;
goto out; goto out_unmap;
} }
/* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
val32 = inl(SMI_EN); val32 = inl(SMI_EN);
...@@ -742,9 +747,10 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, ...@@ -742,9 +747,10 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
release_region(TCOBASE, 0x20); release_region(TCOBASE, 0x20);
unreg_smi_en: unreg_smi_en:
release_region(SMI_EN, 4); release_region(SMI_EN, 4);
out: out_unmap:
if (iTCO_wdt_private.iTCO_version == 2) if (iTCO_wdt_private.iTCO_version == 2)
iounmap(iTCO_wdt_private.gcs); iounmap(iTCO_wdt_private.gcs);
out:
pci_dev_put(iTCO_wdt_private.pdev); pci_dev_put(iTCO_wdt_private.pdev);
iTCO_wdt_private.ACPIBASE = 0; iTCO_wdt_private.ACPIBASE = 0;
return ret; return ret;
......
...@@ -83,7 +83,6 @@ static int indydog_open(struct inode *inode, struct file *file) ...@@ -83,7 +83,6 @@ static int indydog_open(struct inode *inode, struct file *file)
indydog_start(); indydog_start();
indydog_ping(); indydog_ping();
indydog_alive = 1;
printk(KERN_INFO "Started watchdog timer.\n"); printk(KERN_INFO "Started watchdog timer.\n");
return nonseekable_open(inode, file); return nonseekable_open(inode, file);
...@@ -113,8 +112,7 @@ static long indydog_ioctl(struct file *file, unsigned int cmd, ...@@ -113,8 +112,7 @@ static long indydog_ioctl(struct file *file, unsigned int cmd,
{ {
int options, retval = -EINVAL; int options, retval = -EINVAL;
static struct watchdog_info ident = { static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | .options = WDIOF_KEEPALIVEPING,
WDIOF_MAGICCLOSE,
.firmware_version = 0, .firmware_version = 0,
.identity = "Hardware Watchdog for SGI IP22", .identity = "Hardware Watchdog for SGI IP22",
}; };
......
...@@ -239,7 +239,8 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd, ...@@ -239,7 +239,8 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
static struct watchdog_info ident = { static struct watchdog_info ident = {
.identity = "IT8712F Watchdog", .identity = "IT8712F Watchdog",
.firmware_version = 1, .firmware_version = 1,
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
}; };
int value; int value;
......
...@@ -293,8 +293,8 @@ static int __init ks8695_wdt_init(void) ...@@ -293,8 +293,8 @@ static int __init ks8695_wdt_init(void)
if not reset to the default */ if not reset to the default */
if (ks8695_wdt_settimeout(wdt_time)) { if (ks8695_wdt_settimeout(wdt_time)) {
ks8695_wdt_settimeout(WDT_DEFAULT_TIME); ks8695_wdt_settimeout(WDT_DEFAULT_TIME);
pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n", pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i"
wdt_time, WDT_MAX_TIME); ", using %d\n", wdt_time, WDT_MAX_TIME);
} }
return platform_driver_register(&ks8695wdt_driver); return platform_driver_register(&ks8695wdt_driver);
} }
......
...@@ -118,7 +118,8 @@ static struct watchdog_info zf_info = { ...@@ -118,7 +118,8 @@ static struct watchdog_info zf_info = {
*/ */
static int action; static int action;
module_param(action, int, 0); module_param(action, int, 0);
MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI"); MODULE_PARM_DESC(action, "after watchdog resets, generate: "
"0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI");
static void zf_ping(unsigned long data); static void zf_ping(unsigned long data);
...@@ -142,7 +143,8 @@ static unsigned long next_heartbeat; ...@@ -142,7 +143,8 @@ static unsigned long next_heartbeat;
#ifndef ZF_DEBUG #ifndef ZF_DEBUG
# define dprintk(format, args...) # define dprintk(format, args...)
#else #else
# define dprintk(format, args...) printk(KERN_DEBUG PFX ":%s:%d: " format, __func__, __LINE__ , ## args) # define dprintk(format, args...) printk(KERN_DEBUG PFX
":%s:%d: " format, __func__, __LINE__ , ## args)
#endif #endif
...@@ -340,7 +342,8 @@ static int zf_close(struct inode *inode, struct file *file) ...@@ -340,7 +342,8 @@ static int zf_close(struct inode *inode, struct file *file)
zf_timer_off(); zf_timer_off();
else { else {
del_timer(&zf_timer); del_timer(&zf_timer);
printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n"); printk(KERN_ERR PFX ": device file closed unexpectedly. "
"Will not stop the WDT!\n");
} }
clear_bit(0, &zf_is_open); clear_bit(0, &zf_is_open);
zf_expect_close = 0; zf_expect_close = 0;
......
...@@ -61,7 +61,9 @@ MODULE_PARM_DESC(nowayout, ...@@ -61,7 +61,9 @@ MODULE_PARM_DESC(nowayout,
#define ONLY_TESTING 0 #define ONLY_TESTING 0
static int mpcore_noboot = ONLY_TESTING; static int mpcore_noboot = ONLY_TESTING;
module_param(mpcore_noboot, int, 0); module_param(mpcore_noboot, int, 0);
MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, set to 1 to ignore reboots, 0 to reboot (default=" __MODULE_STRING(ONLY_TESTING) ")"); MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, "
"set to 1 to ignore reboots, 0 to reboot (default="
__MODULE_STRING(ONLY_TESTING) ")");
/* /*
* This is the interrupt handler. Note that we only use this * This is the interrupt handler. Note that we only use this
...@@ -416,7 +418,8 @@ static struct platform_driver mpcore_wdt_driver = { ...@@ -416,7 +418,8 @@ static struct platform_driver mpcore_wdt_driver = {
}, },
}; };
static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. mpcore_noboot=%d mpcore_margin=%d sec (nowayout= %d)\n"; static char banner[] __initdata = KERN_INFO "MPcore Watchdog Timer: 0.1. "
"mpcore_noboot=%d mpcore_margin=%d sec (nowayout= %d)\n";
static int __init mpcore_wdt_init(void) static int __init mpcore_wdt_init(void)
{ {
......
...@@ -206,7 +206,7 @@ static struct miscdevice mtx1_wdt_misc = { ...@@ -206,7 +206,7 @@ static struct miscdevice mtx1_wdt_misc = {
}; };
static int mtx1_wdt_probe(struct platform_device *pdev) static int __devinit mtx1_wdt_probe(struct platform_device *pdev)
{ {
int ret; int ret;
...@@ -229,7 +229,7 @@ static int mtx1_wdt_probe(struct platform_device *pdev) ...@@ -229,7 +229,7 @@ static int mtx1_wdt_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int mtx1_wdt_remove(struct platform_device *pdev) static int __devexit mtx1_wdt_remove(struct platform_device *pdev)
{ {
/* FIXME: do we need to lock this test ? */ /* FIXME: do we need to lock this test ? */
if (mtx1_wdt_device.queue) { if (mtx1_wdt_device.queue) {
...@@ -242,7 +242,7 @@ static int mtx1_wdt_remove(struct platform_device *pdev) ...@@ -242,7 +242,7 @@ static int mtx1_wdt_remove(struct platform_device *pdev)
static struct platform_driver mtx1_wdt = { static struct platform_driver mtx1_wdt = {
.probe = mtx1_wdt_probe, .probe = mtx1_wdt_probe,
.remove = mtx1_wdt_remove, .remove = __devexit_p(mtx1_wdt_remove),
.driver.name = "mtx1-wdt", .driver.name = "mtx1-wdt",
.driver.owner = THIS_MODULE, .driver.owner = THIS_MODULE,
}; };
......
...@@ -246,7 +246,7 @@ static struct miscdevice pnx4008_wdt_miscdev = { ...@@ -246,7 +246,7 @@ static struct miscdevice pnx4008_wdt_miscdev = {
.fops = &pnx4008_wdt_fops, .fops = &pnx4008_wdt_fops,
}; };
static int pnx4008_wdt_probe(struct platform_device *pdev) static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
{ {
int ret = 0, size; int ret = 0, size;
struct resource *res; struct resource *res;
...@@ -299,7 +299,7 @@ static int pnx4008_wdt_probe(struct platform_device *pdev) ...@@ -299,7 +299,7 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
return ret; return ret;
} }
static int pnx4008_wdt_remove(struct platform_device *pdev) static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
{ {
misc_deregister(&pnx4008_wdt_miscdev); misc_deregister(&pnx4008_wdt_miscdev);
if (wdt_clk) { if (wdt_clk) {
...@@ -321,7 +321,7 @@ static struct platform_driver platform_wdt_driver = { ...@@ -321,7 +321,7 @@ static struct platform_driver platform_wdt_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = pnx4008_wdt_probe, .probe = pnx4008_wdt_probe,
.remove = pnx4008_wdt_remove, .remove = __devexit_p(pnx4008_wdt_remove),
}; };
static int __init pnx4008_wdt_init(void) static int __init pnx4008_wdt_init(void)
......
...@@ -245,7 +245,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) ...@@ -245,7 +245,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int rdc321x_wdt_remove(struct platform_device *pdev) static int __devexit rdc321x_wdt_remove(struct platform_device *pdev)
{ {
if (rdc321x_wdt_device.queue) { if (rdc321x_wdt_device.queue) {
rdc321x_wdt_device.queue = 0; rdc321x_wdt_device.queue = 0;
...@@ -259,7 +259,7 @@ static int rdc321x_wdt_remove(struct platform_device *pdev) ...@@ -259,7 +259,7 @@ static int rdc321x_wdt_remove(struct platform_device *pdev)
static struct platform_driver rdc321x_wdt_driver = { static struct platform_driver rdc321x_wdt_driver = {
.probe = rdc321x_wdt_probe, .probe = rdc321x_wdt_probe,
.remove = rdc321x_wdt_remove, .remove = __devexit_p(rdc321x_wdt_remove),
.driver = { .driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "rdc321x-wdt", .name = "rdc321x-wdt",
......
...@@ -345,8 +345,8 @@ static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv, ...@@ -345,8 +345,8 @@ static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv,
return platform_get_resource_byname(pdv, type, buf); return platform_get_resource_byname(pdv, type, buf);
} }
/* No hotplugging on the platform bus - use __init */ /* No hotplugging on the platform bus - use __devinit */
static int __init wdt_gpi_probe(struct platform_device *pdv) static int __devinit wdt_gpi_probe(struct platform_device *pdv)
{ {
int res; int res;
const struct resource const struct resource
...@@ -373,7 +373,7 @@ static int __init wdt_gpi_probe(struct platform_device *pdv) ...@@ -373,7 +373,7 @@ static int __init wdt_gpi_probe(struct platform_device *pdv)
return res; return res;
} }
static int __exit wdt_gpi_remove(struct platform_device *dev) static int __devexit wdt_gpi_remove(struct platform_device *dev)
{ {
int res; int res;
......
...@@ -68,15 +68,10 @@ MODULE_PARM_DESC(tmr_atboot, ...@@ -68,15 +68,10 @@ MODULE_PARM_DESC(tmr_atboot,
__MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT)); __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT));
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)"); MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, "
"0 to reboot (default depends on ONLY_TESTING)");
MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug, (default 0)"); MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug, (default 0)");
typedef enum close_state {
CLOSE_STATE_NOT,
CLOSE_STATE_ALLOW = 0x4021
} close_state_t;
static unsigned long open_lock; static unsigned long open_lock;
static struct device *wdt_dev; /* platform device attached to */ static struct device *wdt_dev; /* platform device attached to */
static struct resource *wdt_mem; static struct resource *wdt_mem;
...@@ -84,7 +79,7 @@ static struct resource *wdt_irq; ...@@ -84,7 +79,7 @@ static struct resource *wdt_irq;
static struct clk *wdt_clock; static struct clk *wdt_clock;
static void __iomem *wdt_base; static void __iomem *wdt_base;
static unsigned int wdt_count; static unsigned int wdt_count;
static close_state_t allow_close; static char expect_close;
static DEFINE_SPINLOCK(wdt_lock); static DEFINE_SPINLOCK(wdt_lock);
/* watchdog control routines */ /* watchdog control routines */
...@@ -211,7 +206,7 @@ static int s3c2410wdt_open(struct inode *inode, struct file *file) ...@@ -211,7 +206,7 @@ static int s3c2410wdt_open(struct inode *inode, struct file *file)
if (nowayout) if (nowayout)
__module_get(THIS_MODULE); __module_get(THIS_MODULE);
allow_close = CLOSE_STATE_NOT; expect_close = 0;
/* start the timer */ /* start the timer */
s3c2410wdt_start(); s3c2410wdt_start();
...@@ -225,13 +220,13 @@ static int s3c2410wdt_release(struct inode *inode, struct file *file) ...@@ -225,13 +220,13 @@ static int s3c2410wdt_release(struct inode *inode, struct file *file)
* Lock it in if it's a module and we set nowayout * Lock it in if it's a module and we set nowayout
*/ */
if (allow_close == CLOSE_STATE_ALLOW) if (expect_close == 42)
s3c2410wdt_stop(); s3c2410wdt_stop();
else { else {
dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n"); dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n");
s3c2410wdt_keepalive(); s3c2410wdt_keepalive();
} }
allow_close = CLOSE_STATE_NOT; expect_close = 0;
clear_bit(0, &open_lock); clear_bit(0, &open_lock);
return 0; return 0;
} }
...@@ -247,7 +242,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data, ...@@ -247,7 +242,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
size_t i; size_t i;
/* In case it was set long ago */ /* In case it was set long ago */
allow_close = CLOSE_STATE_NOT; expect_close = 0;
for (i = 0; i != len; i++) { for (i = 0; i != len; i++) {
char c; char c;
...@@ -255,7 +250,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data, ...@@ -255,7 +250,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
if (get_user(c, data + i)) if (get_user(c, data + i))
return -EFAULT; return -EFAULT;
if (c == 'V') if (c == 'V')
allow_close = CLOSE_STATE_ALLOW; expect_close = 42;
} }
} }
s3c2410wdt_keepalive(); s3c2410wdt_keepalive();
...@@ -263,7 +258,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data, ...@@ -263,7 +258,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
return len; return len;
} }
#define OPTIONS WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE #define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
static const struct watchdog_info s3c2410_wdt_ident = { static const struct watchdog_info s3c2410_wdt_ident = {
.options = OPTIONS, .options = OPTIONS,
...@@ -331,7 +326,7 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param) ...@@ -331,7 +326,7 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param)
} }
/* device interface */ /* device interface */
static int s3c2410wdt_probe(struct platform_device *pdev) static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
{ {
struct resource *res; struct resource *res;
struct device *dev; struct device *dev;
...@@ -404,7 +399,8 @@ static int s3c2410wdt_probe(struct platform_device *pdev) ...@@ -404,7 +399,8 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
"tmr_margin value out of range, default %d used\n", "tmr_margin value out of range, default %d used\n",
CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);
else else
dev_info(dev, "default timer value is out of range, cannot start\n"); dev_info(dev, "default timer value is out of range, "
"cannot start\n");
} }
ret = misc_register(&s3c2410wdt_miscdev); ret = misc_register(&s3c2410wdt_miscdev);
...@@ -453,7 +449,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev) ...@@ -453,7 +449,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
return ret; return ret;
} }
static int s3c2410wdt_remove(struct platform_device *dev) static int __devexit s3c2410wdt_remove(struct platform_device *dev)
{ {
release_resource(wdt_mem); release_resource(wdt_mem);
kfree(wdt_mem); kfree(wdt_mem);
...@@ -515,7 +511,7 @@ static int s3c2410wdt_resume(struct platform_device *dev) ...@@ -515,7 +511,7 @@ static int s3c2410wdt_resume(struct platform_device *dev)
static struct platform_driver s3c2410wdt_driver = { static struct platform_driver s3c2410wdt_driver = {
.probe = s3c2410wdt_probe, .probe = s3c2410wdt_probe,
.remove = s3c2410wdt_remove, .remove = __devexit_p(s3c2410wdt_remove),
.shutdown = s3c2410wdt_shutdown, .shutdown = s3c2410wdt_shutdown,
.suspend = s3c2410wdt_suspend, .suspend = s3c2410wdt_suspend,
.resume = s3c2410wdt_resume, .resume = s3c2410wdt_resume,
......
...@@ -93,7 +93,7 @@ static int expect_close; ...@@ -93,7 +93,7 @@ static int expect_close;
static const struct watchdog_info ident = { static const struct watchdog_info ident = {
.options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING, WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.identity = "SiByte Watchdog", .identity = "SiByte Watchdog",
}; };
...@@ -269,9 +269,10 @@ irqreturn_t sbwdog_interrupt(int irq, void *addr) ...@@ -269,9 +269,10 @@ irqreturn_t sbwdog_interrupt(int irq, void *addr)
* if it's the second watchdog timer, it's for those users * if it's the second watchdog timer, it's for those users
*/ */
if (wd_cfg_reg == user_dog) if (wd_cfg_reg == user_dog)
printk(KERN_CRIT printk(KERN_CRIT "%s in danger of initiating system reset "
"%s in danger of initiating system reset in %ld.%01ld seconds\n", "in %ld.%01ld seconds\n",
ident.identity, wd_init / 1000000, (wd_init / 100000) % 10); ident.identity,
wd_init / 1000000, (wd_init / 100000) % 10);
else else
cfg |= 1; cfg |= 1;
......
...@@ -372,8 +372,9 @@ static int __init sbc60xxwdt_init(void) ...@@ -372,8 +372,9 @@ static int __init sbc60xxwdt_init(void)
wdt_miscdev.minor, rc); wdt_miscdev.minor, rc);
goto err_out_reboot; goto err_out_reboot;
} }
printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n", printk(KERN_INFO PFX
timeout, nowayout); "WDT driver for 60XX single board computer initialised. "
"timeout=%d sec (nowayout=%d)\n", timeout, nowayout);
return 0; return 0;
......
...@@ -280,8 +280,8 @@ static int sbc8360_close(struct inode *inode, struct file *file) ...@@ -280,8 +280,8 @@ static int sbc8360_close(struct inode *inode, struct file *file)
if (expect_close == 42) if (expect_close == 42)
sbc8360_stop(); sbc8360_stop();
else else
printk(KERN_CRIT PFX printk(KERN_CRIT PFX "SBC8360 device closed unexpectedly. "
"SBC8360 device closed unexpectedly. SBC8360 will not stop!\n"); "SBC8360 will not stop!\n");
clear_bit(0, &sbc8360_is_open); clear_bit(0, &sbc8360_is_open);
expect_close = 0; expect_close = 0;
......
...@@ -107,8 +107,7 @@ static long epx_c3_ioctl(struct file *file, unsigned int cmd, ...@@ -107,8 +107,7 @@ static long epx_c3_ioctl(struct file *file, unsigned int cmd,
int options, retval = -EINVAL; int options, retval = -EINVAL;
int __user *argp = (void __user *)arg; int __user *argp = (void __user *)arg;
static const struct watchdog_info ident = { static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | .options = WDIOF_KEEPALIVEPING,
WDIOF_MAGICCLOSE,
.firmware_version = 0, .firmware_version = 0,
.identity = "Winsystems EPX-C3 H/W Watchdog", .identity = "Winsystems EPX-C3 H/W Watchdog",
}; };
...@@ -174,8 +173,8 @@ static struct notifier_block epx_c3_notifier = { ...@@ -174,8 +173,8 @@ static struct notifier_block epx_c3_notifier = {
.notifier_call = epx_c3_notify_sys, .notifier_call = epx_c3_notify_sys,
}; };
static const char banner[] __initdata = static const char banner[] __initdata = KERN_INFO PFX
KERN_INFO PFX "Hardware Watchdog Timer for Winsystems EPX-C3 SBC: 0.1\n"; "Hardware Watchdog Timer for Winsystems EPX-C3 SBC: 0.1\n";
static int __init watchdog_init(void) static int __init watchdog_init(void)
{ {
...@@ -219,6 +218,9 @@ module_init(watchdog_init); ...@@ -219,6 +218,9 @@ module_init(watchdog_init);
module_exit(watchdog_exit); module_exit(watchdog_exit);
MODULE_AUTHOR("Calin A. Culianu <calin@ajvar.org>"); MODULE_AUTHOR("Calin A. Culianu <calin@ajvar.org>");
MODULE_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!"); MODULE_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!");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
...@@ -108,7 +108,9 @@ static int scx200_wdt_open(struct inode *inode, struct file *file) ...@@ -108,7 +108,9 @@ static int scx200_wdt_open(struct inode *inode, struct file *file)
static int scx200_wdt_release(struct inode *inode, struct file *file) static int scx200_wdt_release(struct inode *inode, struct file *file)
{ {
if (expect_close != 42) if (expect_close != 42)
printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n"); printk(KERN_WARNING NAME
": watchdog device closed unexpectedly, "
"will not disable the watchdog timer\n");
else if (!nowayout) else if (!nowayout)
scx200_wdt_disable(); scx200_wdt_disable();
expect_close = 0; expect_close = 0;
...@@ -163,7 +165,8 @@ static long scx200_wdt_ioctl(struct file *file, unsigned int cmd, ...@@ -163,7 +165,8 @@ static long scx200_wdt_ioctl(struct file *file, unsigned int cmd,
static const struct watchdog_info ident = { static const struct watchdog_info ident = {
.identity = "NatSemi SCx200 Watchdog", .identity = "NatSemi SCx200 Watchdog",
.firmware_version = 1, .firmware_version = 1,
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
}; };
int new_margin; int new_margin;
......
...@@ -494,7 +494,9 @@ MODULE_LICENSE("GPL"); ...@@ -494,7 +494,9 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
module_param(clock_division_ratio, int, 0); module_param(clock_division_ratio, int, 0);
MODULE_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) ")"); MODULE_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) ")");
module_param(heartbeat, int, 0); module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat, MODULE_PARM_DESC(heartbeat,
......
...@@ -71,7 +71,9 @@ static int soft_noboot = 0; ...@@ -71,7 +71,9 @@ static int soft_noboot = 0;
#endif /* ONLY_TESTING */ #endif /* ONLY_TESTING */
module_param(soft_noboot, int, 0); module_param(soft_noboot, int, 0);
MODULE_PARM_DESC(soft_noboot, "Softdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)"); MODULE_PARM_DESC(soft_noboot,
"Softdog action, set to 1 to ignore reboots, 0 to reboot "
"(default depends on ONLY_TESTING)");
/* /*
* Our timer * Our timer
...@@ -264,7 +266,8 @@ static struct notifier_block softdog_notifier = { ...@@ -264,7 +266,8 @@ static struct notifier_block softdog_notifier = {
.notifier_call = softdog_notify_sys, .notifier_call = softdog_notify_sys,
}; };
static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.07 initialized. soft_noboot=%d soft_margin=%d sec (nowayout= %d)\n"; static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.07 "
"initialized. soft_noboot=%d soft_margin=%d sec (nowayout= %d)\n";
static int __init watchdog_init(void) static int __init watchdog_init(void)
{ {
......
...@@ -413,7 +413,8 @@ static int __init wdt_init(void) ...@@ -413,7 +413,8 @@ static int __init wdt_init(void)
w83697hf_init(); w83697hf_init();
if (early_disable) { if (early_disable) {
if (wdt_running()) if (wdt_running())
printk(KERN_WARNING PFX "Stopping previously enabled watchdog until userland kicks in\n"); printk(KERN_WARNING PFX "Stopping previously enabled "
"watchdog until userland kicks in\n");
wdt_disable(); wdt_disable();
} }
......
...@@ -49,12 +49,7 @@ MODULE_LICENSE("GPL"); ...@@ -49,12 +49,7 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
MODULE_ALIAS_MISCDEV(TEMP_MINOR); MODULE_ALIAS_MISCDEV(TEMP_MINOR);
#ifdef CONFIG_WATCHDOG_NOWAYOUT static int wdrtas_nowayout = WATCHDOG_NOWAYOUT;
static int wdrtas_nowayout = 1;
#else
static int wdrtas_nowayout = 0;
#endif
static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0);
static char wdrtas_expect_close; static char wdrtas_expect_close;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment