iio: adc: ti-ads1015: Use guard(mutex) and factor out code for INFO_RAW
authorJonathan Cameron <Jonathan.Cameron@huawei.com>
Sun, 9 Mar 2025 16:58:16 +0000 (16:58 +0000)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Tue, 22 Apr 2025 18:09:55 +0000 (19:09 +0100)
By use of automatic lock release and introducing a new utility
function to handle the core activity of reading the ADC channel,
many more complex code flows can be replaced by direct returns.

Cc: Marek Vasut <marex@denx.de>
Reviewed-by: David Lechner <dlechner@baylibre.com>
Link: https://patch.msgid.link/20250309165819.1346684-6-jic23@kernel.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/ti-ads1015.c

index 4355726..7119824 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/cleanup.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/i2c.h>
@@ -533,6 +534,31 @@ static int ads1015_read_avail(struct iio_dev *indio_dev,
        }
 }
 
+static int __ads1015_read_info_raw(struct ads1015_data *data,
+                                  struct iio_chan_spec const *chan, int *val)
+{
+       int ret;
+
+       if (ads1015_event_channel_enabled(data) &&
+           data->event_channel != chan->address)
+               return -EBUSY;
+
+       ret = ads1015_set_power_state(data, true);
+       if (ret < 0)
+               return ret;
+
+       ret = ads1015_get_adc_result(data, chan->address, val);
+       if (ret < 0) {
+               ads1015_set_power_state(data, false);
+               return ret;
+       }
+
+       *val = sign_extend32(*val >> chan->scan_type.shift,
+                            chan->scan_type.realbits - 1);
+
+       return ads1015_set_power_state(data, false);
+}
+
 static int ads1015_read_raw(struct iio_dev *indio_dev,
                            struct iio_chan_spec const *chan, int *val,
                            int *val2, long mask)
@@ -540,58 +566,30 @@ static int ads1015_read_raw(struct iio_dev *indio_dev,
        int ret, idx;
        struct ads1015_data *data = iio_priv(indio_dev);
 
-       mutex_lock(&data->lock);
+       guard(mutex)(&data->lock);
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
                ret = iio_device_claim_direct_mode(indio_dev);
                if (ret)
-                       break;
-
-               if (ads1015_event_channel_enabled(data) &&
-                               data->event_channel != chan->address) {
-                       ret = -EBUSY;
-                       goto release_direct;
-               }
-
-               ret = ads1015_set_power_state(data, true);
-               if (ret < 0)
-                       goto release_direct;
-
-               ret = ads1015_get_adc_result(data, chan->address, val);
-               if (ret < 0) {
-                       ads1015_set_power_state(data, false);
-                       goto release_direct;
-               }
-
-               *val = sign_extend32(*val >> chan->scan_type.shift,
-                                    chan->scan_type.realbits - 1);
-
-               ret = ads1015_set_power_state(data, false);
-               if (ret < 0)
-                       goto release_direct;
-
-               ret = IIO_VAL_INT;
-release_direct:
+                       return ret;
+               ret = __ads1015_read_info_raw(data, chan, val);
                iio_device_release_direct_mode(indio_dev);
-               break;
+               if (ret)
+                       return ret;
+
+               return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
                idx = data->channel_data[chan->address].pga;
                *val = ads1015_fullscale_range[idx];
                *val2 = chan->scan_type.realbits - 1;
-               ret = IIO_VAL_FRACTIONAL_LOG2;
-               break;
+               return IIO_VAL_FRACTIONAL_LOG2;
        case IIO_CHAN_INFO_SAMP_FREQ:
                idx = data->channel_data[chan->address].data_rate;
                *val = data->chip->data_rate[idx];
-               ret = IIO_VAL_INT;
-               break;
+               return IIO_VAL_INT;
        default:
-               ret = -EINVAL;
-               break;
+               return -EINVAL;
        }
