From patchwork Fri May 8 13:53:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536657 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 9E1EF81 for ; Fri, 8 May 2020 13:54:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8B8952495A for ; Fri, 8 May 2020 13:54:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728126AbgEHNyP (ORCPT ); Fri, 8 May 2020 09:54:15 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:42464 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726817AbgEHNyO (ORCPT ); Fri, 8 May 2020 09:54:14 -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 048Din7F007092; Fri, 8 May 2020 09:53:58 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtef2j5c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:53:58 -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 048Dru0p040796 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:53:56 -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; Fri, 8 May 2020 06:53:55 -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; Fri, 8 May 2020 06:53:55 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpwl030263; Fri, 8 May 2020 09:53:53 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 01/14] iio: Move scan mask management to the core Date: Fri, 8 May 2020 16:53:35 +0300 Message-ID: <20200508135348.15229-2-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 suspectscore=2 clxscore=1015 phishscore=0 mlxlogscore=999 adultscore=0 mlxscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080122 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 | 16 ++++----- drivers/iio/industrialio-buffer.c | 36 +++++++++++++++------ drivers/iio/inkern.c | 15 +++++++++ include/linux/iio/consumer.h | 10 ++++++ 4 files changed, 58 insertions(+), 19 deletions(-) diff --git a/drivers/iio/buffer/industrialio-buffer-cb.c b/drivers/iio/buffer/industrialio-buffer-cb.c index 47c96f7f4976..3db389ea3f4e 100644 --- a/drivers/iio/buffer/industrialio-buffer-cb.c +++ b/drivers/iio/buffer/industrialio-buffer-cb.c @@ -34,7 +34,7 @@ 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(&cb_buff->buffer); kfree(cb_buff); } @@ -72,27 +72,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 eae39eaf49af..7eed97c1df14 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -208,6 +208,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 -EINVAL; + + 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 @@ -1306,14 +1326,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; @@ -1334,7 +1350,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(buffer->buffer_group.attrs); @@ -1349,7 +1365,7 @@ void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) if (!buffer) return; - bitmap_free(buffer->scan_mask); + iio_buffer_free_scanmask(buffer); kfree(buffer->buffer_group.attrs); kfree(buffer->scan_el_group.attrs); iio_free_chan_devattr_list(&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 May 8 13:53:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536659 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 6FBB681 for ; Fri, 8 May 2020 13:55:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6179924958 for ; Fri, 8 May 2020 13:55:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728605AbgEHNy6 (ORCPT ); Fri, 8 May 2020 09:54:58 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:42942 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727778AbgEHNyO (ORCPT ); Fri, 8 May 2020 09:54:14 -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 048Dqt4F016877; Fri, 8 May 2020 09:54:01 -0400 Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtek2gcj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:01 -0400 Received: from ASHBMBX8.ad.analog.com (ashbmbx8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 048Ds0eB038773 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:00 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) 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, 8 May 2020 09:53:56 -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, 8 May 2020 09:53:56 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpwm030263; Fri, 8 May 2020 09:53:54 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 02/14] iio: hw_consumer: use new scanmask functions Date: Fri, 8 May 2020 16:53:36 +0300 Message-ID: <20200508135348.15229-3-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 mlxlogscore=999 lowpriorityscore=0 phishscore=0 clxscore=1015 mlxscore=0 bulkscore=0 malwarescore=0 suspectscore=2 adultscore=0 spamscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080123 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 May 8 13:53:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536661 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 7654B81 for ; Fri, 8 May 2020 13:55:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 67FBE20708 for ; Fri, 8 May 2020 13:55:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728021AbgEHNzI (ORCPT ); Fri, 8 May 2020 09:55:08 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:42488 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726904AbgEHNyO (ORCPT ); Fri, 8 May 2020 09:54:14 -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 048Diipc006142; Fri, 8 May 2020 09:54:01 -0400 Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtef2j5m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:01 -0400 Received: from ASHBMBX8.ad.analog.com (ashbmbx8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 048Ds0eC038773 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:00 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) 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, 8 May 2020 09:53:58 -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, 8 May 2020 09:53:58 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpwn030263; Fri, 8 May 2020 09:53:55 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 03/14] iio: buffer: add back-ref from iio_buffer to iio_dev Date: Fri, 8 May 2020 16:53:37 +0300 Message-ID: <20200508135348.15229-4-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 suspectscore=0 clxscore=1015 phishscore=0 mlxlogscore=942 adultscore=0 mlxscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080122 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org An IIO device will have multiple buffers, but it shouldn't be allowed that an IIO buffer should belong to more than 1 IIO device. Once things get moved more from IIO device to the IIO buffer, and an IIO device will be able to have more than 1 buffer attached, there will be a need for a back-ref to the IIO device [from the IIO buffer]. This change adds that. Signed-off-by: Alexandru Ardelean --- drivers/iio/industrialio-buffer.c | 2 ++ include/linux/iio/buffer_impl.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 7eed97c1df14..3b1071deba00 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1493,5 +1493,7 @@ void iio_device_attach_buffer(struct iio_dev *indio_dev, struct iio_buffer *buffer) { indio_dev->buffer = iio_buffer_get(buffer); + + indio_dev->buffer->indio_dev = indio_dev; } EXPORT_SYMBOL_GPL(iio_device_attach_buffer); diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h index a63dc07b7350..67d73d465e02 100644 --- a/include/linux/iio/buffer_impl.h +++ b/include/linux/iio/buffer_impl.h @@ -69,6 +69,9 @@ struct iio_buffer_access_funcs { * those writing new buffer implementations. */ struct iio_buffer { + /** @indio_dev: IIO device to which this buffer belongs to. */ + struct iio_dev *indio_dev; + /** @length: Number of datums in buffer. */ unsigned int length; From patchwork Fri May 8 13:53:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536635 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 F03D414C0 for ; Fri, 8 May 2020 13:54:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DE17F2495C for ; Fri, 8 May 2020 13:54:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727827AbgEHNyO (ORCPT ); Fri, 8 May 2020 09:54:14 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:42468 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727769AbgEHNyO (ORCPT ); Fri, 8 May 2020 09:54:14 -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 048Dib8I031165; Fri, 8 May 2020 09:54:02 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtef2j5q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:02 -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 048Ds1rA040814 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:01 -0400 Received: from SCSQMBX11.ad.analog.com (10.77.17.10) 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; Fri, 8 May 2020 06:53:59 -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; Fri, 8 May 2020 06:53:59 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpwo030263; Fri, 8 May 2020 09:53:57 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 04/14] iio: core,buffer: wrap iio_buffer_put() call into iio_buffers_put() Date: Fri, 8 May 2020 16:53:38 +0300 Message-ID: <20200508135348.15229-5-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 suspectscore=2 clxscore=1015 phishscore=0 mlxlogscore=913 adultscore=0 mlxscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080122 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org The name (and the wrapper) seems superfluous now, but when more buffers will be attached to the IIO device this will be a bit more useful. Signed-off-by: Alexandru Ardelean --- drivers/iio/iio_core.h | 4 ++++ drivers/iio/industrialio-buffer.c | 10 ++++++++++ drivers/iio/industrialio-core.c | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h index fd9a5f1d5e51..39ec0344fb68 100644 --- a/drivers/iio/iio_core.h +++ b/drivers/iio/iio_core.h @@ -51,6 +51,8 @@ void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev); #define iio_buffer_poll_addr (&iio_buffer_poll) #define iio_buffer_read_outer_addr (&iio_buffer_read_outer) +void iio_device_buffers_put(struct iio_dev *indio_dev); + void iio_disable_all_buffers(struct iio_dev *indio_dev); void iio_buffer_wakeup_poll(struct iio_dev *indio_dev); @@ -66,6 +68,8 @@ static inline int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) static inline void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) {} +static inline void iio_device_buffers_put(struct iio_dev *indio_dev) {} + static inline void iio_disable_all_buffers(struct iio_dev *indio_dev) {} static inline void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) {} diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 3b1071deba00..93f187455461 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1371,6 +1371,16 @@ void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); } +void iio_device_buffers_put(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer = indio_dev->buffer; + + if (!buffer) + return; + + iio_buffer_put(buffer); +} + /** * iio_validate_scan_mask_onehot() - Validates that exactly one channel is selected * @indio_dev: the iio device diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 462d3e810013..32c489139cd2 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1481,7 +1481,7 @@ static void iio_dev_release(struct device *device) iio_device_unregister_eventset(indio_dev); iio_device_unregister_sysfs(indio_dev); - iio_buffer_put(indio_dev->buffer); + iio_device_buffers_put(indio_dev); ida_simple_remove(&iio_ida, indio_dev->id); kfree(indio_dev); From patchwork Fri May 8 13:53:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536663 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 15F6314C0 for ; Fri, 8 May 2020 13:55:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 07C4524958 for ; Fri, 8 May 2020 13:55:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727937AbgEHNzI (ORCPT ); Fri, 8 May 2020 09:55:08 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:42472 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727092AbgEHNyO (ORCPT ); Fri, 8 May 2020 09:54:14 -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 048Dr3v9016945; Fri, 8 May 2020 09:54:03 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtek2gcn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:02 -0400 Received: from ASHBMBX9.ad.analog.com (ashbmbx9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 048Ds1Cv040822 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:01 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 8 May 2020 09:54:00 -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, 8 May 2020 09:54:00 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpwp030263; Fri, 8 May 2020 09:53:58 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 05/14] iio: core: register chardev only if needed Date: Fri, 8 May 2020 16:53:39 +0300 Message-ID: <20200508135348.15229-6-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 mlxlogscore=999 lowpriorityscore=0 phishscore=0 clxscore=1015 mlxscore=0 bulkscore=0 malwarescore=0 suspectscore=2 adultscore=0 spamscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080123 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org The final intent is to localize all buffer ops into the industrialio-buffer.c file, to be able to add support for multiple buffers per IIO device. We only need a chardev if we need to support buffers and/or events. With this change, a chardev will be created only if an IIO buffer is attached OR an event_interface is configured. Otherwise, no chardev will be created, and the IIO device will get registered with the 'device_add()' call. Quite a lot of IIO devices don't really need a chardev, so this is a minor improvement to the IIO core, as the IIO device will take up (slightly) fewer resources. What's important to remember, is that removing a chardev also requires that 'indio_dev->dev.devt' to be initialized. If it is, a '/dev/iio:deviceX' file will be created by the kernel, regardless of whether it has a chardev attached to it or not. If that field is not initialized, cdev_device_{add,del}() behave{s} like device_{add,del}(). Also, since we plan to add more chardevs for IIO buffers, we need to consider now a separate IDA object just for chardevs. Currently, the only benefit is that chardev IDs will be continuous. However, when adding a chardev per IIO buffer, the IDs for the chardev could outpace the IDs for IIO devices, so these should be decoupled. Signed-off-by: Alexandru Ardelean --- drivers/iio/industrialio-core.c | 58 +++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 32c489139cd2..d74279efeca4 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -35,6 +35,9 @@ /* IDA to assign each registered device a unique id */ static DEFINE_IDA(iio_ida); +/* IDA to assign each registered character device a unique id */ +static DEFINE_IDA(iio_chrdev_ida); + static dev_t iio_devt; #define IIO_DEV_MAX 256 @@ -1680,8 +1683,40 @@ static int iio_check_unique_scan_index(struct iio_dev *indio_dev) return 0; } +static int iio_device_alloc_chrdev_id(struct device *dev) +{ + int id; + + id = ida_simple_get(&iio_chrdev_ida, 0, 0, GFP_KERNEL); + if (id < 0) { + /* cannot use a dev_err as the name isn't available */ + dev_err(dev, "failed to get device id\n"); + return id; + } + + dev->devt = MKDEV(MAJOR(iio_devt), id); + + return 0; +} + +static void iio_device_free_chrdev_id(struct device *dev) +{ + if (!dev->devt) + return; + ida_simple_remove(&iio_chrdev_ida, MINOR(dev->devt)); +} + static const struct iio_buffer_setup_ops noop_ring_setup_ops; +static const struct file_operations iio_event_fileops = { + .owner = THIS_MODULE, + .llseek = noop_llseek, + .unlocked_ioctl = iio_ioctl, + .compat_ioctl = compat_ptr_ioctl, + .open = iio_chrdev_open, + .release = iio_chrdev_release, +}; + int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) { int ret; @@ -1701,9 +1736,6 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) if (ret < 0) return ret; - /* configure elements for the chrdev */ - indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); - iio_device_register_debugfs(indio_dev); ret = iio_buffer_alloc_sysfs_and_mask(indio_dev); @@ -1732,16 +1764,27 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) indio_dev->setup_ops == NULL) indio_dev->setup_ops = &noop_ring_setup_ops; - cdev_init(&indio_dev->chrdev, &iio_buffer_fileops); + if (indio_dev->buffer) + cdev_init(&indio_dev->chrdev, &iio_buffer_fileops); + else if (indio_dev->event_interface) + cdev_init(&indio_dev->chrdev, &iio_event_fileops); - indio_dev->chrdev.owner = this_mod; + if (indio_dev->buffer || indio_dev->event_interface) { + indio_dev->chrdev.owner = this_mod; + + ret = iio_device_alloc_chrdev_id(&indio_dev->dev); + if (ret) + goto error_unreg_eventset; + } ret = cdev_device_add(&indio_dev->chrdev, &indio_dev->dev); - if (ret < 0) - goto error_unreg_eventset; + if (ret) + goto error_free_chrdev_id; return 0; +error_free_chrdev_id: + iio_device_free_chrdev_id(&indio_dev->dev); error_unreg_eventset: iio_device_unregister_eventset(indio_dev); error_free_sysfs: @@ -1761,6 +1804,7 @@ EXPORT_SYMBOL(__iio_device_register); void iio_device_unregister(struct iio_dev *indio_dev) { cdev_device_del(&indio_dev->chrdev, &indio_dev->dev); + iio_device_free_chrdev_id(&indio_dev->dev); mutex_lock(&indio_dev->info_exist_lock); From patchwork Fri May 8 13:53:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536655 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 4701617EF for ; Fri, 8 May 2020 13:54:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2E9C22495A for ; Fri, 8 May 2020 13:54:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728299AbgEHNyR (ORCPT ); Fri, 8 May 2020 09:54:17 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:44210 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727769AbgEHNyQ (ORCPT ); Fri, 8 May 2020 09:54:16 -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 048DiaSA030459; Fri, 8 May 2020 09:54:03 -0400 Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtef2j5s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:03 -0400 Received: from ASHBMBX8.ad.analog.com (ashbmbx8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 048Ds2HW038785 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:02 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) 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, 8 May 2020 09:54:01 -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, 8 May 2020 09:54:01 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpwq030263; Fri, 8 May 2020 09:53:59 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 06/14] iio: buffer,event: duplicate chardev creation for buffers & events Date: Fri, 8 May 2020 16:53:40 +0300 Message-ID: <20200508135348.15229-7-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 suspectscore=2 clxscore=1015 phishscore=0 mlxlogscore=999 adultscore=0 mlxscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080122 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch moves the chardev creation into industrialio-buffer.c & industrialio-event.c. The move has to be in a single step (which makes the patch a bit big), in order to pass the reference of the chardev to 'indio_dev->chrdev'. For structure purposes, industrialio-core.c should be the place where cdev_device_add()/device_add() gets called, and the deletion function as well. What happens after this patch is: - 'indio_dev->chrdev' is converted to a pointer - if there is an IIO buffer, iio_device_buffer_attach_chrdev() will attach it's chardev to 'indio_chrdev' - if it doesn't, the event interface will attach a reference to it's chardev (if it is instantiated) via iio_device_event_attach_chrdev() That way, the control of the 'legacy' chardev is still visible in 'industrialio-core.c'. So, each logic file (for buffers & events) shouldn't hide things too much away from the core file. Signed-off-by: Alexandru Ardelean --- drivers/iio/iio_core.h | 16 ++--- drivers/iio/industrialio-buffer.c | 90 +++++++++++++++++++++++++--- drivers/iio/industrialio-core.c | 99 +++---------------------------- drivers/iio/industrialio-event.c | 98 +++++++++++++++++++++++++++++- include/linux/iio/buffer_impl.h | 7 +++ include/linux/iio/iio.h | 6 +- 6 files changed, 204 insertions(+), 112 deletions(-) diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h index 39ec0344fb68..a527a66be9e5 100644 --- a/drivers/iio/iio_core.h +++ b/drivers/iio/iio_core.h @@ -40,17 +40,14 @@ ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals); #ifdef CONFIG_IIO_BUFFER struct poll_table_struct; -__poll_t iio_buffer_poll(struct file *filp, - struct poll_table_struct *wait); -ssize_t iio_buffer_read_outer(struct file *filp, char __user *buf, - size_t n, loff_t *f_ps); +long iio_device_event_ioctl(struct iio_dev *indio_dev, struct file *filp, + unsigned int cmd, unsigned long arg); + +void iio_device_buffer_attach_chrdev(struct iio_dev *indio_dev); int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev); void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev); -#define iio_buffer_poll_addr (&iio_buffer_poll) -#define iio_buffer_read_outer_addr (&iio_buffer_read_outer) - void iio_device_buffers_put(struct iio_dev *indio_dev); void iio_disable_all_buffers(struct iio_dev *indio_dev); @@ -58,8 +55,7 @@ void iio_buffer_wakeup_poll(struct iio_dev *indio_dev); #else -#define iio_buffer_poll_addr NULL -#define iio_buffer_read_outer_addr NULL +static inline void iio_device_buffer_attach_chrdev(struct iio_dev *indio_dev) {} static inline int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) { @@ -77,8 +73,8 @@ static inline void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) {} int iio_device_register_eventset(struct iio_dev *indio_dev); void iio_device_unregister_eventset(struct iio_dev *indio_dev); +void iio_device_event_attach_chrdev(struct iio_dev *indio_dev); void iio_device_wakeup_eventset(struct iio_dev *indio_dev); -int iio_event_getfd(struct iio_dev *indio_dev); struct iio_event_interface; bool iio_event_enabled(const struct iio_event_interface *ev_int); diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 93f187455461..1400688f5e42 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -99,11 +99,11 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf, * Return: negative values corresponding to error codes or ret != 0 * for ending the reading activity **/ -ssize_t iio_buffer_read_outer(struct file *filp, char __user *buf, - size_t n, loff_t *f_ps) +static ssize_t iio_buffer_read_outer(struct file *filp, char __user *buf, + size_t n, loff_t *f_ps) { - struct iio_dev *indio_dev = filp->private_data; - struct iio_buffer *rb = indio_dev->buffer; + struct iio_buffer *rb = filp->private_data; + struct iio_dev *indio_dev = rb->indio_dev; DEFINE_WAIT_FUNC(wait, woken_wake_function); size_t datum_size; size_t to_wait; @@ -165,11 +165,11 @@ ssize_t iio_buffer_read_outer(struct file *filp, char __user *buf, * Return: (EPOLLIN | EPOLLRDNORM) if data is available for reading * or 0 for other cases */ -__poll_t iio_buffer_poll(struct file *filp, +static __poll_t iio_buffer_poll(struct file *filp, struct poll_table_struct *wait) { - struct iio_dev *indio_dev = filp->private_data; - struct iio_buffer *rb = indio_dev->buffer; + struct iio_buffer *rb = filp->private_data; + struct iio_dev *indio_dev = rb->indio_dev; if (!indio_dev->info || rb == NULL) return 0; @@ -180,6 +180,48 @@ __poll_t iio_buffer_poll(struct file *filp, return 0; } +/** + * iio_buffer_chrdev_open() - chrdev file open for buffer access + * @inode: Inode structure for identifying the device in the file system + * @filp: File structure for iio device used to keep and later access + * private data + * + * Return: 0 on success or -EBUSY if the device is already opened + **/ +static int iio_buffer_chrdev_open(struct inode *inode, struct file *filp) +{ + struct iio_buffer *buffer = container_of(inode->i_cdev, + struct iio_buffer, chrdev); + + if (test_and_set_bit(IIO_BUSY_BIT_POS, &buffer->file_ops_flags)) + return -EBUSY; + + iio_buffer_get(buffer); + + filp->private_data = buffer; + + return 0; +} + +/** + * iio_buffer_chrdev_release() - chrdev file close for buffer access + * @inode: Inode structure pointer for the char device + * @filp: File structure pointer for the char device + * + * Return: 0 for successful release + */ +static int iio_buffer_chrdev_release(struct inode *inode, struct file *filp) +{ + struct iio_buffer *buffer = container_of(inode->i_cdev, + struct iio_buffer, chrdev); + + clear_bit(IIO_BUSY_BIT_POS, &buffer->file_ops_flags); + + iio_buffer_put(buffer); + + return 0; +} + /** * iio_buffer_wakeup_poll - Wakes up the buffer waitqueue * @indio_dev: The IIO device @@ -1149,6 +1191,17 @@ void iio_disable_all_buffers(struct iio_dev *indio_dev) iio_buffer_deactivate_all(indio_dev); } +static long iio_buffer_ioctl(struct file *filep, unsigned int cmd, + unsigned long arg) +{ + struct iio_buffer *buffer = filep->private_data; + + if (!buffer || !buffer->access) + return -ENODEV; + + return iio_device_event_ioctl(buffer->indio_dev, filep, cmd, arg); +} + static ssize_t iio_buffer_store_enable(struct device *dev, struct device_attribute *attr, const char *buf, @@ -1371,6 +1424,29 @@ void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); } +static const struct file_operations iio_buffer_fileops = { + .read = iio_buffer_read_outer, + .release = iio_buffer_chrdev_release, + .open = iio_buffer_chrdev_open, + .poll = iio_buffer_poll, + .owner = THIS_MODULE, + .llseek = noop_llseek, + .unlocked_ioctl = iio_buffer_ioctl, + .compat_ioctl = compat_ptr_ioctl, +}; + +void iio_device_buffer_attach_chrdev(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer = indio_dev->buffer; + + if (!buffer) + return; + + cdev_init(&buffer->chrdev, &iio_buffer_fileops); + + indio_dev->chrdev = &buffer->chrdev; +} + void iio_device_buffers_put(struct iio_dev *indio_dev) { struct iio_buffer *buffer = indio_dev->buffer; diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index d74279efeca4..32e045c7f0c1 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1587,79 +1587,6 @@ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv) } EXPORT_SYMBOL_GPL(devm_iio_device_alloc); -/** - * iio_chrdev_open() - chrdev file open for buffer access and ioctls - * @inode: Inode structure for identifying the device in the file system - * @filp: File structure for iio device used to keep and later access - * private data - * - * Return: 0 on success or -EBUSY if the device is already opened - **/ -static int iio_chrdev_open(struct inode *inode, struct file *filp) -{ - struct iio_dev *indio_dev = container_of(inode->i_cdev, - struct iio_dev, chrdev); - - if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) - return -EBUSY; - - iio_device_get(indio_dev); - - filp->private_data = indio_dev; - - return 0; -} - -/** - * iio_chrdev_release() - chrdev file close buffer access and ioctls - * @inode: Inode structure pointer for the char device - * @filp: File structure pointer for the char device - * - * Return: 0 for successful release - */ -static int iio_chrdev_release(struct inode *inode, struct file *filp) -{ - struct iio_dev *indio_dev = container_of(inode->i_cdev, - struct iio_dev, chrdev); - clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); - iio_device_put(indio_dev); - - return 0; -} - -/* Somewhat of a cross file organization violation - ioctls here are actually - * event related */ -static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct iio_dev *indio_dev = filp->private_data; - int __user *ip = (int __user *)arg; - int fd; - - if (!indio_dev->info) - return -ENODEV; - - if (cmd == IIO_GET_EVENT_FD_IOCTL) { - fd = iio_event_getfd(indio_dev); - if (fd < 0) - return fd; - if (copy_to_user(ip, &fd, sizeof(fd))) - return -EFAULT; - return 0; - } - return -EINVAL; -} - -static const struct file_operations iio_buffer_fileops = { - .read = iio_buffer_read_outer_addr, - .release = iio_chrdev_release, - .open = iio_chrdev_open, - .poll = iio_buffer_poll_addr, - .owner = THIS_MODULE, - .llseek = noop_llseek, - .unlocked_ioctl = iio_ioctl, - .compat_ioctl = compat_ptr_ioctl, -}; - static int iio_check_unique_scan_index(struct iio_dev *indio_dev) { int i, j; @@ -1708,15 +1635,6 @@ static void iio_device_free_chrdev_id(struct device *dev) static const struct iio_buffer_setup_ops noop_ring_setup_ops; -static const struct file_operations iio_event_fileops = { - .owner = THIS_MODULE, - .llseek = noop_llseek, - .unlocked_ioctl = iio_ioctl, - .compat_ioctl = compat_ptr_ioctl, - .open = iio_chrdev_open, - .release = iio_chrdev_release, -}; - int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) { int ret; @@ -1764,20 +1682,21 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) indio_dev->setup_ops == NULL) indio_dev->setup_ops = &noop_ring_setup_ops; - if (indio_dev->buffer) - cdev_init(&indio_dev->chrdev, &iio_buffer_fileops); - else if (indio_dev->event_interface) - cdev_init(&indio_dev->chrdev, &iio_event_fileops); + iio_device_buffer_attach_chrdev(indio_dev); + + /* No chrdev attached from buffer, we go with event-only chrdev */ + if (!indio_dev->chrdev) + iio_device_event_attach_chrdev(indio_dev); - if (indio_dev->buffer || indio_dev->event_interface) { - indio_dev->chrdev.owner = this_mod; + if (indio_dev->chrdev) { + indio_dev->chrdev->owner = this_mod; ret = iio_device_alloc_chrdev_id(&indio_dev->dev); if (ret) goto error_unreg_eventset; } - ret = cdev_device_add(&indio_dev->chrdev, &indio_dev->dev); + ret = cdev_device_add(indio_dev->chrdev, &indio_dev->dev); if (ret) goto error_free_chrdev_id; @@ -1803,7 +1722,7 @@ EXPORT_SYMBOL(__iio_device_register); **/ void iio_device_unregister(struct iio_dev *indio_dev) { - cdev_device_del(&indio_dev->chrdev, &indio_dev->dev); + cdev_device_del(indio_dev->chrdev, &indio_dev->dev); iio_device_free_chrdev_id(&indio_dev->dev); mutex_lock(&indio_dev->info_exist_lock); diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 5b17c92d3b50..0674b2117c98 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -30,6 +30,8 @@ * @flags: file operations related flags including busy flag. * @group: event interface sysfs attribute group * @read_lock: lock to protect kfifo read operations + * @chrdev: associated chardev for this event + * @indio_dev: IIO device to which this event interface belongs to */ struct iio_event_interface { wait_queue_head_t wait; @@ -39,6 +41,9 @@ struct iio_event_interface { unsigned long flags; struct attribute_group group; struct mutex read_lock; + + struct cdev chrdev; + struct iio_dev *indio_dev; }; bool iio_event_enabled(const struct iio_event_interface *ev_int) @@ -182,7 +187,7 @@ static const struct file_operations iio_event_chrdev_fileops = { .llseek = noop_llseek, }; -int iio_event_getfd(struct iio_dev *indio_dev) +static int iio_event_getfd(struct iio_dev *indio_dev) { struct iio_event_interface *ev_int = indio_dev->event_interface; int fd; @@ -215,6 +220,97 @@ int iio_event_getfd(struct iio_dev *indio_dev) return fd; } +/** + * iio_chrdev_open() - chrdev file open for event ioctls + * @inode: Inode structure for identifying the device in the file system + * @filp: File structure for iio device used to keep and later access + * private data + * + * Return: 0 on success or -EBUSY if the device is already opened + **/ +static int iio_chrdev_open(struct inode *inode, struct file *filp) +{ + struct iio_event_interface *ev = + container_of(inode->i_cdev, struct iio_event_interface, chrdev); + + if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev->flags)) + return -EBUSY; + + iio_device_get(ev->indio_dev); + + filp->private_data = ev; + + return 0; +} + +/** + * iio_chrdev_release() - chrdev file close for event ioctls + * @inode: Inode structure pointer for the char device + * @filp: File structure pointer for the char device + * + * Return: 0 for successful release + */ +static int iio_chrdev_release(struct inode *inode, struct file *filp) +{ + struct iio_event_interface *ev = + container_of(inode->i_cdev, struct iio_event_interface, chrdev); + + clear_bit(IIO_BUSY_BIT_POS, &ev->flags); + iio_device_put(ev->indio_dev); + + return 0; +} + +long iio_device_event_ioctl(struct iio_dev *indio_dev, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + int __user *ip = (int __user *)arg; + int fd; + + if (!indio_dev->info) + return -ENODEV; + + if (cmd == IIO_GET_EVENT_FD_IOCTL) { + fd = iio_event_getfd(indio_dev); + if (fd < 0) + return fd; + if (copy_to_user(ip, &fd, sizeof(fd))) + return -EFAULT; + return 0; + } + return -EINVAL; +} + +static long iio_event_ioctl_wrapper(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct iio_event_interface *ev = filp->private_data; + + return iio_device_event_ioctl(ev->indio_dev, filp, cmd, arg); +} + +static const struct file_operations iio_event_fileops = { + .release = iio_chrdev_release, + .open = iio_chrdev_open, + .owner = THIS_MODULE, + .llseek = noop_llseek, + .unlocked_ioctl = iio_event_ioctl_wrapper, + .compat_ioctl = compat_ptr_ioctl, +}; + +void iio_device_event_attach_chrdev(struct iio_dev *indio_dev) +{ + struct iio_event_interface *ev = indio_dev->event_interface; + + if (!ev) + return; + + cdev_init(&ev->chrdev, &iio_event_fileops); + + ev->indio_dev = indio_dev; + indio_dev->chrdev = &ev->chrdev; +} + static const char * const iio_ev_type_text[] = { [IIO_EV_TYPE_THRESH] = "thresh", [IIO_EV_TYPE_MAG] = "mag", diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h index 67d73d465e02..46fc977deae3 100644 --- a/include/linux/iio/buffer_impl.h +++ b/include/linux/iio/buffer_impl.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IIO_BUFFER_GENERIC_IMPL_H_ #define _IIO_BUFFER_GENERIC_IMPL_H_ +#include #include #include @@ -72,6 +73,12 @@ struct iio_buffer { /** @indio_dev: IIO device to which this buffer belongs to. */ struct iio_dev *indio_dev; + /** @chrdev: associated character device. */ + struct cdev chrdev; + + /** @file_ops_flags: file ops related flags including busy flag. */ + unsigned long file_ops_flags; + /** @length: Number of datums in buffer. */ unsigned int length; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 5f9f439a4f01..52992be44e9e 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -516,10 +516,9 @@ struct iio_buffer_setup_ops { * @info_exist_lock: [INTERN] lock to prevent use during removal * @setup_ops: [DRIVER] callbacks to call before and after buffer * enable/disable - * @chrdev: [INTERN] associated character device + * @chrdev: [INTERN] reference to associated character device * @groups: [INTERN] attribute groups * @groupcounter: [INTERN] index of next attribute group - * @flags: [INTERN] file ops related flags including busy flag. * @debugfs_dentry: [INTERN] device specific debugfs dentry. * @cached_reg_addr: [INTERN] cached register address for debugfs reads. */ @@ -559,12 +558,11 @@ struct iio_dev { clockid_t clock_id; struct mutex info_exist_lock; const struct iio_buffer_setup_ops *setup_ops; - struct cdev chrdev; + struct cdev *chrdev; #define IIO_MAX_GROUPS 6 const struct attribute_group *groups[IIO_MAX_GROUPS + 1]; int groupcounter; - unsigned long flags; #if defined(CONFIG_DEBUG_FS) struct dentry *debugfs_dentry; unsigned cached_reg_addr; From patchwork Fri May 8 13:53:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536639 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 2AB5381 for ; Fri, 8 May 2020 13:54:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1DE55216FD for ; Fri, 8 May 2020 13:54:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728290AbgEHNyR (ORCPT ); Fri, 8 May 2020 09:54:17 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:46322 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728154AbgEHNyQ (ORCPT ); Fri, 8 May 2020 09:54:16 -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 048DqtAj016883; Fri, 8 May 2020 09:54:05 -0400 Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtek2gcq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:04 -0400 Received: from ASHBMBX8.ad.analog.com (ashbmbx8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 048Ds3cS038790 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:03 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) 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, 8 May 2020 09:54:02 -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, 8 May 2020 09:54:02 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpwr030263; Fri, 8 May 2020 09:54:00 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 07/14] iio: core: add simple centralized mechanism for ioctl() handlers Date: Fri, 8 May 2020 16:53:41 +0300 Message-ID: <20200508135348.15229-8-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 mlxlogscore=999 lowpriorityscore=0 phishscore=0 clxscore=1015 mlxscore=0 bulkscore=0 malwarescore=0 suspectscore=2 adultscore=0 spamscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080123 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org The aim of this is to reduce the organization violation of ioctl() calls in IIO core. Currently, since the chardev is split across files, event ioctl() calls need to be called in buffer ioctl() calls. The 'industrialio-core.c' file will provide a 'iio_device_ioctl()' which will iterate over a list of ioctls registered with the IIO device. These can be event ioctl() or buffer ioctl() calls, or something else. This is needed, since there is currently one chardev per IIO device and that is used for both event handling and reading from the buffer. Each ioctl() will have to return a IIO_IOCTL_UNHANDLED code (which is positive 1), if the ioctl() did not handle the call in any. This eliminates any potential ambiguities; if we were to have used error codes it would have been uncertain whether they were actual errors, or whether the registered ioctl() doesn't service the command. If any ioctl() returns 0, it was considered that it was serviced successfully and the loop will exit. One assumption for all registered ioctl() handlers is that they are statically allocated, so the iio_device_unregister() which just remove all of them from the device's ioctl() handler list. Also, something that is a bit hard to do [at this point] and may not be worth the effort of doing, is to check whether registered ioctl() calls/commands overlap. This should be unlikely to happen, and should get caught at review time. Though, new ioctl() calls would likely not be added too often. Signed-off-by: Alexandru Ardelean --- drivers/iio/iio_core.h | 14 ++++++++++++++ drivers/iio/industrialio-core.c | 33 +++++++++++++++++++++++++++++++++ include/linux/iio/iio.h | 2 ++ 3 files changed, 49 insertions(+) diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h index a527a66be9e5..34c3e19229d8 100644 --- a/drivers/iio/iio_core.h +++ b/drivers/iio/iio_core.h @@ -17,6 +17,20 @@ struct iio_dev; extern struct device_type iio_device_type; +#define IIO_IOCTL_UNHANDLED 1 +struct iio_ioctl_handler { + struct list_head entry; + long (*ioctl)(struct iio_dev *indio_dev, struct file *filp, + unsigned int cmd, unsigned long arg); +}; + +long iio_device_ioctl(struct iio_dev *indio_dev, struct file *filp, + unsigned int cmd, unsigned long arg); + +void iio_device_ioctl_handler_register(struct iio_dev *indio_dev, + struct iio_ioctl_handler *h); +void iio_device_ioctl_handler_unregister(struct iio_ioctl_handler *h); + int __iio_add_chan_devattr(const char *postfix, struct iio_chan_spec const *chan, ssize_t (*func)(struct device *dev, diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 32e045c7f0c1..5df3af5e7dcb 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1534,6 +1534,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) } dev_set_name(&dev->dev, "iio:device%d", dev->id); INIT_LIST_HEAD(&dev->buffer_list); + INIT_LIST_HEAD(&dev->ioctl_handlers); return dev; } @@ -1587,6 +1588,33 @@ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv) } EXPORT_SYMBOL_GPL(devm_iio_device_alloc); +void iio_device_ioctl_handler_register(struct iio_dev *indio_dev, + struct iio_ioctl_handler *h) +{ + /* this assumes that all ioctl() handlers are statically allocated */ + list_add_tail(&h->entry, &indio_dev->ioctl_handlers); +} + +long iio_device_ioctl(struct iio_dev *indio_dev, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct iio_ioctl_handler *h; + int ret; + + if (!indio_dev->info) + return -ENODEV; + + list_for_each_entry(h, &indio_dev->ioctl_handlers, entry) { + ret = h->ioctl(indio_dev, filp, cmd, arg); + if (ret == 0) + return 0; + if (ret != IIO_IOCTL_UNHANDLED) + return ret; + } + + return -EINVAL; +} + static int iio_check_unique_scan_index(struct iio_dev *indio_dev) { int i, j; @@ -1722,6 +1750,8 @@ EXPORT_SYMBOL(__iio_device_register); **/ void iio_device_unregister(struct iio_dev *indio_dev) { + struct iio_ioctl_handler *h, *t; + cdev_device_del(indio_dev->chrdev, &indio_dev->dev); iio_device_free_chrdev_id(&indio_dev->dev); @@ -1731,6 +1761,9 @@ void iio_device_unregister(struct iio_dev *indio_dev) iio_disable_all_buffers(indio_dev); + list_for_each_entry_safe(h, t, &indio_dev->ioctl_handlers, entry) + list_del(&h->entry); + indio_dev->info = NULL; iio_device_wakeup_eventset(indio_dev); diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 52992be44e9e..b6ca8d85629e 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -488,6 +488,7 @@ struct iio_buffer_setup_ops { * @currentmode: [DRIVER] current operating mode * @dev: [DRIVER] device structure, should be assigned a parent * and owner + * @ioctl_handlers: [INTERN] list of registered ioctl handlers * @event_interface: [INTERN] event chrdevs associated with interrupt lines * @buffer: [DRIVER] any buffer present * @buffer_list: [INTERN] list of all buffers currently attached @@ -529,6 +530,7 @@ struct iio_dev { int modes; int currentmode; struct device dev; + struct list_head ioctl_handlers; struct iio_event_interface *event_interface; From patchwork Fri May 8 13:53:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536653 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 E766614C0 for ; Fri, 8 May 2020 13:54:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D51532495E for ; Fri, 8 May 2020 13:54:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728344AbgEHNyw (ORCPT ); Fri, 8 May 2020 09:54:52 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:49716 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728313AbgEHNyS (ORCPT ); Fri, 8 May 2020 09:54:18 -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 048Diipd006142; Fri, 8 May 2020 09:54:06 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtef2j5x-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:06 -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 048Ds4KK040838 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:05 -0400 Received: from SCSQMBX11.ad.analog.com (10.77.17.10) 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; Fri, 8 May 2020 06:54:04 -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; Fri, 8 May 2020 06:54:03 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpws030263; Fri, 8 May 2020 09:54:01 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 08/14] iio: core: use new common ioctl() mechanism Date: Fri, 8 May 2020 16:53:42 +0300 Message-ID: <20200508135348.15229-9-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 suspectscore=0 clxscore=1015 phishscore=0 mlxlogscore=999 adultscore=0 mlxscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080122 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This change makes use of the new centralized ioctl() mechanism. The event interface registers it's ioctl() handler to IIO device. Both the buffer & event interface call 'iio_device_ioctl()', which should take care of all of indio_dev's ioctl() calls. Later, we may add per-buffer ioctl() calls, and since each buffer will get it's own chardev, the buffer ioctl() handler will need a bit of tweaking for the first/legacy buffer (i.e. indio_dev->buffer). Also, those per-buffer ioctl() calls will not be registered with this mechanism. Signed-off-by: Alexandru Ardelean --- drivers/iio/iio_core.h | 3 --- drivers/iio/industrialio-buffer.c | 2 +- drivers/iio/industrialio-event.c | 14 ++++++++------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h index 34c3e19229d8..f68de4af2738 100644 --- a/drivers/iio/iio_core.h +++ b/drivers/iio/iio_core.h @@ -54,9 +54,6 @@ ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals); #ifdef CONFIG_IIO_BUFFER struct poll_table_struct; -long iio_device_event_ioctl(struct iio_dev *indio_dev, struct file *filp, - unsigned int cmd, unsigned long arg); - void iio_device_buffer_attach_chrdev(struct iio_dev *indio_dev); int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev); diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 1400688f5e42..e7a847e7b103 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1199,7 +1199,7 @@ static long iio_buffer_ioctl(struct file *filep, unsigned int cmd, if (!buffer || !buffer->access) return -ENODEV; - return iio_device_event_ioctl(buffer->indio_dev, filep, cmd, arg); + return iio_device_ioctl(buffer->indio_dev, filep, cmd, arg); } static ssize_t iio_buffer_store_enable(struct device *dev, diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 0674b2117c98..1961c1d19370 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -32,6 +32,7 @@ * @read_lock: lock to protect kfifo read operations * @chrdev: associated chardev for this event * @indio_dev: IIO device to which this event interface belongs to + * @ioctl_handler: handler for event ioctl() calls */ struct iio_event_interface { wait_queue_head_t wait; @@ -44,6 +45,7 @@ struct iio_event_interface { struct cdev chrdev; struct iio_dev *indio_dev; + struct iio_ioctl_handler ioctl_handler; }; bool iio_event_enabled(const struct iio_event_interface *ev_int) @@ -261,15 +263,12 @@ static int iio_chrdev_release(struct inode *inode, struct file *filp) return 0; } -long iio_device_event_ioctl(struct iio_dev *indio_dev, struct file *filp, +static long iio_event_ioctl(struct iio_dev *indio_dev, struct file *filp, unsigned int cmd, unsigned long arg) { int __user *ip = (int __user *)arg; int fd; - if (!indio_dev->info) - return -ENODEV; - if (cmd == IIO_GET_EVENT_FD_IOCTL) { fd = iio_event_getfd(indio_dev); if (fd < 0) @@ -278,7 +277,7 @@ long iio_device_event_ioctl(struct iio_dev *indio_dev, struct file *filp, return -EFAULT; return 0; } - return -EINVAL; + return IIO_IOCTL_UNHANDLED; } static long iio_event_ioctl_wrapper(struct file *filp, unsigned int cmd, @@ -286,7 +285,7 @@ static long iio_event_ioctl_wrapper(struct file *filp, unsigned int cmd, { struct iio_event_interface *ev = filp->private_data; - return iio_device_event_ioctl(ev->indio_dev, filp, cmd, arg); + return iio_device_ioctl(ev->indio_dev, filp, cmd, arg); } static const struct file_operations iio_event_fileops = { @@ -308,7 +307,10 @@ void iio_device_event_attach_chrdev(struct iio_dev *indio_dev) cdev_init(&ev->chrdev, &iio_event_fileops); ev->indio_dev = indio_dev; + ev->ioctl_handler.ioctl = iio_event_ioctl; indio_dev->chrdev = &ev->chrdev; + + iio_device_ioctl_handler_register(indio_dev, &ev->ioctl_handler); } static const char * const iio_ev_type_text[] = { From patchwork Fri May 8 13:53:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536651 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 03CE681 for ; Fri, 8 May 2020 13:54:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E90E220708 for ; Fri, 8 May 2020 13:54:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727917AbgEHNys (ORCPT ); Fri, 8 May 2020 09:54:48 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:52062 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728344AbgEHNyU (ORCPT ); Fri, 8 May 2020 09:54:20 -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 048Dqt4G016877; Fri, 8 May 2020 09:54:08 -0400 Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtek2gcy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:08 -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 048Ds6Za038800 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:07 -0400 Received: from SCSQCASHYB6.ad.analog.com (10.77.17.132) 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; Fri, 8 May 2020 06:54:05 -0700 Received: from SCSQMBX10.ad.analog.com (10.77.17.5) by SCSQCASHYB6.ad.analog.com (10.77.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 8 May 2020 06:53:32 -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; Fri, 8 May 2020 06:54:04 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpwt030263; Fri, 8 May 2020 09:54:03 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 09/14] iio: buffer: split buffer sysfs creation to take buffer as primary arg Date: Fri, 8 May 2020 16:53:43 +0300 Message-ID: <20200508135348.15229-10-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 mlxlogscore=999 lowpriorityscore=0 phishscore=0 clxscore=1015 mlxscore=0 bulkscore=0 malwarescore=0 suspectscore=2 adultscore=0 spamscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080123 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Currently the iio_buffer_{alloc,free}_sysfs_and_mask() take 'indio_dev' as primary argument. This change converts to take an IIO buffer as a primary argument. That will allow the functions to get called for multiple buffers. Signed-off-by: Alexandru Ardelean --- drivers/iio/industrialio-buffer.c | 46 ++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index e7a847e7b103..6b1b5d5387bd 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1312,26 +1312,14 @@ static struct attribute *iio_buffer_attrs[] = { &dev_attr_data_available.attr, }; -int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) +static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) { + struct iio_dev *indio_dev = buffer->indio_dev; struct iio_dev_attr *p; struct attribute **attr; - struct iio_buffer *buffer = indio_dev->buffer; int ret, i, attrn, attrcount, attrcount_orig = 0; const struct iio_chan_spec *channels; - channels = indio_dev->channels; - if (channels) { - int ml = indio_dev->masklength; - - for (i = 0; i < indio_dev->num_channels; i++) - ml = max(ml, channels[i].scan_index + 1); - indio_dev->masklength = ml; - } - - if (!buffer) - return 0; - attrcount = 0; if (buffer->attrs) { while (buffer->attrs[attrcount] != NULL) @@ -1411,19 +1399,45 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) return ret; } -void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) +int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) { struct iio_buffer *buffer = indio_dev->buffer; + const struct iio_chan_spec *channels; + int i; + + channels = indio_dev->channels; + if (channels) { + int ml = indio_dev->masklength; + + for (i = 0; i < indio_dev->num_channels; i++) + ml = max(ml, channels[i].scan_index + 1); + indio_dev->masklength = ml; + } if (!buffer) - return; + return 0; + + return __iio_buffer_alloc_sysfs_and_mask(buffer); +} +static void __iio_buffer_free_sysfs_and_mask(struct iio_buffer *buffer) +{ iio_buffer_free_scanmask(buffer); kfree(buffer->buffer_group.attrs); kfree(buffer->scan_el_group.attrs); iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); } +void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer = indio_dev->buffer; + + if (!buffer) + return; + + __iio_buffer_free_sysfs_and_mask(buffer); +} + static const struct file_operations iio_buffer_fileops = { .read = iio_buffer_read_outer, .release = iio_buffer_chrdev_release, From patchwork Fri May 8 13:53:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536641 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 9C8BB14C0 for ; Fri, 8 May 2020 13:54:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8BA5B20708 for ; Fri, 8 May 2020 13:54:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728371AbgEHNyV (ORCPT ); Fri, 8 May 2020 09:54:21 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:52286 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728353AbgEHNyU (ORCPT ); Fri, 8 May 2020 09:54:20 -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 048Dib8J031165; Fri, 8 May 2020 09:54:09 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtef2j64-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:08 -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 048Ds7aP040856 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:07 -0400 Received: from SCSQMBX11.ad.analog.com (10.77.17.10) 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; Fri, 8 May 2020 06:54:06 -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; Fri, 8 May 2020 06:54:05 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpwu030263; Fri, 8 May 2020 09:54:04 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 10/14] iio: buffer: remove attrcount_orig var from sysfs creation Date: Fri, 8 May 2020 16:53:44 +0300 Message-ID: <20200508135348.15229-11-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 suspectscore=2 clxscore=1015 phishscore=0 mlxlogscore=999 adultscore=0 mlxscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080122 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org The variable no longer does anything. It's around because of some older code that required it to keep track of certain attribute numbers. Signed-off-by: Alexandru Ardelean --- drivers/iio/industrialio-buffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 6b1b5d5387bd..efebf74a05af 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1317,7 +1317,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) struct iio_dev *indio_dev = buffer->indio_dev; struct iio_dev_attr *p; struct attribute **attr; - int ret, i, attrn, attrcount, attrcount_orig = 0; + int ret, i, attrn, attrcount; const struct iio_chan_spec *channels; attrcount = 0; @@ -1349,7 +1349,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) indio_dev->groups[indio_dev->groupcounter++] = &buffer->buffer_group; - attrcount = attrcount_orig; + attrcount = 0; INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list); channels = indio_dev->channels; if (channels) { @@ -1382,7 +1382,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) ret = -ENOMEM; goto error_free_scan_mask; } - attrn = attrcount_orig; + attrn = 0; list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l) buffer->scan_el_group.attrs[attrn++] = &p->dev_attr.attr; From patchwork Fri May 8 13:53:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536647 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 B1C5514C0 for ; Fri, 8 May 2020 13:54:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9ABD320708 for ; Fri, 8 May 2020 13:54:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728418AbgEHNyY (ORCPT ); Fri, 8 May 2020 09:54:24 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:53496 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728366AbgEHNyW (ORCPT ); Fri, 8 May 2020 09:54:22 -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 048Dqt4H016877; Fri, 8 May 2020 09:54:09 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtek2gd1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:09 -0400 Received: from ASHBMBX9.ad.analog.com (ashbmbx9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 048Ds8OV040859 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:08 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 8 May 2020 09:54:07 -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, 8 May 2020 09:54:06 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpwv030263; Fri, 8 May 2020 09:54:05 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 11/14] iio: buffer: add underlying device object and convert buffers to devices Date: Fri, 8 May 2020 16:53:45 +0300 Message-ID: <20200508135348.15229-12-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 mlxlogscore=999 lowpriorityscore=0 phishscore=0 clxscore=1015 mlxscore=0 bulkscore=0 malwarescore=0 suspectscore=2 adultscore=0 spamscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080123 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org WIP Currently, IIO is broken here. Each buffer is now an object. The part where this is broken is backwards compatibility. We need to: - convert all external buffer attributes to unpack to IIO buffers and not IIO devices - symlink the 'scan_elements' folder of the (first) IIO buffer device to the IIO device - symlink the chardev of the first IIO buffer device to the IIO device Signed-off-by: Alexandru Ardelean --- drivers/iio/iio_core.h | 11 ++-- drivers/iio/industrialio-buffer.c | 98 ++++++++++++++++++++++++------- drivers/iio/industrialio-core.c | 39 +++++++----- include/linux/iio/buffer_impl.h | 6 ++ include/linux/iio/iio.h | 2 +- 5 files changed, 116 insertions(+), 40 deletions(-) diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h index f68de4af2738..890577766f9b 100644 --- a/drivers/iio/iio_core.h +++ b/drivers/iio/iio_core.h @@ -54,10 +54,13 @@ ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals); #ifdef CONFIG_IIO_BUFFER struct poll_table_struct; +int iio_device_alloc_chrdev_id(struct device *dev); +void iio_device_free_chrdev_id(struct device *dev); + void iio_device_buffer_attach_chrdev(struct iio_dev *indio_dev); -int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev); -void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev); +int iio_device_buffers_init(struct iio_dev *indio_dev); +void iio_device_buffers_cleanup(struct iio_dev *indio_dev); void iio_device_buffers_put(struct iio_dev *indio_dev); @@ -68,12 +71,12 @@ void iio_buffer_wakeup_poll(struct iio_dev *indio_dev); static inline void iio_device_buffer_attach_chrdev(struct iio_dev *indio_dev) {} -static inline int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) +static inline int iio_device_buffers_init(struct iio_dev *indio_dev) { return 0; } -static inline void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) {} +static inline void iio_device_buffers_cleanup(struct iio_dev *indio_dev) {} static inline void iio_device_buffers_put(struct iio_dev *indio_dev) {} diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index efebf74a05af..6c35de7ebd9e 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1235,8 +1235,6 @@ static ssize_t iio_buffer_store_enable(struct device *dev, return (ret < 0) ? ret : len; } -static const char * const iio_scan_elements_group_name = "scan_elements"; - static ssize_t iio_buffer_show_watermark(struct device *dev, struct device_attribute *attr, char *buf) @@ -1312,7 +1310,7 @@ static struct attribute *iio_buffer_attrs[] = { &dev_attr_data_available.attr, }; -static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) +static int iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) { struct iio_dev *indio_dev = buffer->indio_dev; struct iio_dev_attr *p; @@ -1344,10 +1342,9 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) attr[attrcount + ARRAY_SIZE(iio_buffer_attrs)] = NULL; - buffer->buffer_group.name = "buffer"; buffer->buffer_group.attrs = attr; - indio_dev->groups[indio_dev->groupcounter++] = &buffer->buffer_group; + buffer->groups[0] = &buffer->buffer_group; attrcount = 0; INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list); @@ -1373,7 +1370,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) goto error_cleanup_dynamic; } - buffer->scan_el_group.name = iio_scan_elements_group_name; + buffer->scan_el_group.name = "scan_elements"; buffer->scan_el_group.attrs = kcalloc(attrcount + 1, sizeof(buffer->scan_el_group.attrs[0]), @@ -1386,7 +1383,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l) buffer->scan_el_group.attrs[attrn++] = &p->dev_attr.attr; - indio_dev->groups[indio_dev->groupcounter++] = &buffer->scan_el_group; + buffer->groups[1] = &buffer->scan_el_group; return 0; @@ -1399,11 +1396,66 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) return ret; } -int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) +static void iio_buffer_free_sysfs_and_mask(struct iio_buffer *buffer) +{ + iio_buffer_free_scanmask(buffer); + kfree(buffer->buffer_group.attrs); + kfree(buffer->scan_el_group.attrs); + iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); +} + +static int iio_device_buffer_init(struct iio_dev *indio_dev, + struct iio_buffer *buffer, + int index) +{ + int ret; + + ret = iio_buffer_alloc_sysfs_and_mask(buffer); + if (ret) + return ret; + + ret = iio_device_alloc_chrdev_id(&buffer->dev); + if (ret) + goto error_free_sysfs_and_mask; + + buffer->dev.parent = &indio_dev->dev; + buffer->dev.groups = buffer->groups; + buffer->dev.bus = &iio_bus_type; + device_initialize(&buffer->dev); + + dev_set_name(&buffer->dev, "iio:buffer%d:%d", + indio_dev->id, index); + + ret = cdev_device_add(&buffer->chrdev, &buffer->dev); + if (ret) + goto error_free_chrdev_id; + + return 0; + +error_free_chrdev_id: + iio_device_free_chrdev_id(&buffer->dev); +error_free_sysfs_and_mask: + iio_buffer_free_sysfs_and_mask(buffer); + return ret; +} + +void iio_device_buffer_cleanup(struct iio_buffer *buffer) +{ + if (!buffer) + return; + + iio_buffer_free_sysfs_and_mask(buffer); + + cdev_device_del(&buffer->chrdev, &buffer->dev); + + iio_device_free_chrdev_id(&buffer->dev); +} + +int iio_device_buffers_init(struct iio_dev *indio_dev) { struct iio_buffer *buffer = indio_dev->buffer; const struct iio_chan_spec *channels; - int i; + int i, ret; channels = indio_dev->channels; if (channels) { @@ -1417,25 +1469,29 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) if (!buffer) return 0; - return __iio_buffer_alloc_sysfs_and_mask(buffer); -} + ret = iio_device_buffer_init(indio_dev, buffer, 0); + if (ret) + return ret; -static void __iio_buffer_free_sysfs_and_mask(struct iio_buffer *buffer) -{ - iio_buffer_free_scanmask(buffer); - kfree(buffer->buffer_group.attrs); - kfree(buffer->scan_el_group.attrs); - iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); + ret = sysfs_create_link(&indio_dev->dev.kobj, + &buffer->dev.kobj, "buffer"); + if (ret) + goto error_cleanup_buffers; + + return 0; + +error_cleanup_buffers: + iio_device_buffer_cleanup(buffer); + return 0; } -void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) +void iio_device_buffers_cleanup(struct iio_dev *indio_dev) { struct iio_buffer *buffer = indio_dev->buffer; - if (!buffer) - return; + sysfs_remove_link(&indio_dev->dev.kobj, "buffer"); - __iio_buffer_free_sysfs_and_mask(buffer); + iio_device_buffer_cleanup(buffer); } static const struct file_operations iio_buffer_fileops = { diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 5df3af5e7dcb..b27fabf13e9c 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1638,7 +1638,7 @@ static int iio_check_unique_scan_index(struct iio_dev *indio_dev) return 0; } -static int iio_device_alloc_chrdev_id(struct device *dev) +int iio_device_alloc_chrdev_id(struct device *dev) { int id; @@ -1654,7 +1654,7 @@ static int iio_device_alloc_chrdev_id(struct device *dev) return 0; } -static void iio_device_free_chrdev_id(struct device *dev) +void iio_device_free_chrdev_id(struct device *dev) { if (!dev->devt) return; @@ -1684,18 +1684,11 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) iio_device_register_debugfs(indio_dev); - ret = iio_buffer_alloc_sysfs_and_mask(indio_dev); - if (ret) { - dev_err(indio_dev->dev.parent, - "Failed to create buffer sysfs interfaces\n"); - goto error_unreg_debugfs; - } - ret = iio_device_register_sysfs(indio_dev); if (ret) { dev_err(indio_dev->dev.parent, "Failed to register sysfs interfaces\n"); - goto error_buffer_free_sysfs; + goto error_unreg_debugfs; } ret = iio_device_register_eventset(indio_dev); if (ret) { @@ -1712,6 +1705,26 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) iio_device_buffer_attach_chrdev(indio_dev); + if (indio_dev->chrdev) { + ret = device_add(&indio_dev->dev); + + if (ret) { + put_device(&indio_dev->dev); + goto error_unreg_eventset; + } + + ret = iio_device_buffers_init(indio_dev); + if (ret) { + device_del(&indio_dev->dev); + + dev_err(indio_dev->dev.parent, + "Failed to create buffer sysfs interfaces\n"); + goto error_unreg_eventset; + } + + return 0; + } + /* No chrdev attached from buffer, we go with event-only chrdev */ if (!indio_dev->chrdev) iio_device_event_attach_chrdev(indio_dev); @@ -1736,8 +1749,6 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) iio_device_unregister_eventset(indio_dev); error_free_sysfs: iio_device_unregister_sysfs(indio_dev); -error_buffer_free_sysfs: - iio_buffer_free_sysfs_and_mask(indio_dev); error_unreg_debugfs: iio_device_unregister_debugfs(indio_dev); return ret; @@ -1752,6 +1763,8 @@ void iio_device_unregister(struct iio_dev *indio_dev) { struct iio_ioctl_handler *h, *t; + iio_device_buffers_cleanup(indio_dev); + cdev_device_del(indio_dev->chrdev, &indio_dev->dev); iio_device_free_chrdev_id(&indio_dev->dev); @@ -1770,8 +1783,6 @@ void iio_device_unregister(struct iio_dev *indio_dev) iio_buffer_wakeup_poll(indio_dev); mutex_unlock(&indio_dev->info_exist_lock); - - iio_buffer_free_sysfs_and_mask(indio_dev); } EXPORT_SYMBOL(iio_device_unregister); diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h index 46fc977deae3..eca3fe630230 100644 --- a/include/linux/iio/buffer_impl.h +++ b/include/linux/iio/buffer_impl.h @@ -104,6 +104,12 @@ struct iio_buffer { unsigned int watermark; /* private: */ + /* @dev: underlying device object. */ + struct device dev; + +#define IIO_BUFFER_MAX_GROUP 2 + const struct attribute_group *groups[IIO_BUFFER_MAX_GROUP + 1]; + /* @scan_timestamp: Does the scan mode include a timestamp. */ bool scan_timestamp; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index b6ca8d85629e..671f5818fa67 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -561,7 +561,7 @@ struct iio_dev { struct mutex info_exist_lock; const struct iio_buffer_setup_ops *setup_ops; struct cdev *chrdev; -#define IIO_MAX_GROUPS 6 +#define IIO_MAX_GROUPS 5 const struct attribute_group *groups[IIO_MAX_GROUPS + 1]; int groupcounter; From patchwork Fri May 8 13:53:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536645 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 CD50381 for ; Fri, 8 May 2020 13:54:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BA48620708 for ; Fri, 8 May 2020 13:54:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727769AbgEHNy0 (ORCPT ); Fri, 8 May 2020 09:54:26 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:57460 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728385AbgEHNyZ (ORCPT ); Fri, 8 May 2020 09:54:25 -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 048Diipe006142; Fri, 8 May 2020 09:54:12 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtef2j6d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:12 -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 048DsAJ0040868 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:11 -0400 Received: from SCSQCASHYB7.ad.analog.com (10.77.17.133) 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; Fri, 8 May 2020 06:54:09 -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; Fri, 8 May 2020 06:54:09 -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; Fri, 8 May 2020 06:54:09 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpww030263; Fri, 8 May 2020 09:54:06 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 12/14] iio: buffer: symlink the scan_elements dir back into IIO device's dir Date: Fri, 8 May 2020 16:53:46 +0300 Message-ID: <20200508135348.15229-13-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 suspectscore=2 clxscore=1015 phishscore=0 mlxlogscore=999 adultscore=0 mlxscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080122 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org WIP Need to explicitly create the scan_elements dir to symlink it. Admittedly we could try to use some kernfs logic to dig out the kobject of the 'scan_elements' group, it doesn't seem to be done outside of the fs/ kernel directory. We need to use the sysfs_() function suite, and that means creating it by hand after the IIO buffer device was created and added so that we have a parent kobject to attach this folder to. After we create it by hand there is a kobject to which to symlink this to back to the IIO device. IIO still broken What's left: - convert all external buffer attributes to unpack to IIO buffers and not IIO devices - symlink the chardev of the first IIO buffer device to the IIO device Signed-off-by: Alexandru Ardelean --- drivers/iio/industrialio-buffer.c | 149 ++++++++++++++++++++++++------ include/linux/iio/buffer_impl.h | 7 +- 2 files changed, 122 insertions(+), 34 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 6c35de7ebd9e..b14281442387 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1310,15 +1310,11 @@ static struct attribute *iio_buffer_attrs[] = { &dev_attr_data_available.attr, }; -static int iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) +static int iio_buffer_alloc_sysfs(struct iio_buffer *buffer) { - struct iio_dev *indio_dev = buffer->indio_dev; - struct iio_dev_attr *p; struct attribute **attr; - int ret, i, attrn, attrcount; - const struct iio_chan_spec *channels; + int attrcount = 0; - attrcount = 0; if (buffer->attrs) { while (buffer->attrs[attrcount] != NULL) attrcount++; @@ -1346,7 +1342,60 @@ static int iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) buffer->groups[0] = &buffer->buffer_group; - attrcount = 0; + return 0; +} + +static ssize_t iio_scan_el_dir_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct device_attribute *dattr = + container_of(attr, struct device_attribute, attr); + struct iio_buffer *buffer = + container_of(kobj, struct iio_buffer, scan_el_dir); + + if (!dattr->show) + return -EIO; + + return dattr->show(&buffer->dev, dattr, buf); +} + +static ssize_t iio_scan_el_dir_store(struct kobject *kobj, + struct attribute *attr, + const char *buf, size_t len) +{ + struct device_attribute *dattr = + container_of(attr, struct device_attribute, attr); + struct iio_buffer *buffer = + container_of(kobj, struct iio_buffer, scan_el_dir); + + if (!dattr->store) + return -EIO; + + return dattr->store(&buffer->dev, dattr, buf, len); +} + +static struct sysfs_ops iio_scan_el_dir_ops = { + .show = iio_scan_el_dir_show, + .store = iio_scan_el_dir_store, +}; + +static void iio_buffer_dir_noop_release(struct kobject *kobj) +{ + /* nothing to do yet */ +} + +static struct kobj_type iio_scan_el_dir_ktype = { + .release = iio_buffer_dir_noop_release, + .sysfs_ops = &iio_scan_el_dir_ops, +}; + +static int iio_buffer_alloc_scan_sysfs(struct iio_buffer *buffer) +{ + struct iio_dev *indio_dev = buffer->indio_dev; + struct iio_dev_attr *p; + int ret, i; + const struct iio_chan_spec *channels; + INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list); channels = indio_dev->channels; if (channels) { @@ -1359,7 +1408,6 @@ static int iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) &channels[i]); if (ret < 0) goto error_cleanup_dynamic; - attrcount += ret; if (channels[i].type == IIO_TIMESTAMP) indio_dev->scan_index_timestamp = channels[i].scan_index; @@ -1370,37 +1418,52 @@ static int iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer) goto error_cleanup_dynamic; } - buffer->scan_el_group.name = "scan_elements"; - - buffer->scan_el_group.attrs = kcalloc(attrcount + 1, - sizeof(buffer->scan_el_group.attrs[0]), - GFP_KERNEL); - if (buffer->scan_el_group.attrs == NULL) { - ret = -ENOMEM; + ret = kobject_init_and_add(&buffer->scan_el_dir, + &iio_scan_el_dir_ktype, &buffer->dev.kobj, + "scan_elements"); + if (ret) goto error_free_scan_mask; - } - attrn = 0; - list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l) - buffer->scan_el_group.attrs[attrn++] = &p->dev_attr.attr; - buffer->groups[1] = &buffer->scan_el_group; + i = 0; + list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l) { + ret = sysfs_create_file(&buffer->scan_el_dir, + &p->dev_attr.attr); + if (ret) + goto error_remove_scan_el_dir; + i++; + } return 0; +error_remove_scan_el_dir: + list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l) { + if (i == 0) + break; + sysfs_remove_file(&buffer->scan_el_dir, &p->dev_attr.attr); + i--; + } + kobject_put(&buffer->scan_el_dir); error_free_scan_mask: iio_buffer_free_scanmask(buffer); error_cleanup_dynamic: iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); - kfree(buffer->buffer_group.attrs); return ret; } -static void iio_buffer_free_sysfs_and_mask(struct iio_buffer *buffer) +static void iio_buffer_free_sysfs(struct iio_buffer *buffer) { iio_buffer_free_scanmask(buffer); kfree(buffer->buffer_group.attrs); - kfree(buffer->scan_el_group.attrs); +} + +static void iio_buffer_free_scan_sysfs(struct iio_buffer *buffer) +{ + struct iio_dev_attr *p; + + list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l) + sysfs_remove_file(&buffer->scan_el_dir, &p->dev_attr.attr); + kobject_put(&buffer->scan_el_dir); iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); } @@ -1410,7 +1473,7 @@ static int iio_device_buffer_init(struct iio_dev *indio_dev, { int ret; - ret = iio_buffer_alloc_sysfs_and_mask(buffer); + ret = iio_buffer_alloc_sysfs(buffer); if (ret) return ret; @@ -1430,12 +1493,18 @@ static int iio_device_buffer_init(struct iio_dev *indio_dev, if (ret) goto error_free_chrdev_id; + ret = iio_buffer_alloc_scan_sysfs(buffer); + if (ret) + goto error_cdev_device_del; + return 0; +error_cdev_device_del: + cdev_device_del(&buffer->chrdev, &buffer->dev); error_free_chrdev_id: iio_device_free_chrdev_id(&buffer->dev); error_free_sysfs_and_mask: - iio_buffer_free_sysfs_and_mask(buffer); + iio_buffer_free_sysfs(buffer); return ret; } @@ -1444,13 +1513,33 @@ void iio_device_buffer_cleanup(struct iio_buffer *buffer) if (!buffer) return; - iio_buffer_free_sysfs_and_mask(buffer); + iio_buffer_free_scan_sysfs(buffer); cdev_device_del(&buffer->chrdev, &buffer->dev); + iio_buffer_free_sysfs(buffer); + iio_device_free_chrdev_id(&buffer->dev); } +static int iio_device_link_legacy_folders(struct iio_dev *indio_dev, + struct iio_buffer *buffer) +{ + int ret; + + ret = sysfs_create_link(&indio_dev->dev.kobj, + &buffer->dev.kobj, "buffer"); + if (ret) + return ret; + + ret = sysfs_create_link(&indio_dev->dev.kobj, + &buffer->scan_el_dir, "scan_elements"); + if (ret) + sysfs_remove_link(&indio_dev->dev.kobj, "buffer"); + + return ret; +} + int iio_device_buffers_init(struct iio_dev *indio_dev) { struct iio_buffer *buffer = indio_dev->buffer; @@ -1473,14 +1562,13 @@ int iio_device_buffers_init(struct iio_dev *indio_dev) if (ret) return ret; - ret = sysfs_create_link(&indio_dev->dev.kobj, - &buffer->dev.kobj, "buffer"); + ret = iio_device_link_legacy_folders(indio_dev, buffer); if (ret) - goto error_cleanup_buffers; + goto error_buffers_cleanup; return 0; -error_cleanup_buffers: +error_buffers_cleanup: iio_device_buffer_cleanup(buffer); return 0; } @@ -1490,6 +1578,7 @@ void iio_device_buffers_cleanup(struct iio_dev *indio_dev) struct iio_buffer *buffer = indio_dev->buffer; sysfs_remove_link(&indio_dev->dev.kobj, "buffer"); + sysfs_remove_link(&indio_dev->dev.kobj, "scan_elements"); iio_device_buffer_cleanup(buffer); } diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h index eca3fe630230..e8203b6d51a1 100644 --- a/include/linux/iio/buffer_impl.h +++ b/include/linux/iio/buffer_impl.h @@ -107,7 +107,7 @@ struct iio_buffer { /* @dev: underlying device object. */ struct device dev; -#define IIO_BUFFER_MAX_GROUP 2 +#define IIO_BUFFER_MAX_GROUP 1 const struct attribute_group *groups[IIO_BUFFER_MAX_GROUP + 1]; /* @scan_timestamp: Does the scan mode include a timestamp. */ @@ -120,10 +120,9 @@ struct iio_buffer { struct attribute_group buffer_group; /* - * @scan_el_group: Attribute group for those attributes not - * created from the iio_chan_info array. + * @scan_el_dir: kobject for the 'scan_elements' directory */ - struct attribute_group scan_el_group; + struct kobject scan_el_dir; /* @attrs: Standard attributes of the buffer. */ const struct attribute **attrs; From patchwork Fri May 8 13:53:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536643 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 63AEC81 for ; Fri, 8 May 2020 13:54:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4C76120708 for ; Fri, 8 May 2020 13:54:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728427AbgEHNy0 (ORCPT ); Fri, 8 May 2020 09:54:26 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:57678 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728390AbgEHNyZ (ORCPT ); Fri, 8 May 2020 09:54:25 -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 048Dib8K031165; Fri, 8 May 2020 09:54:12 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtef2j6c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:12 -0400 Received: from ASHBMBX9.ad.analog.com (ashbmbx9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 048DsBvm040869 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:11 -0400 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 8 May 2020 09:54:10 -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, 8 May 2020 09:54:10 -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, 8 May 2020 09:54:10 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpwx030263; Fri, 8 May 2020 09:54:07 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 13/14] iio: unpack all iio buffer attributes correctly Date: Fri, 8 May 2020 16:53:47 +0300 Message-ID: <20200508135348.15229-14-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 suspectscore=0 clxscore=1015 phishscore=0 mlxlogscore=999 adultscore=0 mlxscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080122 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org WIP This change fixes how IIO buffer attributes get unpacked. There could be a saner way to unpack these without needed to change the drivers that attach buffer attributes incorrectly via iio_buffer_set_attrs() It seems that the design idea was that there is a single buffer per IIO device, so all drivers attached buffer attributes for FIFO to the IIO buffer. Now with the change to add a device object to the IIO buffer, and shifting around the device-attributes, a 'device' object unpacks to an IIO buffer object, which needs some special handling.' One idea to fix this, is to get rid of iio_buffer_set_attrs() somehow. Or, to maybe allocate some wrapper device-attributes. With this change, IIO still needs (to work with the older ABI): - symlink the chardev of the first IIO buffer device to the IIO device Signed-off-by: Alexandru Ardelean --- drivers/iio/accel/adxl372.c | 6 ++- drivers/iio/accel/bmc150-accel-core.c | 6 ++- .../buffer/industrialio-buffer-dmaengine.c | 4 +- drivers/iio/industrialio-buffer.c | 51 +++++++++++-------- include/linux/iio/buffer.h | 3 ++ 5 files changed, 42 insertions(+), 28 deletions(-) diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index 60daf04ce188..528bce008671 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c @@ -745,7 +745,8 @@ static ssize_t adxl372_get_fifo_enabled(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_buffer *buffer = dev_to_iio_buffer(dev); + struct iio_dev *indio_dev = iio_buffer_get_attached_iio_dev(buffer); struct adxl372_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", st->fifo_mode); @@ -755,7 +756,8 @@ static ssize_t adxl372_get_fifo_watermark(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_buffer *buffer = dev_to_iio_buffer(dev); + struct iio_dev *indio_dev = iio_buffer_get_attached_iio_dev(buffer); struct adxl372_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", st->watermark); diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 121b4e89f038..c02287165980 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -763,7 +763,8 @@ static ssize_t bmc150_accel_get_fifo_watermark(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_buffer *buffer = dev_to_iio_buffer(dev); + struct iio_dev *indio_dev = iio_buffer_get_attached_iio_dev(buffer); struct bmc150_accel_data *data = iio_priv(indio_dev); int wm; @@ -778,7 +779,8 @@ static ssize_t bmc150_accel_get_fifo_state(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_buffer *buffer = dev_to_iio_buffer(dev); + struct iio_dev *indio_dev = iio_buffer_get_attached_iio_dev(buffer); struct bmc150_accel_data *data = iio_priv(indio_dev); bool state; diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 6dedf12b69a4..7728fdadcc3e 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -130,9 +130,9 @@ static const struct iio_dma_buffer_ops iio_dmaengine_default_ops = { static ssize_t iio_dmaengine_buffer_get_length_align(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_buffer *buffer = dev_to_iio_buffer(dev); struct dmaengine_buffer *dmaengine_buffer = - iio_buffer_to_dmaengine_buffer(indio_dev->buffer); + iio_buffer_to_dmaengine_buffer(buffer); return sprintf(buf, "%zu\n", dmaengine_buffer->align); } diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index b14281442387..aa2f46c0949f 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -29,6 +29,19 @@ static const char * const iio_endian_prefix[] = { [IIO_LE] = "le", }; +struct iio_buffer *dev_to_iio_buffer(struct device *dev) +{ + return container_of(dev, struct iio_buffer, dev); +} +EXPORT_SYMBOL_GPL(dev_to_iio_buffer); + +struct iio_dev *iio_buffer_get_attached_iio_dev(struct iio_buffer *buffer) +{ + return buffer ? NULL : buffer->indio_dev; +} +EXPORT_SYMBOL_GPL(iio_buffer_get_attached_iio_dev); + + static bool iio_buffer_is_active(struct iio_buffer *buf) { return !list_empty(&buf->buffer_list); @@ -324,9 +337,8 @@ static ssize_t iio_scan_el_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct iio_buffer *buffer = dev_to_iio_buffer(dev); int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; /* Ensure ret is 0 or 1. */ ret = !!test_bit(to_iio_dev_attr(attr)->address, @@ -436,10 +448,10 @@ static ssize_t iio_scan_el_store(struct device *dev, const char *buf, size_t len) { + struct iio_buffer *buffer = dev_to_iio_buffer(dev); + struct iio_dev *indio_dev = buffer->indio_dev; int ret; bool state; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = strtobool(buf, &state); @@ -474,8 +486,7 @@ static ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; + struct iio_buffer *buffer = dev_to_iio_buffer(dev); return sprintf(buf, "%d\n", buffer->scan_timestamp); } @@ -485,9 +496,9 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, const char *buf, size_t len) { + struct iio_buffer *buffer = dev_to_iio_buffer(dev); + struct iio_dev *indio_dev = buffer->indio_dev; int ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; bool state; ret = strtobool(buf, &state); @@ -563,8 +574,7 @@ static ssize_t iio_buffer_read_length(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; + struct iio_buffer *buffer = dev_to_iio_buffer(dev); return sprintf(buf, "%d\n", buffer->length); } @@ -573,8 +583,8 @@ static ssize_t iio_buffer_write_length(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; + struct iio_buffer *buffer = dev_to_iio_buffer(dev); + struct iio_dev *indio_dev = buffer->indio_dev; unsigned int val; int ret; @@ -606,8 +616,7 @@ static ssize_t iio_buffer_show_enable(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; + struct iio_buffer *buffer = dev_to_iio_buffer(dev); return sprintf(buf, "%d\n", iio_buffer_is_active(buffer)); } @@ -1207,10 +1216,10 @@ static ssize_t iio_buffer_store_enable(struct device *dev, const char *buf, size_t len) { + struct iio_buffer *buffer = dev_to_iio_buffer(dev); + struct iio_dev *indio_dev = buffer->indio_dev; int ret; bool requested_state; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; bool inlist; ret = strtobool(buf, &requested_state); @@ -1239,8 +1248,7 @@ static ssize_t iio_buffer_show_watermark(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; + struct iio_buffer *buffer = dev_to_iio_buffer(dev); return sprintf(buf, "%u\n", buffer->watermark); } @@ -1250,8 +1258,8 @@ static ssize_t iio_buffer_store_watermark(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; + struct iio_buffer *buffer = dev_to_iio_buffer(dev); + struct iio_dev *indio_dev = buffer->indio_dev; unsigned int val; int ret; @@ -1284,8 +1292,7 @@ static ssize_t iio_dma_show_data_available(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; + struct iio_buffer *buffer = dev_to_iio_buffer(dev); return sprintf(buf, "%zu\n", iio_buffer_data_available(buffer)); } diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index fbba4093f06c..a688e98c694c 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -11,6 +11,9 @@ struct iio_buffer; +struct iio_buffer *dev_to_iio_buffer(struct device *dev); +struct iio_dev *iio_buffer_get_attached_iio_dev(struct iio_buffer *buffer); + void iio_buffer_set_attrs(struct iio_buffer *buffer, const struct attribute **attrs); From patchwork Fri May 8 13:53:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Ardelean X-Patchwork-Id: 11536649 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 7FDD714C0 for ; Fri, 8 May 2020 13:54:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6E34020708 for ; Fri, 8 May 2020 13:54:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728535AbgEHNym (ORCPT ); Fri, 8 May 2020 09:54:42 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:57498 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728387AbgEHNyY (ORCPT ); Fri, 8 May 2020 09:54:24 -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 048Dqt9C016870; Fri, 8 May 2020 09:54:12 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30vtek2gd6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 09:54:12 -0400 Received: from ASHBMBX9.ad.analog.com (ashbmbx9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 048DsBT8040872 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 8 May 2020 09:54:11 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 8 May 2020 09:54:10 -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, 8 May 2020 09:54:10 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 048Drpx0030263; Fri, 8 May 2020 09:54:09 -0400 From: Alexandru Ardelean To: , CC: , , Alexandru Ardelean Subject: [RFC PATCH 14/14] iio: buffer: convert single buffer to list of buffers Date: Fri, 8 May 2020 16:53:48 +0300 Message-ID: <20200508135348.15229-15-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com> References: <20200508135348.15229-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-08_13:2020-05-08,2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 mlxlogscore=777 lowpriorityscore=0 phishscore=0 clxscore=1015 mlxscore=0 bulkscore=0 malwarescore=0 suspectscore=0 adultscore=0 spamscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005080123 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org WIP Time to add support for multiple buffers. At this point it should be just managing a list. Signed-off-by: Alexandru Ardelean --- drivers/iio/industrialio-buffer.c | 74 ++++++++++++++++++++++--------- drivers/iio/industrialio-core.c | 1 + include/linux/iio/buffer_impl.h | 3 ++ include/linux/iio/iio.h | 2 + 4 files changed, 58 insertions(+), 22 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index aa2f46c0949f..c335484a6651 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -244,12 +244,13 @@ static int iio_buffer_chrdev_release(struct inode *inode, struct file *filp) */ void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) { - struct iio_buffer *buffer = indio_dev->buffer; + struct iio_buffer *b; - if (!buffer) + if (list_empty(&indio_dev->attached_buffers)) return; - wake_up(&buffer->pollq); + list_for_each_entry(b, &indio_dev->attached_buffers, attached_entry) + wake_up(&b->pollq); } void iio_buffer_init(struct iio_buffer *buffer) @@ -1547,10 +1548,27 @@ static int iio_device_link_legacy_folders(struct iio_dev *indio_dev, return ret; } +static void __iio_device_buffers_cleanup(struct iio_dev *indio_dev, int idx) +{ + struct iio_buffer *b; + + if (list_empty(&indio_dev->attached_buffers)) + return; + + list_for_each_entry(b, &indio_dev->attached_buffers, attached_entry) { + if (idx == 0) + break; + + iio_device_buffer_cleanup(b); + if (idx > 0) + idx--; + } +} + int iio_device_buffers_init(struct iio_dev *indio_dev) { - struct iio_buffer *buffer = indio_dev->buffer; const struct iio_chan_spec *channels; + struct iio_buffer *b; int i, ret; channels = indio_dev->channels; @@ -1562,32 +1580,38 @@ int iio_device_buffers_init(struct iio_dev *indio_dev) indio_dev->masklength = ml; } - if (!buffer) + if (list_empty(&indio_dev->attached_buffers)) return 0; - ret = iio_device_buffer_init(indio_dev, buffer, 0); - if (ret) - return ret; + i = 0; + list_for_each_entry(b, &indio_dev->attached_buffers, attached_entry) { + ret = iio_device_buffer_init(indio_dev, b, i); + if (ret) + goto error_buffers_cleanup; - ret = iio_device_link_legacy_folders(indio_dev, buffer); - if (ret) - goto error_buffers_cleanup; + if (i == 0) { + ret = iio_device_link_legacy_folders(indio_dev, b); + if (ret) { + iio_device_buffer_cleanup(b); + goto error_buffers_cleanup; + } + } + i++; + } return 0; error_buffers_cleanup: - iio_device_buffer_cleanup(buffer); - return 0; + __iio_device_buffers_cleanup(indio_dev, i); + return ret; } void iio_device_buffers_cleanup(struct iio_dev *indio_dev) { - struct iio_buffer *buffer = indio_dev->buffer; - sysfs_remove_link(&indio_dev->dev.kobj, "buffer"); sysfs_remove_link(&indio_dev->dev.kobj, "scan_elements"); - iio_device_buffer_cleanup(buffer); + __iio_device_buffers_cleanup(indio_dev, -1); } static const struct file_operations iio_buffer_fileops = { @@ -1615,12 +1639,13 @@ void iio_device_buffer_attach_chrdev(struct iio_dev *indio_dev) void iio_device_buffers_put(struct iio_dev *indio_dev) { - struct iio_buffer *buffer = indio_dev->buffer; + struct iio_buffer *b; - if (!buffer) + if (list_empty(&indio_dev->attached_buffers)) return; - iio_buffer_put(buffer); + list_for_each_entry(b, &indio_dev->attached_buffers, attached_entry) + iio_buffer_put(b); } /** @@ -1733,7 +1758,7 @@ void iio_buffer_put(struct iio_buffer *buffer) EXPORT_SYMBOL_GPL(iio_buffer_put); /** - * iio_device_attach_buffer - Attach a buffer to a IIO device + * iio_device_attach_buffer_dir - Attach a buffer to a IIO device direction * @indio_dev: The device the buffer should be attached to * @buffer: The buffer to attach to the device * @@ -1744,8 +1769,13 @@ EXPORT_SYMBOL_GPL(iio_buffer_put); void iio_device_attach_buffer(struct iio_dev *indio_dev, struct iio_buffer *buffer) { - indio_dev->buffer = iio_buffer_get(buffer); + buffer = iio_buffer_get(buffer); + buffer->indio_dev = indio_dev; + + /* keep this for legacy */ + if (!indio_dev->buffer) + indio_dev->buffer = buffer; - indio_dev->buffer->indio_dev = indio_dev; + list_add_tail(&buffer->attached_entry, &indio_dev->attached_buffers); } EXPORT_SYMBOL_GPL(iio_device_attach_buffer); diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index b27fabf13e9c..067e5de76b6c 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1534,6 +1534,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) } dev_set_name(&dev->dev, "iio:device%d", dev->id); INIT_LIST_HEAD(&dev->buffer_list); + INIT_LIST_HEAD(&dev->attached_buffers); INIT_LIST_HEAD(&dev->ioctl_handlers); return dev; diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h index e8203b6d51a1..9ee3a7c0a657 100644 --- a/include/linux/iio/buffer_impl.h +++ b/include/linux/iio/buffer_impl.h @@ -130,6 +130,9 @@ struct iio_buffer { /* @demux_bounce: Buffer for doing gather from incoming scan. */ void *demux_bounce; + /* @attached_buffers: Entry in the devices list of attached buffers. */ + struct list_head attached_entry; + /* @buffer_list: Entry in the devices list of current buffers. */ struct list_head buffer_list; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 671f5818fa67..32ba1a303454 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -492,6 +492,7 @@ struct iio_buffer_setup_ops { * @event_interface: [INTERN] event chrdevs associated with interrupt lines * @buffer: [DRIVER] any buffer present * @buffer_list: [INTERN] list of all buffers currently attached + * @attached_buffers: [INTERN] list of all attached buffers * @scan_bytes: [INTERN] num bytes captured to be fed to buffer demux * @mlock: [INTERN] lock used to prevent simultaneous device state * changes @@ -536,6 +537,7 @@ struct iio_dev { struct iio_buffer *buffer; struct list_head buffer_list; + struct list_head attached_buffers; int scan_bytes; struct mutex mlock;