summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorDavid Lechner <dlechner@baylibre.com>2026-03-07 19:44:13 -0600
committerJonathan Cameron <jic23@kernel.org>2026-04-27 09:58:15 +0100
commitd05e3c1460e47aa61e58cc6947cf7c9fc1371d7e (patch)
tree1253b8ddf87d9d607e70f02fde65410527e7a31a /include/linux
parent99577250145316cb5840867f0278ddd8e0de8689 (diff)
iio: buffer: fix timestamp alignment when quaternion in scan
Fix timestamp alignment when a scan buffer contains an element larger than sizeof(int64_t). Currently s32 quaternions are the only such element, and the one driver that has this (hid-sensor-rotation) has a workaround in place already so this change does not affect it. Previously, we assumed that the timestamp would always be 8-byte aligned relative to the end of the scan buffer, but in the case of a scan buffer a 16-byte quaternion vector, scan_bytes == 32, but the timestamp needs to be placed at offset 16, not 24. ts_offset is now a value in bytes so we have to change how the array access is done. Signed-off-by: David Lechner <dlechner@baylibre.com> Reviewed-by: Nuno Sá <nuno.sa@analog.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/iio/buffer.h12
1 files changed, 10 insertions, 2 deletions
diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h
index d37f82678f71..8fd0d57d238f 100644
--- a/include/linux/iio/buffer.h
+++ b/include/linux/iio/buffer.h
@@ -34,8 +34,16 @@ static inline int iio_push_to_buffers_with_timestamp(struct iio_dev *indio_dev,
void *data, int64_t timestamp)
{
if (ACCESS_PRIVATE(indio_dev, scan_timestamp)) {
- size_t ts_offset = indio_dev->scan_bytes / sizeof(int64_t) - 1;
- ((int64_t *)data)[ts_offset] = timestamp;
+ size_t ts_offset = ACCESS_PRIVATE(indio_dev, scan_timestamp_offset);
+
+ /*
+ * The size of indio_dev->scan_bytes is always aligned to the
+ * largest scan element's alignment (see iio_compute_scan_bytes()).
+ * So there may be padding after the timestamp. ts_offset contains
+ * the offset in bytes that was already computed for correctly
+ * aligning the timestamp.
+ */
+ *(int64_t *)(data + ts_offset) = timestamp;
}
return iio_push_to_buffers(indio_dev, data);