On Sun, 6 Oct 2019 15:21:55 +0200 Lorenzo Bianconi <lorenzo@xxxxxxxxxx> wrote: > Rely on st_lsm6dsx_read_locked in st_lsm6dsx_report_motion_event since > it can run concurrently with sensor hub configuration. Move event > related code in st_lsm6dsx_report_motion_event > > Fixes: 1aabad1fb5e9 ("iio: imu: st_lsm6dsx: add motion report function and call from interrupt") > Signed-off-by: Lorenzo Bianconi <lorenzo@xxxxxxxxxx> Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it. Thanks, Jonathan > --- > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 34 ++++++++++++-------- > 1 file changed, 20 insertions(+), 14 deletions(-) > > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c > index 8a813ddba19c..df270905f21d 100644 > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c > @@ -1757,10 +1757,23 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, > return iio_dev; > } > > -static void st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw, int data) > +static bool > +st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw) > { > - s64 timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]); > + const struct st_lsm6dsx_event_settings *event_settings; > + int err, data; > + s64 timestamp; > > + if (!hw->enable_event) > + return false; > + > + event_settings = &hw->settings->event_settings; > + err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg, > + &data, sizeof(data)); > + if (err < 0) > + return false; > + > + timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]); > if ((data & hw->settings->event_settings.wakeup_src_z_mask) && > (hw->enable_event & BIT(IIO_MOD_Z))) > iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], > @@ -1790,30 +1803,23 @@ static void st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw, int data) > IIO_EV_TYPE_THRESH, > IIO_EV_DIR_EITHER), > timestamp); > + > + return data & event_settings->wakeup_src_status_mask; > } > > static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) > { > struct st_lsm6dsx_hw *hw = private; > + bool event; > int count; > - int data, err; > - > - if (hw->enable_event) { > - err = regmap_read(hw->regmap, > - hw->settings->event_settings.wakeup_src_reg, > - &data); > - if (err < 0) > - return IRQ_NONE; > > - if (data & hw->settings->event_settings.wakeup_src_status_mask) > - st_lsm6dsx_report_motion_event(hw, data); > - } > + event = st_lsm6dsx_report_motion_event(hw); > > mutex_lock(&hw->fifo_lock); > count = hw->settings->fifo_ops.read_fifo(hw); > mutex_unlock(&hw->fifo_lock); > > - return count ? IRQ_HANDLED : IRQ_NONE; > + return count || event ? IRQ_HANDLED : IRQ_NONE; > } > > static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)