From fd7b673c92731fc6c0b1e999adfd87b6762ee797 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 16 Mar 2012 09:14:00 +0100 Subject: [PATCH] watchdog: Add support for WDIOC_GETTIMELEFT IOCTL in watchdog core This patch adds support for WDIOC_GETTIMELEFT IOCTL in watchdog core. So, there is another function pointer added to struct watchdog_ops, which can be passed by drivers to support this IOCTL. Related documentation is updated too. Signed-off-by: Viresh Kumar Signed-off-by: Linus Walleij Signed-off-by: Wim Van Sebroeck --- Documentation/watchdog/convert_drivers_to_kernel_api.txt | 4 ++++ Documentation/watchdog/watchdog-kernel-api.txt | 4 +++- drivers/watchdog/watchdog_dev.c | 5 +++++ include/linux/watchdog.h | 2 ++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Documentation/watchdog/convert_drivers_to_kernel_api.txt b/Documentation/watchdog/convert_drivers_to_kernel_api.txt index be8119bb15d..271b8850dde 100644 --- a/Documentation/watchdog/convert_drivers_to_kernel_api.txt +++ b/Documentation/watchdog/convert_drivers_to_kernel_api.txt @@ -59,6 +59,10 @@ Here is a overview of the functions and probably needed actions: WDIOC_GETTIMEOUT: No preparations needed + WDIOC_GETTIMELEFT: + It needs get_timeleft() callback to be defined. Otherwise it + will return EOPNOTSUPP + Other IOCTLs can be served using the ioctl-callback. Note that this is mainly intended for porting old drivers; new drivers should not invent private IOCTLs. Private IOCTLs are processed first. When the callback returns with diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt index 7d9d1da762b..227f6cd0e5f 100644 --- a/Documentation/watchdog/watchdog-kernel-api.txt +++ b/Documentation/watchdog/watchdog-kernel-api.txt @@ -1,6 +1,6 @@ The Linux WatchDog Timer Driver Core kernel API. =============================================== -Last reviewed: 29-Nov-2011 +Last reviewed: 16-Mar-2012 Wim Van Sebroeck @@ -77,6 +77,7 @@ struct watchdog_ops { int (*ping)(struct watchdog_device *); unsigned int (*status)(struct watchdog_device *); int (*set_timeout)(struct watchdog_device *, unsigned int); + unsigned int (*get_timeleft)(struct watchdog_device *); long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long); }; @@ -123,6 +124,7 @@ they are supported. These optional routines/operations are: because the watchdog does not necessarily has a 1 second resolution). (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the watchdog's info structure). +* get_timeleft: this routines returns the time that's left before a reset. * ioctl: if this routine is present then it will be called first before we do our own internal ioctl call handling. This routine should return -ENOIOCTLCMD if a command is not supported. The parameters that are passed to the ioctl diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index c6e1b8dd80c..8558da912c4 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -236,6 +236,11 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, if (wdd->timeout == 0) return -EOPNOTSUPP; return put_user(wdd->timeout, p); + case WDIOC_GETTIMELEFT: + if (!wdd->ops->get_timeleft) + return -EOPNOTSUPP; + + return put_user(wdd->ops->get_timeleft(wdd), p); default: return -ENOTTY; } diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h index de75167093b..ac40716b44e 100644 --- a/include/linux/watchdog.h +++ b/include/linux/watchdog.h @@ -66,6 +66,7 @@ struct watchdog_device; * @ping: The routine that sends a keepalive ping to the watchdog device. * @status: The routine that shows the status of the watchdog device. * @set_timeout:The routine for setting the watchdog devices timeout value. + * @get_timeleft:The routine that get's the time that's left before a reset. * @ioctl: The routines that handles extra ioctl calls. * * The watchdog_ops structure contains a list of low-level operations @@ -82,6 +83,7 @@ struct watchdog_ops { int (*ping)(struct watchdog_device *); unsigned int (*status)(struct watchdog_device *); int (*set_timeout)(struct watchdog_device *, unsigned int); + unsigned int (*get_timeleft)(struct watchdog_device *); long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long); };