Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: Specify supported modes for buffers

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>

authored by

Lars-Peter Clausen and committed by
Jonathan Cameron
225d59ad 629bc023

+24 -3
+2
drivers/iio/buffer_cb.c
··· 33 33 static const struct iio_buffer_access_funcs iio_cb_access = { 34 34 .store_to = &iio_buffer_cb_store_to, 35 35 .release = &iio_buffer_cb_release, 36 + 37 + .modes = INDIO_BUFFER_SOFTWARE | INDIO_BUFFER_TRIGGERED, 36 38 }; 37 39 38 40 struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
+15 -3
drivers/iio/industrialio-buffer.c
··· 604 604 const unsigned long *scan_mask; 605 605 struct iio_buffer *buffer; 606 606 bool scan_timestamp; 607 + unsigned int modes; 607 608 608 609 memset(config, 0, sizeof(*config)); 609 610 ··· 616 615 list_is_singular(&indio_dev->buffer_list)) 617 616 return 0; 618 617 618 + modes = indio_dev->modes; 619 + 620 + list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) { 621 + if (buffer == remove_buffer) 622 + continue; 623 + modes &= buffer->access->modes; 624 + } 625 + 626 + if (insert_buffer) 627 + modes &= insert_buffer->access->modes; 628 + 619 629 /* Definitely possible for devices to support both of these. */ 620 - if ((indio_dev->modes & INDIO_BUFFER_TRIGGERED) && indio_dev->trig) { 630 + if ((modes & INDIO_BUFFER_TRIGGERED) && indio_dev->trig) { 621 631 config->mode = INDIO_BUFFER_TRIGGERED; 622 - } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) { 632 + } else if (modes & INDIO_BUFFER_HARDWARE) { 623 633 config->mode = INDIO_BUFFER_HARDWARE; 624 - } else if (indio_dev->modes & INDIO_BUFFER_SOFTWARE) { 634 + } else if (modes & INDIO_BUFFER_SOFTWARE) { 625 635 config->mode = INDIO_BUFFER_SOFTWARE; 626 636 } else { 627 637 /* Can only occur on first buffer */
+2
drivers/iio/kfifo_buf.c
··· 135 135 .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo, 136 136 .set_length = &iio_set_length_kfifo, 137 137 .release = &iio_kfifo_buffer_release, 138 + 139 + .modes = INDIO_BUFFER_SOFTWARE | INDIO_BUFFER_TRIGGERED, 138 140 }; 139 141 140 142 struct iio_buffer *iio_kfifo_allocate(void)
+2
drivers/staging/iio/accel/sca3000_ring.c
··· 258 258 .read_first_n = &sca3000_read_first_n_hw_rb, 259 259 .data_available = sca3000_ring_buf_data_available, 260 260 .release = sca3000_ring_release, 261 + 262 + .modes = INDIO_BUFFER_HARDWARE, 261 263 }; 262 264 263 265 int sca3000_configure_ring(struct iio_dev *indio_dev)
+3
include/linux/iio/buffer.h
··· 29 29 * @set_length: set number of datums in buffer 30 30 * @release: called when the last reference to the buffer is dropped, 31 31 * should free all resources allocated by the buffer. 32 + * @modes: Supported operating modes by this buffer type 32 33 * 33 34 * The purpose of this structure is to make the buffer element 34 35 * modular as event for a given driver, different usecases may require ··· 52 51 int (*set_length)(struct iio_buffer *buffer, int length); 53 52 54 53 void (*release)(struct iio_buffer *buffer); 54 + 55 + unsigned int modes; 55 56 }; 56 57 57 58 /**