Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
bdc91033
Commit
bdc91033
authored
Jan 09, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linux-dj.bkbits.net/watchdog
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
9cb52295
59409421
Changes
23
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
2293 additions
and
438 deletions
+2293
-438
drivers/char/watchdog/Kconfig
drivers/char/watchdog/Kconfig
+20
-0
drivers/char/watchdog/Makefile
drivers/char/watchdog/Makefile
+5
-0
drivers/char/watchdog/acquirewdt.c
drivers/char/watchdog/acquirewdt.c
+52
-44
drivers/char/watchdog/advantechwdt.c
drivers/char/watchdog/advantechwdt.c
+45
-35
drivers/char/watchdog/alim7101_wdt.c
drivers/char/watchdog/alim7101_wdt.c
+345
-0
drivers/char/watchdog/eurotechwdt.c
drivers/char/watchdog/eurotechwdt.c
+264
-252
drivers/char/watchdog/i810-tco.c
drivers/char/watchdog/i810-tco.c
+3
-1
drivers/char/watchdog/ib700wdt.c
drivers/char/watchdog/ib700wdt.c
+44
-30
drivers/char/watchdog/indydog.c
drivers/char/watchdog/indydog.c
+182
-0
drivers/char/watchdog/machzwd.c
drivers/char/watchdog/machzwd.c
+9
-8
drivers/char/watchdog/mixcomwd.c
drivers/char/watchdog/mixcomwd.c
+23
-4
drivers/char/watchdog/pcwd.c
drivers/char/watchdog/pcwd.c
+73
-38
drivers/char/watchdog/sbc60xxwdt.c
drivers/char/watchdog/sbc60xxwdt.c
+3
-3
drivers/char/watchdog/sc1200wdt.c
drivers/char/watchdog/sc1200wdt.c
+479
-0
drivers/char/watchdog/sc520_wdt.c
drivers/char/watchdog/sc520_wdt.c
+394
-0
drivers/char/watchdog/shwdt.c
drivers/char/watchdog/shwdt.c
+9
-9
drivers/char/watchdog/softdog.c
drivers/char/watchdog/softdog.c
+20
-1
drivers/char/watchdog/w83877f_wdt.c
drivers/char/watchdog/w83877f_wdt.c
+3
-3
drivers/char/watchdog/wafer5823wdt.c
drivers/char/watchdog/wafer5823wdt.c
+262
-0
drivers/char/watchdog/wdt.c
drivers/char/watchdog/wdt.c
+24
-7
drivers/char/watchdog/wdt977.c
drivers/char/watchdog/wdt977.c
+18
-0
drivers/char/watchdog/wdt_pci.c
drivers/char/watchdog/wdt_pci.c
+15
-3
include/linux/watchdog.h
include/linux/watchdog.h
+1
-0
No files found.
drivers/char/watchdog/Kconfig
View file @
bdc91033
...
...
@@ -283,4 +283,24 @@ config MACHZ_WDT
The module is called machzwd.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
config W83877F_WDT
tristate "W83877F Computer Watchdog"
depends on WATCHDOG
config SC520_WDT
tristate "AMD Elan SC520 processor Watchdog"
depends on WATCHDOG
config ALIM7101_WDT
tristate "ALi M7101 PMU Computer Watchdog"
depends on WATCHDOG
config SC1200_WDT
tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
depends on WATCHDOG
config WAFER_WDT
tristate "ICP Wafer 5823 Single Board Computer Watchdog"
depends on WATCHDOG
endmenu
drivers/char/watchdog/Makefile
View file @
bdc91033
...
...
@@ -23,3 +23,8 @@ obj-$(CONFIG_MACHZ_WDT) += machzwd.o
obj-$(CONFIG_SH_WDT)
+=
shwdt.o
obj-$(CONFIG_EUROTECH_WDT)
+=
eurotechwdt.o
obj-$(CONFIG_SOFT_WATCHDOG)
+=
softdog.o
obj-$(CONFIG_W83877F_WDT)
+=
w83877f_wdt.o
obj-$(CONFIG_SC520_WDT)
+=
sc520_wdt.o
obj-$(CONFIG_ALIM7101_WDT)
+=
alim7101_wdt.o
obj-$(CONFIG_SC1200_WDT)
+=
sc1200wdt.o
obj-$(CONFIG_WAFER_WDT)
+=
wafer5823wdt.o
drivers/char/watchdog/acquirewdt.c
View file @
bdc91033
...
...
@@ -45,6 +45,7 @@
static
int
acq_is_open
;
static
spinlock_t
acq_lock
;
static
int
expect_close
=
0
;
/*
* You must set these - there is no sane way to probe for this board.
...
...
@@ -79,8 +80,20 @@ static ssize_t acq_write(struct file *file, const char *buf, size_t count, loff_
if
(
ppos
!=
&
file
->
f_pos
)
return
-
ESPIPE
;
if
(
count
)
{
if
(
count
)
{
if
(
!
nowayout
)
{
size_t
i
;
expect_close
=
0
;
for
(
i
=
0
;
i
!=
count
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
buf
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
1
;
}
}
acq_ping
();
return
1
;
}
...
...
@@ -97,9 +110,11 @@ static ssize_t acq_read(struct file *file, char *buf, size_t count, loff_t *ppos
static
int
acq_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
static
struct
watchdog_info
ident
=
static
struct
watchdog_info
ident
=
{
WDIOF_KEEPALIVEPING
,
1
,
"Acquire WDT"
.
options
=
WDIOF_KEEPALIVEPING
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"Acquire WDT"
};
switch
(
cmd
)
...
...
@@ -126,39 +141,35 @@ static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static
int
acq_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
switch
(
minor
(
inode
->
i_rdev
))
{
case
WATCHDOG_MINOR
:
if
((
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
))
{
spin_lock
(
&
acq_lock
);
if
(
acq_is_open
)
{
if
(
acq_is_open
)
{
spin_unlock
(
&
acq_lock
);
return
-
EBUSY
;
}
if
(
nowayout
)
{
if
(
nowayout
)
MOD_INC_USE_COUNT
;
}
/*
* Activate
*/
/* Activate */
acq_is_open
=
1
;
inb_p
(
WDT_START
);
spin_unlock
(
&
acq_lock
);
return
0
;
default:
}
else
{
return
-
ENODEV
;
}
}
static
int
acq_close
(
struct
inode
*
inode
,
struct
file
*
file
)
{
if
(
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
if
(
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
spin_lock
(
&
acq_lock
);
if
(
!
nowayout
)
{
if
(
expect_close
)
inb_p
(
WDT_STOP
);
}
else
printk
(
KERN_CRIT
"WDT closed unexpectedly. WDT will not stop!
\n
"
);
acq_is_open
=
0
;
spin_unlock
(
&
acq_lock
);
}
...
...
@@ -173,10 +184,9 @@ static int acq_notify_sys(struct notifier_block *this, unsigned long code,
void
*
unused
)
{
if
(
code
==
SYS_DOWN
||
code
==
SYS_HALT
)
{
/* Turn the card off */
inb_p
(
WDT_STOP
);
}
return
NOTIFY_DONE
;
}
...
...
@@ -196,9 +206,9 @@ static struct file_operations acq_fops = {
static
struct
miscdevice
acq_miscdev
=
{
WATCHDOG_MINOR
,
"watchdog"
,
&
acq_fops
.
minor
=
WATCHDOG_MINOR
,
.
name
=
"watchdog"
,
.
fops
=
&
acq_fops
};
...
...
@@ -207,11 +217,11 @@ static struct miscdevice acq_miscdev=
* turn the timebomb registers off.
*/
static
struct
notifier_block
acq_notifier
=
static
struct
notifier_block
acq_notifier
=
{
acq_notify_sys
,
NULL
,
0
.
notifier_call
=
acq_notify_sys
,
.
next
=
NULL
,
.
priority
=
0
};
static
int
__init
acq_init
(
void
)
...
...
@@ -221,13 +231,11 @@ static int __init acq_init(void)
spin_lock_init
(
&
acq_lock
);
if
(
misc_register
(
&
acq_miscdev
))
return
-
ENODEV
;
if
(
!
request_region
(
WDT_STOP
,
1
,
"Acquire WDT"
))
{
if
(
!
request_region
(
WDT_STOP
,
1
,
"Acquire WDT"
))
{
misc_deregister
(
&
acq_miscdev
);
return
-
EIO
;
}
if
(
!
request_region
(
WDT_START
,
1
,
"Acquire WDT"
))
{
if
(
!
request_region
(
WDT_START
,
1
,
"Acquire WDT"
))
{
release_region
(
WDT_STOP
,
1
);
misc_deregister
(
&
acq_miscdev
);
return
-
EIO
;
...
...
drivers/char/watchdog/advantechwdt.c
View file @
bdc91033
...
...
@@ -47,6 +47,7 @@
#include <linux/smp_lock.h>
static
int
advwdt_is_open
;
static
char
adv_expect_close
;
static
spinlock_t
advwdt_lock
;
/*
...
...
@@ -99,10 +100,22 @@ advwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
return
-
ESPIPE
;
if
(
count
)
{
if
(
!
nowayout
)
{
size_t
i
;
adv_expect_close
=
0
;
for
(
i
=
0
;
i
!=
count
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
buf
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
adv_expect_close
=
42
;
}
}
advwdt_ping
();
return
1
;
}
return
0
;
return
count
;
}
static
ssize_t
...
...
@@ -116,7 +129,9 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned
long
arg
)
{
static
struct
watchdog_info
ident
=
{
WDIOF_KEEPALIVEPING
,
1
,
"Advantech WDT"
.
options
=
WDIOF_KEEPALIVEPING
|
WDIOF_SETTIMEOUT
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"Advantech WDT"
};
switch
(
cmd
)
{
...
...
@@ -143,25 +158,22 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static
int
advwdt_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
switch
(
minor
(
inode
->
i_rdev
))
{
case
WATCHDOG_MINOR
:
if
(
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
spin_lock
(
&
advwdt_lock
);
if
(
advwdt_is_open
)
{
spin_unlock
(
&
advwdt_lock
);
return
-
EBUSY
;
}
if
(
nowayout
)
{
if
(
nowayout
)
MOD_INC_USE_COUNT
;
}
/*
* Activate
*/
/* Activate */
advwdt_is_open
=
1
;
advwdt_ping
();
spin_unlock
(
&
advwdt_lock
);
return
0
;
default:
}
else
{
return
-
ENODEV
;
}
}
...
...
@@ -171,9 +183,9 @@ advwdt_close(struct inode *inode, struct file *file)
{
if
(
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
spin_lock
(
&
advwdt_lock
);
if
(
!
nowayout
)
{
if
(
!
nowayout
)
inb_p
(
WDT_STOP
);
}
advwdt_is_open
=
0
;
spin_unlock
(
&
advwdt_lock
);
}
...
...
@@ -188,10 +200,10 @@ static int
advwdt_notify_sys
(
struct
notifier_block
*
this
,
unsigned
long
code
,
void
*
unused
)
{
if
(
code
==
SYS_DOWN
||
code
==
SYS_HALT
)
{
if
(
code
==
SYS_DOWN
||
code
==
SYS_HALT
)
/* Turn the WDT off */
inb_p
(
WDT_STOP
);
}
return
NOTIFY_DONE
;
}
...
...
@@ -209,9 +221,9 @@ static struct file_operations advwdt_fops = {
};
static
struct
miscdevice
advwdt_miscdev
=
{
WATCHDOG_MINOR
,
"watchdog"
,
&
advwdt_fops
.
minor
=
WATCHDOG_MINOR
,
.
name
=
"watchdog"
,
.
fops
=
&
advwdt_fops
};
/*
...
...
@@ -220,9 +232,9 @@ static struct miscdevice advwdt_miscdev = {
*/
static
struct
notifier_block
advwdt_notifier
=
{
advwdt_notify_sys
,
NULL
,
0
.
notifier_call
=
advwdt_notify_sys
,
.
next
=
NULL
,
.
priority
=
0
};
static
void
__init
...
...
@@ -276,5 +288,3 @@ module_exit(advwdt_exit);
MODULE_LICENSE
(
"GPL"
);
/* end of advantechwdt.c */
drivers/char/watchdog/alim7101_wdt.c
0 → 100644
View file @
bdc91033
/*
* ALi M7101 PMU Computer Watchdog Timer driver for Linux 2.4.x
*
* Based on w83877f_wdt.c by Scott Jennings <management@oro.net>
* and the Cobalt kernel WDT timer driver by Tim Hockin
* <thockin@cobaltnet.com>
*
* (c)2002 Steve Hill <steve@navaho.co.uk>
*
* Theory of operation:
* A Watchdog Timer (WDT) is a hardware circuit that can
* reset the computer system in case of a software fault.
* You probably knew that already.
*
* Usually a userspace daemon will notify the kernel WDT driver
* via the /proc/watchdog special device file that userspace is
* still alive, at regular intervals. When such a notification
* occurs, the driver will usually tell the hardware watchdog
* that everything is in order, and that the watchdog should wait
* for yet another little while to reset the system.
* If userspace fails (RAM error, kernel bug, whatever), the
* notifications cease to occur, and the hardware watchdog will
* reset the system (causing a reboot) after the timeout occurs.
*
* This WDT driver is different from most other Linux WDT
* drivers in that the driver will ping the watchdog by itself,
* because this particular WDT has a very short timeout (1.6
* seconds) and it would be insane to count on any userspace
* daemon always getting scheduled within that time frame.
*/
#include <linux/module.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/pci.h>
#define OUR_NAME "alim7101_wdt"
#define WDT_ENABLE 0x9C
#define WDT_DISABLE 0x8C
#define ALI_7101_WDT 0x92
#define ALI_WDT_ARM 0x01
/*
* We're going to use a 1 second timeout.
* If we reset the watchdog every ~250ms we should be safe. */
#define WDT_INTERVAL (HZ/4+1)
/*
* We must not require too good response from the userspace daemon.
* Here we require the userspace daemon to send us a heartbeat
* char to /dev/watchdog every 30 seconds.
*/
#define WDT_HEARTBEAT (HZ * 30)
static
void
wdt_timer_ping
(
unsigned
long
);
static
struct
timer_list
timer
;
static
unsigned
long
next_heartbeat
;
static
unsigned
long
wdt_is_open
;
static
int
wdt_expect_close
;
static
struct
pci_dev
*
alim7101_pmu
;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static
int
nowayout
=
1
;
#else
static
int
nowayout
=
0
;
#endif
MODULE_PARM
(
nowayout
,
"i"
);
MODULE_PARM_DESC
(
nowayout
,
"Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"
);
/*
* Whack the dog
*/
static
void
wdt_timer_ping
(
unsigned
long
data
)
{
/* If we got a heartbeat pulse within the WDT_US_INTERVAL
* we agree to ping the WDT
*/
char
tmp
;
if
(
time_before
(
jiffies
,
next_heartbeat
))
{
/* Ping the WDT (this is actually a disarm/arm sequence) */
pci_read_config_byte
(
alim7101_pmu
,
0x92
,
&
tmp
);
pci_write_config_byte
(
alim7101_pmu
,
ALI_7101_WDT
,
(
tmp
&
~
ALI_WDT_ARM
));
pci_write_config_byte
(
alim7101_pmu
,
ALI_7101_WDT
,
(
tmp
|
ALI_WDT_ARM
));
}
else
{
printk
(
OUR_NAME
": Heartbeat lost! Will not ping the watchdog
\n
"
);
}
/* Re-set the timer interval */
timer
.
expires
=
jiffies
+
WDT_INTERVAL
;
add_timer
(
&
timer
);
}
/*
* Utility routines
*/
static
void
wdt_change
(
int
writeval
)
{
char
tmp
;
pci_read_config_byte
(
alim7101_pmu
,
0x92
,
&
tmp
);
if
(
writeval
==
WDT_ENABLE
)
pci_write_config_byte
(
alim7101_pmu
,
ALI_7101_WDT
,
(
tmp
|
ALI_WDT_ARM
));
else
pci_write_config_byte
(
alim7101_pmu
,
ALI_7101_WDT
,
(
tmp
&
~
ALI_WDT_ARM
));
}
static
void
wdt_startup
(
void
)
{
next_heartbeat
=
jiffies
+
WDT_HEARTBEAT
;
/* We must enable before we kick off the timer in case the timer
occurs as we ping it */
wdt_change
(
WDT_ENABLE
);
/* Start the timer */
timer
.
expires
=
jiffies
+
WDT_INTERVAL
;
add_timer
(
&
timer
);
printk
(
OUR_NAME
": Watchdog timer is now enabled.
\n
"
);
}
static
void
wdt_turnoff
(
void
)
{
/* Stop the timer */
del_timer_sync
(
&
timer
);
wdt_change
(
WDT_DISABLE
);
printk
(
OUR_NAME
": Watchdog timer is now disabled...
\n
"
);
}
/*
* /dev/watchdog handling
*/
static
ssize_t
fop_write
(
struct
file
*
file
,
const
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
/* We can't seek */
if
(
ppos
!=
&
file
->
f_pos
)
return
-
ESPIPE
;
/* See if we got the magic character */
if
(
count
)
{
if
(
!
nowayout
)
{
size_t
ofs
;
/* note: just in case someone wrote the magic character
* five months ago... */
wdt_expect_close
=
0
;
/* now scan */
for
(
ofs
=
0
;
ofs
!=
count
;
ofs
++
)
{
char
c
;
if
(
get_user
(
c
,
buf
+
ofs
))
return
-
EFAULT
;
if
(
c
==
'V'
)
wdt_expect_close
=
1
;
}
}
/* someone wrote to us, we should restart timer */
next_heartbeat
=
jiffies
+
WDT_HEARTBEAT
;
return
1
;
};
return
0
;
}
static
ssize_t
fop_read
(
struct
file
*
file
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
/* No can do */
return
-
EINVAL
;
}
static
int
fop_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
/* Just in case we're already talking to someone... */
if
(
test_and_set_bit
(
0
,
&
wdt_is_open
))
return
-
EBUSY
;
/* Good, fire up the show */
wdt_startup
();
return
0
;
}
static
int
fop_close
(
struct
inode
*
inode
,
struct
file
*
file
)
{
if
(
wdt_expect_close
)
wdt_turnoff
();
else
printk
(
OUR_NAME
": device file closed unexpectedly. Will not stop the WDT!
\n
"
);
clear_bit
(
0
,
&
wdt_is_open
);
return
0
;
}
static
int
fop_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"ALiM7101"
};
switch
(
cmd
)
{
case
WDIOC_GETSUPPORT
:
return
copy_to_user
((
struct
watchdog_info
*
)
arg
,
&
ident
,
sizeof
(
ident
))
?-
EFAULT
:
0
;
case
WDIOC_KEEPALIVE
:
next_heartbeat
=
jiffies
+
WDT_HEARTBEAT
;
return
0
;
default:
return
-
ENOTTY
;
}
}
static
struct
file_operations
wdt_fops
=
{
.
owner
=
THIS_MODULE
,
.
llseek
=
no_llseek
,
.
read
=
fop_read
,
.
write
=
fop_write
,
.
open
=
fop_open
,
.
release
=
fop_close
,
.
ioctl
=
fop_ioctl
};
static
struct
miscdevice
wdt_miscdev
=
{
.
minor
=
WATCHDOG_MINOR
,
.
name
=
"watchdog"
,
.
fops
=&
wdt_fops
};
/*
* Notifier for system down
*/
static
int
wdt_notify_sys
(
struct
notifier_block
*
this
,
unsigned
long
code
,
void
*
unused
)
{
if
(
code
==
SYS_DOWN
||
code
==
SYS_HALT
)
wdt_turnoff
();
if
(
code
==
SYS_RESTART
)
{
/*
* Cobalt devices have no way of rebooting themselves other than
* getting the watchdog to pull reset, so we restart the watchdog on
* reboot with no heartbeat
*/
wdt_change
(
WDT_ENABLE
);
printk
(
OUR_NAME
": Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.
\n
"
);
}
return
NOTIFY_DONE
;
}
/*
* The WDT needs to learn about soft shutdowns in order to
* turn the timebomb registers off.
*/
static
struct
notifier_block
wdt_notifier
=
{
.
notifier_call
=
wdt_notify_sys
,
.
next
=
0
,
.
priority
=
0
};
static
void
__exit
alim7101_wdt_unload
(
void
)
{
wdt_turnoff
();
/* Deregister */
misc_deregister
(
&
wdt_miscdev
);
unregister_reboot_notifier
(
&
wdt_notifier
);
}
static
int
__init
alim7101_wdt_init
(
void
)
{
int
rc
=
-
EBUSY
;
struct
pci_dev
*
ali1543_south
;
char
tmp
;
printk
(
KERN_INFO
OUR_NAME
": Steve Hill <steve@navaho.co.uk>.
\n
"
);
alim7101_pmu
=
pci_find_device
(
PCI_VENDOR_ID_AL
,
PCI_DEVICE_ID_AL_M7101
,
NULL
);
if
(
!
alim7101_pmu
)
{
printk
(
KERN_INFO
OUR_NAME
": ALi M7101 PMU not present - WDT not set
\n
"
);
return
-
EBUSY
;
}
/* Set the WDT in the PMU to 1 second */
pci_write_config_byte
(
alim7101_pmu
,
ALI_7101_WDT
,
0x02
);
ali1543_south
=
pci_find_device
(
PCI_VENDOR_ID_AL
,
PCI_DEVICE_ID_AL_M1533
,
NULL
);
if
(
!
ali1543_south
)
{
printk
(
KERN_INFO
OUR_NAME
": ALi 1543 South-Bridge not present - WDT not set
\n
"
);
return
-
EBUSY
;
}
pci_read_config_byte
(
ali1543_south
,
0x5e
,
&
tmp
);
if
((
tmp
&
0x1e
)
!=
0x12
)
{
printk
(
KERN_INFO
OUR_NAME
": ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set
\n
"
);
return
-
EBUSY
;
}
init_timer
(
&
timer
);
timer
.
function
=
wdt_timer_ping
;
timer
.
data
=
1
;
rc
=
misc_register
(
&
wdt_miscdev
);
if
(
rc
)
return
rc
;
rc
=
register_reboot_notifier
(
&
wdt_notifier
);
if
(
rc
)
{
misc_deregister
(
&
wdt_miscdev
);
return
rc
;
}
printk
(
KERN_INFO
OUR_NAME
": WDT driver for ALi M7101 initialised.
\n
"
);
return
0
;
}
module_init
(
alim7101_wdt_init
);
module_exit
(
alim7101_wdt_unload
);
MODULE_AUTHOR
(
"Steve Hill"
);
MODULE_LICENSE
(
"GPL"
);
drivers/char/watchdog/eurotechwdt.c
View file @
bdc91033
...
...
@@ -19,7 +19,7 @@
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.
*
*
(c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>*
*
(c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*
* 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
* Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
...
...
@@ -49,6 +49,7 @@
static
int
eurwdt_is_open
;
static
spinlock_t
eurwdt_lock
;
static
char
eur_expect_close
;
/*
* You must set these - there is no sane way to probe for this board.
...
...
@@ -80,10 +81,10 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
#define WDT_CTRL_REG 0x30
#define WDT_OUTPIN_CFG 0xe2
#define WDT_EVENT_INT
0x00
#define WDT_EVENT_REBOOT
0x08
#define WDT_EVENT_INT
0x00
#define WDT_EVENT_REBOOT
0x08
#define WDT_UNIT_SEL 0xf1
#define WDT_UNIT_SECS
0x80
#define WDT_UNIT_SECS
0x80
#define WDT_TIMEOUT_VAL 0xf2
#define WDT_TIMER_CFG 0xf3
...
...
@@ -103,7 +104,7 @@ static int __init eurwdt_setup(char *str)
{
int
ints
[
4
];
str
=
get_options
(
str
,
ARRAY_SIZE
(
ints
),
ints
);
str
=
get_options
(
str
,
ARRAY_SIZE
(
ints
),
ints
);
if
(
ints
[
0
]
>
0
)
{
io
=
ints
[
1
];
...
...
@@ -170,8 +171,8 @@ static void eurwdt_activate_timer(void)
{
eurwdt_disable_timer
();
eurwdt_write_reg
(
WDT_CTRL_REG
,
0x01
);
/* activate the WDT */
eurwdt_write_reg
(
WDT_OUTPIN_CFG
,
!
strcmp
(
"int"
,
ev
)
?
WDT_EVENT_INT
:
WDT_EVENT_REBOOT
);
eurwdt_write_reg
(
WDT_OUTPIN_CFG
,
!
strcmp
(
"int"
,
ev
)
?
WDT_EVENT_INT
:
WDT_EVENT_REBOOT
);
/* Setting interrupt line */
if
(
irq
==
2
||
irq
>
15
||
irq
<
0
)
{
printk
(
KERN_ERR
": invalid irq number
\n
"
);
...
...
@@ -179,6 +180,7 @@ static void eurwdt_activate_timer(void)
}
if
(
irq
==
0
)
printk
(
KERN_INFO
": interrupt disabled
\n
"
);
eurwdt_write_reg
(
WDT_TIMER_CFG
,
irq
<<
4
);
eurwdt_write_reg
(
WDT_UNIT_SEL
,
WDT_UNIT_SECS
);
/* we use seconds */
...
...
@@ -234,6 +236,19 @@ loff_t *ppos)
return
-
ESPIPE
;
if
(
count
)
{
if
(
!
nowayout
)
{
size_t
i
;
eur_expect_close
=
0
;
for
(
i
=
0
;
i
!=
count
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
buf
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
eur_expect_close
=
42
;
}
}
eurwdt_ping
();
/* the default timeout */
return
1
;
}
...
...
@@ -310,9 +325,8 @@ static int eurwdt_open(struct inode *inode, struct file *file)
spin_unlock
(
&
eurwdt_lock
);
return
-
EBUSY
;
}
if
(
nowayout
)
{
if
(
nowayout
)
MOD_INC_USE_COUNT
;
}
eurwdt_is_open
=
1
;
...
...
@@ -322,7 +336,6 @@ static int eurwdt_open(struct inode *inode, struct file *file)
spin_unlock
(
&
eurwdt_lock
);
MOD_INC_USE_COUNT
;
return
0
;
case
TEMP_MINOR
:
...
...
@@ -348,11 +361,10 @@ static int eurwdt_open(struct inode *inode, struct file *file)
static
int
eurwdt_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
if
(
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
if
(
!
nowayout
)
{
if
(
!
nowayout
)
eurwdt_disable_timer
();
}
eurwdt_is_open
=
0
;
eurwdt_is_open
=
0
;
MOD_DEC_USE_COUNT
;
}
...
...
@@ -479,16 +491,16 @@ static int __init eurwdt_init(void)
spin_lock_init
(
&
eurwdt_lock
);
out:
out:
return
ret
;
outreg:
outreg:
release_region
(
io
,
2
);
outirq:
outirq:
free_irq
(
irq
,
NULL
);
outmisc:
outmisc:
misc_deregister
(
&
eurwdt_miscdev
);
goto
out
;
}
...
...
drivers/char/watchdog/i810-tco.c
View file @
bdc91033
...
...
@@ -244,7 +244,9 @@ static int i810tco_ioctl (struct inode *inode, struct file *file,
int
options
,
retval
=
-
EINVAL
;
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_SETTIMEOUT
|
WDIOF_KEEPALIVEPING
,
.
options
=
WDIOF_SETTIMEOUT
|
WDIOF_KEEPALIVEPING
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
0
,
.
identity
=
"i810 TCO timer"
,
};
...
...
drivers/char/watchdog/ib700wdt.c
View file @
bdc91033
...
...
@@ -54,6 +54,7 @@
static
int
ibwdt_is_open
;
static
spinlock_t
ibwdt_lock
;
static
int
expect_close
=
0
;
/*
*
...
...
@@ -136,6 +137,21 @@ ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
return
-
ESPIPE
;
if
(
count
)
{
if
(
!
nowayout
)
{
size_t
i
;
/* In case it was set long ago */
expect_close
=
0
;
for
(
i
=
0
;
i
!=
count
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
buf
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
1
;
}
}
ibwdt_ping
();
return
1
;
}
...
...
@@ -153,7 +169,9 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned
long
arg
)
{
static
struct
watchdog_info
ident
=
{
WDIOF_KEEPALIVEPING
,
1
,
"IB700 WDT"
.
options
=
WDIOF_KEEPALIVEPING
|
WDIOF_SETTIMEOUT
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"IB700 WDT"
};
switch
(
cmd
)
{
...
...
@@ -180,25 +198,21 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static
int
ibwdt_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
switch
(
minor
(
inode
->
i_rdev
))
{
case
WATCHDOG_MINOR
:
if
(
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
spin_lock
(
&
ibwdt_lock
);
if
(
ibwdt_is_open
)
{
spin_unlock
(
&
ibwdt_lock
);
return
-
EBUSY
;
}
if
(
nowayout
)
{
if
(
nowayout
)
MOD_INC_USE_COUNT
;
}
/*
* Activate
*/
/* Activate */
ibwdt_is_open
=
1
;
ibwdt_ping
();
spin_unlock
(
&
ibwdt_lock
);
return
0
;
default:
}
else
{
return
-
ENODEV
;
}
}
...
...
@@ -206,16 +220,16 @@ ibwdt_open(struct inode *inode, struct file *file)
static
int
ibwdt_close
(
struct
inode
*
inode
,
struct
file
*
file
)
{
lock_kernel
();
if
(
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
spin_lock
(
&
ibwdt_lock
);
if
(
!
nowayout
)
{
if
(
expect_close
)
outb_p
(
timeout_val
,
WDT_STOP
);
}
else
printk
(
KERN_CRIT
"WDT device closed unexpectedly. WDT will not stop!
\n
"
);
ibwdt_is_open
=
0
;
spin_unlock
(
&
ibwdt_lock
);
}
unlock_kernel
();
return
0
;
}
...
...
@@ -248,9 +262,9 @@ static struct file_operations ibwdt_fops = {
};
static
struct
miscdevice
ibwdt_miscdev
=
{
WATCHDOG_MINOR
,
"watchdog"
,
&
ibwdt_fops
.
minor
=
WATCHDOG_MINOR
,
.
name
=
"watchdog"
,
.
fops
=
&
ibwdt_fops
};
/*
...
...
@@ -259,9 +273,9 @@ static struct miscdevice ibwdt_miscdev = {
*/
static
struct
notifier_block
ibwdt_notifier
=
{
ibwdt_notify_sys
,
NULL
,
0
.
notifier_call
=
ibwdt_notify_sys
,
.
next
=
NULL
,
.
priority
=
0
};
static
int
__init
...
...
drivers/char/watchdog/indydog.c
0 → 100644
View file @
bdc91033
/*
* IndyDog 0.2 A Hardware Watchdog Device for SGI IP22
*
* (c) Copyright 2002 Guido Guenther <agx@sigxcpu.org>, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* based on softdog.c by Alan Cox <alan@redhat.com>
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/sgi/sgimc.h>
static
unsigned
long
indydog_alive
;
static
struct
sgimc_misc_ctrl
*
mcmisc_regs
;
static
int
expect_close
=
0
;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static
int
nowayout
=
1
;
#else
static
int
nowayout
=
0
;
#endif
MODULE_PARM
(
nowayout
,
"i"
);
MODULE_PARM_DESC
(
nowayout
,
"Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"
);
static
void
indydog_ping
()
{
mcmisc_regs
->
watchdogt
=
0
;
}
/*
* Allow only one person to hold it open
*/
static
int
indydog_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
u32
mc_ctrl0
;
if
(
test_and_set_bit
(
0
,
&
indydog_alive
)
)
return
-
EBUSY
;
if
(
nowayout
)
MOD_INC_USE_COUNT
;
/*
* Activate timer
*/
mcmisc_regs
=
(
struct
sgimc_misc_ctrl
*
)(
KSEG1
+
0x1fa00000
);
mc_ctrl0
=
mcmisc_regs
->
cpuctrl0
|
SGIMC_CCTRL0_WDOG
;
mcmisc_regs
->
cpuctrl0
=
mc_ctrl0
;
indydog_ping
();
printk
(
"Started watchdog timer.
\n
"
);
return
0
;
}
static
int
indydog_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
/*
* Shut off the timer.
* Lock it in if it's a module and we set nowayout
*/
if
(
expect_close
)
{
u32
mc_ctrl0
=
mcmisc_regs
->
cpuctrl0
;
mc_ctrl0
&=
~
SGIMC_CCTRL0_WDOG
;
mcmisc_regs
->
cpuctrl0
=
mc_ctrl0
;
printk
(
"Stopped watchdog timer.
\n
"
);
}
else
{
printk
(
KERN_CRIT
"WDT device closed unexpectedly. WDT will not stop!
\n
"
);
}
clear_bit
(
0
,
&
indydog_alive
);
return
0
;
}
static
ssize_t
indydog_write
(
struct
file
*
file
,
const
char
*
data
,
size_t
len
,
loff_t
*
ppos
)
{
/* Can't seek (pwrite) on this device */
if
(
ppos
!=
&
file
->
f_pos
)
return
-
ESPIPE
;
/* Refresh the timer. */
if
(
len
)
{
if
(
!
nowayout
)
{
size_t
i
;
/* In case it was set long ago */
expect_close
=
0
;
for
(
i
=
0
;
i
!=
len
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
data
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
1
;
}
}
indydog_ping
();
return
1
;
}
return
0
;
}
static
int
indydog_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_MAGICCLOSE
,
.
identity
=
"Hardware Watchdog for SGI IP22"
,
};
switch
(
cmd
)
{
default:
return
-
ENOIOCTLCMD
;
case
WDIOC_GETSUPPORT
:
if
(
copy_to_user
((
struct
watchdog_info
*
)
arg
,
&
ident
,
sizeof
(
ident
)))
return
-
EFAULT
;
return
0
;
case
WDIOC_GETSTATUS
:
case
WDIOC_GETBOOTSTATUS
:
return
put_user
(
0
,(
int
*
)
arg
);
case
WDIOC_KEEPALIVE
:
indydog_ping
();
return
0
;
}
}
static
struct
file_operations
indydog_fops
=
{
.
owner
=
THIS_MODULE
,
.
write
=
indydog_write
,
.
ioctl
=
indydog_ioctl
,
.
open
=
indydog_open
,
.
release
=
indydog_release
,
};
static
struct
miscdevice
indydog_miscdev
=
{
.
minor
=
WATCHDOG_MINOR
,
.
name
=
"watchdog"
,
.
fops
=
&
indydog_fops
,
};
static
const
char
banner
[]
__initdata
=
KERN_INFO
"Hardware Watchdog Timer for SGI IP22: 0.2
\n
"
;
static
int
__init
watchdog_init
(
void
)
{
int
ret
;
ret
=
misc_register
(
&
indydog_miscdev
);
if
(
ret
)
return
ret
;
printk
(
banner
);
return
0
;
}
static
void
__exit
watchdog_exit
(
void
)
{
misc_deregister
(
&
indydog_miscdev
);
}
module_init
(
watchdog_init
);
module_exit
(
watchdog_exit
);
MODULE_LICENSE
(
"GPL"
);
drivers/char/watchdog/machzwd.c
View file @
bdc91033
...
...
@@ -117,7 +117,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
#define PFX "machzwd"
static
struct
watchdog_info
zf_info
=
{
.
options
=
WDIOF_KEEPALIVEPING
,
.
options
=
WDIOF_KEEPALIVEPING
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"ZF-Logic watchdog"
};
...
...
@@ -314,7 +314,7 @@ static ssize_t zf_write(struct file *file, const char *buf, size_t count,
/* See if we got the magic character */
if
(
count
){
/*
/*
* no need to check for close confirmation
* no way to disable watchdog ;)
*/
...
...
@@ -328,7 +328,7 @@ static ssize_t zf_write(struct file *file, const char *buf, size_t count,
zf_expect_close
=
0
;
/* now scan */
for
(
ofs
=
0
;
ofs
!=
count
;
ofs
++
){
for
(
ofs
=
0
;
ofs
!=
count
;
ofs
++
){
char
c
;
if
(
get_user
(
c
,
buf
+
ofs
))
return
-
EFAULT
;
...
...
@@ -338,6 +338,7 @@ static ssize_t zf_write(struct file *file, const char *buf, size_t count,
}
}
}
/*
* Well, anyhow someone wrote to us,
* we should return that favour
...
...
@@ -395,9 +396,9 @@ static int zf_open(struct inode *inode, struct file *file)
return
-
EBUSY
;
}
if
(
nowayout
)
{
if
(
nowayout
)
MOD_INC_USE_COUNT
;
}
zf_is_open
=
1
;
spin_unlock
(
&
zf_lock
);
...
...
drivers/char/watchdog/mixcomwd.c
View file @
bdc91033
...
...
@@ -62,6 +62,7 @@ static long mixcomwd_opened; /* long req'd for setbit --RR */
static
int
watchdog_port
;
static
int
mixcomwd_timer_alive
;
static
struct
timer_list
mixcomwd_timer
=
TIMER_INITIALIZER
(
NULL
,
0
,
0
);
static
int
expect_close
=
0
;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static
int
nowayout
=
1
;
...
...
@@ -109,8 +110,7 @@ static int mixcomwd_open(struct inode *inode, struct file *file)
static
int
mixcomwd_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
if
(
!
nowayout
)
{
if
(
expect_close
)
{
if
(
mixcomwd_timer_alive
)
{
printk
(
KERN_ERR
"mixcomwd: release called while internal timer alive"
);
return
-
EBUSY
;
...
...
@@ -121,7 +121,10 @@ static int mixcomwd_release(struct inode *inode, struct file *file)
mixcomwd_timer
.
data
=
0
;
mixcomwd_timer_alive
=
1
;
add_timer
(
&
mixcomwd_timer
);
}
else
{
printk
(
KERN_CRIT
"mixcomwd: WDT device closed unexpectedly. WDT will not stop!
\n
"
);
}
clear_bit
(
0
,
&
mixcomwd_opened
);
return
0
;
}
...
...
@@ -135,6 +138,20 @@ static ssize_t mixcomwd_write(struct file *file, const char *data, size_t len, l
if
(
len
)
{
if
(
!
nowayout
)
{
size_t
i
;
/* In case it was set long ago */
expect_close
=
0
;
for
(
i
=
0
;
i
!=
len
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
data
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
1
;
}
}
mixcomwd_ping
();
return
1
;
}
...
...
@@ -146,7 +163,9 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
{
int
status
;
static
struct
watchdog_info
ident
=
{
WDIOF_KEEPALIVEPING
,
1
,
"MixCOM watchdog"
.
options
=
WDIOF_KEEPALIVEPING
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"MixCOM watchdog"
};
switch
(
cmd
)
...
...
drivers/char/watchdog/pcwd.c
View file @
bdc91033
...
...
@@ -40,6 +40,8 @@
* fairly useless proc entry.
* 990610 removed said useless proc code for the merge <alan>
* 000403 Removed last traces of proc code. <davej>
* 011214 Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com>
* Added timeout module option to override default
*/
#include <linux/module.h>
...
...
@@ -76,7 +78,7 @@
*/
static
int
pcwd_ioports
[]
=
{
0x270
,
0x350
,
0x370
,
0x000
};
#define WD_VER "1.1
0 (06/05/99
)"
#define WD_VER "1.1
2 (12/14/2001
)"
/*
* It should be noted that PCWD_REVISION_B was removed because A and B
...
...
@@ -88,7 +90,23 @@ static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 };
#define PCWD_REVISION_A 1
#define PCWD_REVISION_C 2
#define WD_TIMEOUT 3
/* 1 1/2 seconds for a timeout */
#define WD_TIMEOUT 4
/* 2 seconds for a timeout */
static
int
timeout_val
=
WD_TIMEOUT
;
static
int
timeout
=
2
;
static
int
expect_close
=
0
;
MODULE_PARM
(
timeout
,
"i"
);
MODULE_PARM_DESC
(
timeout
,
"Watchdog timeout in seconds (default=2)"
);
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static
int
nowayout
=
1
;
#else
static
int
nowayout
=
0
;
#endif
MODULE_PARM
(
nowayout
,
"i"
);
MODULE_PARM_DESC
(
nowayout
,
"Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"
);
/*
* These are the defines for the PC Watchdog card, revision A.
...
...
@@ -121,7 +139,7 @@ static int __init pcwd_checkcard(void)
if
(
prev_card_dat
==
0xFF
)
return
0
;
while
(
count
<
WD_TIMEOUT
)
{
while
(
count
<
timeout_val
)
{
/* Read the raw card data from the port, and strip off the
first 4 bits */
...
...
@@ -256,7 +274,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
else
cdat
=
inb
(
current_readport
+
1
);
spin_unlock
(
&
io_lock
);
rv
=
0
;
rv
=
WDIOF_MAGICCLOSE
;
if
(
revision
==
PCWD_REVISION_A
)
{
...
...
@@ -385,8 +403,22 @@ static ssize_t pcwd_write(struct file *file, const char *buf, size_t len,
if
(
ppos
!=
&
file
->
f_pos
)
return
-
ESPIPE
;
if
(
len
)
{
if
(
len
)
{
if
(
!
nowayout
)
{
size_t
i
;
/* In case it was set long ago */
expect_close
=
0
;
for
(
i
=
0
;
i
!=
len
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
buf
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
1
;
}
}
pcwd_send_heartbeat
();
return
1
;
}
...
...
@@ -395,23 +427,21 @@ static ssize_t pcwd_write(struct file *file, const char *buf, size_t len,
static
int
pcwd_open
(
struct
inode
*
ino
,
struct
file
*
filep
)
{
switch
(
minor
(
ino
->
i_rdev
))
{
switch
(
minor
(
ino
->
i_rdev
))
{
case
WATCHDOG_MINOR
:
if
(
!
atomic_dec_and_test
(
&
open_allowed
)
)
{
if
(
!
atomic_dec_and_test
(
&
open_allowed
)
)
{
atomic_inc
(
&
open_allowed
);
return
-
EBUSY
;
}
MOD_INC_USE_COUNT
;
/* Enable the port */
if
(
revision
==
PCWD_REVISION_C
)
{
if
(
revision
==
PCWD_REVISION_C
)
{
spin_lock
(
&
io_lock
);
outb_p
(
0x00
,
current_readport
+
3
);
spin_unlock
(
&
io_lock
);
}
return
(
0
);
case
TEMP_MINOR
:
return
(
0
);
default:
...
...
@@ -448,9 +478,8 @@ static ssize_t pcwd_read(struct file *file, char *buf, size_t count,
static
int
pcwd_close
(
struct
inode
*
ino
,
struct
file
*
filep
)
{
if
(
minor
(
ino
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
#ifndef CONFIG_WATCHDOG_NOWAYOUT
if
(
minor
(
ino
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
if
(
expect_close
)
{
/* Disable the board */
if
(
revision
==
PCWD_REVISION_C
)
{
spin_lock
(
&
io_lock
);
...
...
@@ -459,7 +488,7 @@ static int pcwd_close(struct inode *ino, struct file *filep)
spin_unlock
(
&
io_lock
);
}
atomic_inc
(
&
open_allowed
);
#endif
}
}
return
0
;
}
...
...
@@ -560,9 +589,15 @@ static struct miscdevice temp_miscdev = {
&
pcwd_fops
};
static
void
__init
pcwd_validate_timeout
(
void
)
{
timeout_val
=
timeout
*
2
;
}
static
int
__init
pcwatchdog_init
(
void
)
{
int
i
,
found
=
0
;
pcwd_validate_timeout
();
spin_lock_init
(
&
io_lock
);
revision
=
PCWD_REVISION_A
;
...
...
drivers/char/watchdog/sbc60xxwdt.c
View file @
bdc91033
...
...
@@ -244,9 +244,9 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
{
static
struct
watchdog_info
ident
=
{
0
,
1
,
"SB60xx"
.
options
=
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"SB60xx"
};
switch
(
cmd
)
...
...
drivers/char/watchdog/sc1200wdt.c
0 → 100644
View file @
bdc91033
/*
* National Semiconductor PC87307/PC97307 (ala SC1200) WDT driver
* (c) Copyright 2002 Zwane Mwaikambo <zwane@commfireservices.com>,
* All Rights Reserved.
* Based on wdt.c and wdt977.c by Alan Cox and Woody Suwalski respectively.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* The author(s) of this software shall not be held liable for damages
* of any nature resulting due to the use of this software. This
* software is provided AS-IS with no warranties.
*
* Changelog:
* 20020220 Zwane Mwaikambo Code based on datasheet, no hardware.
* 20020221 Zwane Mwaikambo Cleanups as suggested by Jeff Garzik and Alan Cox.
* 20020222 Zwane Mwaikambo Added probing.
* 20020225 Zwane Mwaikambo Added ISAPNP support.
* 20020412 Rob Radez Broke out start/stop functions
* <rob@osinvestor.com> Return proper status instead of temperature warning
* Add WDIOC_GETBOOTSTATUS and WDIOC_SETOPTIONS ioctls
* Fix CONFIG_WATCHDOG_NOWAYOUT
* 20020530 Joel Becker Add Matt Domsch's nowayout module option
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
#include <linux/ioport.h>
#include <asm/semaphore.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/isapnp.h>
#include <linux/pci.h>
#define SC1200_MODULE_VER "build 20020303"
#define SC1200_MODULE_NAME "sc1200wdt"
#define PFX SC1200_MODULE_NAME ": "
#define MAX_TIMEOUT 255
/* 255 minutes */
#define PMIR (io)
/* Power Management Index Register */
#define PMDR (io+1)
/* Power Management Data Register */
/* Data Register indexes */
#define FER1 0x00
/* Function enable register 1 */
#define FER2 0x01
/* Function enable register 2 */
#define PMC1 0x02
/* Power Management Ctrl 1 */
#define PMC2 0x03
/* Power Management Ctrl 2 */
#define PMC3 0x04
/* Power Management Ctrl 3 */
#define WDTO 0x05
/* Watchdog timeout register */
#define WDCF 0x06
/* Watchdog config register */
#define WDST 0x07
/* Watchdog status register */
/* WDCF bitfields - which devices assert WDO */
#define KBC_IRQ 0x01
/* Keyboard Controller */
#define MSE_IRQ 0x02
/* Mouse */
#define UART1_IRQ 0x03
/* Serial0 */
#define UART2_IRQ 0x04
/* Serial1 */
/* 5 -7 are reserved */
static
char
banner
[]
__initdata
=
KERN_INFO
PFX
SC1200_MODULE_VER
;
static
int
timeout
=
1
;
static
int
io
=
-
1
;
static
int
io_len
=
2
;
/* for non plug and play */
struct
semaphore
open_sem
;
static
char
expect_close
;
spinlock_t
sc1200wdt_lock
;
/* io port access serialisation */
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
static
int
isapnp
=
1
;
static
struct
pci_dev
*
wdt_dev
;
MODULE_PARM
(
isapnp
,
"i"
);
MODULE_PARM_DESC
(
isapnp
,
"When set to 0 driver ISA PnP support will be disabled"
);
#endif
MODULE_PARM
(
io
,
"i"
);
MODULE_PARM_DESC
(
io
,
"io port"
);
MODULE_PARM
(
timeout
,
"i"
);
MODULE_PARM_DESC
(
timeout
,
"range is 0-255 minutes, default is 1"
);
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static
int
nowayout
=
1
;
#else
static
int
nowayout
=
0
;
#endif
MODULE_PARM
(
nowayout
,
"i"
);
MODULE_PARM_DESC
(
nowayout
,
"Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"
);
/* Read from Data Register */
static
inline
void
sc1200wdt_read_data
(
unsigned
char
index
,
unsigned
char
*
data
)
{
spin_lock
(
&
sc1200wdt_lock
);
outb_p
(
index
,
PMIR
);
*
data
=
inb
(
PMDR
);
spin_unlock
(
&
sc1200wdt_lock
);
}
/* Write to Data Register */
static
inline
void
sc1200wdt_write_data
(
unsigned
char
index
,
unsigned
char
data
)
{
spin_lock
(
&
sc1200wdt_lock
);
outb_p
(
index
,
PMIR
);
outb
(
data
,
PMDR
);
spin_unlock
(
&
sc1200wdt_lock
);
}
static
void
sc1200wdt_start
(
void
)
{
unsigned
char
reg
;
sc1200wdt_read_data
(
WDCF
,
&
reg
);
/* assert WDO when any of the following interrupts are triggered too */
reg
|=
(
KBC_IRQ
|
MSE_IRQ
|
UART1_IRQ
|
UART2_IRQ
);
sc1200wdt_write_data
(
WDCF
,
reg
);
/* set the timeout and get the ball rolling */
sc1200wdt_write_data
(
WDTO
,
timeout
);
}
static
void
sc1200wdt_stop
(
void
)
{
sc1200wdt_write_data
(
WDTO
,
0
);
}
/* This returns the status of the WDO signal, inactive high. */
static
inline
int
sc1200wdt_status
(
void
)
{
unsigned
char
ret
;
sc1200wdt_read_data
(
WDST
,
&
ret
);
/* If the bit is inactive, the watchdog is enabled, so return
* KEEPALIVEPING which is a bit of a kludge because there's nothing
* else for enabled/disabled status
*/
return
(
ret
&
0x01
)
?
0
:
WDIOF_KEEPALIVEPING
;
/* bits 1 - 7 are undefined */
}
static
int
sc1200wdt_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
/* allow one at a time */
if
(
down_trylock
(
&
open_sem
))
return
-
EBUSY
;
if
(
timeout
>
MAX_TIMEOUT
)
timeout
=
MAX_TIMEOUT
;
sc1200wdt_start
();
printk
(
KERN_INFO
PFX
"Watchdog enabled, timeout = %d min(s)"
,
timeout
);
return
0
;
}
static
int
sc1200wdt_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
int
new_timeout
;
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_KEEPALIVEPING
|
WDIOF_SETTIMEOUT
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
0
,
.
identity
=
"PC87307/PC97307"
};
switch
(
cmd
)
{
default:
return
-
ENOTTY
;
/* Keep Pavel Machek amused ;) */
case
WDIOC_GETSUPPORT
:
if
(
copy_to_user
((
struct
watchdog_info
*
)
arg
,
&
ident
,
sizeof
ident
))
return
-
EFAULT
;
return
0
;
case
WDIOC_GETSTATUS
:
return
put_user
(
sc1200wdt_status
(),
(
int
*
)
arg
);
case
WDIOC_GETBOOTSTATUS
:
return
put_user
(
0
,
(
int
*
)
arg
);
case
WDIOC_KEEPALIVE
:
sc1200wdt_write_data
(
WDTO
,
timeout
);
return
0
;
case
WDIOC_SETTIMEOUT
:
if
(
get_user
(
new_timeout
,
(
int
*
)
arg
))
return
-
EFAULT
;
/* the API states this is given in secs */
new_timeout
/=
60
;
if
(
new_timeout
<
0
||
new_timeout
>
MAX_TIMEOUT
)
return
-
EINVAL
;
timeout
=
new_timeout
;
sc1200wdt_write_data
(
WDTO
,
timeout
);
/* fall through and return the new timeout */
case
WDIOC_GETTIMEOUT
:
return
put_user
(
timeout
*
60
,
(
int
*
)
arg
);
case
WDIOC_SETOPTIONS
:
{
int
options
,
retval
=
-
EINVAL
;
if
(
get_user
(
options
,
(
int
*
)
arg
))
return
-
EFAULT
;
if
(
options
&
WDIOS_DISABLECARD
)
{
sc1200wdt_stop
();
retval
=
0
;
}
if
(
options
&
WDIOS_ENABLECARD
)
{
sc1200wdt_start
();
retval
=
0
;
}
return
retval
;
}
}
}
static
int
sc1200wdt_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
if
(
expect_close
==
42
)
{
sc1200wdt_stop
();
printk
(
KERN_INFO
PFX
"Watchdog disabled
\n
"
);
}
else
{
sc1200wdt_write_data
(
WDTO
,
timeout
);
printk
(
KERN_CRIT
PFX
"Unexpected close!, timeout = %d min(s)
\n
"
,
timeout
);
}
up
(
&
open_sem
);
expect_close
=
0
;
return
0
;
}
static
ssize_t
sc1200wdt_write
(
struct
file
*
file
,
const
char
*
data
,
size_t
len
,
loff_t
*
ppos
)
{
if
(
ppos
!=
&
file
->
f_pos
)
return
-
ESPIPE
;
if
(
len
)
{
if
(
!
nowayout
)
{
size_t
i
;
expect_close
=
0
;
for
(
i
=
0
;
i
!=
len
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
data
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
42
;
}
}
sc1200wdt_write_data
(
WDTO
,
timeout
);
return
len
;
}
return
0
;
}
static
int
sc1200wdt_notify_sys
(
struct
notifier_block
*
this
,
unsigned
long
code
,
void
*
unused
)
{
if
(
code
==
SYS_DOWN
||
code
==
SYS_HALT
)
sc1200wdt_stop
();
return
NOTIFY_DONE
;
}
static
struct
notifier_block
sc1200wdt_notifier
=
{
notifier_call:
sc1200wdt_notify_sys
};
static
struct
file_operations
sc1200wdt_fops
=
{
owner:
THIS_MODULE
,
write:
sc1200wdt_write
,
ioctl:
sc1200wdt_ioctl
,
open:
sc1200wdt_open
,
release:
sc1200wdt_release
};
static
struct
miscdevice
sc1200wdt_miscdev
=
{
minor:
WATCHDOG_MINOR
,
name:
"watchdog"
,
fops:
&
sc1200wdt_fops
,
};
static
int
__init
sc1200wdt_probe
(
void
)
{
/* The probe works by reading the PMC3 register's default value of 0x0e
* there is one caveat, if the device disables the parallel port or any
* of the UARTs we won't be able to detect it.
* Nb. This could be done with accuracy by reading the SID registers, but
* we don't have access to those io regions.
*/
unsigned
char
reg
;
sc1200wdt_read_data
(
PMC3
,
&
reg
);
reg
&=
0x0f
;
/* we don't want the UART busy bits */
return
(
reg
==
0x0e
)
?
0
:
-
ENODEV
;
}
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
static
int
__init
sc1200wdt_isapnp_probe
(
void
)
{
int
ret
;
/* The WDT is logical device 8 on the main device */
wdt_dev
=
isapnp_find_dev
(
NULL
,
ISAPNP_VENDOR
(
'N'
,
'S'
,
'C'
),
ISAPNP_FUNCTION
(
0x08
),
NULL
);
if
(
!
wdt_dev
)
return
-
ENODEV
;
if
(
wdt_dev
->
prepare
(
wdt_dev
)
<
0
)
{
printk
(
KERN_ERR
PFX
"ISA PnP found device that could not be autoconfigured
\n
"
);
return
-
EAGAIN
;
}
if
(
!
(
pci_resource_flags
(
wdt_dev
,
0
)
&
IORESOURCE_IO
))
{
printk
(
KERN_ERR
PFX
"ISA PnP could not find io ports
\n
"
);
return
-
ENODEV
;
}
ret
=
wdt_dev
->
activate
(
wdt_dev
);
if
(
ret
&&
(
ret
!=
-
EBUSY
))
return
-
ENOMEM
;
/* io port resource overriding support? */
io
=
pci_resource_start
(
wdt_dev
,
0
);
io_len
=
pci_resource_len
(
wdt_dev
,
0
);
printk
(
KERN_DEBUG
PFX
"ISA PnP found device at io port %#x/%d
\n
"
,
io
,
io_len
);
return
0
;
}
#endif
/* CONFIG_ISAPNP */
static
int
__init
sc1200wdt_init
(
void
)
{
int
ret
;
printk
(
banner
);
spin_lock_init
(
&
sc1200wdt_lock
);
sema_init
(
&
open_sem
,
1
);
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
if
(
isapnp
)
{
ret
=
sc1200wdt_isapnp_probe
();
if
(
ret
)
goto
out_clean
;
}
#endif
if
(
io
==
-
1
)
{
printk
(
KERN_ERR
PFX
"io parameter must be specified
\n
"
);
ret
=
-
EINVAL
;
goto
out_clean
;
}
if
(
!
request_region
(
io
,
io_len
,
SC1200_MODULE_NAME
))
{
printk
(
KERN_ERR
PFX
"Unable to register IO port %#x
\n
"
,
io
);
ret
=
-
EBUSY
;
goto
out_pnp
;
}
ret
=
sc1200wdt_probe
();
if
(
ret
)
goto
out_io
;
ret
=
register_reboot_notifier
(
&
sc1200wdt_notifier
);
if
(
ret
)
{
printk
(
KERN_ERR
PFX
"Unable to register reboot notifier err = %d
\n
"
,
ret
);
goto
out_io
;
}
ret
=
misc_register
(
&
sc1200wdt_miscdev
);
if
(
ret
)
{
printk
(
KERN_ERR
PFX
"Unable to register miscdev on minor %d
\n
"
,
WATCHDOG_MINOR
);
goto
out_rbt
;
}
/* ret = 0 */
out_clean:
return
ret
;
out_rbt:
unregister_reboot_notifier
(
&
sc1200wdt_notifier
);
out_io:
release_region
(
io
,
io_len
);
out_pnp:
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
if
(
isapnp
&&
wdt_dev
)
wdt_dev
->
deactivate
(
wdt_dev
);
#endif
goto
out_clean
;
}
static
void
__exit
sc1200wdt_exit
(
void
)
{
misc_deregister
(
&
sc1200wdt_miscdev
);
unregister_reboot_notifier
(
&
sc1200wdt_notifier
);
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
if
(
isapnp
&&
wdt_dev
)
wdt_dev
->
deactivate
(
wdt_dev
);
#endif
release_region
(
io
,
io_len
);
}
#ifndef MODULE
static
int
__init
sc1200wdt_setup
(
char
*
str
)
{
int
ints
[
4
];
str
=
get_options
(
str
,
ARRAY_SIZE
(
ints
),
ints
);
if
(
ints
[
0
]
>
0
)
{
io
=
ints
[
1
];
if
(
ints
[
0
]
>
1
)
timeout
=
ints
[
2
];
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
if
(
ints
[
0
]
>
2
)
isapnp
=
ints
[
3
];
#endif
}
return
1
;
}
__setup
(
"sc1200wdt="
,
sc1200wdt_setup
);
#endif
/* MODULE */
module_init
(
sc1200wdt_init
);
module_exit
(
sc1200wdt_exit
);
MODULE_AUTHOR
(
"Zwane Mwaikambo <zwane@commfireservices.com>"
);
MODULE_DESCRIPTION
(
"Driver for National Semiconductor PC87307/PC97307 watchdog component"
);
MODULE_LICENSE
(
"GPL"
);
EXPORT_NO_SYMBOLS
;
drivers/char/watchdog/sc520_wdt.c
0 → 100644
View file @
bdc91033
/*
* AMD Elan SC520 processor Watchdog Timer driver for Linux 2.4.x
*
* Based on acquirewdt.c by Alan Cox,
* and sbc60xxwdt.c by Jakob Oestergaard <jakob@ostenfeld.dk>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* The authors do NOT admit liability nor provide warranty for
* any of this software. This material is provided "AS-IS" in
* the hope that it may be useful for others.
*
* (c) Copyright 2001 Scott Jennings <linuxdrivers@oro.net>
* 9/27 - 2001 [Initial release]
*
* Additional fixes Alan Cox
* - Fixed formatting
* - Removed debug printks
* - Fixed SMP built kernel deadlock
* - Switched to private locks not lock_kernel
* - Used ioremap/writew/readw
* - Added NOWAYOUT support
*
* Theory of operation:
* A Watchdog Timer (WDT) is a hardware circuit that can
* reset the computer system in case of a software fault.
* You probably knew that already.
*
* Usually a userspace daemon will notify the kernel WDT driver
* via the /proc/watchdog special device file that userspace is
* still alive, at regular intervals. When such a notification
* occurs, the driver will usually tell the hardware watchdog
* that everything is in order, and that the watchdog should wait
* for yet another little while to reset the system.
* If userspace fails (RAM error, kernel bug, whatever), the
* notifications cease to occur, and the hardware watchdog will
* reset the system (causing a reboot) after the timeout occurs.
*
* This WDT driver is different from most other Linux WDT
* drivers in that the driver will ping the watchdog by itself,
* because this particular WDT has a very short timeout (1.6
* seconds) and it would be insane to count on any userspace
* daemon always getting scheduled within that time frame.
*
* This driver uses memory mapped IO, and spinlock.
*/
#include <linux/module.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
/*
* The SC520 can timeout anywhere from 492us to 32.21s.
* If we reset the watchdog every ~250ms we should be safe.
*/
#define WDT_INTERVAL (HZ/4+1)
/*
* We must not require too good response from the userspace daemon.
* Here we require the userspace daemon to send us a heartbeat
* char to /dev/watchdog every 30 seconds.
*/
#define WDT_HEARTBEAT (HZ * 30)
/*
* AMD Elan SC520 timeout value is 492us times a power of 2 (0-7)
*
* 0: 492us 2: 1.01s 4: 4.03s 6: 16.22s
* 1: 503ms 3: 2.01s 5: 8.05s 7: 32.21s
*/
#define TIMEOUT_EXPONENT ( 1 << 3 )
/* 0x08 = 2.01s */
/* #define MMCR_BASE_DEFAULT 0xfffef000 */
#define MMCR_BASE_DEFAULT ((__u16 *)0xffffe)
#define OFFS_WDTMRCTL ((unsigned int)0xcb0)
#define WDT_ENB 0x8000
/* [15] Watchdog Timer Enable */
#define WDT_WRST_ENB 0x4000
/* [14] Watchdog Timer Reset Enable */
#define OUR_NAME "sc520_wdt"
#define WRT_DOG(data) *wdtmrctl=data
static
__u16
*
wdtmrctl
;
static
void
wdt_timer_ping
(
unsigned
long
);
static
struct
timer_list
timer
;
static
unsigned
long
next_heartbeat
;
static
unsigned
long
wdt_is_open
;
static
int
wdt_expect_close
;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static
int
nowayout
=
1
;
#else
static
int
nowayout
=
0
;
#endif
MODULE_PARM
(
nowayout
,
"i"
);
MODULE_PARM_DESC
(
nowayout
,
"Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"
);
static
spinlock_t
wdt_spinlock
;
/*
* Whack the dog
*/
static
void
wdt_timer_ping
(
unsigned
long
data
)
{
/* If we got a heartbeat pulse within the WDT_US_INTERVAL
* we agree to ping the WDT
*/
if
(
time_before
(
jiffies
,
next_heartbeat
))
{
/* Ping the WDT */
spin_lock
(
&
wdt_spinlock
);
writew
(
0xAAAA
,
wdtmrctl
);
writew
(
0x5555
,
wdtmrctl
);
spin_unlock
(
&
wdt_spinlock
);
/* Re-set the timer interval */
timer
.
expires
=
jiffies
+
WDT_INTERVAL
;
add_timer
(
&
timer
);
}
else
{
printk
(
OUR_NAME
": Heartbeat lost! Will not ping the watchdog
\n
"
);
}
}
/*
* Utility routines
*/
static
void
wdt_config
(
int
writeval
)
{
__u16
dummy
;
unsigned
long
flags
;
/* buy some time (ping) */
spin_lock_irqsave
(
&
wdt_spinlock
,
flags
);
dummy
=
readw
(
wdtmrctl
);
/* ensure write synchronization */
writew
(
0xAAAA
,
wdtmrctl
);
writew
(
0x5555
,
wdtmrctl
);
/* make WDT configuration register writable one time */
writew
(
0x3333
,
wdtmrctl
);
writew
(
0xCCCC
,
wdtmrctl
);
/* write WDT configuration register */
writew
(
writeval
,
wdtmrctl
);
spin_unlock_irqrestore
(
&
wdt_spinlock
,
flags
);
}
static
void
wdt_startup
(
void
)
{
next_heartbeat
=
jiffies
+
WDT_HEARTBEAT
;
/* Start the timer */
timer
.
expires
=
jiffies
+
WDT_INTERVAL
;
add_timer
(
&
timer
);
wdt_config
(
WDT_ENB
|
WDT_WRST_ENB
|
TIMEOUT_EXPONENT
);
printk
(
OUR_NAME
": Watchdog timer is now enabled.
\n
"
);
}
static
void
wdt_turnoff
(
void
)
{
if
(
!
nowayout
)
{
/* Stop the timer */
del_timer
(
&
timer
);
wdt_config
(
0
);
printk
(
OUR_NAME
": Watchdog timer is now disabled...
\n
"
);
}
}
/*
* /dev/watchdog handling
*/
static
ssize_t
fop_write
(
struct
file
*
file
,
const
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
/* We can't seek */
if
(
ppos
!=
&
file
->
f_pos
)
return
-
ESPIPE
;
/* See if we got the magic character */
if
(
count
)
{
size_t
ofs
;
/* note: just in case someone wrote the magic character
* five months ago... */
wdt_expect_close
=
0
;
/* now scan */
for
(
ofs
=
0
;
ofs
!=
count
;
ofs
++
)
{
char
c
;
if
(
get_user
(
c
,
buf
+
ofs
))
return
-
EFAULT
;
if
(
c
==
'V'
)
wdt_expect_close
=
1
;
}
/* Well, anyhow someone wrote to us, we should return that favour */
next_heartbeat
=
jiffies
+
WDT_HEARTBEAT
;
return
1
;
}
return
0
;
}
static
int
fop_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
switch
(
minor
(
inode
->
i_rdev
))
{
case
WATCHDOG_MINOR
:
/* Just in case we're already talking to someone... */
if
(
test_and_set_bit
(
0
,
&
wdt_is_open
))
return
-
EBUSY
;
/* Good, fire up the show */
wdt_startup
();
if
(
nowayout
)
MOD_INC_USE_COUNT
;
return
0
;
default:
return
-
ENODEV
;
}
}
static
int
fop_close
(
struct
inode
*
inode
,
struct
file
*
file
)
{
if
(
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
if
(
wdt_expect_close
)
wdt_turnoff
();
else
{
del_timer
(
&
timer
);
printk
(
OUR_NAME
": device file closed unexpectedly. Will not stop the WDT!
\n
"
);
}
}
clear_bit
(
0
,
&
wdt_is_open
);
return
0
;
}
static
long
long
fop_llseek
(
struct
file
*
file
,
long
long
offset
,
int
origin
)
{
return
-
ESPIPE
;
}
static
int
fop_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"SC520"
};
switch
(
cmd
)
{
default:
return
-
ENOIOCTLCMD
;
case
WDIOC_GETSUPPORT
:
return
copy_to_user
((
struct
watchdog_info
*
)
arg
,
&
ident
,
sizeof
(
ident
))
?-
EFAULT
:
0
;
case
WDIOC_KEEPALIVE
:
next_heartbeat
=
jiffies
+
WDT_HEARTBEAT
;
return
0
;
}
}
static
struct
file_operations
wdt_fops
=
{
owner:
THIS_MODULE
,
llseek:
fop_llseek
,
write:
fop_write
,
open:
fop_open
,
release:
fop_close
,
ioctl:
fop_ioctl
};
static
struct
miscdevice
wdt_miscdev
=
{
WATCHDOG_MINOR
,
"watchdog"
,
&
wdt_fops
};
/*
* Notifier for system down
*/
static
int
wdt_notify_sys
(
struct
notifier_block
*
this
,
unsigned
long
code
,
void
*
unused
)
{
if
(
code
==
SYS_DOWN
||
code
==
SYS_HALT
)
wdt_turnoff
();
return
NOTIFY_DONE
;
}
/*
* The WDT needs to learn about soft shutdowns in order to
* turn the timebomb registers off.
*/
static
struct
notifier_block
wdt_notifier
=
{
wdt_notify_sys
,
0
,
0
};
static
void
__exit
sc520_wdt_unload
(
void
)
{
wdt_turnoff
();
/* Deregister */
misc_deregister
(
&
wdt_miscdev
);
iounmap
(
wdtmrctl
);
unregister_reboot_notifier
(
&
wdt_notifier
);
}
static
int
__init
sc520_wdt_init
(
void
)
{
int
rc
=
-
EBUSY
;
unsigned
long
cbar
;
spin_lock_init
(
&
wdt_spinlock
);
init_timer
(
&
timer
);
timer
.
function
=
wdt_timer_ping
;
timer
.
data
=
0
;
rc
=
misc_register
(
&
wdt_miscdev
);
if
(
rc
)
goto
err_out_region2
;
rc
=
register_reboot_notifier
(
&
wdt_notifier
);
if
(
rc
)
goto
err_out_miscdev
;
/* get the Base Address Register */
cbar
=
inl_p
(
0xfffc
);
printk
(
OUR_NAME
": CBAR: 0x%08lx
\n
"
,
cbar
);
/* check if MMCR aliasing bit is set */
if
(
cbar
&
0x80000000
)
{
printk
(
OUR_NAME
": MMCR Aliasing enabled.
\n
"
);
wdtmrctl
=
(
__u16
*
)(
cbar
&
0x3fffffff
);
}
else
{
printk
(
OUR_NAME
"!!! WARNING !!!
\n
"
"
\t
MMCR Aliasing found NOT enabled!
\n
"
"
\t
Using default value of: %p
\n
"
"
\t
This has not been tested!
\n
"
"
\t
Please email Scott Jennings <smj@oro.net>
\n
"
"
\t
and Bill Jennings <bj@oro.net> if it works!
\n
"
,
MMCR_BASE_DEFAULT
);
wdtmrctl
=
MMCR_BASE_DEFAULT
;
}
wdtmrctl
=
(
__u16
*
)((
char
*
)
wdtmrctl
+
OFFS_WDTMRCTL
);
wdtmrctl
=
ioremap
((
unsigned
long
)
wdtmrctl
,
2
);
printk
(
KERN_INFO
OUR_NAME
": WDT driver for SC520 initialised.
\n
"
);
return
0
;
err_out_miscdev:
misc_deregister
(
&
wdt_miscdev
);
err_out_region2:
return
rc
;
}
module_init
(
sc520_wdt_init
);
module_exit
(
sc520_wdt_unload
);
MODULE_AUTHOR
(
"Scott and Bill Jennings"
);
MODULE_DESCRIPTION
(
"Driver for watchdog timer in AMD
\"
Elan
\"
SC520 uProcessor"
);
MODULE_LICENSE
(
"GPL"
);
EXPORT_NO_SYMBOLS
;
drivers/char/watchdog/shwdt.c
View file @
bdc91033
...
...
@@ -334,21 +334,21 @@ static struct file_operations sh_wdt_fops = {
};
static
struct
watchdog_info
sh_wdt_info
=
{
WDIOF_KEEPALIVEPING
,
1
,
"SH WDT"
,
.
options
=
WDIOF_KEEPALIVEPING
|
WDIOF_SETTIMEOUT
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"SH WDT"
,
};
static
struct
notifier_block
sh_wdt_notifier
=
{
sh_wdt_notify_sys
,
NULL
,
0
.
notifier_call
=
sh_wdt_notify_sys
,
.
next
=
NULL
,
.
priority
=
0
};
static
struct
miscdevice
sh_wdt_miscdev
=
{
WATCHDOG_MINOR
,
"watchdog"
,
&
sh_wdt_fops
,
.
minor
=
WATCHDOG_MINOR
,
.
name
=
"watchdog"
,
.
fops
&
sh_wdt_fops
,
};
/**
...
...
drivers/char/watchdog/softdog.c
View file @
bdc91033
...
...
@@ -47,6 +47,7 @@
#define TIMER_MARGIN 60
/* (secs) Default is 1 minute */
static
int
expect_close
=
0
;
static
int
soft_margin
=
TIMER_MARGIN
;
/* in seconds */
MODULE_PARM
(
soft_margin
,
"i"
);
...
...
@@ -114,6 +115,8 @@ static int softdog_release(struct inode *inode, struct file *file)
*/
if
(
!
nowayout
)
{
del_timer
(
&
watchdog_ticktock
);
}
else
{
printk
(
KERN_CRIT
"SOFTDOG: WDT device closed unexpectedly. WDT will not stop!
\n
"
);
}
timer_alive
=
0
;
return
0
;
...
...
@@ -129,6 +132,21 @@ static ssize_t softdog_write(struct file *file, const char *data, size_t len, lo
* Refresh the timer.
*/
if
(
len
)
{
if
(
!
nowayout
)
{
size_t
i
;
/* In case it was set long ago */
expect_close
=
0
;
for
(
i
=
0
;
i
!=
len
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
data
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
1
;
}
}
mod_timer
(
&
watchdog_ticktock
,
jiffies
+
(
soft_margin
*
HZ
));
return
1
;
}
...
...
@@ -139,6 +157,7 @@ static int softdog_ioctl(struct inode *inode, struct file *file,
unsigned
int
cmd
,
unsigned
long
arg
)
{
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_SETTIMEOUT
|
WDIOF_MAGICCLOSE
,
.
identity
=
"Software Watchdog"
,
};
switch
(
cmd
)
{
...
...
drivers/char/watchdog/w83877f_wdt.c
View file @
bdc91033
...
...
@@ -251,9 +251,9 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
{
static
struct
watchdog_info
ident
=
{
0
,
1
,
"W83877F"
.
options
=
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"W83877F"
};
switch
(
cmd
)
...
...
drivers/char/watchdog/wafer5823wdt.c
0 → 100644
View file @
bdc91033
/*
* ICP Wafer 5823 Single Board Computer WDT driver for Linux 2.4.x
* http://www.icpamerica.com/wafer_5823.php
* May also work on other similar models
*
* (c) Copyright 2002 Justin Cormack <justin@street-vision.com>
*
* Release 0.02
*
* Based on advantechwdt.c which is based on wdt.c.
* Original copyright messages:
*
* (c) Copyright 1996-1997 Alan Cox <alan@redhat.com>, All Rights Reserved.
* http://www.redhat.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.
*
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/spinlock.h>
static
unsigned
long
wafwdt_is_open
;
static
spinlock_t
wafwdt_lock
;
static
int
expect_close
=
0
;
/*
* You must set these - there is no sane way to probe for this board.
*
* To enable, write the timeout value in seconds (1 to 255) to I/O
* port WDT_START, then read the port to start the watchdog. To pat
* the dog, read port WDT_STOP to stop the timer, then read WDT_START
* to restart it again.
*/
#define WDT_START 0x443
#define WDT_STOP 0x843
#define WD_TIMO 60
/* 1 minute */
static
int
wd_margin
=
WD_TIMO
;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static
int
nowayout
=
1
;
#else
static
int
nowayout
=
0
;
#endif
MODULE_PARM
(
nowayout
,
"i"
);
MODULE_PARM_DESC
(
nowayout
,
"Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"
);
static
void
wafwdt_ping
(
void
)
{
/* pat watchdog */
spin_lock
(
&
wafwdt_lock
);
inb_p
(
WDT_STOP
);
inb_p
(
WDT_START
);
spin_unlock
(
&
wafwdt_lock
);
}
static
void
wafwdt_start
(
void
)
{
/* start up watchdog */
outb_p
(
wd_margin
,
WDT_START
);
inb_p
(
WDT_START
);
}
static
void
wafwdt_stop
(
void
)
{
/* stop watchdog */
inb_p
(
WDT_STOP
);
}
static
ssize_t
wafwdt_write
(
struct
file
*
file
,
const
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
/* Can't seek (pwrite) on this device */
if
(
ppos
!=
&
file
->
f_pos
)
return
-
ESPIPE
;
if
(
count
)
{
if
(
!
nowayout
)
{
size_t
i
;
/* In case it was set long ago */
expect_close
=
0
;
for
(
i
=
0
;
i
!=
count
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
buf
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
1
;
}
}
wafwdt_ping
();
return
1
;
}
return
0
;
}
static
int
wafwdt_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
int
new_margin
;
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_KEEPALIVEPING
|
WDIOF_SETTIMEOUT
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"Wafer 5823 WDT"
};
int
one
=
1
;
switch
(
cmd
)
{
case
WDIOC_GETSUPPORT
:
if
(
copy_to_user
((
struct
watchdog_info
*
)
arg
,
&
ident
,
sizeof
(
ident
)))
return
-
EFAULT
;
break
;
case
WDIOC_GETSTATUS
:
if
(
copy_to_user
((
int
*
)
arg
,
&
one
,
sizeof
(
int
)))
return
-
EFAULT
;
break
;
case
WDIOC_KEEPALIVE
:
wafwdt_ping
();
break
;
case
WDIOC_SETTIMEOUT
:
if
(
get_user
(
new_margin
,
(
int
*
)
arg
))
return
-
EFAULT
;
if
((
new_margin
<
1
)
||
(
new_margin
>
255
))
return
-
EINVAL
;
wd_margin
=
new_margin
;
wafwdt_stop
();
wafwdt_start
();
/* Fall */
case
WDIOC_GETTIMEOUT
:
return
put_user
(
wd_margin
,
(
int
*
)
arg
);
default:
return
-
ENOTTY
;
}
return
0
;
}
static
int
wafwdt_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
if
(
test_and_set_bit
(
0
,
&
wafwdt_is_open
))
return
-
EBUSY
;
wafwdt_start
();
return
0
;
}
static
int
wafwdt_close
(
struct
inode
*
inode
,
struct
file
*
file
)
{
clear_bit
(
0
,
&
wafwdt_is_open
);
if
(
expect_close
)
{
wafwdt_stop
();
}
else
{
printk
(
KERN_CRIT
"WDT device closed unexpectedly. WDT will not stop!
\n
"
);
}
return
0
;
}
/*
* Notifier for system down
*/
static
int
wafwdt_notify_sys
(
struct
notifier_block
*
this
,
unsigned
long
code
,
void
*
unused
)
{
if
(
code
==
SYS_DOWN
||
code
==
SYS_HALT
)
{
/* Turn the WDT off */
wafwdt_stop
();
}
return
NOTIFY_DONE
;
}
/*
* Kernel Interfaces
*/
static
struct
file_operations
wafwdt_fops
=
{
owner:
THIS_MODULE
,
write:
wafwdt_write
,
ioctl:
wafwdt_ioctl
,
open:
wafwdt_open
,
release:
wafwdt_close
,
};
static
struct
miscdevice
wafwdt_miscdev
=
{
WATCHDOG_MINOR
,
"watchdog"
,
&
wafwdt_fops
};
/*
* The WDT needs to learn about soft shutdowns in order to
* turn the timebomb registers off.
*/
static
struct
notifier_block
wafwdt_notifier
=
{
wafwdt_notify_sys
,
NULL
,
0
};
static
int
__init
wafwdt_init
(
void
)
{
printk
(
KERN_INFO
"WDT driver for Wafer 5823 single board computer initialising.
\n
"
);
spin_lock_init
(
&
wafwdt_lock
);
if
(
!
request_region
(
WDT_STOP
,
1
,
"Wafer 5823 WDT"
))
goto
error
;
if
(
!
request_region
(
WDT_START
,
1
,
"Wafer 5823 WDT"
))
goto
error2
;
if
(
misc_register
(
&
wafwdt_miscdev
)
<
0
)
goto
error3
;
register_reboot_notifier
(
&
wafwdt_notifier
);
return
0
;
error3:
release_region
(
WDT_START
,
1
);
error2:
release_region
(
WDT_STOP
,
1
);
error:
return
-
ENODEV
;
}
static
void
__exit
wafwdt_exit
(
void
)
{
misc_deregister
(
&
wafwdt_miscdev
);
unregister_reboot_notifier
(
&
wafwdt_notifier
);
release_region
(
WDT_STOP
,
1
);
release_region
(
WDT_START
,
1
);
}
module_init
(
wafwdt_init
);
module_exit
(
wafwdt_exit
);
MODULE_AUTHOR
(
"Justin Cormack"
);
MODULE_LICENSE
(
"GPL"
);
EXPORT_NO_SYMBOLS
;
/* end of wafer5823wdt.c */
drivers/char/watchdog/wdt.c
View file @
bdc91033
...
...
@@ -52,6 +52,7 @@
#include <asm/system.h>
static
unsigned
long
wdt_is_open
;
static
int
expect_close
;
/*
* You must set these - there is no sane way to probe for this board.
...
...
@@ -258,8 +259,21 @@ static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_
if
(
ppos
!=
&
file
->
f_pos
)
return
-
ESPIPE
;
if
(
count
)
{
if
(
count
)
{
if
(
!
nowayout
)
{
size_t
i
;
/* In case it was set long ago */
expect_close
=
0
;
for
(
i
=
0
;
i
!=
count
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
buf
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
1
;
}
}
wdt_ping
();
return
1
;
}
...
...
@@ -317,10 +331,11 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
{
static
struct
watchdog_info
ident
=
{
WDIOF_OVERHEAT
|
WDIOF_POWERUNDER
|
WDIOF_POWEROVER
|
WDIOF_EXTERN1
|
WDIOF_EXTERN2
|
WDIOF_FANFAULT
,
1
,
"WDT500/501"
.
options
=
WDIOF_OVERHEAT
|
WDIOF_POWERUNDER
|
WDIOF_POWEROVER
|
WDIOF_EXTERN1
|
WDIOF_EXTERN2
|
WDIOF_FANFAULT
|
WDIOF_SETTIMEOUT
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"WDT500/501"
};
ident
.
options
&=
WDT_OPTION_MASK
;
/* Mask down to the card we have */
...
...
@@ -399,9 +414,11 @@ static int wdt_release(struct inode *inode, struct file *file)
{
if
(
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
if
(
!
nowayout
)
{
if
(
expect_close
)
{
inb_p
(
WDT_DC
);
/* Disable counters */
wdt_ctr_load
(
2
,
0
);
/* 0 length reset pulses now */
}
else
{
printk
(
KERN_CRIT
"wdt: WDT device closed unexpectedly. WDT will not stop!
\n
"
);
}
clear_bit
(
0
,
&
wdt_is_open
);
}
...
...
drivers/char/watchdog/wdt977.c
View file @
bdc91033
...
...
@@ -41,6 +41,7 @@ static int timeout = DEFAULT_TIMEOUT*60; /* TO in seconds from user */
static
int
timeoutM
=
DEFAULT_TIMEOUT
;
/* timeout in minutes */
static
unsigned
long
timer_alive
;
static
int
testmode
;
static
int
expect_close
=
0
;
MODULE_PARM
(
timeout
,
"i"
);
MODULE_PARM_DESC
(
timeout
,
"Watchdog timeout in seconds (60..15300), default=60"
);
...
...
@@ -196,6 +197,8 @@ static int wdt977_release(struct inode *inode, struct file *file)
clear_bit
(
0
,
&
timer_alive
);
printk
(
KERN_INFO
"Wdt977 Watchdog: shutdown
\n
"
);
}
else
{
printk
(
KERN_CRIT
"WDT device closed unexpectedly. WDT will not stop!
\n
"
);
}
return
0
;
}
...
...
@@ -220,6 +223,21 @@ static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, lo
if
(
count
)
{
if
(
!
nowayout
)
{
size_t
i
;
/* In case it was set long ago */
expect_close
=
0
;
for
(
i
=
0
;
i
!=
len
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
data
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
1
;
}
}
kick_wdog
();
return
1
;
}
...
...
drivers/char/watchdog/wdt_pci.c
View file @
bdc91033
...
...
@@ -73,6 +73,7 @@
#endif
static
unsigned
long
wdt_is_open
;
static
int
expect_close
=
0
;
/*
* You must set these - there is no sane way to probe for this board.
...
...
@@ -276,6 +277,16 @@ static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, lo
if
(
count
)
{
if
(
!
nowayout
)
{
size_t
i
;
for
(
i
=
0
;
i
!=
count
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
buf
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
1
;
}
}
wdtpci_ping
();
return
1
;
}
...
...
@@ -334,7 +345,8 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_OVERHEAT
|
WDIOF_POWERUNDER
|
WDIOF_POWEROVER
|
WDIOF_EXTERN1
|
WDIOF_EXTERN2
|
WDIOF_FANFAULT
,
WDIOF_EXTERN2
|
WDIOF_FANFAULT
|
WDIOF_SETTIMEOUT
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
identity
=
"WDT500/501PCI"
,
};
...
...
include/linux/watchdog.h
View file @
bdc91033
...
...
@@ -39,6 +39,7 @@ struct watchdog_info {
#define WDIOF_CARDRESET 0x0020
/* Card previously reset the CPU */
#define WDIOF_POWEROVER 0x0040
/* Power over voltage */
#define WDIOF_SETTIMEOUT 0x0080
/* Set timeout (in seconds) */
#define WDIOF_MAGICCLOSE 0x0100
/* Supports magic close char */
#define WDIOF_KEEPALIVEPING 0x8000
/* Keep alive ping reply */
#define WDIOS_DISABLECARD 0x0001
/* Turn off the watchdog timer */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment