diff options
author | Greg Lee <glee@swspec.com> | 2011-09-12 20:28:46 -0400 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2011-11-05 21:16:39 +0100 |
commit | c63b6d02be22899a5c8d47b8ee40e0534cd01a43 (patch) | |
tree | 5ac9fab3b39834efb4eff5f91cbce9d2eda48cf1 | |
parent | 86b5912880453532440358b1486410ad49ef7672 (diff) | |
download | linux-c63b6d02be22899a5c8d47b8ee40e0534cd01a43.tar.bz2 |
watchdog: Add WDIOC_GETTIMELEFT ioctl support to w83627 watchdog driver
Add WDIOC_GETTIMELEFT ioctl allowing you to check how much time is left
on the watchdog counter before a reset occurs.
Signed-off-by: Greg Lee <glee [at] swspec.com>
Signed-off-by: Padraig Brady <P@draigbrady.com>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Signed-off-by: Andrew Morton <akpm@google.com>
-rw-r--r-- | drivers/watchdog/w83627hf_wdt.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index e5c91d4404ed..dd5d67548758 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c @@ -142,7 +142,7 @@ static void w83627hf_init(void) w83627hf_unselect_wd_register(); } -static void wdt_ctrl(int timeout) +static void wdt_set_time(int timeout) { spin_lock(&io_lock); @@ -158,13 +158,13 @@ static void wdt_ctrl(int timeout) static int wdt_ping(void) { - wdt_ctrl(timeout); + wdt_set_time(timeout); return 0; } static int wdt_disable(void) { - wdt_ctrl(0); + wdt_set_time(0); return 0; } @@ -176,6 +176,24 @@ static int wdt_set_heartbeat(int t) return 0; } +static int wdt_get_time(void) +{ + int timeleft; + + spin_lock(&io_lock); + + w83627hf_select_wd_register(); + + outb_p(0xF6, WDT_EFER); /* Select CRF6 */ + timeleft = inb_p(WDT_EFDR); /* Read Timeout counter to CRF6 */ + + w83627hf_unselect_wd_register(); + + spin_unlock(&io_lock); + + return timeleft; +} + static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { @@ -202,7 +220,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; - int new_timeout; + int timeval; static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, @@ -238,14 +256,17 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) wdt_ping(); break; case WDIOC_SETTIMEOUT: - if (get_user(new_timeout, p)) + if (get_user(timeval, p)) return -EFAULT; - if (wdt_set_heartbeat(new_timeout)) + if (wdt_set_heartbeat(timeval)) return -EINVAL; wdt_ping(); /* Fall */ case WDIOC_GETTIMEOUT: return put_user(timeout, p); + case WDIOC_GETTIMELEFT: + timeval = wdt_get_time(); + return put_user(timeval, p); default: return -ENOTTY; } |