Skip to content

Commit

Permalink
iio: imu: inv_icm42600: stabilized timestamp in interrupt
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jean-Baptiste Maneyrol authored and Jonathan Cameron committed Jun 2, 2024
1 parent 95444b9 commit d7bd473
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
19 changes: 17 additions & 2 deletions drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,15 @@ int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st)
latency_accel = period_accel * wm_accel;

/* 0 value for watermark means that the sensor is turned off */
if (wm_gyro == 0 && wm_accel == 0)
return 0;

if (latency_gyro == 0) {
watermark = wm_accel;
st->fifo.watermark.eff_accel = wm_accel;
} else if (latency_accel == 0) {
watermark = wm_gyro;
st->fifo.watermark.eff_gyro = wm_gyro;
} else {
/* compute the smallest latency that is a multiple of both */
if (latency_gyro <= latency_accel)
Expand All @@ -241,6 +246,13 @@ int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st)
watermark = latency / period;
if (watermark < 1)
watermark = 1;
/* update effective watermark */
st->fifo.watermark.eff_gyro = latency / period_gyro;
if (st->fifo.watermark.eff_gyro < 1)
st->fifo.watermark.eff_gyro = 1;
st->fifo.watermark.eff_accel = latency / period_accel;
if (st->fifo.watermark.eff_accel < 1)
st->fifo.watermark.eff_accel = 1;
}

/* compute watermark value in bytes */
Expand Down Expand Up @@ -514,7 +526,7 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
/* handle gyroscope timestamp and FIFO data parsing */
if (st->fifo.nb.gyro > 0) {
ts = &gyro_st->ts;
inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro,
inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_gyro,
st->timestamp.gyro);
ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
if (ret)
Expand All @@ -524,7 +536,7 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
/* handle accelerometer timestamp and FIFO data parsing */
if (st->fifo.nb.accel > 0) {
ts = &accel_st->ts;
inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel,
inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_accel,
st->timestamp.accel);
ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
if (ret)
Expand Down Expand Up @@ -577,6 +589,9 @@ int inv_icm42600_buffer_init(struct inv_icm42600_state *st)
unsigned int val;
int ret;

st->fifo.watermark.eff_gyro = 1;
st->fifo.watermark.eff_accel = 1;

/*
* Default FIFO configuration (bits 7 to 5)
* - use invalid value
Expand Down
2 changes: 2 additions & 0 deletions drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ struct inv_icm42600_fifo {
struct {
unsigned int gyro;
unsigned int accel;
unsigned int eff_gyro;
unsigned int eff_accel;
} watermark;
size_t count;
struct {
Expand Down
1 change: 1 addition & 0 deletions drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ static int inv_icm42600_irq_init(struct inv_icm42600_state *st, int irq,
if (ret)
return ret;

irq_type |= IRQF_ONESHOT;
return devm_request_threaded_irq(dev, irq, inv_icm42600_irq_timestamp,
inv_icm42600_irq_handler, irq_type,
"inv_icm42600", st);
Expand Down

0 comments on commit d7bd473

Please sign in to comment.