Message ID | 20250209180624.701140-3-jic23@kernel.org (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | iio: improve handling of direct mode claim and release | expand |
On Sun, 2025-02-09 at 18:05 +0000, Jonathan Cameron wrote: > From: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > Auto cleanup based release of the lock allows for simpler code flow in a > few functions with large multiplexing style switch statements and no > common operations following the switch. > > Suggested-by: David Lechner <dlechner@baylibre.com> > Cc: Tomasz Duszynski <tomasz.duszynski@octakon.com> > Reviewed-by: David Lechner <dlechner@baylibre.com> > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > --- > v2: Fix include ordering (David) > --- > drivers/iio/chemical/scd30_core.c | 63 ++++++++++++++----------------- > include/linux/iio/iio.h | 1 + > 2 files changed, 29 insertions(+), 35 deletions(-) > > diff --git a/drivers/iio/chemical/scd30_core.c > b/drivers/iio/chemical/scd30_core.c > index d613c54cb28d..23ba46f7ca32 100644 > --- a/drivers/iio/chemical/scd30_core.c > +++ b/drivers/iio/chemical/scd30_core.c > @@ -5,6 +5,7 @@ > * Copyright (c) 2020 Tomasz Duszynski <tomasz.duszynski@octakon.com> > */ > #include <linux/bits.h> > +#include <linux/cleanup.h> > #include <linux/completion.h> > #include <linux/delay.h> > #include <linux/device.h> > @@ -198,112 +199,104 @@ static int scd30_read_raw(struct iio_dev *indio_dev, > struct iio_chan_spec const > int *val, int *val2, long mask) > { > struct scd30_state *state = iio_priv(indio_dev); > - int ret = -EINVAL; > + int ret; > u16 tmp; > > - mutex_lock(&state->lock); > + guard(mutex)(&state->lock); > switch (mask) { > case IIO_CHAN_INFO_RAW: > case IIO_CHAN_INFO_PROCESSED: > if (chan->output) { > *val = state->pressure_comp; > - ret = IIO_VAL_INT; > - break; > + return IIO_VAL_INT; > } > > ret = iio_device_claim_direct_mode(indio_dev); > if (ret) > - break; > + return ret; > > ret = scd30_read(state); > if (ret) { > iio_device_release_direct_mode(indio_dev); > - break; > + return ret; > } > > *val = state->meas[chan->address]; > iio_device_release_direct_mode(indio_dev); > - ret = IIO_VAL_INT; > - break; > + return IIO_VAL_INT; > case IIO_CHAN_INFO_SCALE: > *val = 0; > *val2 = 1; > - ret = IIO_VAL_INT_PLUS_MICRO; > - break; > + return IIO_VAL_INT_PLUS_MICRO; > case IIO_CHAN_INFO_SAMP_FREQ: > ret = scd30_command_read(state, CMD_MEAS_INTERVAL, &tmp); > if (ret) > - break; > + return ret; > > *val = 0; > *val2 = 1000000000 / tmp; > - ret = IIO_VAL_INT_PLUS_NANO; > - break; > + return IIO_VAL_INT_PLUS_NANO; > case IIO_CHAN_INFO_CALIBBIAS: > ret = scd30_command_read(state, CMD_TEMP_OFFSET, &tmp); > if (ret) > - break; > + return ret; > > *val = tmp; > - ret = IIO_VAL_INT; > - break; > + return IIO_VAL_INT; > + default: > + return -EINVAL; > } > - mutex_unlock(&state->lock); > - > - return ret; > } > > static int scd30_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec > const *chan, > int val, int val2, long mask) > { > struct scd30_state *state = iio_priv(indio_dev); > - int ret = -EINVAL; > + int ret; > > - mutex_lock(&state->lock); > + guard(mutex)(&state->lock); > switch (mask) { > case IIO_CHAN_INFO_SAMP_FREQ: > if (val) > - break; > + return -EINVAL; > > val = 1000000000 / val2; > if (val < SCD30_MEAS_INTERVAL_MIN_S || val > > SCD30_MEAS_INTERVAL_MAX_S) > - break; > + return -EINVAL; > > ret = scd30_command_write(state, CMD_MEAS_INTERVAL, val); > if (ret) > - break; > + return ret; > > state->meas_interval = val; > - break; > + return 0; > case IIO_CHAN_INFO_RAW: > switch (chan->type) { > case IIO_PRESSURE: > if (val < SCD30_PRESSURE_COMP_MIN_MBAR || > val > SCD30_PRESSURE_COMP_MAX_MBAR) > - break; > + return -EINVAL; > > ret = scd30_command_write(state, CMD_START_MEAS, > val); > if (ret) > - break; > + return ret; > > state->pressure_comp = val; > - break; > + return 0; > default: > - break; > + return -EINVAL; > } > - break; > case IIO_CHAN_INFO_CALIBBIAS: > if (val < 0 || val > SCD30_TEMP_OFFSET_MAX) > - break; > + return -EINVAL; > /* > * Manufacturer does not explicitly specify min/max sensible > * values hence check is omitted for simplicity. > */ > - ret = scd30_command_write(state, CMD_TEMP_OFFSET / 10, val); > + return scd30_command_write(state, CMD_TEMP_OFFSET / 10, val); > + default: > + return -EINVAL; > } > - mutex_unlock(&state->lock); > - > - return ret; > } > > static int scd30_write_raw_get_fmt(struct iio_dev *indio_dev, struct > iio_chan_spec const *chan, > diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h > index fe33835b19cf..5ed03e36178f 100644 > --- a/include/linux/iio/iio.h > +++ b/include/linux/iio/iio.h > @@ -10,6 +10,7 @@ > #include <linux/device.h> > #include <linux/cdev.h> > #include <linux/cleanup.h> > +#include <linux/compiler_types.h> Hmm, here it is... I guess some messed rebase and squash :) - Nuno Sá
diff --git a/drivers/iio/chemical/scd30_core.c b/drivers/iio/chemical/scd30_core.c index d613c54cb28d..23ba46f7ca32 100644 --- a/drivers/iio/chemical/scd30_core.c +++ b/drivers/iio/chemical/scd30_core.c @@ -5,6 +5,7 @@ * Copyright (c) 2020 Tomasz Duszynski <tomasz.duszynski@octakon.com> */ #include <linux/bits.h> +#include <linux/cleanup.h> #include <linux/completion.h> #include <linux/delay.h> #include <linux/device.h> @@ -198,112 +199,104 @@ static int scd30_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const int *val, int *val2, long mask) { struct scd30_state *state = iio_priv(indio_dev); - int ret = -EINVAL; + int ret; u16 tmp; - mutex_lock(&state->lock); + guard(mutex)(&state->lock); switch (mask) { case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_PROCESSED: if (chan->output) { *val = state->pressure_comp; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; } ret = iio_device_claim_direct_mode(indio_dev); if (ret) - break; + return ret; ret = scd30_read(state); if (ret) { iio_device_release_direct_mode(indio_dev); - break; + return ret; } *val = state->meas[chan->address]; iio_device_release_direct_mode(indio_dev); - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: *val = 0; *val2 = 1; - ret = IIO_VAL_INT_PLUS_MICRO; - break; + return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_SAMP_FREQ: ret = scd30_command_read(state, CMD_MEAS_INTERVAL, &tmp); if (ret) - break; + return ret; *val = 0; *val2 = 1000000000 / tmp; - ret = IIO_VAL_INT_PLUS_NANO; - break; + return IIO_VAL_INT_PLUS_NANO; case IIO_CHAN_INFO_CALIBBIAS: ret = scd30_command_read(state, CMD_TEMP_OFFSET, &tmp); if (ret) - break; + return ret; *val = tmp; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; + default: + return -EINVAL; } - mutex_unlock(&state->lock); - - return ret; } static int scd30_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { struct scd30_state *state = iio_priv(indio_dev); - int ret = -EINVAL; + int ret; - mutex_lock(&state->lock); + guard(mutex)(&state->lock); switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: if (val) - break; + return -EINVAL; val = 1000000000 / val2; if (val < SCD30_MEAS_INTERVAL_MIN_S || val > SCD30_MEAS_INTERVAL_MAX_S) - break; + return -EINVAL; ret = scd30_command_write(state, CMD_MEAS_INTERVAL, val); if (ret) - break; + return ret; state->meas_interval = val; - break; + return 0; case IIO_CHAN_INFO_RAW: switch (chan->type) { case IIO_PRESSURE: if (val < SCD30_PRESSURE_COMP_MIN_MBAR || val > SCD30_PRESSURE_COMP_MAX_MBAR) - break; + return -EINVAL; ret = scd30_command_write(state, CMD_START_MEAS, val); if (ret) - break; + return ret; state->pressure_comp = val; - break; + return 0; default: - break; + return -EINVAL; } - break; case IIO_CHAN_INFO_CALIBBIAS: if (val < 0 || val > SCD30_TEMP_OFFSET_MAX) - break; + return -EINVAL; /* * Manufacturer does not explicitly specify min/max sensible * values hence check is omitted for simplicity. */ - ret = scd30_command_write(state, CMD_TEMP_OFFSET / 10, val); + return scd30_command_write(state, CMD_TEMP_OFFSET / 10, val); + default: + return -EINVAL; } - mutex_unlock(&state->lock); - - return ret; } static int scd30_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index fe33835b19cf..5ed03e36178f 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -10,6 +10,7 @@ #include <linux/device.h> #include <linux/cdev.h> #include <linux/cleanup.h> +#include <linux/compiler_types.h> #include <linux/slab.h> #include <linux/iio/types.h> /* IIO TODO LIST */