Skip to content

Commit

Permalink
watchdog: WatchDog Timer Driver Core - Add basic ioctl functionality
Browse files Browse the repository at this point in the history
This part add's the basic ioctl functionality to the
WatchDog Timer Driver Core framework. The supported
ioctl call's are:
	WDIOC_GETSUPPORT
	WDIOC_GETSTATUS
	WDIOC_GETBOOTSTATUS

Signed-off-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Wolfram Sang <w.sang@pengutronix.de>
  • Loading branch information
Wim Van Sebroeck committed Jul 28, 2011
1 parent 4331604 commit 2fa0356
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Documentation/watchdog/watchdog-kernel-api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ The watchdog device structure looks like this:
struct watchdog_device {
const struct watchdog_info *info;
const struct watchdog_ops *ops;
unsigned int bootstatus;
void *driver_data;
unsigned long status;
};
Expand All @@ -49,6 +50,8 @@ It contains following fields:
* info: a pointer to a watchdog_info structure. This structure gives some
additional information about the watchdog timer itself. (Like it's unique name)
* ops: a pointer to the list of watchdog operations that the watchdog supports.
* bootstatus: status of the device after booting (reported with watchdog
WDIOF_* status bits).
* driver_data: a pointer to the drivers private data of a watchdog device.
This data should only be accessed via the watchdog_set_drvadata and
watchdog_get_drvdata routines.
Expand All @@ -65,6 +68,7 @@ struct watchdog_ops {
int (*stop)(struct watchdog_device *);
/* optional operations */
int (*ping)(struct watchdog_device *);
unsigned int (*status)(struct watchdog_device *);
};

It is important that you first define the module owner of the watchdog timer
Expand Down Expand Up @@ -97,6 +101,8 @@ they are supported. These optional routines/operations are:
the watchdog timer driver core does: to send a keepalive ping to the watchdog
timer hardware it will either use the ping operation (when available) or the
start operation (when the ping operation is not available).
* status: this routine checks the status of the watchdog timer device. The
status of the device is reported with watchdog WDIOF_* status flags/bits.

The status bits should (preferably) be set with the set_bit and clear_bit alike
bit-operations. The status bits that are defined are:
Expand Down
32 changes: 32 additions & 0 deletions drivers/watchdog/watchdog_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,37 @@ static ssize_t watchdog_write(struct file *file, const char __user *data,
return len;
}

/*
* watchdog_ioctl: handle the different ioctl's for the watchdog device.
* @file: file handle to the device
* @cmd: watchdog command
* @arg: argument pointer
*
* The watchdog API defines a common set of functions for all watchdogs
* according to their available features.
*/

static long watchdog_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
unsigned int val;

switch (cmd) {
case WDIOC_GETSUPPORT:
return copy_to_user(argp, wdd->info,
sizeof(struct watchdog_info)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
val = wdd->ops->status ? wdd->ops->status(wdd) : 0;
return put_user(val, p);
case WDIOC_GETBOOTSTATUS:
return put_user(wdd->bootstatus, p);
default:
return -ENOTTY;
}
}

/*
* watchdog_open: open the /dev/watchdog device.
* @inode: inode of device
Expand Down Expand Up @@ -163,6 +194,7 @@ static int watchdog_release(struct inode *inode, struct file *file)
static const struct file_operations watchdog_fops = {
.owner = THIS_MODULE,
.write = watchdog_write,
.unlocked_ioctl = watchdog_ioctl,
.open = watchdog_open,
.release = watchdog_release,
};
Expand Down
4 changes: 4 additions & 0 deletions include/linux/watchdog.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct watchdog_device;
* @start: The routine for starting the watchdog device.
* @stop: The routine for stopping the 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.
*
* The watchdog_ops structure contains a list of low-level operations
* that control a watchdog device. It also contains the module that owns
Expand All @@ -81,12 +82,14 @@ struct watchdog_ops {
int (*stop)(struct watchdog_device *);
/* optional operations */
int (*ping)(struct watchdog_device *);
unsigned int (*status)(struct watchdog_device *);
};

/** struct watchdog_device - The structure that defines a watchdog device
*
* @info: Pointer to a watchdog_info structure.
* @ops: Pointer to the list of watchdog operations.
* @bootstatus: Status of the watchdog device at boot.
* @driver-data:Pointer to the drivers private data.
* @status: Field that contains the devices internal status bits.
*
Expand All @@ -99,6 +102,7 @@ struct watchdog_ops {
struct watchdog_device {
const struct watchdog_info *info;
const struct watchdog_ops *ops;
unsigned int bootstatus;
void *driver_data;
unsigned long status;
/* Bit numbers for status flags */
Expand Down

0 comments on commit 2fa0356

Please sign in to comment.