}
/*
- * The two functions w83697hf_get_reg() and w83697hf_set_reg()
- * must be called with the device unlocked.
+ * The three functions w83697hf_get_reg(), w83697hf_set_reg() and
+ * w83697hf_write_timeout() must be called with the device unlocked.
*/
static unsigned char
}
static void
-w83697hf_select_wd_register(void)
+w83697hf_write_timeout(int timeout)
{
- w83697hf_unlock();
-
- w83697hf_set_reg(0x29, 0x20); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */
+ w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */
+}
+static void
+w83697hf_select_wdt(void)
+{
+ w83697hf_unlock();
w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */
- w83697hf_set_reg(0x30, 0x01); /* Enable timer/activate GPIO2 via bit 0 */
}
-static void
-w83697hf_unselect_wd_register(void)
+static inline void
+w83697hf_deselect_wdt(void)
{
w83697hf_lock();
}
static void
w83697hf_init(void)
{
- unsigned char t;
+ unsigned char bbuf;
- w83697hf_select_wd_register();
+ w83697hf_select_wdt();
- t = w83697hf_get_reg(0xF3); /* Read CRF3 */
- if (t != 0) {
- printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout);
- w83697hf_set_reg(0xF3, timeout); /* Write new timeout */
- }
- t = w83697hf_get_reg(0xF4); /* Read CRF4 */
- t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */
- w83697hf_set_reg(0xF4, t); /* Write back to CRF4 */
+ bbuf = w83697hf_get_reg(0x29);
+ bbuf &= ~0x60;
+ bbuf |= 0x20;
+ w83697hf_set_reg(0x29, bbuf); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */
- w83697hf_unselect_wd_register();
+ bbuf = w83697hf_get_reg(0xF3);
+ bbuf &= ~0x04;
+ w83697hf_set_reg(0xF3, bbuf); /* Count mode is seconds */
+
+ w83697hf_deselect_wdt();
}
-static void
-wdt_ctrl(int timeout)
+static int
+wdt_ping(void)
{
spin_lock(&io_lock);
+ w83697hf_select_wdt();
- w83697hf_select_wd_register();
-
- w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */
-
- w83697hf_unselect_wd_register();
+ w83697hf_write_timeout(timeout);
+ w83697hf_deselect_wdt();
spin_unlock(&io_lock);
+ return 0;
}
static int
-wdt_ping(void)
+wdt_enable(void)
{
- wdt_ctrl(timeout);
+ spin_lock(&io_lock);
+ w83697hf_select_wdt();
+
+ w83697hf_write_timeout(timeout);
+ w83697hf_set_reg(0x30, 1); /* Enable timer */
+
+ w83697hf_deselect_wdt();
+ spin_unlock(&io_lock);
return 0;
}
static int
wdt_disable(void)
{
- wdt_ctrl(0);
+ spin_lock(&io_lock);
+ w83697hf_select_wdt();
+
+ w83697hf_set_reg(0x30, 0); /* Disable timer */
+ w83697hf_write_timeout(0);
+
+ w83697hf_deselect_wdt();
+ spin_unlock(&io_lock);
return 0;
}
}
if (options & WDIOS_ENABLECARD) {
- wdt_ping();
+ wdt_enable();
retval = 0;
}
* Activate
*/
- wdt_ping();
+ wdt_enable();
return nonseekable_open(inode, file);
}
goto out;
found:
+ w83697hf_init();
+ wdt_disable(); /* Disable watchdog until first use */
if (wdt_set_heartbeat(timeout)) {
wdt_set_heartbeat(WATCHDOG_TIMEOUT);
WATCHDOG_TIMEOUT);
}
- w83697hf_init();
-
ret = register_reboot_notifier(&wdt_notifier);
if (ret != 0) {
printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",