diff options
author | Gwendal Grignou <gwendal@chromium.org> | 2018-07-13 16:43:01 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-07-14 04:58:17 -0700 |
commit | 0a3f63f67aea7da6df6df2040f8c3647a1510ece (patch) | |
tree | 9c9f6a369a49ed83d07ec3871e8861ab70ffa5f2 /driver | |
parent | 1e5d1d319f1836f4a14eb42c6b4d8e177344941f (diff) | |
download | chrome-ec-0a3f63f67aea7da6df6df2040f8c3647a1510ece.tar.gz |
driver: bmi160: Preserve the timestamp before releasing interrupt
Collect timestamp before resetting the interrupt line:
After reading, it is possible for the timestamp to change,
before we can process the FIFO.
BUG=b:67743747
BRANCH=scarlet
TEST=CtsHardwareTestCases
Change-Id: I283f8efb1098a38c76caf326b6416a386ab221cd
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1137438
Commit-Ready: Alexandru M Stan <amstan@chromium.org>
Tested-by: Alexandru M Stan <amstan@chromium.org>
Reviewed-by: Alexandru M Stan <amstan@chromium.org>
Diffstat (limited to 'driver')
-rw-r--r-- | driver/accelgyro_bmi160.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/driver/accelgyro_bmi160.c b/driver/accelgyro_bmi160.c index c46862d8a9..85a6ff5235 100644 --- a/driver/accelgyro_bmi160.c +++ b/driver/accelgyro_bmi160.c @@ -27,7 +27,7 @@ #define CPRINTS(format, args...) cprints(CC_ACCEL, format, ## args) #ifdef CONFIG_ACCEL_FIFO -static uint32_t last_interrupt_timestamp; +static volatile uint32_t last_interrupt_timestamp; #endif /* @@ -788,7 +788,7 @@ static uint8_t bmi160_buffer[BMI160_FIFO_BUFFER]; * @bp: current pointer in the buffer, updated when processing the header. */ static int bmi160_decode_header(struct motion_sensor_t *s, - enum fifo_header hdr, uint8_t **bp) + enum fifo_header hdr, uint32_t last_ts, uint8_t **bp) { if ((hdr & BMI160_FH_MODE_MASK) == BMI160_EMPTY && (hdr & BMI160_FH_PARM_MASK) != 0) { @@ -820,7 +820,7 @@ static int bmi160_decode_header(struct motion_sensor_t *s, vector.data[Z] = v[Z]; vector.sensor_num = i + (s - motion_sensors); motion_sense_fifo_add_data(&vector, s + i, 3, - last_interrupt_timestamp); + last_ts); *bp += (i == MOTIONSENSE_TYPE_MAG ? 8 : 6); } } @@ -841,7 +841,7 @@ static int bmi160_decode_header(struct motion_sensor_t *s, * for spoof_mode in order to load the sensor stack with the spoofed * data. See accelgyro_bmi160.c::load_fifo for an example. */ -static int load_fifo(struct motion_sensor_t *s) +static int load_fifo(struct motion_sensor_t *s, uint32_t last_ts) { int done = 0; struct bmi160_drv_data_t *data = BMI160_GET_DATA(s); @@ -891,7 +891,7 @@ static int load_fifo(struct motion_sensor_t *s) switch (state) { case FIFO_HEADER: { enum fifo_header hdr = *bp++; - if (bmi160_decode_header(s, hdr, &bp)) + if (bmi160_decode_header(s, hdr, last_ts, &bp)) continue; /* Other cases */ hdr &= 0xdc; @@ -1089,13 +1089,19 @@ static void irq_set_orientation(struct motion_sensor_t *s, */ static int irq_handler(struct motion_sensor_t *s, uint32_t *event) { - int interrupt; + uint32_t interrupt, last_ts; if ((s->type != MOTIONSENSE_TYPE_ACCEL) || (!(*event & CONFIG_ACCELGYRO_BMI160_INT_EVENT))) return EC_ERROR_NOT_HANDLED; do { + /* + * Collect timestamp before resetting the interrupt line: + * After reading, it is possible for the timestamp to change, + * before we can process the FIFO. + */ + last_ts = last_interrupt_timestamp; raw_read32(s->port, s->addr, BMI160_INT_STATUS_0, &interrupt); #ifdef CONFIG_GESTURE_SENSOR_BATTERY_TAP @@ -1108,7 +1114,7 @@ static int irq_handler(struct motion_sensor_t *s, uint32_t *event) #endif #ifdef CONFIG_ACCEL_FIFO if (interrupt & (BMI160_FWM_INT | BMI160_FFULL_INT)) - load_fifo(s); + load_fifo(s, last_ts); #endif #ifdef CONFIG_BMI160_ORIENTATION_SENSOR irq_set_orientation(s, interrupt); |