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

iio: dummy: Use a fixed structure to build up scan to push to buffers.

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>

+18 -7
+18 -7
drivers/iio/dummy/iio_simple_dummy_buffer.c
··· 31 31 [DUMMY_INDEX_ACCELX] = 344, 32 32 }; 33 33 34 + struct dummy_scan { 35 + s16 data[ARRAY_SIZE(fakedata)]; 36 + aligned_s64 timestamp; 37 + }; 38 + 34 39 /** 35 40 * iio_simple_dummy_trigger_h() - the trigger handler function 36 41 * @irq: the interrupt number ··· 50 45 { 51 46 struct iio_poll_func *pf = p; 52 47 struct iio_dev *indio_dev = pf->indio_dev; 48 + struct dummy_scan *scan; 53 49 int i = 0, j; 54 - u16 *data; 55 50 56 - data = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); 57 - if (!data) 51 + /* 52 + * Note that some buses such as SPI require DMA safe buffers which 53 + * cannot be on the stack. Two easy ways to do this: 54 + * - Local kzalloc (as done here) 55 + * - A buffer at the end of the structure accessed via iio_priv() 56 + * that is marked __aligned(IIO_DMA_MINALIGN). 57 + */ 58 + scan = kzalloc(sizeof(*scan), GFP_KERNEL); 59 + if (!scan) 58 60 goto done; 59 61 60 62 /* ··· 81 69 * constant table fakedata. 82 70 */ 83 71 iio_for_each_active_channel(indio_dev, j) 84 - data[i++] = fakedata[j]; 72 + scan->data[i++] = fakedata[j]; 85 73 86 - iio_push_to_buffers_with_timestamp(indio_dev, data, 74 + iio_push_to_buffers_with_timestamp(indio_dev, scan, 87 75 iio_get_time_ns(indio_dev)); 88 76 89 - kfree(data); 90 - 77 + kfree(scan); 91 78 done: 92 79 /* 93 80 * Tell the core we are done with this trigger and ready for the