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 16:16:39 -0400 |
commit | c63b6d02be22899a5c8d47b8ee40e0534cd01a43 (patch) | |
tree | 5ac9fab3b39834efb4eff5f91cbce9d2eda48cf1 /drivers/watchdog | |
parent | 86b5912880453532440358b1486410ad49ef7672 (diff) |
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>
Diffstat (limited to 'drivers/watchdog')
-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) | |||
142 | w83627hf_unselect_wd_register(); | 142 | w83627hf_unselect_wd_register(); |
143 | } | 143 | } |
144 | 144 | ||
145 | static void wdt_ctrl(int timeout) | 145 | static void wdt_set_time(int timeout) |
146 | { | 146 | { |
147 | spin_lock(&io_lock); | 147 | spin_lock(&io_lock); |
148 | 148 | ||
@@ -158,13 +158,13 @@ static void wdt_ctrl(int timeout) | |||
158 | 158 | ||
159 | static int wdt_ping(void) | 159 | static int wdt_ping(void) |
160 | { | 160 | { |
161 | wdt_ctrl(timeout); | 161 | wdt_set_time(timeout); |
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | 164 | ||
165 | static int wdt_disable(void) | 165 | static int wdt_disable(void) |
166 | { | 166 | { |
167 | wdt_ctrl(0); | 167 | wdt_set_time(0); |
168 | return 0; | 168 | return 0; |
169 | } | 169 | } |
170 | 170 | ||
@@ -176,6 +176,24 @@ static int wdt_set_heartbeat(int t) | |||
176 | return 0; | 176 | return 0; |
177 | } | 177 | } |
178 | 178 | ||
179 | static int wdt_get_time(void) | ||
180 | { | ||
181 | int timeleft; | ||
182 | |||
183 | spin_lock(&io_lock); | ||
184 | |||
185 | w83627hf_select_wd_register(); | ||
186 | |||
187 | outb_p(0xF6, WDT_EFER); /* Select CRF6 */ | ||
188 | timeleft = inb_p(WDT_EFDR); /* Read Timeout counter to CRF6 */ | ||
189 | |||
190 | w83627hf_unselect_wd_register(); | ||
191 | |||
192 | spin_unlock(&io_lock); | ||
193 | |||
194 | return timeleft; | ||
195 | } | ||
196 | |||
179 | static ssize_t wdt_write(struct file *file, const char __user *buf, | 197 | static ssize_t wdt_write(struct file *file, const char __user *buf, |
180 | size_t count, loff_t *ppos) | 198 | size_t count, loff_t *ppos) |
181 | { | 199 | { |
@@ -202,7 +220,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
202 | { | 220 | { |
203 | void __user *argp = (void __user *)arg; | 221 | void __user *argp = (void __user *)arg; |
204 | int __user *p = argp; | 222 | int __user *p = argp; |
205 | int new_timeout; | 223 | int timeval; |
206 | static const struct watchdog_info ident = { | 224 | static const struct watchdog_info ident = { |
207 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | | 225 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
208 | WDIOF_MAGICCLOSE, | 226 | WDIOF_MAGICCLOSE, |
@@ -238,14 +256,17 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
238 | wdt_ping(); | 256 | wdt_ping(); |
239 | break; | 257 | break; |
240 | case WDIOC_SETTIMEOUT: | 258 | case WDIOC_SETTIMEOUT: |
241 | if (get_user(new_timeout, p)) | 259 | if (get_user(timeval, p)) |
242 | return -EFAULT; | 260 | return -EFAULT; |
243 | if (wdt_set_heartbeat(new_timeout)) | 261 | if (wdt_set_heartbeat(timeval)) |
244 | return -EINVAL; | 262 | return -EINVAL; |
245 | wdt_ping(); | 263 | wdt_ping(); |
246 | /* Fall */ | 264 | /* Fall */ |
247 | case WDIOC_GETTIMEOUT: | 265 | case WDIOC_GETTIMEOUT: |
248 | return put_user(timeout, p); | 266 | return put_user(timeout, p); |
267 | case WDIOC_GETTIMELEFT: | ||
268 | timeval = wdt_get_time(); | ||
269 | return put_user(timeval, p); | ||
249 | default: | 270 | default: |
250 | return -ENOTTY; | 271 | return -ENOTTY; |
251 | } | 272 | } |