Commit 841b4bc2 authored by Pádraig Brady's avatar Pádraig Brady Committed by Christoph Hellwig

[WATCHDOG] v2.6.6 w83627hf_wdt.c-patch

Add w83627hf_select_wd_register and w83627hf_unselect_wd_register.
Add w83627hf_init to fix initialization problem on certain motherboards.
Make ping and disable code return 0 (int) on success.
Extract set_heartbeat code to seperate function.
parent dfc2505c
......@@ -72,7 +72,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
#define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */
static void
wdt_ctrl(int timeout)
w83627hf_select_wd_register(void)
{
outb_p(0x87, WDT_EFER); /* Enter extended function mode */
outb_p(0x87, WDT_EFER); /* Again according to manual */
......@@ -81,23 +81,64 @@ wdt_ctrl(int timeout)
outb_p(0x08, WDT_EFDR); /* select logical device 8 (GPIO2) */
outb_p(0x30, WDT_EFER); /* select CR30 */
outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */
}
static void
w83627hf_unselect_wd_register(void)
{
outb_p(0xAA, WDT_EFER); /* Leave extended function mode */
}
/* tyan motherboards seem to set F5 to 0x4C ?
* So explicitly init to appropriate value. */
static void
w83627hf_init(void)
{
unsigned char t;
w83627hf_select_wd_register();
outb_p(0xF5, WDT_EFER); /* Select CRF5 */
t=inb_p(WDT_EFDR); /* read CRF5 */
t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */
outb_p(t, WDT_EFDR); /* Write back to CRF5 */
w83627hf_unselect_wd_register();
}
static void
wdt_ctrl(int timeout)
{
w83627hf_select_wd_register();
outb_p(0xF6, WDT_EFER); /* Select CRF6 */
outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF6 */
outb_p(0xAA, WDT_EFER); /* Leave extended function mode */
w83627hf_unselect_wd_register();
}
static void
static int
wdt_ping(void)
{
wdt_ctrl(timeout);
return 0;
}
static void
static int
wdt_disable(void)
{
wdt_ctrl(0);
return 0;
}
static int
wdt_set_heartbeat(int t)
{
if ((t < 1) || (t > 63))
return -EINVAL;
timeout = t;
return 0;
}
static ssize_t
......@@ -134,7 +175,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 1,
.identity = "Advantech WDT",
.identity = "W83627HF WDT",
};
switch (cmd) {
......@@ -154,9 +195,8 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case WDIOC_SETTIMEOUT:
if (get_user(new_timeout, (int *)arg))
return -EFAULT;
if ((new_timeout < 1) || (new_timeout > 63))
if (wdt_set_heartbeat(new_timeout))
return -EINVAL;
timeout = new_timeout;
wdt_ping();
/* Fall */
......@@ -211,8 +251,8 @@ wdt_close(struct inode *inode, struct file *file)
printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
wdt_ping();
}
clear_bit(0, &wdt_is_open);
expect_close = 0;
clear_bit(0, &wdt_is_open);
return 0;
}
......@@ -266,10 +306,10 @@ wdt_init(void)
printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF Super I/O chip initialising.\n");
if (timeout < 1 || timeout > 63) {
timeout = WATCHDOG_TIMEOUT;
printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n",
timeout);
if (wdt_set_heartbeat(timeout)) {
wdt_set_heartbeat(WATCHDOG_TIMEOUT);
printk (KERN_INFO PFX "timeout value must be 1<=timeout<=63, using %d\n",
WATCHDOG_TIMEOUT);
}
if (!request_region(wdt_io, 1, WATCHDOG_NAME)) {
......@@ -279,6 +319,8 @@ wdt_init(void)
goto out;
}
w83627hf_init();
ret = register_reboot_notifier(&wdt_notifier);
if (ret != 0) {
printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
......
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