diff options
author | Christian Gromm <christian.gromm@microchip.com> | 2015-09-28 17:18:57 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-09-29 03:18:53 +0200 |
commit | aac997dfdd58eec1add02dae09030caeddc1abe6 (patch) | |
tree | 16d2ce84c89c921396744775d76ad0a4b24f70d8 /drivers/staging/most/aim-cdev | |
parent | 48ab5a339de2b1cd006b7783d1555e4711bf77e5 (diff) | |
download | linux-aac997dfdd58eec1add02dae09030caeddc1abe6.tar.bz2 |
staging: most: add poll syscall to AIM cdev
This patch adds the implementation of the poll syscall to the AIM cdev.
To have the full functionality, a helper function is needed in the
core module to retrieve the instantaneous availability of tx buffers.
Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/most/aim-cdev')
-rw-r--r-- | drivers/staging/most/aim-cdev/cdev.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/staging/most/aim-cdev/cdev.c b/drivers/staging/most/aim-cdev/cdev.c index 23c3f6e7340c..930ada0922f3 100644 --- a/drivers/staging/most/aim-cdev/cdev.c +++ b/drivers/staging/most/aim-cdev/cdev.c @@ -18,6 +18,7 @@ #include <linux/slab.h> #include <linux/device.h> #include <linux/cdev.h> +#include <linux/poll.h> #include <linux/kfifo.h> #include <linux/uaccess.h> #include <linux/idr.h> @@ -31,6 +32,7 @@ static struct most_aim cdev_aim; struct aim_channel { wait_queue_head_t wq; + wait_queue_head_t poll_wq; struct cdev cdev; struct device *dev; struct mutex io_mutex; @@ -271,6 +273,28 @@ start_copy: return retval; } +static inline bool __must_check IS_ERR_OR_FALSE(int x) +{ + return x <= 0; +} + +static unsigned int aim_poll(struct file *filp, poll_table *wait) +{ + struct aim_channel *c = filp->private_data; + unsigned int mask = 0; + + poll_wait(filp, &c->poll_wq, wait); + + if (c->cfg->direction == MOST_CH_RX) { + if (!kfifo_is_empty(&c->fifo)) + mask |= POLLIN | POLLRDNORM; + } else { + if (!IS_ERR_OR_FALSE(channel_has_mbo(c->iface, c->channel_id))) + mask |= POLLOUT | POLLWRNORM; + } + return mask; +} + /** * Initialization of struct file_operations */ @@ -280,6 +304,7 @@ static const struct file_operations channel_fops = { .write = aim_write, .open = aim_open, .release = aim_close, + .poll = aim_poll, }; /** @@ -434,6 +459,7 @@ static int aim_probe(struct most_interface *iface, int channel_id, goto error_alloc_kfifo; } init_waitqueue_head(&channel->wq); + init_waitqueue_head(&channel->poll_wq); mutex_init(&channel->io_mutex); spin_lock_irqsave(&ch_list_lock, cl_flags); list_add_tail(&channel->list, &channel_list); |