Commit 335eaedc authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Greg Kroah-Hartman

iio: imu: st_lsm6dsx: introduce conf_lock mutex

Add conf_lock mutex to prevent concurrent FIFO configuration update

Fixes: 290a6ce1 (iio: imu: add support to lsm6dsx driver)
Signed-off-by: default avatarLorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7b9ebe42
...@@ -130,6 +130,7 @@ struct st_lsm6dsx_sensor { ...@@ -130,6 +130,7 @@ struct st_lsm6dsx_sensor {
* @irq: Device interrupt line (I2C or SPI). * @irq: Device interrupt line (I2C or SPI).
* @lock: Mutex to protect read and write operations. * @lock: Mutex to protect read and write operations.
* @fifo_lock: Mutex to prevent concurrent access to the hw FIFO. * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO.
* @conf_lock: Mutex to prevent concurrent FIFO configuration update.
* @fifo_mode: FIFO operating mode supported by the device. * @fifo_mode: FIFO operating mode supported by the device.
* @enable_mask: Enabled sensor bitmask. * @enable_mask: Enabled sensor bitmask.
* @sip: Total number of samples (acc/gyro) in a given pattern. * @sip: Total number of samples (acc/gyro) in a given pattern.
...@@ -144,6 +145,7 @@ struct st_lsm6dsx_hw { ...@@ -144,6 +145,7 @@ struct st_lsm6dsx_hw {
struct mutex lock; struct mutex lock;
struct mutex fifo_lock; struct mutex fifo_lock;
struct mutex conf_lock;
enum st_lsm6dsx_fifo_mode fifo_mode; enum st_lsm6dsx_fifo_mode fifo_mode;
u8 enable_mask; u8 enable_mask;
......
...@@ -325,38 +325,40 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable) ...@@ -325,38 +325,40 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable)
struct st_lsm6dsx_hw *hw = sensor->hw; struct st_lsm6dsx_hw *hw = sensor->hw;
int err; int err;
mutex_lock(&hw->conf_lock);
if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS) { if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS) {
err = st_lsm6dsx_flush_fifo(hw); err = st_lsm6dsx_flush_fifo(hw);
if (err < 0) if (err < 0)
return err; goto out;
} }
if (enable) { if (enable) {
err = st_lsm6dsx_sensor_enable(sensor); err = st_lsm6dsx_sensor_enable(sensor);
if (err < 0) if (err < 0)
return err; goto out;
} else { } else {
err = st_lsm6dsx_sensor_disable(sensor); err = st_lsm6dsx_sensor_disable(sensor);
if (err < 0) if (err < 0)
return err; goto out;
} }
err = st_lsm6dsx_set_fifo_odr(sensor, enable); err = st_lsm6dsx_set_fifo_odr(sensor, enable);
if (err < 0) if (err < 0)
return err; goto out;
err = st_lsm6dsx_update_decimators(hw); err = st_lsm6dsx_update_decimators(hw);
if (err < 0) if (err < 0)
return err; goto out;
err = st_lsm6dsx_update_watermark(sensor, sensor->watermark); err = st_lsm6dsx_update_watermark(sensor, sensor->watermark);
if (err < 0) if (err < 0)
return err; goto out;
if (hw->enable_mask) { if (hw->enable_mask) {
err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT); err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
if (err < 0) if (err < 0)
return err; goto out;
/* /*
* store enable buffer timestamp as reference to compute * store enable buffer timestamp as reference to compute
...@@ -365,7 +367,10 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable) ...@@ -365,7 +367,10 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable)
sensor->ts = iio_get_time_ns(iio_dev); sensor->ts = iio_get_time_ns(iio_dev);
} }
return 0; out:
mutex_unlock(&hw->conf_lock);
return err;
} }
static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private) static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private)
......
...@@ -528,7 +528,12 @@ static int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val) ...@@ -528,7 +528,12 @@ static int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
if (val < 1 || val > hw->settings->max_fifo_size) if (val < 1 || val > hw->settings->max_fifo_size)
return -EINVAL; return -EINVAL;
mutex_lock(&hw->conf_lock);
err = st_lsm6dsx_update_watermark(sensor, val); err = st_lsm6dsx_update_watermark(sensor, val);
mutex_unlock(&hw->conf_lock);
if (err < 0) if (err < 0)
return err; return err;
...@@ -739,6 +744,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, ...@@ -739,6 +744,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,
mutex_init(&hw->lock); mutex_init(&hw->lock);
mutex_init(&hw->fifo_lock); mutex_init(&hw->fifo_lock);
mutex_init(&hw->conf_lock);
hw->dev = dev; hw->dev = dev;
hw->irq = irq; hw->irq = irq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment