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
Kirill Smelkov
linux
Commits
77a557ae
Commit
77a557ae
authored
Feb 11, 2004
by
Wim Van Sebroeck
Committed by
Linus Torvalds
Feb 11, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[WATCHDOG] v2.6.2 shwdt-cleanup
Make heartbeat a module parameter and some general clean-up.
parent
aeee0c35
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
90 additions
and
41 deletions
+90
-41
drivers/char/watchdog/shwdt.c
drivers/char/watchdog/shwdt.c
+90
-41
No files found.
drivers/char/watchdog/shwdt.c
View file @
77a557ae
...
@@ -33,6 +33,8 @@
...
@@ -33,6 +33,8 @@
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/watchdog.h>
#include <asm/watchdog.h>
#define PFX "shwdt: "
/*
/*
* Default clock division ratio is 5.25 msecs. For an additional table of
* Default clock division ratio is 5.25 msecs. For an additional table of
* values, consult the asm-sh/watchdog.h. Overload this at module load
* values, consult the asm-sh/watchdog.h. Overload this at module load
...
@@ -70,7 +72,9 @@ static struct watchdog_info sh_wdt_info;
...
@@ -70,7 +72,9 @@ static struct watchdog_info sh_wdt_info;
static
char
shwdt_expect_close
;
static
char
shwdt_expect_close
;
static
struct
timer_list
timer
;
static
struct
timer_list
timer
;
static
unsigned
long
next_heartbeat
;
static
unsigned
long
next_heartbeat
;
static
int
heartbeat
=
30
;
#define WATCHDOG_HEARTBEAT 30
/* 30 sec default heartbeat */
static
int
heartbeat
=
WATCHDOG_HEARTBEAT
;
/* in seconds */
#ifdef CONFIG_WATCHDOG_NOWAYOUT
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static
int
nowayout
=
1
;
static
int
nowayout
=
1
;
...
@@ -87,8 +91,8 @@ static void sh_wdt_start(void)
...
@@ -87,8 +91,8 @@ static void sh_wdt_start(void)
{
{
__u8
csr
;
__u8
csr
;
mod_timer
(
&
timer
,
next_ping_period
(
clock_division_ratio
));
next_heartbeat
=
jiffies
+
(
heartbeat
*
HZ
);
next_heartbeat
=
jiffies
+
(
heartbeat
*
HZ
);
mod_timer
(
&
timer
,
next_ping_period
(
clock_division_ratio
));
csr
=
sh_wdt_read_csr
();
csr
=
sh_wdt_read_csr
();
csr
|=
WTCSR_WT
|
clock_division_ratio
;
csr
|=
WTCSR_WT
|
clock_division_ratio
;
...
@@ -141,6 +145,30 @@ static void sh_wdt_stop(void)
...
@@ -141,6 +145,30 @@ static void sh_wdt_stop(void)
sh_wdt_write_csr
(
csr
);
sh_wdt_write_csr
(
csr
);
}
}
/**
* sh_wdt_keepalive - Keep the Userspace Watchdog Alive
*
* The Userspace watchdog got a KeepAlive: schedule the next heartbeat.
*/
static
void
sh_wdt_keepalive
(
void
)
{
next_heartbeat
=
jiffies
+
(
heartbeat
*
HZ
);
}
/**
* sh_wdt_set_heartbeat - Set the Userspace Watchdog heartbeat
*
* Set the Userspace Watchdog heartbeat
*/
static
int
sh_wdt_set_heartbeat
(
int
t
)
{
if
((
t
<
1
)
||
(
t
>
3600
))
/* arbitrary upper limit */
return
-
EINVAL
;
heartbeat
=
t
;
return
0
;
}
/**
/**
* sh_wdt_ping - Ping the Watchdog
* sh_wdt_ping - Ping the Watchdog
*
*
...
@@ -160,6 +188,8 @@ static void sh_wdt_ping(unsigned long data)
...
@@ -160,6 +188,8 @@ static void sh_wdt_ping(unsigned long data)
sh_wdt_write_cnt
(
0
);
sh_wdt_write_cnt
(
0
);
mod_timer
(
&
timer
,
next_ping_period
(
clock_division_ratio
));
mod_timer
(
&
timer
,
next_ping_period
(
clock_division_ratio
));
}
else
{
printk
(
KERN_WARNING
PFX
"Heartbeat lost! Will not ping the watchdog
\n
"
);
}
}
}
}
...
@@ -193,11 +223,11 @@ static int sh_wdt_open(struct inode *inode, struct file *file)
...
@@ -193,11 +223,11 @@ static int sh_wdt_open(struct inode *inode, struct file *file)
*/
*/
static
int
sh_wdt_close
(
struct
inode
*
inode
,
struct
file
*
file
)
static
int
sh_wdt_close
(
struct
inode
*
inode
,
struct
file
*
file
)
{
{
if
(
!
nowayout
&&
shwdt_expect_close
==
42
)
{
if
(
shwdt_expect_close
==
42
)
{
sh_wdt_stop
();
sh_wdt_stop
();
}
else
{
}
else
{
printk
(
KERN_CRIT
"shwdt:
Unexpected close, not stopping watchdog!
\n
"
);
printk
(
KERN_CRIT
PFX
"
Unexpected close, not stopping watchdog!
\n
"
);
next_heartbeat
=
jiffies
+
(
heartbeat
*
HZ
);
sh_wdt_keepalive
(
);
}
}
clear_bit
(
0
,
&
shwdt_is_open
);
clear_bit
(
0
,
&
shwdt_is_open
);
...
@@ -224,18 +254,20 @@ static ssize_t sh_wdt_write(struct file *file, const char *buf,
...
@@ -224,18 +254,20 @@ static ssize_t sh_wdt_write(struct file *file, const char *buf,
return
-
ESPIPE
;
return
-
ESPIPE
;
if
(
count
)
{
if
(
count
)
{
size_t
i
;
if
(
!
nowayout
)
{
size_t
i
;
shwdt_expect_close
=
0
;
shwdt_expect_close
=
0
;
for
(
i
=
0
;
i
!=
count
;
i
++
)
{
for
(
i
=
0
;
i
!=
count
;
i
++
)
{
char
c
;
char
c
;
if
(
get_user
(
c
,
buf
+
i
))
if
(
get_user
(
c
,
buf
+
i
))
return
-
EFAULT
;
return
-
EFAULT
;
if
(
c
==
'V'
)
if
(
c
==
'V'
)
shwdt_expect_close
=
42
;
shwdt_expect_close
=
42
;
}
}
}
next_heartbeat
=
jiffies
+
(
heartbeat
*
HZ
);
sh_wdt_keepalive
(
);
}
}
return
count
;
return
count
;
...
@@ -255,38 +287,32 @@ static ssize_t sh_wdt_write(struct file *file, const char *buf,
...
@@ -255,38 +287,32 @@ static ssize_t sh_wdt_write(struct file *file, const char *buf,
static
int
sh_wdt_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
static
int
sh_wdt_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
unsigned
int
cmd
,
unsigned
long
arg
)
{
{
int
new_timeout
;
int
new_heartbeat
;
int
options
,
retval
=
-
EINVAL
;
switch
(
cmd
)
{
switch
(
cmd
)
{
case
WDIOC_GETSUPPORT
:
case
WDIOC_GETSUPPORT
:
if
(
copy_to_user
((
struct
watchdog_info
*
)
arg
,
return
copy_to_user
((
struct
watchdog_info
*
)
arg
,
&
sh_wdt_info
,
&
sh_wdt_info
,
sizeof
(
sh_wdt_info
)))
{
sizeof
(
sh_wdt_info
))
?
-
EFAULT
:
0
;
return
-
EFAULT
;
}
break
;
case
WDIOC_GETSTATUS
:
case
WDIOC_GETSTATUS
:
case
WDIOC_GETBOOTSTATUS
:
case
WDIOC_GETBOOTSTATUS
:
return
put_user
(
0
,
(
int
*
)
arg
);
return
put_user
(
0
,
(
int
*
)
arg
);
case
WDIOC_KEEPALIVE
:
case
WDIOC_KEEPALIVE
:
next_heartbeat
=
jiffies
+
(
heartbeat
*
HZ
);
sh_wdt_keepalive
();
return
0
;
break
;
case
WDIOC_SETTIMEOUT
:
case
WDIOC_SETTIMEOUT
:
if
(
get_user
(
new_
timeou
t
,
(
int
*
)
arg
))
if
(
get_user
(
new_
heartbea
t
,
(
int
*
)
arg
))
return
-
EFAULT
;
return
-
EFAULT
;
if
(
new_timeout
<
1
||
new_timeout
>
3600
)
/* arbitrary upper limit */
if
(
sh_wdt_set_heartbeat
(
new_heartbeat
))
return
-
EINVAL
;
return
-
EINVAL
;
heartbeat
=
new_timeout
;
next_heartbeat
=
jiffies
+
(
heartbeat
*
HZ
);
sh_wdt_keepalive
(
);
/* Fall */
/* Fall */
case
WDIOC_GETTIMEOUT
:
case
WDIOC_GETTIMEOUT
:
return
put_user
(
heartbeat
,
(
int
*
)
arg
);
return
put_user
(
heartbeat
,
(
int
*
)
arg
);
case
WDIOC_SETOPTIONS
:
case
WDIOC_SETOPTIONS
:
{
int
options
,
retval
=
-
EINVAL
;
if
(
get_user
(
options
,
(
int
*
)
arg
))
if
(
get_user
(
options
,
(
int
*
)
arg
))
return
-
EFAULT
;
return
-
EFAULT
;
...
@@ -301,7 +327,6 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file,
...
@@ -301,7 +327,6 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file,
}
}
return
retval
;
return
retval
;
}
default:
default:
return
-
ENOIOCTLCMD
;
return
-
ENOIOCTLCMD
;
}
}
...
@@ -346,7 +371,6 @@ static struct watchdog_info sh_wdt_info = {
...
@@ -346,7 +371,6 @@ static struct watchdog_info sh_wdt_info = {
static
struct
notifier_block
sh_wdt_notifier
=
{
static
struct
notifier_block
sh_wdt_notifier
=
{
.
notifier_call
=
sh_wdt_notify_sys
,
.
notifier_call
=
sh_wdt_notify_sys
,
.
priority
=
0
,
};
};
static
struct
miscdevice
sh_wdt_miscdev
=
{
static
struct
miscdevice
sh_wdt_miscdev
=
{
...
@@ -363,21 +387,42 @@ static struct miscdevice sh_wdt_miscdev = {
...
@@ -363,21 +387,42 @@ static struct miscdevice sh_wdt_miscdev = {
*/
*/
static
int
__init
sh_wdt_init
(
void
)
static
int
__init
sh_wdt_init
(
void
)
{
{
if
(
misc_register
(
&
sh_wdt_miscdev
))
{
int
rc
;
printk
(
KERN_ERR
"shwdt: Can't register misc device
\n
"
);
return
-
EINVAL
;
if
((
clock_division_ratio
<
0x5
)
||
(
clock_division_ratio
>
0x7
))
{
clock_division_ratio
=
WTCSR_CKS_4096
;
printk
(
KERN_INFO
PFX
"clock_division_ratio value must be 0x5<=x<=0x7, using %d
\n
"
,
clock_division_ratio
);
}
}
if
(
register_reboot_notifier
(
&
sh_wdt_notifier
))
{
if
(
sh_wdt_set_heartbeat
(
heartbeat
))
printk
(
KERN_ERR
"shwdt: Can't register reboot notifier
\n
"
);
{
misc_deregister
(
&
sh_wdt_miscdev
);
heartbeat
=
WATCHDOG_HEARTBEAT
;
return
-
EINVAL
;
printk
(
KERN_INFO
PFX
"heartbeat value must be 1<=x<=3600, using %d
\n
"
,
heartbeat
);
}
}
init_timer
(
&
timer
);
init_timer
(
&
timer
);
timer
.
function
=
sh_wdt_ping
;
timer
.
function
=
sh_wdt_ping
;
timer
.
data
=
0
;
timer
.
data
=
0
;
rc
=
register_reboot_notifier
(
&
sh_wdt_notifier
);
if
(
rc
)
{
printk
(
KERN_ERR
PFX
"Can't register reboot notifier (err=%d)
\n
"
,
rc
);
return
rc
;
}
rc
=
misc_register
(
&
sh_wdt_miscdev
)
if
(
rc
)
{
printk
(
KERN_ERR
PFX
"Can't register miscdev on minor=%d (err=%d)
\n
"
,
sh_wdt_miscdev
.
minor
,
rc
);
unregister_reboot_notifier
(
&
sh_wdt_notifier
);
return
rc
;
}
printk
(
KERN_INFO
PFX
"initialized. heartbeat=%d sec (nowayout=%d)
\n
"
,
heartbeat
,
nowayout
);
return
0
;
return
0
;
}
}
...
@@ -389,17 +434,21 @@ static int __init sh_wdt_init(void)
...
@@ -389,17 +434,21 @@ static int __init sh_wdt_init(void)
*/
*/
static
void
__exit
sh_wdt_exit
(
void
)
static
void
__exit
sh_wdt_exit
(
void
)
{
{
unregister_reboot_notifier
(
&
sh_wdt_notifier
);
misc_deregister
(
&
sh_wdt_miscdev
);
misc_deregister
(
&
sh_wdt_miscdev
);
unregister_reboot_notifier
(
&
sh_wdt_notifier
);
}
}
MODULE_AUTHOR
(
"Paul Mundt <lethal@linux-sh.org>"
);
MODULE_AUTHOR
(
"Paul Mundt <lethal@linux-sh.org>"
);
MODULE_DESCRIPTION
(
"SuperH watchdog driver"
);
MODULE_DESCRIPTION
(
"SuperH watchdog driver"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
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). Defaults to 0x7."
);
MODULE_PARM_DESC
(
clock_division_ratio
,
"Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). Defaults to 0x7."
);
module_param
(
heartbeat
,
int
,
0
);
MODULE_PARM_DESC
(
heartbeat
,
"Watchdog heartbeat in seconds. (1<=heartbeat<=3600, default="
__MODULE_STRING
(
WATCHDOG_HEARTBEAT
)
")"
);
module_param
(
nowayout
,
int
,
0
);
module_param
(
nowayout
,
int
,
0
);
MODULE_PARM_DESC
(
nowayout
,
"Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"
);
MODULE_PARM_DESC
(
nowayout
,
"Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"
);
...
...
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