Commit d7a83bc3 authored by Jonathan Cameron's avatar Jonathan Cameron
Browse files

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: 5075e072 ("iio: imu: adis: generalize burst mode support")
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: default avatarNuno Sá <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20210613151039.569883-5-jic23@kernel.org
parent b5ca2046
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -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;

	iio_push_to_buffers_with_timestamp(indio_dev, 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_trigger_notify_done(indio_dev->trig);