]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iio: imu: kmx61: Use guard(mutex)() over manual locking
authorMaxwell Doose <m32285159@gmail.com>
Thu, 21 May 2026 22:30:43 +0000 (17:30 -0500)
committerJonathan Cameron <jic23@kernel.org>
Sun, 31 May 2026 10:01:47 +0000 (11:01 +0100)
Include linux/cleanup.h to take advantage of new macros.

Replace manual mutex_lock() and mutex_unlock() calls across the file
with guard(mutex)() and scoped_guard() where appropriate to simplify
error paths and eliminate manual locking calls.

Add new helper function kmx61_read_for_each_active_channel() to mitigate
certain style issues and to prevent notifying that the IRQ is finished
whilst holding the lock.

Update certain returns, and add default case to return -EINVAL in
kmx61_read_raw().

Remove now-redundant gotos and ret variables, as the new RAII macros
make them unneeded.

Signed-off-by: Maxwell Doose <m32285159@gmail.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/imu/kmx61.c

index a4d176f81f0efcfb32dade6f4fecfe1b54edd19b..b8a8297b39af3253ef00107598aae08e56517781 100644 (file)
@@ -7,6 +7,7 @@
  * IIO driver for KMX61 (7-bit I2C slave address 0x0E or 0x0F).
  */
 
