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
2ac7e7a9
Commit
2ac7e7a9
authored
Jan 14, 2003
by
Dave Jones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[WATCHDOG] Final 2.4 bits for advantechwdt
parent
d75013dd
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
111 additions
and
84 deletions
+111
-84
drivers/char/watchdog/advantechwdt.c
drivers/char/watchdog/advantechwdt.c
+111
-84
No files found.
drivers/char/watchdog/advantechwdt.c
View file @
2ac7e7a9
...
@@ -22,7 +22,6 @@
...
@@ -22,7 +22,6 @@
*
*
* 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
* 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
* Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
* Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
* Added timeout module option to override default
*/
*/
#include <linux/config.h>
#include <linux/config.h>
...
@@ -40,31 +39,24 @@
...
@@ -40,31 +39,24 @@
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/system.h>
static
int
advwdt_is_open
;
static
unsigned
long
advwdt_is_open
;
static
char
adv_expect_close
;
static
char
adv_expect_close
;
static
spinlock_t
advwdt_lock
;
/*
/*
* You must set these - there is no sane way to probe for this board.
* You must set these - there is no sane way to probe for this board.
*
*
* To enable or restart, write the timeout value in seconds (1 to 63)
* To enable or restart, write the timeout value in seconds (1 to 63)
* to I/O port
WDT_START. To disable, read I/O port WDT_STOP
.
* to I/O port
wdt_start. To disable, read I/O port wdt_stop
.
* Both are 0x443 for most boards (tested on a PCA-6276VE-00B1), but
* Both are 0x443 for most boards (tested on a PCA-6276VE-00B1), but
* check your manual (at least the PCA-6159 seems to be different -
* check your manual (at least the PCA-6159 seems to be different -
* the manual says
WDT_STOP
is 0x43, not 0x443).
* the manual says
wdt_stop
is 0x43, not 0x443).
* (0x43 is also a write-only control register for the 8254 timer!)
* (0x43 is also a write-only control register for the 8254 timer!)
*
* TODO: module parameters to set the I/O port addresses
*/
*/
#define WDT_STOP 0x443
static
int
wdt_stop
=
0x443
;
#define WDT_START 0x443
static
int
wdt_start
=
0x443
;
#define WD_TIMO 60
/* 1 minute */
static
int
timeout
=
WD_TIMO
;
/* in seconds */
static
int
wd_margin
=
60
;
/* 60 sec default timeout */
MODULE_PARM
(
timeout
,
"i"
);
MODULE_PARM_DESC
(
timeout
,
"Watchdog timeout in seconds (default=60)"
);
#ifdef CONFIG_WATCHDOG_NOWAYOUT
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static
int
nowayout
=
1
;
static
int
nowayout
=
1
;
...
@@ -79,11 +71,43 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
...
@@ -79,11 +71,43 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
* Kernel methods.
* 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
static
void
advwdt_ping
(
void
)
advwdt_ping
(
void
)
{
{
/* Write a watchdog value */
/* Write a watchdog value */
outb_p
(
timeout
,
WDT_START
);
outb_p
(
wd_margin
,
wdt_start
);
}
static
void
advwdt_disable
(
void
)
{
inb_p
(
wdt_stop
);
}
}
static
ssize_t
static
ssize_t
...
@@ -112,16 +136,11 @@ advwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
...
@@ -112,16 +136,11 @@ advwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
return
count
;
return
count
;
}
}
static
ssize_t
advwdt_read
(
struct
file
*
file
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
return
-
EINVAL
;
}
static
int
static
int
advwdt_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
advwdt_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
unsigned
long
arg
)
{
{
int
new_margin
;
static
struct
watchdog_info
ident
=
{
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_KEEPALIVEPING
|
WDIOF_SETTIMEOUT
|
WDIOF_MAGICCLOSE
,
.
options
=
WDIOF_KEEPALIVEPING
|
WDIOF_SETTIMEOUT
|
WDIOF_MAGICCLOSE
,
.
firmware_version
=
1
,
.
firmware_version
=
1
,
...
@@ -135,14 +154,45 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
...
@@ -135,14 +154,45 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
break
;
break
;
case
WDIOC_GETSTATUS
:
case
WDIOC_GETSTATUS
:
if
(
copy_to_user
((
int
*
)
arg
,
&
advwdt_is_open
,
sizeof
(
int
)))
case
WDIOC_GETBOOTSTATUS
:
return
-
EFAULT
;
return
put_user
(
0
,
(
int
*
)
arg
);
break
;
case
WDIOC_KEEPALIVE
:
case
WDIOC_KEEPALIVE
:
advwdt_ping
();
advwdt_ping
();
break
;
break
;
case
WDIOC_SETTIMEOUT
:
if
(
get_user
(
new_margin
,
(
int
*
)
arg
))
return
-
EFAULT
;
if
((
new_margin
<
1
)
||
(
new_margin
>
63
))
return
-
EINVAL
;
wd_margin
=
new_margin
;
advwdt_ping
();
/* Fall */
case
WDIOC_GETTIMEOUT
:
return
put_user
(
wd_margin
,
(
int
*
)
arg
);
case
WDIOC_SETOPTIONS
:
{
int
options
,
retval
=
-
EINVAL
;
if
(
get_user
(
options
,
(
int
*
)
arg
))
return
-
EFAULT
;
if
(
options
&
WDIOS_DISABLECARD
)
{
advwdt_disable
();
retval
=
0
;
}
if
(
options
&
WDIOS_ENABLECARD
)
{
advwdt_ping
();
retval
=
0
;
}
return
retval
;
}
default:
default:
return
-
ENOTTY
;
return
-
ENOTTY
;
}
}
...
@@ -152,37 +202,27 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
...
@@ -152,37 +202,27 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static
int
static
int
advwdt_open
(
struct
inode
*
inode
,
struct
file
*
file
)
advwdt_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
{
if
(
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
if
(
test_and_set_bit
(
0
,
&
advwdt_is_open
))
spin_lock
(
&
advwdt_lock
);
if
(
advwdt_is_open
)
{
spin_unlock
(
&
advwdt_lock
);
return
-
EBUSY
;
return
-
EBUSY
;
}
/*
* Activate
if
(
nowayout
)
*/
MOD_INC_USE_COUNT
;
/* Activate */
advwdt_is_open
=
1
;
advwdt_ping
();
advwdt_ping
();
spin_unlock
(
&
advwdt_lock
);
return
0
;
return
0
;
}
else
{
return
-
ENODEV
;
}
}
}
static
int
static
int
advwdt_close
(
struct
inode
*
inode
,
struct
file
*
file
)
advwdt_close
(
struct
inode
*
inode
,
struct
file
*
file
)
{
{
if
(
minor
(
inode
->
i_rdev
)
==
WATCHDOG_MINOR
)
{
if
(
adv_expect_close
==
42
)
{
spin_lock
(
&
advwdt_lock
);
advwdt_disable
();
if
(
!
nowayout
)
}
else
{
inb_p
(
WDT_STOP
);
printk
(
KERN_CRIT
"advancetechwdt: Unexpected close, not stopping watchdog!
\n
"
);
advwdt_ping
();
advwdt_is_open
=
0
;
spin_unlock
(
&
advwdt_lock
);
}
}
clear_bit
(
0
,
&
advwdt_is_open
);
adv_expect_close
=
0
;
return
0
;
return
0
;
}
}
...
@@ -194,10 +234,10 @@ static int
...
@@ -194,10 +234,10 @@ static int
advwdt_notify_sys
(
struct
notifier_block
*
this
,
unsigned
long
code
,
advwdt_notify_sys
(
struct
notifier_block
*
this
,
unsigned
long
code
,
void
*
unused
)
void
*
unused
)
{
{
if
(
code
==
SYS_DOWN
||
code
==
SYS_HALT
)
if
(
code
==
SYS_DOWN
||
code
==
SYS_HALT
)
{
/* Turn the WDT off */
/* Turn the WDT off */
inb_p
(
WDT_STOP
);
advwdt_disable
(
);
}
return
NOTIFY_DONE
;
return
NOTIFY_DONE
;
}
}
...
@@ -207,7 +247,6 @@ advwdt_notify_sys(struct notifier_block *this, unsigned long code,
...
@@ -207,7 +247,6 @@ advwdt_notify_sys(struct notifier_block *this, unsigned long code,
static
struct
file_operations
advwdt_fops
=
{
static
struct
file_operations
advwdt_fops
=
{
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
read
=
advwdt_read
,
.
write
=
advwdt_write
,
.
write
=
advwdt_write
,
.
ioctl
=
advwdt_ioctl
,
.
ioctl
=
advwdt_ioctl
,
.
open
=
advwdt_open
,
.
open
=
advwdt_open
,
...
@@ -231,35 +270,22 @@ static struct notifier_block advwdt_notifier = {
...
@@ -231,35 +270,22 @@ static struct notifier_block advwdt_notifier = {
.
priority
=
0
.
priority
=
0
};
};
static
void
__init
advwdt_validate_timeout
(
void
)
{
if
(
timeout
<
1
||
timeout
>
63
)
{
timeout
=
WD_TIMO
;
printk
(
KERN_INFO
"advantechwdt: timeout value must be 1 <= x <= 63, using %d
\n
"
,
timeout
);
}
}
static
int
__init
static
int
__init
advwdt_init
(
void
)
advwdt_init
(
void
)
{
{
printk
(
"WDT driver for Advantech single board computer initialising.
\n
"
);
printk
(
KERN_INFO
"WDT driver for Advantech single board computer initialising.
\n
"
);
advwdt_validate_timeout
();
spin_lock_init
(
&
advwdt_lock
);
if
(
misc_register
(
&
advwdt_miscdev
))
if
(
misc_register
(
&
advwdt_miscdev
))
return
-
ENODEV
;
return
-
ENODEV
;
#if WDT_START != WDT_STOP
if
(
wdt_stop
!=
wdt_start
)
if
(
!
request_region
(
WDT_STOP
,
1
,
"Advantech WDT"
))
{
if
(
!
request_region
(
wdt_stop
,
1
,
"Advantech WDT"
))
{
misc_deregister
(
&
advwdt_miscdev
);
misc_deregister
(
&
advwdt_miscdev
);
return
-
EIO
;
return
-
EIO
;
}
}
#endif
if
(
!
request_region
(
wdt_start
,
1
,
"Advantech WDT"
))
{
if
(
!
request_region
(
WDT_START
,
1
,
"Advantech WDT"
))
{
misc_deregister
(
&
advwdt_miscdev
);
misc_deregister
(
&
advwdt_miscdev
);
#if WDT_START != WDT_STOP
if
(
wdt_stop
!=
wdt_start
)
release_region
(
WDT_STOP
,
1
);
release_region
(
wdt_stop
,
1
);
#endif
return
-
EIO
;
return
-
EIO
;
}
}
register_reboot_notifier
(
&
advwdt_notifier
);
register_reboot_notifier
(
&
advwdt_notifier
);
...
@@ -271,14 +297,15 @@ advwdt_exit(void)
...
@@ -271,14 +297,15 @@ advwdt_exit(void)
{
{
misc_deregister
(
&
advwdt_miscdev
);
misc_deregister
(
&
advwdt_miscdev
);
unregister_reboot_notifier
(
&
advwdt_notifier
);
unregister_reboot_notifier
(
&
advwdt_notifier
);
#if WDT_START != WDT_STOP
if
(
wdt_stop
!=
wdt_start
)
release_region
(
WDT_STOP
,
1
);
release_region
(
wdt_stop
,
1
);
#endif
release_region
(
wdt_start
,
1
);
release_region
(
WDT_START
,
1
);
}
}
module_init
(
advwdt_init
);
module_init
(
advwdt_init
);
module_exit
(
advwdt_exit
);
module_exit
(
advwdt_exit
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Marek Michalkiewicz <marekm@linux.org.pl>"
);
MODULE_DESCRIPTION
(
"Advantech Single Board Computer WDT driver"
);
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