diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c index 6806481873be..5a5e6e4fbe34 100644 --- a/drivers/iio/orientation/hid-sensor-rotation.c +++ b/drivers/iio/orientation/hid-sensor-rotation.c @@ -20,7 +20,12 @@ struct dev_rot_state { struct hid_sensor_hub_attribute_info quaternion; struct { IIO_DECLARE_QUATERNION(s32, sampled_vals); - aligned_s64 timestamp; + /* + * ABI regression avoidance: There are two copies of the same + * timestamp in case of userspace depending on broken alignment + * from older kernels. + */ + aligned_s64 timestamp[2]; } scan; int scale_pre_decml; int scale_post_decml; @@ -154,8 +159,19 @@ static int dev_rot_proc_event(struct hid_sensor_hub_device *hsdev, if (!rot_state->timestamp) rot_state->timestamp = iio_get_time_ns(indio_dev); - iio_push_to_buffers_with_timestamp(indio_dev, &rot_state->scan, - rot_state->timestamp); + /* + * ABI regression avoidance: IIO previously had an incorrect + * implementation of iio_push_to_buffers_with_timestamp() that + * put the timestamp in the last 8 bytes of the buffer, which + * was incorrect according to the IIO ABI. To avoid breaking + * userspace that may be depending on this broken behavior, we + * put the timestamp in both the correct place [0] and the old + * incorrect place [1]. + */ + rot_state->scan.timestamp[0] = rot_state->timestamp; + rot_state->scan.timestamp[1] = rot_state->timestamp; + + iio_push_to_buffers(indio_dev, &rot_state->scan); rot_state->timestamp = 0; }