| From 84c7bfd3f5c56b246d5fc0c4cef8a3db24236e20 Mon Sep 17 00:00:00 2001 |
| From: Jean-Baptiste Maneyrol <JManeyrol@invensense.com> |
| Date: Wed, 16 Oct 2019 14:43:28 +0000 |
| Subject: [PATCH] iio: imu: inv_mpu6050: fix no data on MPU6050 |
| |
| commit 6e82ae6b8d11b948b74e71396efd8e074c415f44 upstream. |
| |
| Some chips have a fifo overflow bit issue where the bit is always |
| set. The result is that every data is dropped. |
| |
| Change fifo overflow management by checking fifo count against |
| a maximum value. |
| |
| Add fifo size in chip hardware set of values. |
| |
| Fixes: f5057e7b2dba ("iio: imu: inv_mpu6050: better fifo overflow handling") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com> |
| Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c |
| index 8a704cd5bddb..3cb41ac357fa 100644 |
| --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c |
| +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c |
| @@ -114,54 +114,63 @@ static const struct inv_mpu6050_hw hw_info[] = { |
| .name = "MPU6050", |
| .reg = ®_set_6050, |
| .config = &chip_config_6050, |
| + .fifo_size = 1024, |
| }, |
| { |
| .whoami = INV_MPU6500_WHOAMI_VALUE, |
| .name = "MPU6500", |
| .reg = ®_set_6500, |
| .config = &chip_config_6050, |
| + .fifo_size = 512, |
| }, |
| { |
| .whoami = INV_MPU6515_WHOAMI_VALUE, |
| .name = "MPU6515", |
| .reg = ®_set_6500, |
| .config = &chip_config_6050, |
| + .fifo_size = 512, |
| }, |
| { |
| .whoami = INV_MPU6000_WHOAMI_VALUE, |
| .name = "MPU6000", |
| .reg = ®_set_6050, |
| .config = &chip_config_6050, |
| + .fifo_size = 1024, |
| }, |
| { |
| .whoami = INV_MPU9150_WHOAMI_VALUE, |
| .name = "MPU9150", |
| .reg = ®_set_6050, |
| .config = &chip_config_6050, |
| + .fifo_size = 1024, |
| }, |
| { |
| .whoami = INV_MPU9250_WHOAMI_VALUE, |
| .name = "MPU9250", |
| .reg = ®_set_6500, |
| .config = &chip_config_6050, |
| + .fifo_size = 512, |
| }, |
| { |
| .whoami = INV_MPU9255_WHOAMI_VALUE, |
| .name = "MPU9255", |
| .reg = ®_set_6500, |
| .config = &chip_config_6050, |
| + .fifo_size = 512, |
| }, |
| { |
| .whoami = INV_ICM20608_WHOAMI_VALUE, |
| .name = "ICM20608", |
| .reg = ®_set_6500, |
| .config = &chip_config_6050, |
| + .fifo_size = 512, |
| }, |
| { |
| .whoami = INV_ICM20602_WHOAMI_VALUE, |
| .name = "ICM20602", |
| .reg = ®_set_icm20602, |
| .config = &chip_config_6050, |
| + .fifo_size = 1008, |
| }, |
| }; |
| |
| diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h |
| index db1c6904388b..51235677c534 100644 |
| --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h |
| +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h |
| @@ -100,12 +100,14 @@ struct inv_mpu6050_chip_config { |
| * @name: name of the chip. |
| * @reg: register map of the chip. |
| * @config: configuration of the chip. |
| + * @fifo_size: size of the FIFO in bytes. |
| */ |
| struct inv_mpu6050_hw { |
| u8 whoami; |
| u8 *name; |
| const struct inv_mpu6050_reg_map *reg; |
| const struct inv_mpu6050_chip_config *config; |
| + size_t fifo_size; |
| }; |
| |
| /* |
| diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c |
| index 5f9a5de0bab4..72d8c5790076 100644 |
| --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c |
| +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c |
| @@ -180,9 +180,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) |
| "failed to ack interrupt\n"); |
| goto flush_fifo; |
| } |
| - /* handle fifo overflow by reseting fifo */ |
| - if (int_status & INV_MPU6050_BIT_FIFO_OVERFLOW_INT) |
| - goto flush_fifo; |
| if (!(int_status & INV_MPU6050_BIT_RAW_DATA_RDY_INT)) { |
| dev_warn(regmap_get_device(st->map), |
| "spurious interrupt with status 0x%x\n", int_status); |
| @@ -211,6 +208,18 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) |
| if (result) |
| goto end_session; |
| fifo_count = get_unaligned_be16(&data[0]); |
| + |
| + /* |
| + * Handle fifo overflow by resetting fifo. |
| + * Reset if there is only 3 data set free remaining to mitigate |
| + * possible delay between reading fifo count and fifo data. |
| + */ |
| + nb = 3 * bytes_per_datum; |
| + if (fifo_count >= st->hw->fifo_size - nb) { |
| + dev_warn(regmap_get_device(st->map), "fifo overflow reset\n"); |
| + goto flush_fifo; |
| + } |
| + |
| /* compute and process all complete datum */ |
| nb = fifo_count / bytes_per_datum; |
| inv_mpu6050_update_period(st, pf->timestamp, nb); |
| -- |
| 2.7.4 |
| |