diff options
author | Lorenzo Bianconi <lorenzo@kernel.org> | 2019-10-06 16:21:55 +0300 |
---|---|---|
committer | Jonathan Cameron <Jonathan.Cameron@huawei.com> | 2019-10-15 23:11:04 +0300 |
commit | 615bd3785b5abf17e50c7940d4f0ce418b65176a (patch) | |
tree | 72c027ba19c31981f04b086535937559dc6bc3d3 /drivers/iio | |
parent | dbcc1fbe5d94796031ba91c417184e89de4cd4ec (diff) | |
download | linux-615bd3785b5abf17e50c7940d4f0ce418b65176a.tar.xz |
iio: imu: st_lsm6dsx: use st_lsm6dsx_read_locked in st_lsm6dsx_report_motion_event
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@kernel.org>
Tested-by: Sean Nyekjaer <sean@geanix.com>
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.c | 34 |
1 files 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 de0049c75eeb..5dfb92d83afc 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -1767,10 +1767,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], @@ -1800,30 +1813,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) |