The DRDY_MASK feature implemented in sensor chips marks gyroscope and
accelerometer invalid samples (i.e. samples that have been acquired during
the settling time of sensor filters) with the special values 0x7FFFh,
0x7FFE, and 0x7FFD.
The driver checks FIFO samples against these special values in order to
discard invalid samples; however, it does the check regardless of the type
of samples being processed, whereas this feature is specific to gyroscope
and accelerometer data. This could cause valid samples to be discarded.
Fix the above check so that it takes into account the type of samples being
processed. To avoid casting to __le16 * when checking sample values, clean
up the type representation for data read from the FIFO.
Fixes: 960506ed2c69 ("iio: imu: st_lsm6dsx: enable drdy-mask if available")
Signed-off-by: Francesco Lavra <flavra@baylibre.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
.../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 31 +++++++++++++------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
index 5b28a3ffcc3d..19232146bd61 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
@@ -365,8 +365,6 @@ static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr,
return 0;
}
-#define ST_LSM6DSX_IIO_BUFF_SIZE (ALIGN(ST_LSM6DSX_SAMPLE_SIZE, \
- sizeof(s64)) + sizeof(s64))
/**
* st_lsm6dsx_read_fifo() - hw FIFO read routine
* @hw: Pointer to instance of struct st_lsm6dsx_hw.
@@ -537,16 +535,24 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
}
#define ST_LSM6DSX_INVALID_SAMPLE 0x7ffd
+static bool st_lsm6dsx_check_data(u8 tag, __le16 *data)
+{
+ if ((tag == ST_LSM6DSX_GYRO_TAG || tag == ST_LSM6DSX_ACC_TAG) &&
+ (s16)le16_to_cpup(data) >= ST_LSM6DSX_INVALID_SAMPLE)
+ return false;
+
+ return true;
+}
+
static int
st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag,
- u8 *data, s64 ts)
+ __le16 *data, s64 ts)
{
- s16 val = le16_to_cpu(*(__le16 *)data);
struct st_lsm6dsx_sensor *sensor;
struct iio_dev *iio_dev;
/* invalid sample during bootstrap phase */
- if (val >= ST_LSM6DSX_INVALID_SAMPLE)
+ if (!st_lsm6dsx_check_data(tag, data))
return -EINVAL;
/*
@@ -609,7 +615,13 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
* must be passed a buffer that is aligned to 8 bytes so
* as to allow insertion of a naturally aligned timestamp.
*/
- u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8);
+ struct {
+ union {
+ __le16 data[3];
+ __le32 fifo_ts;
+ };
+ aligned_s64 timestamp;
+ } iio_buff = { };
u8 tag;
bool reset_ts = false;
int i, err, read_len;
@@ -648,7 +660,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
for (i = 0; i < pattern_len;
i += ST_LSM6DSX_TAGGED_SAMPLE_SIZE) {
- memcpy(iio_buff, &hw->buff[i + ST_LSM6DSX_TAG_SIZE],
+ memcpy(&iio_buff, &hw->buff[i + ST_LSM6DSX_TAG_SIZE],
ST_LSM6DSX_SAMPLE_SIZE);
tag = hw->buff[i] >> 3;
@@ -659,7 +671,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
* B0 = ts[7:0], B1 = ts[15:8], B2 = ts[23:16],
* B3 = ts[31:24]
*/
- ts = le32_to_cpu(*((__le32 *)iio_buff));
+ ts = le32_to_cpu(iio_buff.fifo_ts);
/*
* check if hw timestamp engine is going to
* reset (the sensor generates an interrupt
@@ -670,7 +682,8 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
reset_ts = true;
ts *= hw->ts_gain;
} else {
- st_lsm6dsx_push_tagged_data(hw, tag, iio_buff,
+ st_lsm6dsx_push_tagged_data(hw, tag,
+ iio_buff.data,
ts);
}
}
--
2.39.5
On Tue, Mar 24, 2026 at 09:47:33AM +0100, Francesco Lavra wrote: > The DRDY_MASK feature implemented in sensor chips marks gyroscope and > accelerometer invalid samples (i.e. samples that have been acquired during > the settling time of sensor filters) with the special values 0x7FFFh, > 0x7FFE, and 0x7FFD. > The driver checks FIFO samples against these special values in order to > discard invalid samples; however, it does the check regardless of the type > of samples being processed, whereas this feature is specific to gyroscope > and accelerometer data. This could cause valid samples to be discarded. > > Fix the above check so that it takes into account the type of samples being > processed. To avoid casting to __le16 * when checking sample values, clean > up the type representation for data read from the FIFO. ... > static int > st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag, > - u8 *data, s64 ts) > + __le16 *data, s64 ts) Dunno why this indentation, but if you need to send a new version, consider static int st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag, __le16 *data, s64 ts) OR static int st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag, __le16 *data, s64 ts) (yes, the second one goes to 83 characters). -- With Best Regards, Andy Shevchenko
On Tue, 24 Mar 2026 14:17:11 +0200 Andy Shevchenko <andriy.shevchenko@intel.com> wrote: > On Tue, Mar 24, 2026 at 09:47:33AM +0100, Francesco Lavra wrote: > > The DRDY_MASK feature implemented in sensor chips marks gyroscope and > > accelerometer invalid samples (i.e. samples that have been acquired during > > the settling time of sensor filters) with the special values 0x7FFFh, > > 0x7FFE, and 0x7FFD. > > The driver checks FIFO samples against these special values in order to > > discard invalid samples; however, it does the check regardless of the type > > of samples being processed, whereas this feature is specific to gyroscope > > and accelerometer data. This could cause valid samples to be discarded. > > > > Fix the above check so that it takes into account the type of samples being > > processed. To avoid casting to __le16 * when checking sample values, clean > > up the type representation for data read from the FIFO. > > ... > > > static int > > st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag, > > - u8 *data, s64 ts) > > + __le16 *data, s64 ts) > > Dunno why this indentation, but if you need to send a new version, consider > > static int st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag, > __le16 *data, s64 ts) > Tweaked to this one. > OR > > static int > st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag, __le16 *data, s64 ts) > > (yes, the second one goes to 83 characters). >
© 2016 - 2026 Red Hat, Inc.