iio: Specify supported modes for buffers
authorLars-Peter Clausen <lars@metafoo.de>
Fri, 29 May 2015 16:14:21 +0000 (18:14 +0200)
committerJonathan Cameron <jic23@kernel.org>
Mon, 1 Jun 2015 10:31:12 +0000 (11:31 +0100)
For each buffer type specify the supported device modes for this buffer.
This allows us for devices which support multiple different operating modes
to pick the correct operating mode based on the modes supported by the
attached buffers.

It also prevents that buffers with conflicting modes are attached
to a device at the same time or that a buffer with a non-supported mode is
attached to a device (e.g. in-kernel callback buffer to a device only
supporting hardware mode).

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/buffer_cb.c
drivers/iio/industrialio-buffer.c
drivers/iio/kfifo_buf.c
drivers/staging/iio/accel/sca3000_ring.c
include/linux/iio/buffer.h

index eb46e728aa2effad51dbf686cb74c4a5cb7fdf3a..1648e6e5a8483bc77ce5c9a8352131d3ff6c99a3 100644 (file)
@@ -33,6 +33,8 @@ static void iio_buffer_cb_release(struct iio_buffer *buffer)
 static const struct iio_buffer_access_funcs iio_cb_access = {
        .store_to = &iio_buffer_cb_store_to,
        .release = &iio_buffer_cb_release,
+
+       .modes = INDIO_BUFFER_SOFTWARE | INDIO_BUFFER_TRIGGERED,
 };
 
 struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
index 209c7ad793c5083ad8c0cff91f9d0ce3501851f6..0a14bd825fe06879b15acd120a2f0142718ca0b7 100644 (file)
@@ -604,6 +604,7 @@ static int iio_verify_update(struct iio_dev *indio_dev,
        const unsigned long *scan_mask;
        struct iio_buffer *buffer;
        bool scan_timestamp;
+       unsigned int modes;
 
        memset(config, 0, sizeof(*config));
 
@@ -615,12 +616,23 @@ static int iio_verify_update(struct iio_dev *indio_dev,
                list_is_singular(&indio_dev->buffer_list))
                        return 0;
 
+       modes = indio_dev->modes;
+
+       list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+               if (buffer == remove_buffer)
+                       continue;
+               modes &= buffer->access->modes;
+       }
+
+       if (insert_buffer)
+               modes &= insert_buffer->access->modes;
+
        /* Definitely possible for devices to support both of these. */
-       if ((indio_dev->modes & INDIO_BUFFER_TRIGGERED) && indio_dev->trig) {
+       if ((modes & INDIO_BUFFER_TRIGGERED) && indio_dev->trig) {
                config->mode = INDIO_BUFFER_TRIGGERED;
-       } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) {
+       } else if (modes & INDIO_BUFFER_HARDWARE) {
                config->mode = INDIO_BUFFER_HARDWARE;
-       } else if (indio_dev->modes & INDIO_BUFFER_SOFTWARE) {
+       } else if (modes & INDIO_BUFFER_SOFTWARE) {
                config->mode = INDIO_BUFFER_SOFTWARE;
        } else {
                /* Can only occur on first buffer */
index 847ca561afe014e83707d04eaef02054f9b2bbfa..db15684a473129ea99317724ea12ff02c774769e 100644 (file)
@@ -135,6 +135,8 @@ static const struct iio_buffer_access_funcs kfifo_access_funcs = {
        .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
        .set_length = &iio_set_length_kfifo,
        .release = &iio_kfifo_buffer_release,
+
+       .modes = INDIO_BUFFER_SOFTWARE | INDIO_BUFFER_TRIGGERED,
 };
 
 struct iio_buffer *iio_kfifo_allocate(void)
index 8589eade1057efd56eb31a0a10555d5be63e25b0..23685e74917e2a5c3f3ab6dc6542f48d5ecbb2a9 100644 (file)
@@ -258,6 +258,8 @@ static const struct iio_buffer_access_funcs sca3000_ring_access_funcs = {
        .read_first_n = &sca3000_read_first_n_hw_rb,
        .data_available = sca3000_ring_buf_data_available,
        .release = sca3000_ring_release,
+
+       .modes = INDIO_BUFFER_HARDWARE,
 };
 
 int sca3000_configure_ring(struct iio_dev *indio_dev)
index eb8622b78ec900e130c701a8128865a327c67c90..1600c55828e0faa463d48509ff86ed22cb71d327 100644 (file)
@@ -29,6 +29,7 @@ struct iio_buffer;
  * @set_length:                set number of datums in buffer
  * @release:           called when the last reference to the buffer is dropped,
  *                     should free all resources allocated by the buffer.
+ * @modes:             Supported operating modes by this buffer type
  *
  * The purpose of this structure is to make the buffer element
  * modular as event for a given driver, different usecases may require
@@ -51,6 +52,8 @@ struct iio_buffer_access_funcs {
        int (*set_length)(struct iio_buffer *buffer, int length);
 
        void (*release)(struct iio_buffer *buffer);
+
+       unsigned int modes;
 };
 
 /**