+#include <linux/cleanup.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/mod_devicetable.h>
@@ -783,7 +784,7 @@ static int kmx61_read_raw(struct iio_dev *indio_dev,
        struct kmx61_data *data = kmx61_get_data(indio_dev);
 
        switch (mask) {
-       case IIO_CHAN_INFO_RAW:
+       case IIO_CHAN_INFO_RAW: {
                switch (chan->type) {
                case IIO_ACCEL:
                        base_reg = KMX61_ACC_XOUT_L;
@@ -794,28 +795,24 @@ static int kmx61_read_raw(struct iio_dev *indio_dev,
                default:
                        return -EINVAL;
                }
-               mutex_lock(&data->lock);
+               guard(mutex)(&data->lock);
 
                ret = kmx61_set_power_state(data, true, chan->address);
-               if (ret) {
-                       mutex_unlock(&data->lock);
+               if (ret)
                        return ret;
-               }
 
                ret = kmx61_read_measurement(data, base_reg, chan->scan_index);
                if (ret < 0) {
                        kmx61_set_power_state(data, false, chan->address);
-                       mutex_unlock(&data->lock);
                        return ret;
                }
                *val = sign_extend32(ret >> chan->scan_type.shift,
                                     chan->scan_type.realbits - 1);
                ret = kmx61_set_power_state(data, false, chan->address);
-
-               mutex_unlock(&data->lock);
                if (ret)
                        return ret;
                return IIO_VAL_INT;
+       }
        case IIO_CHAN_INFO_SCALE:
                switch (chan->type) {
                case IIO_ACCEL:
@@ -830,45 +827,46 @@ static int kmx61_read_raw(struct iio_dev *indio_dev,
                default:
                        return -EINVAL;
                }
-       case IIO_CHAN_INFO_SAMP_FREQ:
+       case IIO_CHAN_INFO_SAMP_FREQ: {
                if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN)
                        return -EINVAL;
 
-               mutex_lock(&data->lock);
+               guard(mutex)(&data->lock);
+
                ret = kmx61_get_odr(data, val, val2, chan->address);
-               mutex_unlock(&data->lock);
                if (ret)
                        return -EINVAL;
                return IIO_VAL_INT_PLUS_MICRO;
        }
-       return -EINVAL;
+       default:
+               return -EINVAL;
+       }
 }
 
 static int kmx61_write_raw(struct iio_dev *indio_dev,
                           struct iio_chan_spec const *chan, int val,
                           int val2, long mask)
 {
-       int ret;
        struct kmx61_data *data = kmx61_get_data(indio_dev);
 
        switch (mask) {
-       case IIO_CHAN_INFO_SAMP_FREQ:
+       case IIO_CHAN_INFO_SAMP_FREQ: {
                if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN)
                        return -EINVAL;
 
-               mutex_lock(&data->lock);
-               ret = kmx61_set_odr(data, val, val2, chan->address);
-               mutex_unlock(&data->lock);
-               return ret;
+               guard(mutex)(&data->lock);
+
+               return kmx61_set_odr(data, val, val2, chan->address);
+       }
        case IIO_CHAN_INFO_SCALE:
                switch (chan->type) {
-               case IIO_ACCEL:
+               case IIO_ACCEL: {
                        if (val != 0)
                                return -EINVAL;
-                       mutex_lock(&data->lock);
-                       ret = kmx61_set_scale(data, val2);
-                       mutex_unlock(&data->lock);
-                       return ret;
+                       guard(mutex)(&data->lock);
+
+                       return kmx61_set_scale(data, val2);
+               }
                default:
                        return -EINVAL;
                }
@@ -945,29 +943,26 @@ static int kmx61_write_event_config(struct iio_dev *indio_dev,
        if (state && data->ev_enable_state)
                return 0;
 
-       mutex_lock(&data->lock);
+       guard(mutex)(&data->lock);
 
        if (!state && data->motion_trig_on) {
                data->ev_enable_state = false;
-               goto err_unlock;
+               return ret;
        }
 
        ret = kmx61_set_power_state(data, state, KMX61_ACC);
        if (ret < 0)
-               goto err_unlock;
+               return ret;
 
        ret = kmx61_setup_any_motion_interrupt(data, state);
        if (ret < 0) {
                kmx61_set_power_state(data, false, KMX61_ACC);
-               goto err_unlock;
+               return ret;
        }
 
        data->ev_enable_state = state;
 
-err_unlock:
-       mutex_unlock(&data->lock);
-
-       return ret;
+       return 0;
 }
 
 static int kmx61_acc_validate_trigger(struct iio_dev *indio_dev,
@@ -1020,11 +1015,11 @@ static int kmx61_data_rdy_trigger_set_state(struct iio_trigger *trig,
        struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
        struct kmx61_data *data = kmx61_get_data(indio_dev);
 
-       mutex_lock(&data->lock);
+       guard(mutex)(&data->lock);
 
        if (!state && data->ev_enable_state && data->motion_trig_on) {
                data->motion_trig_on = false;
-               goto err_unlock;
+               return ret;
        }
 
        if (data->acc_dready_trig == trig || data->motion_trig == trig)
@@ -1034,7 +1029,7 @@ static int kmx61_data_rdy_trigger_set_state(struct iio_trigger *trig,
 
        ret = kmx61_set_power_state(data, state, device);
        if (ret < 0)
-               goto err_unlock;
+               return ret;
 
        if (data->acc_dready_trig == trig || data->mag_dready_trig == trig)
                ret = kmx61_setup_new_data_interrupt(data, state, device);
@@ -1042,7 +1037,7 @@ static int kmx61_data_rdy_trigger_set_state(struct iio_trigger *trig,
                ret = kmx61_setup_any_motion_interrupt(data, state);
        if (ret < 0) {
                kmx61_set_power_state(data, false, device);
-               goto err_unlock;
+               return ret;
        }
 
        if (data->acc_dready_trig == trig)
@@ -1051,10 +1046,8 @@ static int kmx61_data_rdy_trigger_set_state(struct iio_trigger *trig,
                data->mag_dready_trig_on = state;
        else
                data->motion_trig_on = state;
-err_unlock:
-       mutex_unlock(&data->lock);
 
-       return ret;
+       return 0;
 }
 
 static void kmx61_trig_reenable(struct iio_trigger *trig)
@@ -1181,30 +1174,49 @@ static irqreturn_t kmx61_data_rdy_trig_poll(int irq, void *private)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t kmx61_trigger_handler(int irq, void *p)
+/**
+ * kmx61_read_for_each_active_channel() - Read each active channel into a buffer
+ *
+ * @indio_dev: IIO Device struct to read from
+ * @buffer: Destination buffer to write to, the array must be of at least size 8
+ *
+ * Return:
+ * 0 on success, negative errno on failure.
+ */
+static int kmx61_read_for_each_active_channel(struct iio_dev *indio_dev, s16 *buffer)
 {
-       struct iio_poll_func *pf = p;
-       struct iio_dev *indio_dev = pf->indio_dev;
        struct kmx61_data *data = kmx61_get_data(indio_dev);
-       int bit, ret, i = 0;
        u8 base;
-       s16 buffer[8] = { };
+       int ret, bit;
+       int i = 0;
 
        if (indio_dev == data->acc_indio_dev)
                base = KMX61_ACC_XOUT_L;
        else
                base = KMX61_MAG_XOUT_L;
 
-       mutex_lock(&data->lock);
+       guard(mutex)(&data->lock);
+
        iio_for_each_active_channel(indio_dev, bit) {
                ret = kmx61_read_measurement(data, base, bit);
-               if (ret < 0) {
-                       mutex_unlock(&data->lock);
-                       goto err;
-               }
+               if (ret < 0)
+                       return ret;
                buffer[i++] = ret;
        }
-       mutex_unlock(&data->lock);
+
+       return 0;
+}
+
+static irqreturn_t kmx61_trigger_handler(int irq, void *p)
+{
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       int ret;
+       s16 buffer[8] = { };
+
+       ret = kmx61_read_for_each_active_channel(indio_dev, buffer);
+       if (ret < 0)
+               goto err;
 
        iio_push_to_buffers(indio_dev, buffer);
 err:
@@ -1419,22 +1431,18 @@ static void kmx61_remove(struct i2c_client *client)
                iio_trigger_unregister(data->motion_trig);
        }
 
-       mutex_lock(&data->lock);
+       guard(mutex)(&data->lock);
+
        kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
-       mutex_unlock(&data->lock);
 }
 
 static int kmx61_suspend(struct device *dev)
 {
-       int ret;
        struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
 
-       mutex_lock(&data->lock);
-       ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG,
-                            false);
-       mutex_unlock(&data->lock);
+       guard(mutex)(&data->lock);
 
-       return ret;
+       return kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, false);
 }
 
 static int kmx61_resume(struct device *dev)
@@ -1453,13 +1461,10 @@ static int kmx61_resume(struct device *dev)
 static int kmx61_runtime_suspend(struct device *dev)
 {
        struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
-       int ret;
 
-       mutex_lock(&data->lock);
-       ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
-       mutex_unlock(&data->lock);
+       guard(mutex)(&data->lock);
 
-       return ret;
+       return kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
 }
 
 static int kmx61_runtime_resume(struct device *dev)