summaryrefslogtreecommitdiffstats
path: root/drivers/iio/imu
diff options
context:
space:
mode:
authorLorenzo Bianconi <lorenzo@kernel.org>2019-10-06 15:21:55 +0200
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2019-10-15 22:11:04 +0200
commit615bd3785b5abf17e50c7940d4f0ce418b65176a (patch)
tree72c027ba19c31981f04b086535937559dc6bc3d3 /drivers/iio/imu
parentdt-bindings: Add max12xx SPI ADC series as trivial devices (diff)
downloadlinux-615bd3785b5abf17e50c7940d4f0ce418b65176a.tar.xz
linux-615bd3785b5abf17e50c7940d4f0ce418b65176a.zip
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/imu')
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c34
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)