Hi Lorenzo, From: Lorenzo Bianconi <lorenzo@xxxxxxxxxx> Date: Sun, Mar 08, 2020 at 00:06:03 > Disable MIPI I3C during 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 > > Reported-by: Mario Tesi <mario.tesi@xxxxxx> > Fixes: 2660b0080bb2 ("iio: imu: st_lsm6dsx: add i3c basic support for LSM6DSO and LSM6DSR") > Signed-off-by: Lorenzo Bianconi <lorenzo@xxxxxxxxxx> > --- > Changes since v1: > - fix comment syntax > --- > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 ++ > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 31 ++++++++++++++++++++ > 2 files changed, 33 insertions(+) > > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h > index f2113a63721a..dfcbe7c42493 100644 > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h > @@ -266,6 +266,7 @@ struct st_lsm6dsx_ext_dev_settings { > * @wai: Sensor WhoAmI default value. > * @reset: register address for reset. > * @boot: register address for boot. > + * @i3c_disable: register address for enabling/disabling I3C (addr + mask). > * @bdu: register address for Block Data Update. > * @max_fifo_size: Sensor max fifo length in FIFO words. > * @id: List of hw id/device name supported by the driver configuration. > @@ -284,6 +285,7 @@ struct st_lsm6dsx_settings { > u8 wai; > struct st_lsm6dsx_reg reset; > struct st_lsm6dsx_reg boot; > + struct st_lsm6dsx_reg i3c_disable; > struct st_lsm6dsx_reg bdu; > u16 max_fifo_size; > struct { > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c > index 84d219ae6aee..a2e775d6eaa0 100644 > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c > @@ -751,6 +751,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { > .addr = 0x12, > .mask = BIT(7), > }, > + .i3c_disable = { > + .addr = 0x18, > + .mask = BIT(1), > + }, > .bdu = { > .addr = 0x12, > .mask = BIT(6), > @@ -1128,6 +1132,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { > .addr = 0x12, > .mask = BIT(7), > }, > + .i3c_disable = { > + .addr = 0x18, > + .mask = BIT(1), > + }, > .bdu = { > .addr = 0x12, > .mask = BIT(6), > @@ -2041,6 +2049,20 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) > const struct st_lsm6dsx_reg *reg; > int err; > > + /* > + * disable MIPI I3C during 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 (hw->settings->i3c_disable.addr) { > + reg = &hw->settings->i3c_disable; > + err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, > + ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); > + if (err < 0) > + return err; > + } > + After disable the i3c interface the dynamic address is no more accessible and fails the initialization. Best regards, Vitor Soares > /* device sw reset */ > reg = &hw->settings->reset; > err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, > @@ -2059,6 +2081,15 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) > > msleep(50); > > + /* enable MIPI I3C */ > + if (hw->settings->i3c_disable.addr) { > + reg = &hw->settings->i3c_disable; > + err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, > + ST_LSM6DSX_SHIFT_VAL(0, reg->mask)); > + if (err < 0) > + return err; > + } > + > /* enable Block Data Update */ > reg = &hw->settings->bdu; > err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, > -- > 2.24.1