Message ID | 20210613151039.569883-5-jic23@kernel.org (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | [v2,1/4] iio: core: Introduce iio_push_to_buffers_with_ts_unaligned() | expand |
> From: Jonathan Cameron <jic23@kernel.org> > Sent: Sunday, June 13, 2021 5:11 PM > To: linux-iio@vger.kernel.org; Andy Shevchenko > <andy.shevchenko@gmail.com>; Sa, Nuno <Nuno.Sa@analog.com> > Cc: Linus Walleij <linus.walleij@linaro.org>; Jan Kiszka > <jan.kiszka@siemens.com>; Jonathan Cameron > <Jonathan.Cameron@huawei.com>; Sa, Nuno > <Nuno.Sa@analog.com> > Subject: [PATCH v2 4/4] iio: imu: adis16400: Fix buffer alignment > requirements. > > [External] > > From: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > 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> > --- > 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 cb8d3ffab6fc..66a83ebd3109 100644 > --- a/drivers/iio/imu/adis16400.c > +++ b/drivers/iio/imu/adis16400.c > @@ -648,13 +648,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); > > -- > 2.32.0 Reviewed-by: Nuno Sá <nuno.sa@analog.com>
diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c index cb8d3ffab6fc..66a83ebd3109 100644 --- a/drivers/iio/imu/adis16400.c +++ b/drivers/iio/imu/adis16400.c @@ -648,13 +648,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);