@@ -698,6 +698,48 @@ static ssize_t watchdog_write(struct file *file, const char __user *data,
return len;
}
+/*
+ * watchdog_read: Pass a read on to the device if it accepts it
+ * @file: file handle to the device
+ * @buf: the buffer to read into
+ * @count: the size of buf in bytes
+ * @ppos: pointer to the file offset
+ *
+ * The watchdog API defines a common set of functions for all watchdogs
+ * according to their available features.
+ */
+
+static ssize_t watchdog_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct watchdog_core_data *wd_data = file->private_data;
+ struct watchdog_device *wdd = wd_data->wdd;
+
+ if (!wdd->ops->read)
+ return -EINVAL;
+ return wdd->ops->read(wdd, file, buf, count, ppos);
+}
+
+static __poll_t watchdog_poll(struct file *file, poll_table *wait)
+{
+ struct watchdog_core_data *wd_data = file->private_data;
+ struct watchdog_device *wdd = wd_data->wdd;
+
+ if (!wdd->ops->poll)
+ return DEFAULT_POLLMASK;
+ return wdd->ops->poll(wdd, file, wait);
+}
+
+static int watchdog_fasync(int fd, struct file *file, int on)
+{
+ struct watchdog_core_data *wd_data = file->private_data;
+ struct watchdog_device *wdd = wd_data->wdd;
+
+ if (!wdd->ops->fasync)
+ return 0;
+ return wdd->ops->fasync(wdd, fd, file, on);
+}
+
/*
* watchdog_ioctl: handle the different ioctl's for the watchdog device.
* @file: file handle to the device
@@ -951,6 +993,9 @@ static int watchdog_release(struct inode *inode, struct file *file)
static const struct file_operations watchdog_fops = {
.owner = THIS_MODULE,
.write = watchdog_write,
+ .read = watchdog_read,
+ .poll = watchdog_poll,
+ .fasync = watchdog_fasync,
.unlocked_ioctl = watchdog_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.open = watchdog_open,
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/notifier.h>
+#include <linux/poll.h>
#include <uapi/linux/watchdog.h>
struct watchdog_ops;
@@ -34,6 +35,9 @@ struct watchdog_governor;
* @get_timeleft:The routine that gets the time left before a reset (in seconds).
* @restart: The routine for restarting the machine.
* @ioctl: The routines that handles extra ioctl calls.
+ * @read: Call this is not NULL and a read comes in on the watchdog dev.
+ * @poll: Call this is not NULL and a poll comes in on the watchdog dev.
+ * @fasync: Call this is not NULL and a fasync comes in on the watchdog dev.
*
* The watchdog_ops structure contains a list of low-level operations
* that control a watchdog device. It also contains the module that owns
@@ -53,6 +57,10 @@ struct watchdog_ops {
unsigned int (*get_timeleft)(struct watchdog_device *);
int (*restart)(struct watchdog_device *, unsigned long, void *);
long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
+ ssize_t (*read)(struct watchdog_device *, struct file *, char __user *,
+ size_t, loff_t *);
+ __poll_t (*poll)(struct watchdog_device *, struct file *, poll_table *);
+ int (*fasync)(struct watchdog_device *, int, struct file *, int);
};
/** struct watchdog_device - The structure that defines a watchdog device