aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/watchdog
diff options
context:
space:
mode:
authorWim Van Sebroeck <wim@iguana.be>2006-05-21 06:48:44 -0400
committerWim Van Sebroeck <wim@iguana.be>2006-06-20 13:00:30 -0400
commit58b519f3e5e491d5a3e320dc525f58ac439bdde4 (patch)
treeefff3a0bd308effbbedce1a50fbb40d71e5b5d96 /drivers/char/watchdog
parente05b59fe7927bc648ac3af3d59dc64a7ee6b22e2 (diff)
[WATCHDOG] add WDIOC_GETTIMELEFT ioctl
Some watchdog drivers have the ability to report the remaining time before the system will reboot. With the WDIOC_GETTIMELEFT ioctl you can now read the time left before the watchdog would reboot your system. The following drivers support this new IOCTL: i8xx_tco.c, pcwd_pci.c and pcwd_usb.c . Signed-off-by: Wim Van Sebroeck <wim@iguana.be> Signed-off-by: Andrew Morton <akpm@osdl.org>
Diffstat (limited to 'drivers/char/watchdog')
-rw-r--r--drivers/char/watchdog/i8xx_tco.c28
-rw-r--r--drivers/char/watchdog/pcwd_pci.c30
-rw-r--r--drivers/char/watchdog/pcwd_usb.c23
3 files changed, 79 insertions, 2 deletions
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
index fa2ba9ebe42a..bfbdbbf3c2f2 100644
--- a/drivers/char/watchdog/i8xx_tco.c
+++ b/drivers/char/watchdog/i8xx_tco.c
@@ -205,6 +205,23 @@ static int tco_timer_set_heartbeat (int t)
205 return 0; 205 return 0;
206} 206}
207 207
208static int tco_timer_get_timeleft (int *time_left)
209{
210 unsigned char val;
211
212 spin_lock(&tco_lock);
213
214 /* read the TCO Timer */
215 val = inb (TCO1_RLD);
216 val &= 0x3f;
217
218 spin_unlock(&tco_lock);
219
220 *time_left = (int)((val * 6) / 10);
221
222 return 0;
223}
224
208/* 225/*
209 * /dev/watchdog handling 226 * /dev/watchdog handling
210 */ 227 */
@@ -272,6 +289,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
272{ 289{
273 int new_options, retval = -EINVAL; 290 int new_options, retval = -EINVAL;
274 int new_heartbeat; 291 int new_heartbeat;
292 int time_left;
275 void __user *argp = (void __user *)arg; 293 void __user *argp = (void __user *)arg;
276 int __user *p = argp; 294 int __user *p = argp;
277 static struct watchdog_info ident = { 295 static struct watchdog_info ident = {
@@ -320,7 +338,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
320 return -EFAULT; 338 return -EFAULT;
321 339
322 if (tco_timer_set_heartbeat(new_heartbeat)) 340 if (tco_timer_set_heartbeat(new_heartbeat))
323 return -EINVAL; 341 return -EINVAL;
324 342
325 tco_timer_keepalive (); 343 tco_timer_keepalive ();
326 /* Fall */ 344 /* Fall */
@@ -329,6 +347,14 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
329 case WDIOC_GETTIMEOUT: 347 case WDIOC_GETTIMEOUT:
330 return put_user(heartbeat, p); 348 return put_user(heartbeat, p);
331 349
350 case WDIOC_GETTIMELEFT:
351 {
352 if (tco_timer_get_timeleft(&time_left))
353 return -EINVAL;
354
355 return put_user(time_left, p);
356 }
357
332 default: 358 default:
333 return -ENOIOCTLCMD; 359 return -ENOIOCTLCMD;
334 } 360 }
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index 2451edbefece..1f40ecefbf72 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -21,7 +21,7 @@
21 */ 21 */
22 22
23/* 23/*
24 * A bells and whistles driver is available from: 24 * A bells and whistles driver is available from:
25 * http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/ 25 * http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/
26 * 26 *
27 * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ 27 * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/
@@ -390,6 +390,24 @@ static int pcipcwd_get_temperature(int *temperature)
390 return 0; 390 return 0;
391} 391}
392 392
393static int pcipcwd_get_timeleft(int *time_left)
394{
395 int msb;
396 int lsb;
397
398 /* Read the time that's left before rebooting */
399 /* Note: if the board is not yet armed then we will read 0xFFFF */
400 send_command(CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb);
401
402 *time_left = (msb << 8) + lsb;
403
404 if (debug >= VERBOSE)
405 printk(KERN_DEBUG PFX "Time left before next reboot: %d\n",
406 *time_left);
407
408 return 0;
409}
410
393/* 411/*
394 * /dev/watchdog handling 412 * /dev/watchdog handling
395 */ 413 */
@@ -512,6 +530,16 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
512 case WDIOC_GETTIMEOUT: 530 case WDIOC_GETTIMEOUT:
513 return put_user(heartbeat, p); 531 return put_user(heartbeat, p);
514 532
533 case WDIOC_GETTIMELEFT:
534 {
535 int time_left;
536
537 if (pcipcwd_get_timeleft(&time_left))
538 return -EFAULT;
539
540 return put_user(time_left, p);
541 }
542
515 default: 543 default:
516 return -ENOIOCTLCMD; 544 return -ENOIOCTLCMD;
517 } 545 }
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index 3fdfda9324fa..0d072bed501d 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -317,6 +317,19 @@ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, int *temp
317 return 0; 317 return 0;
318} 318}
319 319
320static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, int *time_left)
321{
322 unsigned char msb, lsb;
323
324 /* Read the time that's left before rebooting */
325 /* Note: if the board is not yet armed then we will read 0xFFFF */
326 usb_pcwd_send_command(usb_pcwd, CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb);
327
328 *time_left = (msb << 8) + lsb;
329
330 return 0;
331}
332
320/* 333/*
321 * /dev/watchdog handling 334 * /dev/watchdog handling
322 */ 335 */
@@ -422,6 +435,16 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
422 case WDIOC_GETTIMEOUT: 435 case WDIOC_GETTIMEOUT:
423 return put_user(heartbeat, p); 436 return put_user(heartbeat, p);
424 437
438 case WDIOC_GETTIMELEFT:
439 {
440 int time_left;
441
442 if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left))
443 return -EFAULT;
444
445 return put_user(time_left, p);
446 }
447
425 default: 448 default:
426 return -ENOIOCTLCMD; 449 return -ENOIOCTLCMD;
427 } 450 }