Commit d87b6141 authored by Dave Jones's avatar Dave Jones

[WATCHDOG] Final 2.4 bits for ib700wdt

parent 950cda48
...@@ -86,15 +86,32 @@ static int expect_close = 0; ...@@ -86,15 +86,32 @@ static int expect_close = 0;
* *
*/ */
static int wd_times[] = {
30, /* 0x0 */
28, /* 0x1 */
26, /* 0x2 */
24, /* 0x3 */
22, /* 0x4 */
20, /* 0x5 */
18, /* 0x6 */
16, /* 0x7 */
14, /* 0x8 */
12, /* 0x9 */
10, /* 0xA */
8, /* 0xB */
6, /* 0xC */
4, /* 0xD */
2, /* 0xE */
0, /* 0xF */
};
#define WDT_STOP 0x441 #define WDT_STOP 0x441
#define WDT_START 0x443 #define WDT_START 0x443
/* Default timeout */
#define WD_TIMO 0 /* 30 seconds +/- 20%, from table */ #define WD_TIMO 0 /* 30 seconds +/- 20%, from table */
static int timeout_val = WD_TIMO; /* value in table */ static int wd_margin = WD_TIMO;
static int timeout = 30; /* in seconds */
MODULE_PARM(timeout,"i");
MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, 0 < n < 30, must be even (default=30)");
#ifdef CONFIG_WATCHDOG_NOWAYOUT #ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1; static int nowayout = 1;
...@@ -105,22 +122,16 @@ static int nowayout = 0; ...@@ -105,22 +122,16 @@ static int nowayout = 0;
MODULE_PARM(nowayout,"i"); MODULE_PARM(nowayout,"i");
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)");
/* /*
* Kernel methods. * Kernel methods.
*/ */
static void __init
ibwdt_validate_timeout(void)
{
timeout_val = (30 - timeout) / 2;
if (timeout_val < 0 || timeout_val > 0xF) timeout_val = WD_TIMO;
}
static void static void
ibwdt_ping(void) ibwdt_ping(void)
{ {
/* Write a watchdog value */ /* Write a watchdog value */
outb_p(timeout_val, WDT_START); outb_p(wd_times[wd_margin], WDT_START);
} }
static ssize_t static ssize_t
...@@ -139,7 +150,6 @@ ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ...@@ -139,7 +150,6 @@ ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
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')
...@@ -162,6 +172,8 @@ static int ...@@ -162,6 +172,8 @@ static int
ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
int i, 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,
...@@ -183,6 +195,22 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -183,6 +195,22 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
ibwdt_ping(); ibwdt_ping();
break; break;
case WDIOC_SETTIMEOUT:
if (get_user(new_margin, (int *)arg))
return -EFAULT;
if ((new_margin < 0) || (new_margin > 30))
return -EINVAL;
for (i = 0x0F; i > -1; i--)
if (wd_times[i] > new_margin)
break;
wd_margin = i;
ibwdt_ping();
/* Fall */
case WDIOC_GETTIMEOUT:
return put_user(wd_times[wd_margin], (int *)arg);
break;
default: default:
return -ENOTTY; return -ENOTTY;
} }
...@@ -217,7 +245,7 @@ ibwdt_close(struct inode *inode, struct file *file) ...@@ -217,7 +245,7 @@ ibwdt_close(struct inode *inode, struct file *file)
if (minor(inode->i_rdev) == WATCHDOG_MINOR) { if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
spin_lock(&ibwdt_lock); spin_lock(&ibwdt_lock);
if (expect_close) if (expect_close)
outb_p(timeout_val, WDT_STOP); outb_p(wd_times[wd_margin], WDT_STOP);
else else
printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n"); printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n");
...@@ -237,7 +265,7 @@ ibwdt_notify_sys(struct notifier_block *this, unsigned long code, ...@@ -237,7 +265,7 @@ ibwdt_notify_sys(struct notifier_block *this, unsigned long code,
{ {
if (code == SYS_DOWN || code == SYS_HALT) { if (code == SYS_DOWN || code == SYS_HALT) {
/* Turn the WDT off */ /* Turn the WDT off */
outb_p(timeout_val, WDT_STOP); outb_p(wd_times[wd_margin], WDT_STOP);
} }
return NOTIFY_DONE; return NOTIFY_DONE;
} }
...@@ -277,7 +305,6 @@ ibwdt_init(void) ...@@ -277,7 +305,6 @@ ibwdt_init(void)
{ {
printk("WDT driver for IB700 single board computer initialising.\n"); printk("WDT driver for IB700 single board computer initialising.\n");
ibwdt_validate_timeout();
spin_lock_init(&ibwdt_lock); spin_lock_init(&ibwdt_lock);
if (misc_register(&ibwdt_miscdev)) if (misc_register(&ibwdt_miscdev))
return -ENODEV; return -ENODEV;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment