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

iio: buffer-dmaengine: Report buffer length requirements

The dmaengine buffer has some length alignment requirements that can differ
from platform to platform. If the length alignment requirements are not met
unexpected behavior like dropping of samples can occur.

Currently these requirements are not reported and applications need to know
the requirements of the platform by some out-of-band means.

Add a new buffer attribute that reports the length alignment requirements
called `length_align_bytes`. The reported length alignment is in bytes that
means the buffer length alignment in sample sets depends on the number of
enabled channels and the bytes per channel. Applications using this
attribute to determine the buffer size requirements need to consider this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Lars-Peter Clausen and committed by
Jonathan Cameron
4538c185 2a4fb4de

+40
+19
Documentation/ABI/testing/sysfs-bus-iio-dma-buffer
··· 1 + What: /sys/bus/iio/devices/iio:deviceX/buffer/length_align_bytes 2 + KernelVersion: 5.4 3 + Contact: linux-iio@vger.kernel.org 4 + Description: 5 + DMA buffers tend to have a alignment requirement for the 6 + buffers. If this alignment requirement is not met samples might 7 + be dropped from the buffer. 8 + 9 + This property reports the alignment requirements in bytes. 10 + This means that the buffer size in bytes needs to be a integer 11 + multiple of the number reported by this file. 12 + 13 + The alignment requirements in number of sample sets will depend 14 + on the enabled channels and the bytes per channel. This means 15 + that the alignment requirement in samples sets might change 16 + depending on which and how many channels are enabled. Whereas 17 + the alignment requirement reported in bytes by this property 18 + will remain static and does not depend on which channels are 19 + enabled.
+21
drivers/iio/buffer/industrialio-buffer-dmaengine.c
··· 13 13 #include <linux/module.h> 14 14 15 15 #include <linux/iio/iio.h> 16 + #include <linux/iio/sysfs.h> 16 17 #include <linux/iio/buffer.h> 17 18 #include <linux/iio/buffer_impl.h> 18 19 #include <linux/iio/buffer-dma.h> ··· 127 126 .abort = iio_dmaengine_buffer_abort, 128 127 }; 129 128 129 + static ssize_t iio_dmaengine_buffer_get_length_align(struct device *dev, 130 + struct device_attribute *attr, char *buf) 131 + { 132 + struct iio_dev *indio_dev = dev_to_iio_dev(dev); 133 + struct dmaengine_buffer *dmaengine_buffer = 134 + iio_buffer_to_dmaengine_buffer(indio_dev->buffer); 135 + 136 + return sprintf(buf, "%u\n", dmaengine_buffer->align); 137 + } 138 + 139 + static IIO_DEVICE_ATTR(length_align_bytes, 0444, 140 + iio_dmaengine_buffer_get_length_align, NULL, 0); 141 + 142 + static const struct attribute *iio_dmaengine_buffer_attrs[] = { 143 + &iio_dev_attr_length_align_bytes.dev_attr.attr, 144 + NULL, 145 + }; 146 + 130 147 /** 131 148 * iio_dmaengine_buffer_alloc() - Allocate new buffer which uses DMAengine 132 149 * @dev: Parent device for the buffer ··· 198 179 199 180 iio_dma_buffer_init(&dmaengine_buffer->queue, chan->device->dev, 200 181 &iio_dmaengine_default_ops); 182 + iio_buffer_set_attrs(&dmaengine_buffer->queue.buffer, 183 + iio_dmaengine_buffer_attrs); 201 184 202 185 dmaengine_buffer->queue.buffer.access = &iio_dmaengine_buffer_ops; 203 186