summaryrefslogtreecommitdiffstats
path: root/drivers/iio/imu/adis16400.c
diff options
context:
space:
mode:
authorJonathan Cameron <Jonathan.Cameron@huawei.com>2021-06-13 17:10:39 +0200
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2021-10-19 09:29:22 +0200
commitd7a83bc38d8dd11b3df7e0db3739be6ced1667af (patch)
tree1d1470b38811c8c337e2afa17019f53db5bda674 /drivers/iio/imu/adis16400.c
parentiio: gyro: mpu3050: Fix alignment and size issues with buffers. (diff)
downloadlinux-d7a83bc38d8dd11b3df7e0db3739be6ced1667af.tar.xz
linux-d7a83bc38d8dd11b3df7e0db3739be6ced1667af.zip
iio: imu: adis16400: Fix buffer alignment requirements.
iio_push_to_buffers_with_timestamp() requires that the buffer is 8 byte alignment to ensure an inserted timestamp is naturally aligned. This requirement was not met here when burst mode is in use beause of a leading u16. Use the new iio_push_to_buffers_with_ts_unaligned() function that has more relaxed requirements. It is somewhat complex to access that actual data length, but a safe bound can be found by using scan_bytes - sizeof(timestamp) so that is used in this path. More efficient approaches exist, but this ensure correctness at the cost of using a bounce buffer. Fixes: 5075e0720d93 ("iio: imu: adis: generalize burst mode support") Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Nuno Sá <nuno.sa@analog.com> Link: https://lore.kernel.org/r/20210613151039.569883-5-jic23@kernel.org
Diffstat (limited to 'drivers/iio/imu/adis16400.c')
-rw-r--r--drivers/iio/imu/adis16400.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c
index b12917a7cb60..9fd30e62d6e8 100644
--- a/drivers/iio/imu/adis16400.c
+++ b/drivers/iio/imu/adis16400.c
@@ -641,13 +641,23 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
if (ret)
dev_err(&adis->spi->dev, "Failed to read data: %d\n", ret);
- if (st->variant->flags & ADIS16400_BURST_DIAG_STAT)
+ if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) {
buffer = adis->buffer + sizeof(u16);
- else
- buffer = adis->buffer;
+ /*
+ * The size here is always larger than, or equal to the true
+ * size of the channel data. This may result in a larger copy
+ * than necessary, but as the target buffer will be
+ * buffer->scan_bytes this will be safe.
+ */
+ iio_push_to_buffers_with_ts_unaligned(indio_dev, buffer,
+ indio_dev->scan_bytes - sizeof(pf->timestamp),
+ pf->timestamp);
+ } else {
+ iio_push_to_buffers_with_timestamp(indio_dev,
+ adis->buffer,
+ pf->timestamp);
+ }
- iio_push_to_buffers_with_timestamp(indio_dev, buffer,
- pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);