summaryrefslogtreecommitdiff
path: root/drivers/iio/dummy/iio_simple_dummy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/dummy/iio_simple_dummy.c')
-rw-r--r--drivers/iio/dummy/iio_simple_dummy.c236
1 files changed, 127 insertions, 109 deletions
diff --git a/drivers/iio/dummy/iio_simple_dummy.c b/drivers/iio/dummy/iio_simple_dummy.c
index c0b7ef900735..8575d4a08963 100644
--- a/drivers/iio/dummy/iio_simple_dummy.c
+++ b/drivers/iio/dummy/iio_simple_dummy.c
@@ -267,6 +267,65 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
},
};
+static int __iio_dummy_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val)
+{
+ struct iio_dummy_state *st = iio_priv(indio_dev);
+
+ guard(mutex)(&st->lock);
+ switch (chan->type) {
+ case IIO_VOLTAGE:
+ if (chan->output) {
+ /* Set integer part to cached value */
+ *val = st->dac_val;
+ return IIO_VAL_INT;
+ } else if (chan->differential) {
+ if (chan->channel == 1)
+ *val = st->differential_adc_val[0];
+ else
+ *val = st->differential_adc_val[1];
+ return IIO_VAL_INT;
+ } else {
+ *val = st->single_ended_adc_val;
+ return IIO_VAL_INT;
+ }
+
+ case IIO_ACCEL:
+ *val = st->accel_val;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int __iio_dummy_read_processed(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val)
+{
+ struct iio_dummy_state *st = iio_priv(indio_dev);
+
+ guard(mutex)(&st->lock);
+ switch (chan->type) {
+ case IIO_STEPS:
+ *val = st->steps;
+ return IIO_VAL_INT;
+ case IIO_ACTIVITY:
+ switch (chan->channel2) {
+ case IIO_MOD_RUNNING:
+ *val = st->activity_running;
+ return IIO_VAL_INT;
+ case IIO_MOD_WALKING:
+ *val = st->activity_walking;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
/**
* iio_dummy_read_raw() - data read function.
* @indio_dev: the struct iio_dev associated with this device instance
@@ -283,65 +342,25 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
long mask)
{
struct iio_dummy_state *st = iio_priv(indio_dev);
- int ret = -EINVAL;
+ int ret;
- mutex_lock(&st->lock);
switch (mask) {
case IIO_CHAN_INFO_RAW: /* magic value - channel value read */
- switch (chan->type) {
- case IIO_VOLTAGE:
- if (chan->output) {
- /* Set integer part to cached value */
- *val = st->dac_val;
- ret = IIO_VAL_INT;
- } else if (chan->differential) {
- if (chan->channel == 1)
- *val = st->differential_adc_val[0];
- else
- *val = st->differential_adc_val[1];
- ret = IIO_VAL_INT;
- } else {
- *val = st->single_ended_adc_val;
- ret = IIO_VAL_INT;
- }
- break;
- case IIO_ACCEL:
- *val = st->accel_val;
- ret = IIO_VAL_INT;
- break;
- default:
- break;
- }
- break;
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
+ ret = __iio_dummy_read_raw(indio_dev, chan, val);
+ iio_device_release_direct(indio_dev);
+ return ret;
case IIO_CHAN_INFO_PROCESSED:
- switch (chan->type) {
- case IIO_STEPS:
- *val = st->steps;
- ret = IIO_VAL_INT;
- break;
- case IIO_ACTIVITY:
- switch (chan->channel2) {
- case IIO_MOD_RUNNING:
- *val = st->activity_running;
- ret = IIO_VAL_INT;
- break;
- case IIO_MOD_WALKING:
- *val = st->activity_walking;
- ret = IIO_VAL_INT;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- break;
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
+ ret = __iio_dummy_read_processed(indio_dev, chan, val);
+ iio_device_release_direct(indio_dev);
+ return ret;
case IIO_CHAN_INFO_OFFSET:
/* only single ended adc -> 7 */
*val = 7;
- ret = IIO_VAL_INT;
- break;
+ return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_VOLTAGE:
@@ -350,60 +369,57 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
/* only single ended adc -> 0.001333 */
*val = 0;
*val2 = 1333;
- ret = IIO_VAL_INT_PLUS_MICRO;
- break;
+ return IIO_VAL_INT_PLUS_MICRO;
case 1:
/* all differential adc -> 0.000001344 */
*val = 0;
*val2 = 1344;
- ret = IIO_VAL_INT_PLUS_NANO;
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return -EINVAL;
}
- break;
default:
- break;
+ return -EINVAL;
}
- break;
- case IIO_CHAN_INFO_CALIBBIAS:
+ case IIO_CHAN_INFO_CALIBBIAS: {
+ guard(mutex)(&st->lock);
/* only the acceleration axis - read from cache */
*val = st->accel_calibbias;
- ret = IIO_VAL_INT;
- break;
- case IIO_CHAN_INFO_CALIBSCALE:
+ return IIO_VAL_INT;
+ }
+ case IIO_CHAN_INFO_CALIBSCALE: {
+ guard(mutex)(&st->lock);
*val = st->accel_calibscale->val;
*val2 = st->accel_calibscale->val2;
- ret = IIO_VAL_INT_PLUS_MICRO;
- break;
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
case IIO_CHAN_INFO_SAMP_FREQ:
*val = 3;
*val2 = 33;
- ret = IIO_VAL_INT_PLUS_NANO;
- break;
- case IIO_CHAN_INFO_ENABLE:
+ return IIO_VAL_INT_PLUS_NANO;
+ case IIO_CHAN_INFO_ENABLE: {
+ guard(mutex)(&st->lock);
switch (chan->type) {
case IIO_STEPS:
*val = st->steps_enabled;
- ret = IIO_VAL_INT;
- break;
+ return IIO_VAL_INT;
default:
- break;
+ return -EINVAL;
}
- break;
- case IIO_CHAN_INFO_CALIBHEIGHT:
+ }
+ case IIO_CHAN_INFO_CALIBHEIGHT: {
+ guard(mutex)(&st->lock);
switch (chan->type) {
case IIO_STEPS:
*val = st->height;
- ret = IIO_VAL_INT;
- break;
+ return IIO_VAL_INT;
default:
- break;
+ return -EINVAL;
}
- break;
-
+ }
default:
- break;
+ return -EINVAL;
}
- mutex_unlock(&st->lock);
- return ret;
}
/**
@@ -426,7 +442,6 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev,
long mask)
{
int i;
- int ret = 0;
struct iio_dummy_state *st = iio_priv(indio_dev);
switch (mask) {
@@ -436,10 +451,10 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev,
if (chan->output == 0)
return -EINVAL;
- /* Locking not required as writing single value */
- mutex_lock(&st->lock);
- st->dac_val = val;
- mutex_unlock(&st->lock);
+ scoped_guard(mutex, &st->lock) {
+ /* Locking not required as writing single value */
+ st->dac_val = val;
+ }
return 0;
default:
return -EINVAL;
@@ -447,9 +462,9 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_PROCESSED:
switch (chan->type) {
case IIO_STEPS:
- mutex_lock(&st->lock);
- st->steps = val;
- mutex_unlock(&st->lock);
+ scoped_guard(mutex, &st->lock) {
+ st->steps = val;
+ }
return 0;
case IIO_ACTIVITY:
if (val < 0)
@@ -470,30 +485,29 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev,
default:
return -EINVAL;
}
- case IIO_CHAN_INFO_CALIBSCALE:
- mutex_lock(&st->lock);
+ case IIO_CHAN_INFO_CALIBSCALE: {
+ guard(mutex)(&st->lock);
/* Compare against table - hard matching here */
for (i = 0; i < ARRAY_SIZE(dummy_scales); i++)
if (val == dummy_scales[i].val &&
val2 == dummy_scales[i].val2)
break;
if (i == ARRAY_SIZE(dummy_scales))
- ret = -EINVAL;
- else
- st->accel_calibscale = &dummy_scales[i];
- mutex_unlock(&st->lock);
- return ret;
+ return -EINVAL;
+ st->accel_calibscale = &dummy_scales[i];
+ return 0;
+ }
case IIO_CHAN_INFO_CALIBBIAS:
- mutex_lock(&st->lock);
- st->accel_calibbias = val;
- mutex_unlock(&st->lock);
+ scoped_guard(mutex, &st->lock) {
+ st->accel_calibbias = val;
+ }
return 0;
case IIO_CHAN_INFO_ENABLE:
switch (chan->type) {
case IIO_STEPS:
- mutex_lock(&st->lock);
- st->steps_enabled = val;
- mutex_unlock(&st->lock);
+ scoped_guard(mutex, &st->lock) {
+ st->steps_enabled = val;
+ }
return 0;
default:
return -EINVAL;
@@ -575,10 +589,9 @@ static struct iio_sw_device *iio_dummy_probe(const char *name)
*/
swd = kzalloc(sizeof(*swd), GFP_KERNEL);
- if (!swd) {
- ret = -ENOMEM;
- goto error_kzalloc;
- }
+ if (!swd)
+ return ERR_PTR(-ENOMEM);
+
/*
* Allocate an IIO device.
*
@@ -590,7 +603,7 @@ static struct iio_sw_device *iio_dummy_probe(const char *name)
indio_dev = iio_device_alloc(parent, sizeof(*st));
if (!indio_dev) {
ret = -ENOMEM;
- goto error_ret;
+ goto error_free_swd;
}
st = iio_priv(indio_dev);
@@ -616,6 +629,10 @@ static struct iio_sw_device *iio_dummy_probe(const char *name)
* indio_dev->name = spi_get_device_id(spi)->name;
*/
indio_dev->name = kstrdup(name, GFP_KERNEL);
+ if (!indio_dev->name) {
+ ret = -ENOMEM;
+ goto error_free_device;
+ }
/* Provide description of available channels */
indio_dev->channels = iio_dummy_channels;
@@ -632,7 +649,7 @@ static struct iio_sw_device *iio_dummy_probe(const char *name)
ret = iio_simple_dummy_events_register(indio_dev);
if (ret < 0)
- goto error_free_device;
+ goto error_free_name;
ret = iio_simple_dummy_configure_buffer(indio_dev);
if (ret < 0)
@@ -649,11 +666,12 @@ error_unconfigure_buffer:
iio_simple_dummy_unconfigure_buffer(indio_dev);
error_unregister_events:
iio_simple_dummy_events_unregister(indio_dev);
+error_free_name:
+ kfree(indio_dev->name);
error_free_device:
iio_device_free(indio_dev);
-error_ret:
+error_free_swd:
kfree(swd);
-error_kzalloc:
return ERR_PTR(ret);
}