summaryrefslogtreecommitdiff
path: root/drivers/iio
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2021-10-07 08:00:31 +0000
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2021-10-19 08:30:45 +0100
commit1546d6718dc92b27935931ee4e4c2e9893ef3066 (patch)
tree3f85ffc0827f58c332958e28bf5022b2858d5ab7 /drivers/iio
parent9eeee3b0bf190b4f677af27e24ba0cd1c030e49b (diff)
iio: kfifo-buffer: Add output buffer support
Add output buffer support to the kfifo buffer implementation. The implementation is straight forward and mostly just wraps the kfifo API to provide the required operations. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com> Signed-off-by: Mihail Chindris <mihail.chindris@analog.com> Link: https://lore.kernel.org/r/20211007080035.2531-3-mihail.chindris@analog.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/buffer/kfifo_buf.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/iio/buffer/kfifo_buf.c b/drivers/iio/buffer/kfifo_buf.c
index 516eb3465de1..416d35a61ae2 100644
--- a/drivers/iio/buffer/kfifo_buf.c
+++ b/drivers/iio/buffer/kfifo_buf.c
@@ -138,10 +138,60 @@ static void iio_kfifo_buffer_release(struct iio_buffer *buffer)
kfree(kf);
}
+static size_t iio_kfifo_buf_space_available(struct iio_buffer *r)
+{
+ struct iio_kfifo *kf = iio_to_kfifo(r);
+ size_t avail;
+
+ mutex_lock(&kf->user_lock);
+ avail = kfifo_avail(&kf->kf);
+ mutex_unlock(&kf->user_lock);
+
+ return avail;
+}
+
+static int iio_kfifo_remove_from(struct iio_buffer *r, void *data)
+{
+ int ret;
+ struct iio_kfifo *kf = iio_to_kfifo(r);
+
+ if (kfifo_size(&kf->kf) < 1)
+ return -EBUSY;
+
+ ret = kfifo_out(&kf->kf, data, 1);
+ if (ret != 1)
+ return -EBUSY;
+
+ wake_up_interruptible_poll(&r->pollq, EPOLLOUT | EPOLLWRNORM);
+
+ return 0;
+}
+
+static int iio_kfifo_write(struct iio_buffer *r, size_t n,
+ const char __user *buf)
+{
+ struct iio_kfifo *kf = iio_to_kfifo(r);
+ int ret, copied;
+
+ mutex_lock(&kf->user_lock);
+ if (!kfifo_initialized(&kf->kf) || n < kfifo_esize(&kf->kf))
+ ret = -EINVAL;
+ else
+ ret = kfifo_from_user(&kf->kf, buf, n, &copied);
+ mutex_unlock(&kf->user_lock);
+ if (ret)
+ return ret;
+
+ return copied;
+}
+
static const struct iio_buffer_access_funcs kfifo_access_funcs = {
.store_to = &iio_store_to_kfifo,
.read = &iio_read_kfifo,
.data_available = iio_kfifo_buf_data_available,
+ .remove_from = &iio_kfifo_remove_from,
+ .write = &iio_kfifo_write,
+ .space_available = &iio_kfifo_buf_space_available,
.request_update = &iio_request_update_kfifo,
.set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
.set_length = &iio_set_length_kfifo,