RE: [RFC PATCH 4/4] iio: Track enabled channels on a per channel basis

From: Sa, Nuno
Date: Fri Apr 24 2020 - 03:51:26 EST



> From: linux-iio-owner@xxxxxxxxxxxxxxx <linux-iio-owner@xxxxxxxxxxxxxxx>
> On Behalf Of Alexandru Ardelean
> Sent: Freitag, 24. April 2020 07:18
> To: linux-iio@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx
> Cc: jic23@xxxxxxxxxx; lars@xxxxxxxxxx; Ardelean, Alexandru
> <alexandru.Ardelean@xxxxxxxxxx>
> Subject: [RFC PATCH 4/4] iio: Track enabled channels on a per channel basis
>
> From: Lars-Peter Clausen <lars@xxxxxxxxxx>
>
> Now that we support multiple channels with the same scan index we can no
> longer use the scan mask to track which channels have been enabled.
> Otherwise it is not possible to enable channels with the same scan index
> independently.
>
> Introduce a new channel mask which is used instead of the scan mask to
> track which channels are enabled. Whenever the channel mask is changed a
> new scan mask is computed based on it.
>
> Signed-off-by: Lars-Peter Clausen <lars@xxxxxxxxxx>
> Signed-off-by: Alexandru Ardelean <alexandru.ardelean@xxxxxxxxxx>
> ---
> drivers/iio/industrialio-buffer.c | 62 +++++++++++++++++++++----------
> drivers/iio/inkern.c | 19 +++++++++-
> include/linux/iio/buffer_impl.h | 3 ++
> include/linux/iio/consumer.h | 2 +
> 4 files changed, 64 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
> index c06691281287..1821a3e32fb3 100644
> --- a/drivers/iio/industrialio-buffer.c
> +++ b/drivers/iio/industrialio-buffer.c
> @@ -216,12 +216,20 @@ int iio_buffer_alloc_scanmask(struct iio_buffer
> *buffer,
> if (buffer->scan_mask == NULL)
> return -ENOMEM;
>
> + buffer->channel_mask = bitmap_zalloc(indio_dev->num_channels,
> + GFP_KERNEL);
> + if (buffer->channel_mask == NULL) {
> + bitmap_free(buffer->scan_mask);
> + return -ENOMEM;
> + }
> +
> return 0;
> }
> EXPORT_SYMBOL_GPL(iio_buffer_alloc_scanmask);
>
> void iio_buffer_free_scanmask(struct iio_buffer *buffer)
> {
> + bitmap_free(buffer->channel_mask);
> bitmap_free(buffer->scan_mask);
> }
> EXPORT_SYMBOL_GPL(iio_buffer_free_scanmask);
> @@ -285,7 +293,7 @@ static ssize_t iio_scan_el_show(struct device *dev,
>
> /* Ensure ret is 0 or 1. */
> ret = !!test_bit(to_iio_dev_attr(attr)->address,
> - indio_dev->buffer->scan_mask);
> + indio_dev->buffer->channel_mask);
>
> return sprintf(buf, "%d\n", ret);
> }
> @@ -330,11 +338,12 @@ static bool iio_validate_scan_mask(struct iio_dev
> *indio_dev,
> * buffers might request, hence this code only verifies that the
> * individual buffers request is plausible.
> */
> -static int iio_scan_mask_set(struct iio_dev *indio_dev,
> - struct iio_buffer *buffer, int bit)
> +static int iio_channel_mask_set(struct iio_dev *indio_dev,
> + struct iio_buffer *buffer, int bit)
> {
> const unsigned long *mask;
> unsigned long *trialmask;
> + unsigned int ch;
>
> trialmask = bitmap_zalloc(indio_dev->masklength, GFP_KERNEL);
> if (trialmask == NULL)
> @@ -343,8 +352,11 @@ static int iio_scan_mask_set(struct iio_dev
> *indio_dev,
> WARN(1, "Trying to set scanmask prior to registering
> buffer\n");
> goto err_invalid_mask;
> }
> - bitmap_copy(trialmask, buffer->scan_mask, indio_dev-
> >masklength);
> - set_bit(bit, trialmask);
> +
> + set_bit(bit, buffer->channel_mask);
> +
> + for_each_set_bit(ch, buffer->channel_mask, indio_dev-
> >num_channels)
> + set_bit(indio_dev->channels[ch].scan_index, trialmask);

So, here if the channels all have the same scan_index, we will end up with a scan_mask which is
different that channel_mask, right? I saw that in our internal driver's we then just access the
channel_mask field directly to know what pieces/channels do we need to enable prior to
buffering, which implies including buffer_impl.h.

So, for me it would make sense to compute scan_mask so that it will be the same as channel_mask
(hmm but that would be a problem when computing the buffer size...) and drivers can correctly use
` validate_scan_mask ()` cb. Alternatively, we need to expose channel_mask either on a new cb or
change the ` validate_scan_mask ()` footprint.

- Nuno Sá