From d7a83bc38d8dd11b3df7e0db3739be6ced1667af Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 13 Jun 2021 16:10:39 +0100 Subject: iio: imu: adis16400: Fix buffer alignment requirements. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Nuno Sá Link: https://lore.kernel.org/r/20210613151039.569883-5-jic23@kernel.org --- drivers/iio/imu/adis16400.c | 20 +++++++++++++++----- 1 file 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); -- cgit