-       mutex_unlock(&data->lock);
-
-       return ret;
 }
 
 static int ads1015_write_raw(struct iio_dev *indio_dev,
@@ -599,23 +597,16 @@ static int ads1015_write_raw(struct iio_dev *indio_dev,
                             int val2, long mask)
 {
        struct ads1015_data *data = iio_priv(indio_dev);
-       int ret;
 
-       mutex_lock(&data->lock);
+       guard(mutex)(&data->lock);
        switch (mask) {
        case IIO_CHAN_INFO_SCALE:
-               ret = ads1015_set_scale(data, chan, val, val2);
-               break;
+               return ads1015_set_scale(data, chan, val, val2);
        case IIO_CHAN_INFO_SAMP_FREQ:
-               ret = ads1015_set_data_rate(data, chan->address, val);
-               break;
+               return ads1015_set_data_rate(data, chan->address, val);
        default:
-               ret = -EINVAL;
-               break;
+               return -EINVAL;
        }
-       mutex_unlock(&data->lock);
-
-       return ret;
 }
 
 static int ads1015_read_event(struct iio_dev *indio_dev,
@@ -624,20 +615,18 @@ static int ads1015_read_event(struct iio_dev *indio_dev,
        int *val2)
 {
        struct ads1015_data *data = iio_priv(indio_dev);
-       int ret;
        unsigned int comp_queue;
        int period;
        int dr;
 
-       mutex_lock(&data->lock);
+       guard(mutex)(&data->lock);
 
        switch (info) {
        case IIO_EV_INFO_VALUE:
                *val = (dir == IIO_EV_DIR_RISING) ?
                        data->thresh_data[chan->address].high_thresh :
                        data->thresh_data[chan->address].low_thresh;
-               ret = IIO_VAL_INT;
-               break;
+               return IIO_VAL_INT;
        case IIO_EV_INFO_PERIOD:
                dr = data->channel_data[chan->address].data_rate;
                comp_queue = data->thresh_data[chan->address].comp_queue;
@@ -646,16 +635,10 @@ static int ads1015_read_event(struct iio_dev *indio_dev,
 
                *val = period / USEC_PER_SEC;
                *val2 = period % USEC_PER_SEC;
-               ret = IIO_VAL_INT_PLUS_MICRO;
-               break;
+               return IIO_VAL_INT_PLUS_MICRO;
        default:
-               ret = -EINVAL;
-               break;
+               return -EINVAL;
        }
-
-       mutex_unlock(&data->lock);
-
-       return ret;
 }
 
 static int ads1015_write_event(struct iio_dev *indio_dev,
@@ -666,24 +649,22 @@ static int ads1015_write_event(struct iio_dev *indio_dev,
        struct ads1015_data *data = iio_priv(indio_dev);
        const int *data_rate = data->chip->data_rate;
        int realbits = chan->scan_type.realbits;
-       int ret = 0;
        long long period;
        int i;
        int dr;
 
-       mutex_lock(&data->lock);
+       guard(mutex)(&data->lock);
 
        switch (info) {
        case IIO_EV_INFO_VALUE:
-               if (val >= 1 << (realbits - 1) || val < -1 << (realbits - 1)) {
-                       ret = -EINVAL;
-                       break;
-               }
+               if (val >= 1 << (realbits - 1) || val < -1 << (realbits - 1))
+                       return -EINVAL;
+
                if (dir == IIO_EV_DIR_RISING)
                        data->thresh_data[chan->address].high_thresh = val;
                else
                        data->thresh_data[chan->address].low_thresh = val;
-               break;
+               return 0;
        case IIO_EV_INFO_PERIOD:
                dr = data->channel_data[chan->address].data_rate;
                period = val * USEC_PER_SEC + val2;
@@ -694,15 +675,10 @@ static int ads1015_write_event(struct iio_dev *indio_dev,
                                break;
                }
                data->thresh_data[chan->address].comp_queue = i;
-               break;
+               return 0;
        default:
-               ret = -EINVAL;
-               break;
+               return -EINVAL;
        }
-
-       mutex_unlock(&data->lock);
-
-       return ret;
 }
 
 static int ads1015_read_event_config(struct iio_dev *indio_dev,
@@ -710,25 +686,19 @@ static int ads1015_read_event_config(struct iio_dev *indio_dev,
        enum iio_event_direction dir)
 {
        struct ads1015_data *data = iio_priv(indio_dev);
-       int ret = 0;
 
-       mutex_lock(&data->lock);
-       if (data->event_channel == chan->address) {
-               switch (dir) {
-               case IIO_EV_DIR_RISING:
-                       ret = 1;
-                       break;
-               case IIO_EV_DIR_EITHER:
-                       ret = (data->comp_mode == ADS1015_CFG_COMP_MODE_WINDOW);
-                       break;
-               default:
-                       ret = -EINVAL;
-                       break;
-               }
-       }
-       mutex_unlock(&data->lock);
+       guard(mutex)(&data->lock);
+       if (data->event_channel != chan->address)
+               return 0;
 
-       return ret;
+       switch (dir) {
+       case IIO_EV_DIR_RISING:
+               return 1;
+       case IIO_EV_DIR_EITHER:
+               return (data->comp_mode == ADS1015_CFG_COMP_MODE_WINDOW);
+       default:
+               return -EINVAL;
+       }
 }
 
 static int ads1015_enable_event_config(struct ads1015_data *data,
@@ -813,14 +783,12 @@ static int ads1015_write_event_config(struct iio_dev *indio_dev,
        int comp_mode = (dir == IIO_EV_DIR_EITHER) ?
                ADS1015_CFG_COMP_MODE_WINDOW : ADS1015_CFG_COMP_MODE_TRAD;
 
-       mutex_lock(&data->lock);
+       guard(mutex)(&data->lock);
 
        /* Prevent from enabling both buffer and event at a time */
        ret = iio_device_claim_direct_mode(indio_dev);
-       if (ret) {
-               mutex_unlock(&data->lock);
+       if (ret)
                return ret;
-       }
 
        if (state)
                ret = ads1015_enable_event_config(data, chan, comp_mode);
@@ -828,8 +796,6 @@ static int ads1015_write_event_config(struct iio_dev *indio_dev,
                ret = ads1015_disable_event_config(data, chan, comp_mode);
 
        iio_device_release_direct_mode(indio_dev);
-       mutex_unlock(&data->lock);
-
        return ret;
 }