From patchwork Fri Apr 24 05:18:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11507115 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C93C61392 for ; Fri, 24 Apr 2020 05:18:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B2FC820767 for ; Fri, 24 Apr 2020 05:18:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726511AbgDXFSK (ORCPT ); Fri, 24 Apr 2020 01:18:10 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:32022 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725823AbgDXFSJ (ORCPT ); Fri, 24 Apr 2020 01:18:09 -0400 Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03O53gd1004889; Fri, 24 Apr 2020 01:17:57 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30fxf6cua3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 01:17:57 -0400 Received: from SCSQMBX10.ad.analog.com (scsqmbx10.ad.analog.com [10.77.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 03O5Ht1x049533 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 24 Apr 2020 01:17:55 -0400 Received: from SCSQMBX10.ad.analog.com (10.77.17.5) by SCSQMBX10.ad.analog.com (10.77.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Thu, 23 Apr 2020 22:17:53 -0700 Received: from zeus.spd.analog.com (10.64.82.11) by SCSQMBX10.ad.analog.com (10.77.17.5) with Microsoft SMTP Server id 15.1.1779.2 via Frontend Transport; Thu, 23 Apr 2020 22:17:53 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 03O5HnSS025747; Fri, 24 Apr 2020 01:17:51 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 1/4] iio: Move scan mask management to the core Date: Fri, 24 Apr 2020 08:18:15 +0300 Message-ID: <20200424051818.6408-2-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200424051818.6408-1-alexandru.ardelean@analog.com> References: <20200424051818.6408-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-04-24_01:2020-04-23,2020-04-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 spamscore=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 suspectscore=2 bulkscore=0 impostorscore=0 mlxlogscore=999 phishscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004240037 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org From: Lars-Peter Clausen Let the core handle the buffer scan mask management including allocation and channel selection. Having this handled in a central place rather than open-coding it all over the place will make it easier to change the implementation. Signed-off-by: Lars-Peter Clausen Signed-off-by: Alexandru Ardelean --- drivers/iio/buffer/industrialio-buffer-cb.c | 17 ++++------ drivers/iio/industrialio-buffer.c | 36 +++++++++++++++------ drivers/iio/inkern.c | 15 +++++++++ include/linux/iio/consumer.h | 10 ++++++ 4 files changed, 58 insertions(+), 20 deletions(-) diff --git a/drivers/iio/buffer/industrialio-buffer-cb.c b/drivers/iio/buffer/industrialio-buffer-cb.c index 47c96f7f4976..b50f1f48cac6 100644 --- a/drivers/iio/buffer/industrialio-buffer-cb.c +++ b/drivers/iio/buffer/industrialio-buffer-cb.c @@ -33,8 +33,7 @@ static int iio_buffer_cb_store_to(struct iio_buffer *buffer, const void *data) static void iio_buffer_cb_release(struct iio_buffer *buffer) { struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer); - - bitmap_free(cb_buff->buffer.scan_mask); + iio_buffer_free_scanmask(buffer); kfree(cb_buff); } @@ -72,27 +71,25 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev, } cb_buff->indio_dev = cb_buff->channels[0].indio_dev; - cb_buff->buffer.scan_mask = bitmap_zalloc(cb_buff->indio_dev->masklength, - GFP_KERNEL); - if (cb_buff->buffer.scan_mask == NULL) { - ret = -ENOMEM; + + ret = iio_buffer_alloc_scanmask(&cb_buff->buffer, cb_buff->indio_dev); + if (ret) goto error_release_channels; - } + chan = &cb_buff->channels[0]; while (chan->indio_dev) { if (chan->indio_dev != cb_buff->indio_dev) { ret = -EINVAL; goto error_free_scan_mask; } - set_bit(chan->channel->scan_index, - cb_buff->buffer.scan_mask); + iio_buffer_channel_enable(&cb_buff->buffer, chan); chan++; } return cb_buff; error_free_scan_mask: - bitmap_free(cb_buff->buffer.scan_mask); + iio_buffer_free_scanmask(&cb_buff->buffer); error_release_channels: iio_channel_release_all(cb_buff->channels); error_free_cb_buff: diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 221157136af6..c06691281287 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -206,6 +206,26 @@ void iio_buffer_init(struct iio_buffer *buffer) } EXPORT_SYMBOL(iio_buffer_init); +int iio_buffer_alloc_scanmask(struct iio_buffer *buffer, + struct iio_dev *indio_dev) +{ + if (!indio_dev->masklength) + return 0; + + buffer->scan_mask = bitmap_zalloc(indio_dev->masklength, GFP_KERNEL); + if (buffer->scan_mask == NULL) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_GPL(iio_buffer_alloc_scanmask); + +void iio_buffer_free_scanmask(struct iio_buffer *buffer) +{ + bitmap_free(buffer->scan_mask); +} +EXPORT_SYMBOL_GPL(iio_buffer_free_scanmask); + /** * iio_buffer_set_attrs - Set buffer specific attributes * @buffer: The buffer for which we are setting attributes @@ -1301,14 +1321,10 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) indio_dev->scan_index_timestamp = channels[i].scan_index; } - if (indio_dev->masklength && buffer->scan_mask == NULL) { - buffer->scan_mask = bitmap_zalloc(indio_dev->masklength, - GFP_KERNEL); - if (buffer->scan_mask == NULL) { - ret = -ENOMEM; - goto error_cleanup_dynamic; - } - } + + ret = iio_buffer_alloc_scanmask(buffer, indio_dev); + if (ret) + goto error_cleanup_dynamic; } buffer->scan_el_group.name = iio_scan_elements_group_name; @@ -1329,7 +1345,7 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) return 0; error_free_scan_mask: - bitmap_free(buffer->scan_mask); + iio_buffer_free_scanmask(buffer); error_cleanup_dynamic: iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); kfree(indio_dev->buffer->buffer_group.attrs); @@ -1342,7 +1358,7 @@ void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) if (!indio_dev->buffer) return; - bitmap_free(indio_dev->buffer->scan_mask); + iio_buffer_free_scanmask(indio_dev->buffer); kfree(indio_dev->buffer->buffer_group.attrs); kfree(indio_dev->buffer->scan_el_group.attrs); iio_free_chan_devattr_list(&indio_dev->buffer->scan_el_dev_attr_list); diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index ede99e0d5371..f35cb9985edc 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -11,6 +11,7 @@ #include #include "iio_core.h" +#include #include #include #include @@ -857,6 +858,20 @@ int iio_write_channel_raw(struct iio_channel *chan, int val) } EXPORT_SYMBOL_GPL(iio_write_channel_raw); +void iio_buffer_channel_enable(struct iio_buffer *buffer, + const struct iio_channel *chan) +{ + set_bit(chan->channel->scan_index, buffer->scan_mask); +} +EXPORT_SYMBOL_GPL(iio_buffer_channel_enable); + +void iio_buffer_channel_disable(struct iio_buffer *buffer, + const struct iio_channel *chan) +{ + clear_bit(chan->channel->scan_index, buffer->scan_mask); +} +EXPORT_SYMBOL_GPL(iio_buffer_channel_disable); + unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan) { const struct iio_chan_spec_ext_info *ext_info; diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index c4118dcb8e05..dbc87c26250a 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -12,6 +12,7 @@ struct iio_dev; struct iio_chan_spec; +struct iio_buffer; struct device; /** @@ -342,6 +343,15 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val, int iio_convert_raw_to_processed(struct iio_channel *chan, int raw, int *processed, unsigned int scale); +void iio_buffer_channel_enable(struct iio_buffer *buffer, + const struct iio_channel *chan); +void iio_buffer_channel_disable(struct iio_buffer *buffer, + const struct iio_channel *chan); + +int iio_buffer_alloc_scanmask(struct iio_buffer *buffer, + struct iio_dev *indio_dev); +void iio_buffer_free_scanmask(struct iio_buffer *buffer); + /** * iio_get_channel_ext_info_count() - get number of ext_info attributes * connected to the channel. From patchwork Fri Apr 24 05:18:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11507121 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A27791392 for ; Fri, 24 Apr 2020 05:18:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 91F5C2076C for ; Fri, 24 Apr 2020 05:18:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726515AbgDXFSK (ORCPT ); Fri, 24 Apr 2020 01:18:10 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:32248 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726078AbgDXFSJ (ORCPT ); Fri, 24 Apr 2020 01:18:09 -0400 Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03O50UPW014606; Fri, 24 Apr 2020 01:17:57 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30fud7n7wd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 01:17:56 -0400 Received: from ASHBMBX8.ad.analog.com (ashbmbx8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 03O5HtsS049534 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 24 Apr 2020 01:17:55 -0400 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 24 Apr 2020 01:17:54 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 24 Apr 2020 01:17:54 -0400 Received: from zeus.spd.analog.com (10.64.82.11) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.1.1779.2 via Frontend Transport; Fri, 24 Apr 2020 01:17:54 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 03O5HnST025747; Fri, 24 Apr 2020 01:17:52 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 2/4] iio: hw_consumer: use new scanmask functions Date: Fri, 24 Apr 2020 08:18:16 +0300 Message-ID: <20200424051818.6408-3-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200424051818.6408-1-alexandru.ardelean@analog.com> References: <20200424051818.6408-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-04-24_01:2020-04-23,2020-04-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxlogscore=999 priorityscore=1501 clxscore=1015 impostorscore=0 suspectscore=2 phishscore=0 mlxscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004240037 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org From: Lars-Peter Clausen This change moves the handling of the scanmasks to the new wrapper functions that were added in a previous commit. Signed-off-by: Lars-Peter Clausen Signed-off-by: Alexandru Ardelean --- drivers/iio/buffer/industrialio-hw-consumer.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/iio/buffer/industrialio-hw-consumer.c b/drivers/iio/buffer/industrialio-hw-consumer.c index f2d27788f666..f1cc72520685 100644 --- a/drivers/iio/buffer/industrialio-hw-consumer.c +++ b/drivers/iio/buffer/industrialio-hw-consumer.c @@ -28,7 +28,6 @@ struct hw_consumer_buffer { struct list_head head; struct iio_dev *indio_dev; struct iio_buffer buffer; - long scan_mask[]; }; static struct hw_consumer_buffer *iio_buffer_to_hw_consumer_buffer( @@ -41,6 +40,8 @@ static void iio_hw_buf_release(struct iio_buffer *buffer) { struct hw_consumer_buffer *hw_buf = iio_buffer_to_hw_consumer_buffer(buffer); + + iio_buffer_free_scanmask(buffer); kfree(hw_buf); } @@ -52,26 +53,34 @@ static const struct iio_buffer_access_funcs iio_hw_buf_access = { static struct hw_consumer_buffer *iio_hw_consumer_get_buffer( struct iio_hw_consumer *hwc, struct iio_dev *indio_dev) { - size_t mask_size = BITS_TO_LONGS(indio_dev->masklength) * sizeof(long); struct hw_consumer_buffer *buf; + int ret; list_for_each_entry(buf, &hwc->buffers, head) { if (buf->indio_dev == indio_dev) return buf; } - buf = kzalloc(sizeof(*buf) + mask_size, GFP_KERNEL); + buf = kzalloc(sizeof(*buf), GFP_KERNEL); if (!buf) return NULL; buf->buffer.access = &iio_hw_buf_access; buf->indio_dev = indio_dev; - buf->buffer.scan_mask = buf->scan_mask; iio_buffer_init(&buf->buffer); + + ret = iio_buffer_alloc_scanmask(&buf->buffer, indio_dev); + if (ret) + goto err_free_buf; + list_add_tail(&buf->head, &hwc->buffers); return buf; + +err_free_buf: + kfree(buf); + return NULL; } /** @@ -106,7 +115,7 @@ struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev) ret = -ENOMEM; goto err_put_buffers; } - set_bit(chan->channel->scan_index, buf->buffer.scan_mask); + iio_buffer_channel_enable(&buf->buffer, chan); chan++; } From patchwork Fri Apr 24 05:18:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11507117 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 98B1814B4 for ; Fri, 24 Apr 2020 05:18:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8B79D2076C for ; Fri, 24 Apr 2020 05:18:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726520AbgDXFSK (ORCPT ); Fri, 24 Apr 2020 01:18:10 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:32638 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726072AbgDXFSK (ORCPT ); Fri, 24 Apr 2020 01:18:10 -0400 Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03O548Ev004974; Fri, 24 Apr 2020 01:17:58 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30fxf6cua4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 01:17:57 -0400 Received: from ASHBMBX8.ad.analog.com (ashbmbx8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 03O5HuXu049540 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 24 Apr 2020 01:17:56 -0400 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 24 Apr 2020 01:17:55 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 24 Apr 2020 01:17:55 -0400 Received: from zeus.spd.analog.com (10.64.82.11) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.1.1779.2 via Frontend Transport; Fri, 24 Apr 2020 01:17:55 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 03O5HnSU025747; Fri, 24 Apr 2020 01:17:53 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 3/4] iio: Allow channels to share storage elements Date: Fri, 24 Apr 2020 08:18:17 +0300 Message-ID: <20200424051818.6408-4-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200424051818.6408-1-alexandru.ardelean@analog.com> References: <20200424051818.6408-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-04-24_01:2020-04-23,2020-04-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 spamscore=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 suspectscore=0 bulkscore=0 impostorscore=0 mlxlogscore=999 phishscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004240037 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org From: Lars-Peter Clausen Currently each IIO channel has it's own storage element in the data stream each with its own unique scan index. This works for a lot of use-cases, but in some is not good enough to represent the hardware accurately. On those devices multiple separate pieces of information are stored within the same storage element and the storage element can't be further broken down into multiple storage elements (e.g. because the data is not aligned). This can for example be status bits stored in unused data bits. E.g. a 14-bit ADC that stores its data in a 16-bit word and uses the two additional bits to convey status information like for example whether a overrange condition has happened. Currently this kind of extra status information is usually ignored and can only be used by applications that have special knowledge about the connected device and its data layout. In addition to that some might also have data channels with less than 8 bits that get packed into the same storage element. Allow two or more channels to use the same scan index, if they their storage element does have the same size. Signed-off-by: Lars-Peter Clausen Signed-off-by: Alexandru Ardelean --- drivers/iio/industrialio-core.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index f4daf19f2a3b..cdf59a51c917 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1651,6 +1651,16 @@ static const struct file_operations iio_buffer_fileops = { .compat_ioctl = compat_ptr_ioctl, }; +static bool iio_chan_same_size(const struct iio_chan_spec *a, + const struct iio_chan_spec *b) +{ + if (a->scan_type.storagebits != b->scan_type.storagebits) + return false; + if (a->scan_type.repeat != b->scan_type.repeat) + return false; + return true; +} + static int iio_check_unique_scan_index(struct iio_dev *indio_dev) { int i, j; @@ -1662,13 +1672,16 @@ static int iio_check_unique_scan_index(struct iio_dev *indio_dev) 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; - } + for (j = i + 1; j < indio_dev->num_channels; j++) { + if (channels[i].scan_index != channels[j].scan_index) + continue; + if (iio_chan_same_size(&channels[i], &channels[j])) + continue; + dev_err(&indio_dev->dev, + "Duplicate scan index %d\n", + channels[i].scan_index); + return -EINVAL; + } } return 0; From patchwork Fri Apr 24 05:18:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11507119 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CE48E14B4 for ; Fri, 24 Apr 2020 05:18:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B35682076C for ; Fri, 24 Apr 2020 05:18:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726072AbgDXFSQ (ORCPT ); Fri, 24 Apr 2020 01:18:16 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:34286 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726540AbgDXFSM (ORCPT ); Fri, 24 Apr 2020 01:18:12 -0400 Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03O50UPX014606; Fri, 24 Apr 2020 01:18:00 -0400 Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com with ESMTP id 30fud7n7wh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 01:18:00 -0400 Received: from SCSQMBX11.ad.analog.com (scsqmbx11.ad.analog.com [10.77.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 03O5Hwf8019485 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 24 Apr 2020 01:17:59 -0400 Received: from SCSQCASHYB7.ad.analog.com (10.77.17.133) by SCSQMBX11.ad.analog.com (10.77.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Thu, 23 Apr 2020 22:17:57 -0700 Received: from SCSQMBX11.ad.analog.com (10.77.17.10) by SCSQCASHYB7.ad.analog.com (10.77.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Thu, 23 Apr 2020 22:17:57 -0700 Received: from zeus.spd.analog.com (10.64.82.11) by SCSQMBX11.ad.analog.com (10.77.17.10) with Microsoft SMTP Server id 15.1.1779.2 via Frontend Transport; Thu, 23 Apr 2020 22:17:56 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 03O5HnSV025747; Fri, 24 Apr 2020 01:17:54 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 4/4] iio: Track enabled channels on a per channel basis Date: Fri, 24 Apr 2020 08:18:18 +0300 Message-ID: <20200424051818.6408-5-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200424051818.6408-1-alexandru.ardelean@analog.com> References: <20200424051818.6408-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-04-24_01:2020-04-23,2020-04-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxlogscore=999 priorityscore=1501 clxscore=1015 impostorscore=0 suspectscore=2 phishscore=0 mlxscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004240037 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org From: Lars-Peter Clausen 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 Signed-off-by: Alexandru Ardelean --- 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); if (!iio_validate_scan_mask(indio_dev, trialmask)) goto err_invalid_mask; @@ -363,28 +375,37 @@ static int iio_scan_mask_set(struct iio_dev *indio_dev, return 0; err_invalid_mask: + clear_bit(bit, buffer->channel_mask); bitmap_free(trialmask); return -EINVAL; } -static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit) +static int iio_channel_mask_clear(struct iio_dev *indio_dev, + struct iio_buffer *buffer, int bit) { - clear_bit(bit, buffer->scan_mask); + unsigned int ch; + + clear_bit(bit, buffer->channel_mask); + + bitmap_clear(buffer->scan_mask, 0, indio_dev->masklength); + + for_each_set_bit(ch, buffer->channel_mask, indio_dev->num_channels) + set_bit(indio_dev->channels[ch].scan_index, buffer->scan_mask); return 0; } -static int iio_scan_mask_query(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit) +static int iio_channel_mask_query(struct iio_dev *indio_dev, + struct iio_buffer *buffer, int bit) { - if (bit > indio_dev->masklength) + if (bit > indio_dev->num_channels) return -EINVAL; - if (!buffer->scan_mask) + if (!buffer->channel_mask) return 0; /* Ensure return value is 0 or 1. */ - return !!test_bit(bit, buffer->scan_mask); -}; + return !!test_bit(bit, buffer->channel_mask); +} static ssize_t iio_scan_el_store(struct device *dev, struct device_attribute *attr, @@ -405,15 +426,15 @@ static ssize_t iio_scan_el_store(struct device *dev, ret = -EBUSY; goto error_ret; } - ret = iio_scan_mask_query(indio_dev, buffer, this_attr->address); + ret = iio_channel_mask_query(indio_dev, buffer, this_attr->address); if (ret < 0) goto error_ret; if (!state && ret) { - ret = iio_scan_mask_clear(buffer, this_attr->address); + ret = iio_channel_mask_clear(indio_dev, buffer, this_attr->address); if (ret) goto error_ret; } else if (state && !ret) { - ret = iio_scan_mask_set(indio_dev, buffer, this_attr->address); + ret = iio_channel_mask_set(indio_dev, buffer, this_attr->address); if (ret) goto error_ret; } @@ -459,7 +480,8 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, } static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan) + const struct iio_chan_spec *chan, + unsigned int address) { int ret, attrcount = 0; struct iio_buffer *buffer = indio_dev->buffer; @@ -491,7 +513,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev, chan, &iio_scan_el_show, &iio_scan_el_store, - chan->scan_index, + address, 0, &indio_dev->dev, &buffer->scan_el_dev_attr_list); @@ -500,7 +522,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev, chan, &iio_scan_el_ts_show, &iio_scan_el_ts_store, - chan->scan_index, + address, 0, &indio_dev->dev, &buffer->scan_el_dev_attr_list); @@ -1313,7 +1335,7 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) continue; ret = iio_buffer_add_channel_sysfs(indio_dev, - &channels[i]); + &channels[i], i); if (ret < 0) goto error_cleanup_dynamic; attrcount += ret; diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index f35cb9985edc..57cf4b01c403 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -150,6 +150,7 @@ static int __of_iio_channel_get(struct iio_channel *channel, if (index < 0) goto err_put; channel->channel = &indio_dev->channels[index]; + channel->channel_index = index; return 0; @@ -861,14 +862,28 @@ EXPORT_SYMBOL_GPL(iio_write_channel_raw); void iio_buffer_channel_enable(struct iio_buffer *buffer, const struct iio_channel *chan) { - set_bit(chan->channel->scan_index, buffer->scan_mask); + unsigned int ch; + + set_bit(chan->channel_index, buffer->channel_mask); + + bitmap_clear(buffer->scan_mask, 0, chan->indio_dev->masklength); + + for_each_set_bit(ch, buffer->channel_mask, chan->indio_dev->num_channels) + set_bit(chan->indio_dev->channels[ch].scan_index, buffer->scan_mask); } EXPORT_SYMBOL_GPL(iio_buffer_channel_enable); void iio_buffer_channel_disable(struct iio_buffer *buffer, const struct iio_channel *chan) { - clear_bit(chan->channel->scan_index, buffer->scan_mask); + unsigned int ch; + + clear_bit(chan->channel_index, buffer->channel_mask); + + bitmap_clear(buffer->scan_mask, 0, chan->indio_dev->masklength); + + for_each_set_bit(ch, buffer->channel_mask, chan->indio_dev->num_channels) + set_bit(chan->indio_dev->channels[ch].scan_index, buffer->scan_mask); } EXPORT_SYMBOL_GPL(iio_buffer_channel_disable); diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h index a63dc07b7350..801e6ffa062c 100644 --- a/include/linux/iio/buffer_impl.h +++ b/include/linux/iio/buffer_impl.h @@ -84,6 +84,9 @@ struct iio_buffer { /** @scan_mask: Bitmask used in masking scan mode elements. */ long *scan_mask; + /** @channel_mask: Bitmask used in masking scan mode elements (per channel). */ + long *channel_mask; + /** @demux_list: List of operations required to demux the scan. */ struct list_head demux_list; diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index dbc87c26250a..6efd7091d3dd 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -19,11 +19,13 @@ struct device; * struct iio_channel - everything needed for a consumer to use a channel * @indio_dev: Device on which the channel exists. * @channel: Full description of the channel. + * @channel_index: Offset of the channel into the devices channel array. * @data: Data about the channel used by consumer. */ struct iio_channel { struct iio_dev *indio_dev; const struct iio_chan_spec *channel; + unsigned int channel_index; void *data; };