Skip to content

Commit d7bd473

Browse files
jmaneyrol-invnjic23
authored andcommitted
iio: imu: inv_icm42600: stabilized timestamp in interrupt
Use IRQF_ONESHOT flag to ensure the timestamp is not updated in the hard handler during the thread handler. And compute and use the effective watermark value that correspond to this first timestamp. This way we can ensure the timestamp is always corresponding to the value used by the timestamping mechanism. Otherwise, it is possible that between FIFO count read and FIFO processing the timestamp is overwritten in the hard handler. Fixes: ec74ae9 ("iio: imu: inv_icm42600: add accurate timestamping") Cc: stable@vger.kernel.org Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com> Link: https://lore.kernel.org/r/20240529154717.651863-1-inv.git-commit@tdk.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
1 parent 95444b9 commit d7bd473

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,15 @@ int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st)
222222
latency_accel = period_accel * wm_accel;
223223

224224
/* 0 value for watermark means that the sensor is turned off */
225+
if (wm_gyro == 0 && wm_accel == 0)
226+
return 0;
227+
225228
if (latency_gyro == 0) {
226229
watermark = wm_accel;
230+
st->fifo.watermark.eff_accel = wm_accel;
227231
} else if (latency_accel == 0) {
228232
watermark = wm_gyro;
233+
st->fifo.watermark.eff_gyro = wm_gyro;
229234
} else {
230235
/* compute the smallest latency that is a multiple of both */
231236
if (latency_gyro <= latency_accel)
@@ -241,6 +246,13 @@ int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st)
241246
watermark = latency / period;
242247
if (watermark < 1)
243248
watermark = 1;
249+
/* update effective watermark */
250+
st->fifo.watermark.eff_gyro = latency / period_gyro;
251+
if (st->fifo.watermark.eff_gyro < 1)
252+
st->fifo.watermark.eff_gyro = 1;
253+
st->fifo.watermark.eff_accel = latency / period_accel;
254+
if (st->fifo.watermark.eff_accel < 1)
255+
st->fifo.watermark.eff_accel = 1;
244256
}
245257

246258
/* compute watermark value in bytes */
@@ -514,7 +526,7 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
514526
/* handle gyroscope timestamp and FIFO data parsing */
515527
if (st->fifo.nb.gyro > 0) {
516528
ts = &gyro_st->ts;
517-
inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro,
529+
inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_gyro,
518530
st->timestamp.gyro);
519531
ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
520532
if (ret)
@@ -524,7 +536,7 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
524536
/* handle accelerometer timestamp and FIFO data parsing */
525537
if (st->fifo.nb.accel > 0) {
526538
ts = &accel_st->ts;
527-
inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel,
539+
inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_accel,
528540
st->timestamp.accel);
529541
ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
530542
if (ret)
@@ -577,6 +589,9 @@ int inv_icm42600_buffer_init(struct inv_icm42600_state *st)
577589
unsigned int val;
578590
int ret;
579591

592+
st->fifo.watermark.eff_gyro = 1;
593+
st->fifo.watermark.eff_accel = 1;
594+
580595
/*
581596
* Default FIFO configuration (bits 7 to 5)
582597
* - use invalid value

drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ struct inv_icm42600_fifo {
3232
struct {
3333
unsigned int gyro;
3434
unsigned int accel;
35+
unsigned int eff_gyro;
36+
unsigned int eff_accel;
3537
} watermark;
3638
size_t count;
3739
struct {

drivers/iio/imu/inv_icm42600/inv_icm42600_core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ static int inv_icm42600_irq_init(struct inv_icm42600_state *st, int irq,
537537
if (ret)
538538
return ret;
539539

540+
irq_type |= IRQF_ONESHOT;
540541
return devm_request_threaded_irq(dev, irq, inv_icm42600_irq_timestamp,
541542
inv_icm42600_irq_handler, irq_type,
542543
"inv_icm42600", st);

0 commit comments

Comments
 (0)