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
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