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

iio: temperature: maxim_thermocouple: use DMA-safe buffer for spi_read()

Replace using stack-allocated buffers with a DMA-safe buffer for use
with spi_read(). This allows the driver to be safely used with
DMA-enabled SPI controllers.

The buffer array is also converted to a struct with a union to make the
usage of the memory in the buffer more clear and ensure proper alignment.

Fixes: 1f25ca11d84a ("iio: temperature: add support for Maxim thermocouple chips")
Signed-off-by: David Lechner <dlechner@baylibre.com>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20250721-iio-use-more-iio_declare_buffer_with_ts-3-v2-1-0c68d41ccf6c@baylibre.com
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

David Lechner and committed by
Jonathan Cameron
ae5bc07e 1cfb22c2

+16 -10
+16 -10
drivers/iio/temperature/maxim_thermocouple.c
··· 11 11 #include <linux/module.h> 12 12 #include <linux/err.h> 13 13 #include <linux/spi/spi.h> 14 + #include <linux/types.h> 14 15 #include <linux/iio/iio.h> 15 16 #include <linux/iio/sysfs.h> 16 17 #include <linux/iio/trigger.h> ··· 122 121 struct spi_device *spi; 123 122 const struct maxim_thermocouple_chip *chip; 124 123 char tc_type; 125 - 126 - u8 buffer[16] __aligned(IIO_DMA_MINALIGN); 124 + /* Buffer for reading up to 2 hardware channels. */ 125 + struct { 126 + union { 127 + __be16 raw16; 128 + __be32 raw32; 129 + __be16 raw[2]; 130 + }; 131 + aligned_s64 timestamp; 132 + } buffer __aligned(IIO_DMA_MINALIGN); 127 133 }; 128 134 129 135 static int maxim_thermocouple_read(struct maxim_thermocouple_data *data, ··· 138 130 { 139 131 unsigned int storage_bytes = data->chip->read_size; 140 132 unsigned int shift = chan->scan_type.shift + (chan->address * 8); 141 - __be16 buf16; 142 - __be32 buf32; 143 133 int ret; 144 134 145 135 switch (storage_bytes) { 146 136 case 2: 147 - ret = spi_read(data->spi, (void *)&buf16, storage_bytes); 148 - *val = be16_to_cpu(buf16); 137 + ret = spi_read(data->spi, &data->buffer.raw16, storage_bytes); 138 + *val = be16_to_cpu(data->buffer.raw16); 149 139 break; 150 140 case 4: 151 - ret = spi_read(data->spi, (void *)&buf32, storage_bytes); 152 - *val = be32_to_cpu(buf32); 141 + ret = spi_read(data->spi, &data->buffer.raw32, storage_bytes); 142 + *val = be32_to_cpu(data->buffer.raw32); 153 143 break; 154 144 default: 155 145 ret = -EINVAL; ··· 172 166 struct maxim_thermocouple_data *data = iio_priv(indio_dev); 173 167 int ret; 174 168 175 - ret = spi_read(data->spi, data->buffer, data->chip->read_size); 169 + ret = spi_read(data->spi, data->buffer.raw, data->chip->read_size); 176 170 if (!ret) { 177 - iio_push_to_buffers_with_ts(indio_dev, data->buffer, 171 + iio_push_to_buffers_with_ts(indio_dev, &data->buffer, 178 172 sizeof(data->buffer), 179 173 iio_get_time_ns(indio_dev)); 180 174 }