iio: dummy: Use a fixed structure to build up scan to push to buffers.
authorJonathan Cameron <Jonathan.Cameron@huawei.com>
Sun, 13 Apr 2025 10:34:29 +0000 (11:34 +0100)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Wed, 21 May 2025 13:20:26 +0000 (14:20 +0100)
It has long been discouraged for drivers to make use of iio_dev->scan_bytes
directly as that is an implementation detail of the core. As such our
example driver should definitely not be doing so.

In order to illustrate the more complex case, where a DMA safe buffer is
needed, continue to kzalloc() the storage (but with a structure definition
to provide an explicit data layout). Also add comments on when a DMA safe
buffer is necessary and the two common ways of obtaining one.

Whilst we have a mixture of signed and unsigned channels, the unsigned
channels have ranges that can be stored in a signed value - hence
use signed storage for all channels, simplifying the structure definition.

Reviewed-by: David Lechner <dlechner@baylibre.com>
Link: https://patch.msgid.link/20250413103443.2420727-7-jic23@kernel.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/dummy/iio_simple_dummy_buffer.c

index 2888803..d0a7343 100644 (file)
@@ -31,6 +31,11 @@ static const s16 fakedata[] = {
        [DUMMY_INDEX_ACCELX] = 344,
 };
 
+struct dummy_scan {
+       s16 data[ARRAY_SIZE(fakedata)];
+       aligned_s64 timestamp;
+};
+
 /**
  * iio_simple_dummy_trigger_h() - the trigger handler function
  * @irq: the interrupt number
@@ -45,11 +50,18 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
 {
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
+       struct dummy_scan *scan;
        int i = 0, j;
-       u16 *data;
 
-       data = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
-       if (!data)
+       /*
+        * Note that some buses such as SPI require DMA safe buffers which
+        * cannot be on the stack. Two easy ways to do this:
+        *  - Local kzalloc (as done here)
+        *  - A buffer at the end of the structure accessed via iio_priv()
+        *    that is marked __aligned(IIO_DMA_MINALIGN).
+        */
+       scan = kzalloc(sizeof(*scan), GFP_KERNEL);
+       if (!scan)
                goto done;
 
        /*
@@ -69,13 +81,12 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
         * constant table fakedata.
         */
        iio_for_each_active_channel(indio_dev, j)
-               data[i++] = fakedata[j];
+               scan->data[i++] = fakedata[j];
 
-       iio_push_to_buffers_with_timestamp(indio_dev, data,
+       iio_push_to_buffers_with_timestamp(indio_dev, scan,
                                           iio_get_time_ns(indio_dev));
 
-       kfree(data);
-
+       kfree(scan);
 done:
        /*
         * Tell the core we are done with this trigger and ready for the