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
e5643ec8
Commit
e5643ec8
authored
Aug 04, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux-watchdog.bkbits.net/linux-2.5-watchdog
into home.osdl.org:/home/torvalds/v2.5/linux
parents
bec09e25
870c2c81
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
82 additions
and
57 deletions
+82
-57
drivers/char/watchdog/advantechwdt.c
drivers/char/watchdog/advantechwdt.c
+82
-57
No files found.
drivers/char/watchdog/advantechwdt.c
View file @
e5643ec8
/*
* Advantech Single Board Computer WDT driver
for Linux 2.4.x
* Advantech Single Board Computer WDT driver
*
* (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
*
...
...
@@ -22,10 +22,14 @@
*
* 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
* Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
*
* 16-Oct-2002 Rob Radez <rob@osinvestor.com>
* Clean up ioctls, clean up init + exit, add expect close support,
* add wdt_start and wdt_stop as parameters.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
...
...
@@ -39,6 +43,9 @@
#include <asm/uaccess.h>
#include <asm/system.h>
#define WATCHDOG_NAME "Advantech WDT"
#define WATCHDOG_TIMEOUT 60
/* 60 sec default timeout */
static
unsigned
long
advwdt_is_open
;
static
char
adv_expect_close
;
...
...
@@ -52,11 +59,18 @@ static char adv_expect_close;
* the manual says wdt_stop is 0x43, not 0x443).
* (0x43 is also a write-only control register for the 8254 timer!)
*/
static
int
wdt_stop
=
0x443
;
module_param
(
wdt_stop
,
int
,
0
);
MODULE_PARM_DESC
(
wdt_stop
,
"Advantech WDT 'stop' io port (default 0x443)"
);
static
int
wdt_start
=
0x443
;
module_param
(
wdt_start
,
int
,
0
);
MODULE_PARM_DESC
(
wdt_start
,
"Advantech WDT 'start' io port (default 0x443)"
);
static
int
wd_margin
=
60
;
/* 60 sec default timeout */
static
int
timeout
=
WATCHDOG_TIMEOUT
;
/* in seconds */
module_param
(
timeout
,
int
,
0
);
MODULE_PARM_DESC
(
timeout
,
"Watchdog timeout in seconds. 1<= timeout <=63, default=60."
);
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static
int
nowayout
=
1
;
...
...
@@ -64,44 +78,18 @@ static int nowayout = 1;
static
int
nowayout
=
0
;
#endif
MODULE_PARM
(
nowayout
,
"i"
);
module_param
(
nowayout
,
int
,
0
);
MODULE_PARM_DESC
(
nowayout
,
"Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"
);
/*
* Kernel methods.
*/
#ifndef MODULE
static
int
__init
adv_setup
(
char
*
str
)
{
int
ints
[
4
];
str
=
get_options
(
str
,
ARRAY_SIZE
(
ints
),
ints
);
if
(
ints
[
0
]
>
0
){
wdt_stop
=
ints
[
1
];
if
(
ints
[
0
]
>
1
)
wdt_start
=
ints
[
2
];
}
return
1
;
}
__setup
(
"advwdt="
,
adv_setup
);
#endif
/* !MODULE */
MODULE_PARM
(
wdt_stop
,
"i"
);
MODULE_PARM_DESC
(
wdt_stop
,
"Advantech WDT 'stop' io port (default 0x443)"
);
MODULE_PARM
(
wdt_start
,
"i"
);
MODULE_PARM_DESC
(
wdt_start
,
"Advantech WDT 'start' io port (default 0x443)"
);
static
void
advwdt_ping
(
void
)
{
/* Write a watchdog value */
outb_p
(
wd_margin
,
wdt_start
);
outb_p
(
timeout
,
wdt_start
);
}
static
void
...
...
@@ -140,7 +128,7 @@ static int
advwdt_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
int
new_
margin
;
int
new_
timeout
;
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_KEEPALIVEPING
|
WDIOF_SETTIMEOUT
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
...
...
@@ -162,16 +150,16 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
break
;
case
WDIOC_SETTIMEOUT
:
if
(
get_user
(
new_
margin
,
(
int
*
)
arg
))
if
(
get_user
(
new_
timeout
,
(
int
*
)
arg
))
return
-
EFAULT
;
if
((
new_
margin
<
1
)
||
(
new_margin
>
63
))
if
((
new_
timeout
<
1
)
||
(
new_timeout
>
63
))
return
-
EINVAL
;
wd_margin
=
new_margin
;
timeout
=
new_timeout
;
advwdt_ping
();
/* Fall */
case
WDIOC_GETTIMEOUT
:
return
put_user
(
wd_margin
,
(
int
*
)
arg
);
return
put_user
(
timeout
,
(
int
*
)
arg
);
case
WDIOC_SETOPTIONS
:
{
...
...
@@ -218,7 +206,7 @@ advwdt_close(struct inode *inode, struct file *file)
if
(
adv_expect_close
==
42
)
{
advwdt_disable
();
}
else
{
printk
(
KERN_CRIT
"advancetechwdt
: Unexpected close, not stopping watchdog!
\n
"
);
printk
(
KERN_CRIT
WATCHDOG_NAME
"
: Unexpected close, not stopping watchdog!
\n
"
);
advwdt_ping
();
}
clear_bit
(
0
,
&
advwdt_is_open
);
...
...
@@ -240,13 +228,14 @@ advwdt_notify_sys(struct notifier_block *this, unsigned long code,
}
return
NOTIFY_DONE
;
}
/*
* Kernel Interfaces
*/
static
struct
file_operations
advwdt_fops
=
{
.
owner
=
THIS_MODULE
,
.
llseek
=
no_llseek
,
.
write
=
advwdt_write
,
.
ioctl
=
advwdt_ioctl
,
.
open
=
advwdt_open
,
...
...
@@ -256,40 +245,76 @@ static struct file_operations advwdt_fops = {
static
struct
miscdevice
advwdt_miscdev
=
{
.
minor
=
WATCHDOG_MINOR
,
.
name
=
"watchdog"
,
.
fops
=
&
advwdt_fops
.
fops
=
&
advwdt_fops
,
};
/*
* The WDT needs to learn about soft shutdowns in order to
* turn the timebomb registers off.
* turn the timebomb registers off.
*/
static
struct
notifier_block
advwdt_notifier
=
{
.
notifier_call
=
advwdt_notify_sys
,
.
next
=
NULL
,
.
priority
=
0
.
priority
=
0
,
};
static
int
__init
advwdt_init
(
void
)
{
int
ret
;
printk
(
KERN_INFO
"WDT driver for Advantech single board computer initialising.
\n
"
);
if
(
misc_register
(
&
advwdt_miscdev
))
return
-
ENODEV
;
if
(
wdt_stop
!=
wdt_start
)
if
(
!
request_region
(
wdt_stop
,
1
,
"Advantech WDT"
))
{
misc_deregister
(
&
advwdt_miscdev
);
return
-
EIO
;
if
(
timeout
<
1
||
timeout
>
63
)
{
timeout
=
WATCHDOG_TIMEOUT
;
printk
(
KERN_INFO
WATCHDOG_NAME
": timeout value must be 1<=x<=63, using %d
\n
"
,
timeout
);
}
if
(
!
request_region
(
wdt_start
,
1
,
"Advantech WDT"
))
{
misc_deregister
(
&
advwdt_miscdev
);
if
(
wdt_stop
!=
wdt_start
)
release_region
(
wdt_stop
,
1
);
return
-
EIO
;
if
(
wdt_stop
!=
wdt_start
)
{
if
(
!
request_region
(
wdt_stop
,
1
,
WATCHDOG_NAME
))
{
printk
(
KERN_ERR
WATCHDOG_NAME
": I/O address 0x%04x already in use
\n
"
,
wdt_stop
);
ret
=
-
EIO
;
goto
out
;
}
}
register_reboot_notifier
(
&
advwdt_notifier
);
return
0
;
if
(
!
request_region
(
wdt_start
,
1
,
WATCHDOG_NAME
))
{
printk
(
KERN_ERR
WATCHDOG_NAME
": I/O address 0x%04x already in use
\n
"
,
wdt_start
);
ret
=
-
EIO
;
goto
unreg_stop
;
}
ret
=
register_reboot_notifier
(
&
advwdt_notifier
);
if
(
ret
!=
0
)
{
printk
(
KERN_ERR
WATCHDOG_NAME
": cannot register reboot notifier (err=%d)
\n
"
,
ret
);
goto
unreg_regions
;
}
ret
=
misc_register
(
&
advwdt_miscdev
);
if
(
ret
!=
0
)
{
printk
(
KERN_ERR
WATCHDOG_NAME
": cannot register miscdev on minor=%d (err=%d)
\n
"
,
WATCHDOG_MINOR
,
ret
);
goto
unreg_reboot
;
}
printk
(
KERN_INFO
WATCHDOG_NAME
": initialized. timeout=%d sec (nowayout=%d)
\n
"
,
timeout
,
nowayout
);
out:
return
ret
;
unreg_reboot:
unregister_reboot_notifier
(
&
advwdt_notifier
);
unreg_regions:
release_region
(
wdt_start
,
1
);
unreg_stop:
if
(
wdt_stop
!=
wdt_start
)
release_region
(
wdt_stop
,
1
);
goto
out
;
}
static
void
__exit
...
...
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