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: 5075e0720d ("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
This commit is contained in:
Jonathan Cameron 2021-06-13 16:10:39 +01:00
Родитель b5ca2046c6
Коммит d7a83bc38d
1 изменённых файлов: 15 добавлений и 5 удалений

Просмотреть файл

@ -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);