From patchwork Fri Apr 24 04:56: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: 11507077 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 B0EC91575 for ; Fri, 24 Apr 2020 04:56:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 98EC82076C for ; Fri, 24 Apr 2020 04:56:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725919AbgDXE4k (ORCPT ); Fri, 24 Apr 2020 00:56:40 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:38278 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725823AbgDXE4k (ORCPT ); Fri, 24 Apr 2020 00:56:40 -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 03O4qul1024418; Fri, 24 Apr 2020 00:56:24 -0400 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-00128a01.pphosted.com with ESMTP id 30fxf6csfu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 00:56:24 -0400 Received: from m0167089.ppops.net (m0167089.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 03O4tF9c030227; Fri, 24 Apr 2020 00:56:24 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30fxf6csfq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 00:56:24 -0400 Received: from ASHBMBX8.ad.analog.com (ashbmbx8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 03O4uNfR047659 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 24 Apr 2020 00:56:23 -0400 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 24 Apr 2020 00:56:22 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 24 Apr 2020 00:56:21 -0400 Received: from zeus.spd.analog.com (10.64.82.11) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.1.1779.2 via Frontend Transport; Fri, 24 Apr 2020 00:56:21 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 03O4uGpk017534; Fri, 24 Apr 2020 00:56:18 -0400 From: Alexandru Ardelean To: , CC: , , , "Jonathan Cameron" , Alexandru Ardelean Subject: [PATCH v4 1/7] iio: Use an early return in iio_device_alloc to simplify code. Date: Fri, 24 Apr 2020 07:56:36 +0300 Message-ID: <20200424045642.4903-2-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200424045642.4903-1-alexandru.ardelean@analog.com> References: <20200424045642.4903-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-04-24_01:2020-04-23,2020-04-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 spamscore=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 suspectscore=0 bulkscore=0 impostorscore=0 mlxlogscore=999 phishscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004240035 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org From: Jonathan Cameron Noticed whilst reviewing Alexandru's patch to the same function. If we simply flip the logic and return NULL immediately after memory allocation failure we reduce the indent of the following block and end up with more 'idiomatic' kernel code. Signed-off-by: Jonathan Cameron Cc: Alexandru Ardelean Reviewed-by: Alexandru Ardelean Signed-off-by: Alexandru Ardelean --- drivers/iio/industrialio-core.c | 46 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index f4daf19f2a3b..3c97090c2ab9 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1492,7 +1492,7 @@ struct device_type iio_device_type = { **/ struct iio_dev *iio_device_alloc(int sizeof_priv) { - struct iio_dev *dev; + struct iio_dev *indio_dev; size_t alloc_size; alloc_size = sizeof(struct iio_dev); @@ -1503,30 +1503,30 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) /* ensure 32-byte alignment of whole construct ? */ alloc_size += IIO_ALIGN - 1; - dev = kzalloc(alloc_size, GFP_KERNEL); - - if (dev) { - dev->dev.groups = dev->groups; - dev->dev.type = &iio_device_type; - dev->dev.bus = &iio_bus_type; - device_initialize(&dev->dev); - dev_set_drvdata(&dev->dev, (void *)dev); - mutex_init(&dev->mlock); - mutex_init(&dev->info_exist_lock); - INIT_LIST_HEAD(&dev->channel_attr_list); - - dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); - if (dev->id < 0) { - /* cannot use a dev_err as the name isn't available */ - pr_err("failed to get device id\n"); - kfree(dev); - return NULL; - } - dev_set_name(&dev->dev, "iio:device%d", dev->id); - INIT_LIST_HEAD(&dev->buffer_list); + indio_dev = kzalloc(alloc_size, GFP_KERNEL); + if (!indio_dev) + return NULL; + + indio_dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); + if (indio_dev->id < 0) { + /* cannot use a dev_err as the name isn't available */ + pr_err("failed to get device id\n"); + kfree(indio_dev); + return NULL; } - return dev; + dev_set_name(&indio_dev->dev, "iio:device%d", indio_dev->id); + indio_dev->dev.groups = indio_dev->groups; + indio_dev->dev.type = &iio_device_type; + indio_dev->dev.bus = &iio_bus_type; + device_initialize(&indio_dev->dev); + dev_set_drvdata(&indio_dev->dev, (void *)indio_dev); + mutex_init(&indio_dev->mlock); + mutex_init(&indio_dev->info_exist_lock); + INIT_LIST_HEAD(&indio_dev->channel_attr_list); + INIT_LIST_HEAD(&indio_dev->buffer_list); + + return indio_dev; } EXPORT_SYMBOL(iio_device_alloc); From patchwork Fri Apr 24 04:56: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: 11507083 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 892E71575 for ; Fri, 24 Apr 2020 04:56:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7B6A220774 for ; Fri, 24 Apr 2020 04:56:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726495AbgDXE4n (ORCPT ); Fri, 24 Apr 2020 00:56:43 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:39852 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726473AbgDXE4m (ORCPT ); Fri, 24 Apr 2020 00:56:42 -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 03O4pBJH031197; Fri, 24 Apr 2020 00:56:25 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30fud7n63t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 00:56:25 -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 03O4uN4A047662 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 24 Apr 2020 00:56:24 -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; Thu, 23 Apr 2020 21:56:22 -0700 Received: from zeus.spd.analog.com (10.64.82.11) by SCSQMBX11.ad.analog.com (10.77.17.10) with Microsoft SMTP Server id 15.1.1779.2 via Frontend Transport; Thu, 23 Apr 2020 21:56:22 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 03O4uGpl017534; Fri, 24 Apr 2020 00:56:20 -0400 From: Alexandru Ardelean To: , CC: , , , Alexandru Ardelean Subject: [PATCH v4 2/7] iio: buffer: add back-ref from iio_buffer to iio_dev Date: Fri, 24 Apr 2020 07:56:37 +0300 Message-ID: <20200424045642.4903-3-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200424045642.4903-1-alexandru.ardelean@analog.com> References: <20200424045642.4903-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-04-24_01:2020-04-23,2020-04-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxlogscore=926 priorityscore=1501 clxscore=1015 impostorscore=0 suspectscore=0 phishscore=0 mlxscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004240035 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 f8706b065247..68c276edb071 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1458,5 +1458,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 Apr 24 04:56: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: 11507091 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 DCF791575 for ; Fri, 24 Apr 2020 04:57:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CF65A20857 for ; Fri, 24 Apr 2020 04:57:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726458AbgDXE4l (ORCPT ); Fri, 24 Apr 2020 00:56:41 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:38806 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725823AbgDXE4l (ORCPT ); Fri, 24 Apr 2020 00:56:41 -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 03O4qti2023387; Fri, 24 Apr 2020 00:56:27 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30fxf6csfy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 00:56:26 -0400 Received: from SCSQMBX11.ad.analog.com (scsqmbx11.ad.analog.com [10.77.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 03O4uP8O047667 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 24 Apr 2020 00:56:25 -0400 Received: from SCSQMBX10.ad.analog.com (10.77.17.5) by SCSQMBX11.ad.analog.com (10.77.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Thu, 23 Apr 2020 21:56:24 -0700 Received: from zeus.spd.analog.com (10.64.82.11) by SCSQMBX10.ad.analog.com (10.77.17.5) with Microsoft SMTP Server id 15.1.1779.2 via Frontend Transport; Thu, 23 Apr 2020 21:56:23 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 03O4uGpm017534; Fri, 24 Apr 2020 00:56:21 -0400 From: Alexandru Ardelean To: , CC: , , , Alexandru Ardelean Subject: [PATCH v4 3/7] iio: core,buffer: wrap iio_buffer_put() call into iio_buffers_put() Date: Fri, 24 Apr 2020 07:56:38 +0300 Message-ID: <20200424045642.4903-4-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200424045642.4903-1-alexandru.ardelean@analog.com> References: <20200424045642.4903-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-04-24_01:2020-04-23,2020-04-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 spamscore=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 suspectscore=2 bulkscore=0 impostorscore=0 mlxlogscore=931 phishscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004240035 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 68c276edb071..bcf5f561c4b5 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1336,6 +1336,16 @@ void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) iio_free_chan_devattr_list(&indio_dev->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 3c97090c2ab9..bac865ff673e 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1475,7 +1475,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 Apr 24 04:56: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: 11507081 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 6335C1575 for ; Fri, 24 Apr 2020 04:56:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5479820776 for ; Fri, 24 Apr 2020 04:56:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726481AbgDXE4m (ORCPT ); Fri, 24 Apr 2020 00:56:42 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:38804 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726298AbgDXE4l (ORCPT ); Fri, 24 Apr 2020 00:56:41 -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 03O4o4ds030564; Fri, 24 Apr 2020 00:56:27 -0400 Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com with ESMTP id 30fud7n63y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 00:56:27 -0400 Received: from ASHBMBX9.ad.analog.com (ashbmbx9.ad.analog.com [10.64.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 03O4uQ89016518 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 24 Apr 2020 00:56:26 -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, 24 Apr 2020 00:56:25 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Fri, 24 Apr 2020 00:56:25 -0400 Received: from zeus.spd.analog.com (10.64.82.11) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.1.1779.2 via Frontend Transport; Fri, 24 Apr 2020 00:56:24 -0400 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 03O4uGpn017534; Fri, 24 Apr 2020 00:56:23 -0400 From: Alexandru Ardelean To: , CC: , , , "Alexandru Ardelean" Subject: [PATCH v4 4/7] iio: core: register chardev only if needed Date: Fri, 24 Apr 2020 07:56:39 +0300 Message-ID: <20200424045642.4903-5-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200424045642.4903-1-alexandru.ardelean@analog.com> References: <20200424045642.4903-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-04-24_01:2020-04-23,2020-04-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxlogscore=999 priorityscore=1501 clxscore=1015 impostorscore=0 suspectscore=0 phishscore=0 mlxscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004240035 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. Signed-off-by: Alexandru Ardelean --- drivers/iio/industrialio-core.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index bac865ff673e..03f5b5baeb94 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1676,6 +1676,15 @@ static int iio_check_unique_scan_index(struct iio_dev *indio_dev) static const struct iio_buffer_setup_ops noop_ring_setup_ops; +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_ioctl, + .compat_ioctl = compat_ptr_ioctl, +}; + int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) { int ret; @@ -1726,11 +1735,18 @@ 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; - ret = cdev_device_add(&indio_dev->chrdev, &indio_dev->dev); + if (indio_dev->buffer || indio_dev->event_interface) + ret = cdev_device_add(&indio_dev->chrdev, &indio_dev->dev); + else + ret = device_add(&indio_dev->dev); + if (ret < 0) goto error_unreg_eventset; @@ -1754,7 +1770,10 @@ EXPORT_SYMBOL(__iio_device_register); **/ void iio_device_unregister(struct iio_dev *indio_dev) { - cdev_device_del(&indio_dev->chrdev, &indio_dev->dev); + if (indio_dev->buffer || indio_dev->event_interface) + cdev_device_del(&indio_dev->chrdev, &indio_dev->dev); + else + device_del(&indio_dev->dev); mutex_lock(&indio_dev->info_exist_lock); From patchwork Fri Apr 24 04:56: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: 11507085 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 2162915AB for ; Fri, 24 Apr 2020 04:56:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 05CE42098B for ; Fri, 24 Apr 2020 04:56:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726473AbgDXE4s (ORCPT ); Fri, 24 Apr 2020 00:56:48 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:41790 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726515AbgDXE4q (ORCPT ); Fri, 24 Apr 2020 00:56:46 -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 03O4o3kP030543; Fri, 24 Apr 2020 00:56:30 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30fud7n643-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 00:56:30 -0400 Received: from SCSQMBX11.ad.analog.com (scsqmbx11.ad.analog.com [10.77.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 03O4uSGG047672 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 24 Apr 2020 00:56:29 -0400 Received: from SCSQMBX10.ad.analog.com (10.77.17.5) by SCSQMBX11.ad.analog.com (10.77.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Thu, 23 Apr 2020 21:56:27 -0700 Received: from zeus.spd.analog.com (10.64.82.11) by SCSQMBX10.ad.analog.com (10.77.17.5) with Microsoft SMTP Server id 15.1.1779.2 via Frontend Transport; Thu, 23 Apr 2020 21:56:27 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 03O4uGpo017534; Fri, 24 Apr 2020 00:56:24 -0400 From: Alexandru Ardelean To: , CC: , , , Alexandru Ardelean Subject: [PATCH v4 5/7] iio: buffer,event: duplicate chardev creation for buffers & events Date: Fri, 24 Apr 2020 07:56:40 +0300 Message-ID: <20200424045642.4903-6-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200424045642.4903-1-alexandru.ardelean@analog.com> References: <20200424045642.4903-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-04-24_01:2020-04-23,2020-04-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxlogscore=999 priorityscore=1501 clxscore=1015 impostorscore=0 suspectscore=2 phishscore=0 mlxscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004240035 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 | 105 ++++-------------------------- drivers/iio/industrialio-event.c | 98 +++++++++++++++++++++++++++- include/linux/iio/buffer_impl.h | 7 ++ include/linux/iio/iio.h | 6 +- 6 files changed, 208 insertions(+), 114 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 bcf5f561c4b5..3daa44deee80 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 @@ -1109,6 +1151,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, @@ -1336,6 +1389,29 @@ void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) iio_free_chan_devattr_list(&indio_dev->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 03f5b5baeb94..07b9aac9ffa5 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1578,79 +1578,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; @@ -1676,15 +1603,6 @@ static int iio_check_unique_scan_index(struct iio_dev *indio_dev) static const struct iio_buffer_setup_ops noop_ring_setup_ops; -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_ioctl, - .compat_ioctl = compat_ptr_ioctl, -}; - int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) { int ret; @@ -1735,16 +1653,17 @@ 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); - indio_dev->chrdev.owner = this_mod; + /* 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) - ret = cdev_device_add(&indio_dev->chrdev, &indio_dev->dev); - else + if (indio_dev->chrdev) { + indio_dev->chrdev->owner = this_mod; + + ret = cdev_device_add(indio_dev->chrdev, &indio_dev->dev); + } else ret = device_add(&indio_dev->dev); if (ret < 0) @@ -1770,13 +1689,15 @@ EXPORT_SYMBOL(__iio_device_register); **/ void iio_device_unregister(struct iio_dev *indio_dev) { - if (indio_dev->buffer || indio_dev->event_interface) - cdev_device_del(&indio_dev->chrdev, &indio_dev->dev); + if (indio_dev->chrdev) + cdev_device_del(indio_dev->chrdev, &indio_dev->dev); else device_del(&indio_dev->dev); mutex_lock(&indio_dev->info_exist_lock); + indio_dev->chrdev = NULL; + iio_device_unregister_debugfs(indio_dev); iio_disable_all_buffers(indio_dev); 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 d63884a54939..88b0f2100180 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 Apr 24 04:56: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: 11507087 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 9E68117EA for ; Fri, 24 Apr 2020 04:56:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8BC252076C for ; Fri, 24 Apr 2020 04:56:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726539AbgDXE4r (ORCPT ); Fri, 24 Apr 2020 00:56:47 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:42530 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726524AbgDXE4q (ORCPT ); Fri, 24 Apr 2020 00:56:46 -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 03O4qti4023387; Fri, 24 Apr 2020 00:56:32 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30fxf6csgc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 00:56:32 -0400 Received: from SCSQMBX11.ad.analog.com (scsqmbx11.ad.analog.com [10.77.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 03O4uU7N047688 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 24 Apr 2020 00:56:31 -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; Thu, 23 Apr 2020 21:56:29 -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; Thu, 23 Apr 2020 21:56:25 -0700 Received: from zeus.spd.analog.com (10.64.82.11) by SCSQMBX10.ad.analog.com (10.77.17.5) with Microsoft SMTP Server id 15.1.1779.2 via Frontend Transport; Thu, 23 Apr 2020 21:56:29 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 03O4uGpp017534; Fri, 24 Apr 2020 00:56:26 -0400 From: Alexandru Ardelean To: , CC: , , , "Alexandru Ardelean" Subject: [PATCH v4 6/7] iio: core: add simple centralized mechanism for ioctl() handlers Date: Fri, 24 Apr 2020 07:56:41 +0300 Message-ID: <20200424045642.4903-7-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200424045642.4903-1-alexandru.ardelean@analog.com> References: <20200424045642.4903-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-04-24_01:2020-04-23,2020-04-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 spamscore=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 suspectscore=0 bulkscore=0 impostorscore=0 mlxlogscore=999 phishscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004240035 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 07b9aac9ffa5..af9d2686bb60 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1525,6 +1525,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) mutex_init(&indio_dev->info_exist_lock); INIT_LIST_HEAD(&indio_dev->channel_attr_list); INIT_LIST_HEAD(&indio_dev->buffer_list); + INIT_LIST_HEAD(&indio_dev->ioctl_handlers); return indio_dev; } @@ -1578,6 +1579,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; @@ -1689,6 +1717,8 @@ EXPORT_SYMBOL(__iio_device_register); **/ void iio_device_unregister(struct iio_dev *indio_dev) { + struct iio_ioctl_handler *h, *t; + if (indio_dev->chrdev) cdev_device_del(indio_dev->chrdev, &indio_dev->dev); else @@ -1702,6 +1732,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 88b0f2100180..f0b63f4f3a8e 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 Apr 24 04:56: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: 11507089 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 14E1D1575 for ; Fri, 24 Apr 2020 04:56:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 06B4D2076C for ; Fri, 24 Apr 2020 04:56:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726535AbgDXE4r (ORCPT ); Fri, 24 Apr 2020 00:56:47 -0400 Received: from mx0a-00128a01.pphosted.com ([148.163.135.77]:42606 "EHLO mx0a-00128a01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726525AbgDXE4q (ORCPT ); Fri, 24 Apr 2020 00:56:46 -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 03O4qto5023590; Fri, 24 Apr 2020 00:56:32 -0400 Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com with ESMTP id 30fxf6csgd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Apr 2020 00:56:32 -0400 Received: from SCSQMBX11.ad.analog.com (scsqmbx11.ad.analog.com [10.77.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 03O4uU7O047688 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 24 Apr 2020 00:56:31 -0400 Received: from SCSQMBX10.ad.analog.com (10.77.17.5) by SCSQMBX11.ad.analog.com (10.77.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Thu, 23 Apr 2020 21:56:30 -0700 Received: from zeus.spd.analog.com (10.64.82.11) by SCSQMBX10.ad.analog.com (10.77.17.5) with Microsoft SMTP Server id 15.1.1779.2 via Frontend Transport; Thu, 23 Apr 2020 21:56:30 -0700 Received: from localhost.localdomain ([10.48.65.12]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 03O4uGpq017534; Fri, 24 Apr 2020 00:56:27 -0400 From: Alexandru Ardelean To: , CC: , , , Alexandru Ardelean Subject: [PATCH v4 7/7] iio: core: use new common ioctl() mechanism Date: Fri, 24 Apr 2020 07:56:42 +0300 Message-ID: <20200424045642.4903-8-alexandru.ardelean@analog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200424045642.4903-1-alexandru.ardelean@analog.com> References: <20200424045642.4903-1-alexandru.ardelean@analog.com> MIME-Version: 1.0 X-ADIRoutedOnPrem: True X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-04-24_01:2020-04-23,2020-04-24 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 spamscore=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 suspectscore=0 bulkscore=0 impostorscore=0 mlxlogscore=999 phishscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004240035 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 3daa44deee80..bd37901bc882 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1159,7 +1159,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[] = {