summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2018-07-13 16:43:01 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2018-07-16 18:25:41 +0000
commit023f4602e86ed9fb7e108287e65c978649005c98 (patch)
tree74ef5767bc4896cf5acda3dede9718c20fd20329
parentcbee5325d37f012cb279f42640921c22d84ed168 (diff)
downloadchrome-ec-023f4602e86ed9fb7e108287e65c978649005c98.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/1137443 Commit-Queue: Alexandru M Stan <amstan@chromium.org> Commit-Queue: Philip Chen <philipchen@chromium.org> Tested-by: Alexandru M Stan <amstan@chromium.org> Tested-by: Philip Chen <philipchen@chromium.org> Trybot-Ready: Alexandru M Stan <amstan@chromium.org> Reviewed-by: Philip Chen <philipchen@chromium.org>
-rw-r--r--driver/accelgyro_bmi160.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/driver/accelgyro_bmi160.c b/driver/accelgyro_bmi160.c
index 443937ba59..0913ba4731 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
/*
@@ -794,7 +794,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) {
@@ -826,7 +826,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);
}
}
@@ -847,7 +847,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);
@@ -897,7 +897,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;
@@ -1095,13 +1095,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
@@ -1114,7 +1120,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);