aboutsummaryrefslogtreecommitdiff
path: root/drivers/iio
diff options
context:
space:
mode:
authorLorenzo Bianconi <lorenzo@kernel.org>2020-03-13 19:06:00 +0100
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2020-04-19 17:50:01 +0100
commit3a63da26db0a864134f023f088d41deacd509997 (patch)
tree4475c56bf2e0f7a36fd5e773a094328a2e4e11b5 /drivers/iio
parent5403f2807623b2e470c889f8d937e2f1a859251e (diff)
iio: imu: st_lsm6dsx: flush hw FIFO before resetting the device
flush hw FIFO before device reset in order to avoid possible races on interrupt line 1. If the first interrupt line is asserted during hw reset the device will work in I3C-only mode (if it is supported) Fixes: 801a6e0af0c6 ("iio: imu: st_lsm6dsx: add support to LSM6DSO") Fixes: 43901008fde0 ("iio: imu: st_lsm6dsx: add support to LSM6DSR") Reported-by: Mario Tesi <mario.tesi@st.com> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Reviewed-by: Vitor Soares <vitor.soares@synopsys.com> Tested-by: Vitor Soares <vitor.soares@synopsys.com> Cc: <Stable@vger.kernel.org> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
index 84d219ae6aee..4426524b59f2 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -2036,11 +2036,21 @@ static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
return 0;
}
-static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
+static int st_lsm6dsx_reset_device(struct st_lsm6dsx_hw *hw)
{
const struct st_lsm6dsx_reg *reg;
int err;
+ /*
+ * flush hw FIFO before device reset in order to avoid
+ * possible races on interrupt line 1. If the first interrupt
+ * line is asserted during hw reset the device will work in
+ * I3C-only mode (if it is supported)
+ */
+ err = st_lsm6dsx_flush_fifo(hw);
+ if (err < 0 && err != -ENOTSUPP)
+ return err;
+
/* device sw reset */
reg = &hw->settings->reset;
err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
@@ -2059,6 +2069,18 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
msleep(50);
+ return 0;
+}
+
+static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
+{
+ const struct st_lsm6dsx_reg *reg;
+ int err;
+
+ err = st_lsm6dsx_reset_device(hw);
+ if (err < 0)
+ return err;
+
/* enable Block Data Update */
reg = &hw->settings->bdu;
err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,