From: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> 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. Signed-off-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> Cc: Marek Vasut <marex@xxxxxxx> --- drivers/iio/adc/ti-ads1015.c | 162 ++++++++++++++--------------------- 1 file changed, 64 insertions(+), 98 deletions(-) diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 4355726b373a..a91ec18ddbec 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -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 -EBUSY; - 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; } -- 2.48.1