iio: Add support for blocking IO on buffers
authorLars-Peter Clausen <lars@metafoo.de>
Mon, 25 Nov 2013 14:56:00 +0000 (14:56 +0000)
committerJonathan Cameron <jic23@kernel.org>
Tue, 3 Dec 2013 20:22:29 +0000 (20:22 +0000)
Currently the IIO buffer interface only allows non-blocking reads. This patch
adds support for blocking IO. In blocking mode the thread will go to sleep if no
data is available and will wait for the buffer implementation to signal that new
data is available by waking up the buffers waitqueue.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/industrialio-buffer.c

index 4dcc3a0f9930535f22e5c9ed8a241fd450312a49..c67d83bdc8f0911f79cd1b5337003219e9d7b8e6 100644 (file)
@@ -56,13 +56,34 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 {
        struct iio_dev *indio_dev = filp->private_data;
        struct iio_buffer *rb = indio_dev->buffer;
+       int ret;
 
        if (!indio_dev->info)
                return -ENODEV;
 
        if (!rb || !rb->access->read_first_n)
                return -EINVAL;
-       return rb->access->read_first_n(rb, n, buf);
+
+       do {
+               if (!iio_buffer_data_available(rb)) {
+                       if (filp->f_flags & O_NONBLOCK)
+                               return -EAGAIN;
+
+                       ret = wait_event_interruptible(rb->pollq,
+                                       iio_buffer_data_available(rb) ||
+                                       indio_dev->info == NULL);
+                       if (ret)
+                               return ret;
+                       if (indio_dev->info == NULL)
+                               return -ENODEV;
+               }
+
+               ret = rb->access->read_first_n(rb, n, buf);
+               if (ret == 0 && (filp->f_flags & O_NONBLOCK))
+                       ret = -EAGAIN;
+        } while (ret == 0);
+
+       return ret;
 }
 
 /**