diff options
author | Vlad Dogaru <vlad.dogaru@intel.com> | 2014-12-29 09:37:48 (GMT) |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2015-01-05 18:59:57 (GMT) |
commit | 8f5d8727a7736024f28101b922d23754c67c2cc8 (patch) | |
tree | 418ae104979d54a65b9a043035bcdcd6d89eeee6 | |
parent | c22d2672c826a67a84fa60c17797315f4c94cedb (diff) | |
download | linux-8f5d8727a7736024f28101b922d23754c67c2cc8.tar.xz |
iio: ensure scan index is unique at device register
Having two or more channels with the same positive scan_index field
makes no sense if the device supports buffering. Prevent this situation
by failing to register such a device.
Signed-off-by: Vlad Dogaru <vlad.dogaru@intel.com>
Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r-- | drivers/iio/industrialio-core.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index b7a397717..69feb91 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1134,6 +1134,29 @@ static const struct file_operations iio_buffer_fileops = { .compat_ioctl = iio_ioctl, }; +static int iio_check_unique_scan_index(struct iio_dev *indio_dev) +{ + int i, j; + const struct iio_chan_spec *channels = indio_dev->channels; + + if (!(indio_dev->modes & INDIO_ALL_BUFFER_MODES)) + return 0; + + for (i = 0; i < indio_dev->num_channels - 1; i++) { + if (channels[i].scan_index < 0) + continue; + for (j = i + 1; j < indio_dev->num_channels; j++) + if (channels[i].scan_index == channels[j].scan_index) { + dev_err(&indio_dev->dev, + "Duplicate scan index %d\n", + channels[i].scan_index); + return -EINVAL; + } + } + + return 0; +} + static const struct iio_buffer_setup_ops noop_ring_setup_ops; /** @@ -1148,6 +1171,10 @@ int iio_device_register(struct iio_dev *indio_dev) if (!indio_dev->dev.of_node && indio_dev->dev.parent) indio_dev->dev.of_node = indio_dev->dev.parent->of_node; + ret = iio_check_unique_scan_index(indio_dev); + if (ret < 0) + return ret; + /* configure elements for the chrdev */ indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); |