All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandru Ardelean <alexandru.ardelean@analog.com>
To: <linux-iio@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Cc: <jic23@kernel.org>, <lars@metafoo.de>,
	Alexandru Ardelean <alexandru.ardelean@analog.com>
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	[thread overview]
Message-ID: <20200508135348.15229-12-alexandru.ardelean@analog.com> (raw)
In-Reply-To: <20200508135348.15229-1-alexandru.ardelean@analog.com>

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 <alexandru.ardelean@analog.com>
---
 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;
 
-- 
2.17.1


  parent reply	other threads:[~2020-05-08 13:54 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-08 13:53 [RFC PATCH 00/14] iio: buffer: add support for multiple buffers Alexandru Ardelean
2020-05-08 13:53 ` [RFC PATCH 01/14] iio: Move scan mask management to the core Alexandru Ardelean
2020-05-08 13:53 ` [RFC PATCH 02/14] iio: hw_consumer: use new scanmask functions Alexandru Ardelean
2020-05-08 13:53 ` [RFC PATCH 03/14] iio: buffer: add back-ref from iio_buffer to iio_dev Alexandru Ardelean
2020-05-08 13:53 ` [RFC PATCH 04/14] iio: core,buffer: wrap iio_buffer_put() call into iio_buffers_put() Alexandru Ardelean
2020-05-08 13:53 ` [RFC PATCH 05/14] iio: core: register chardev only if needed Alexandru Ardelean
2020-05-24 16:40   ` Jonathan Cameron
2020-05-08 13:53 ` [RFC PATCH 06/14] iio: buffer,event: duplicate chardev creation for buffers & events Alexandru Ardelean
2020-05-08 13:53 ` [RFC PATCH 07/14] iio: core: add simple centralized mechanism for ioctl() handlers Alexandru Ardelean
2020-05-24 16:45   ` Jonathan Cameron
2020-05-25  7:24     ` Ardelean, Alexandru
2020-05-08 13:53 ` [RFC PATCH 08/14] iio: core: use new common ioctl() mechanism Alexandru Ardelean
2020-05-24 16:47   ` Jonathan Cameron
2020-05-25  7:27     ` Ardelean, Alexandru
2020-05-31 15:20       ` Jonathan Cameron
2020-05-08 13:53 ` [RFC PATCH 09/14] iio: buffer: split buffer sysfs creation to take buffer as primary arg Alexandru Ardelean
2020-05-24 16:49   ` Jonathan Cameron
2020-05-25  7:28     ` Ardelean, Alexandru
2020-05-31 15:21       ` Jonathan Cameron
2020-05-08 13:53 ` [RFC PATCH 10/14] iio: buffer: remove attrcount_orig var from sysfs creation Alexandru Ardelean
2020-05-08 13:53 ` Alexandru Ardelean [this message]
2020-05-08 13:53 ` [RFC PATCH 12/14] iio: buffer: symlink the scan_elements dir back into IIO device's dir Alexandru Ardelean
2020-05-08 13:53 ` [RFC PATCH 13/14] iio: unpack all iio buffer attributes correctly Alexandru Ardelean
2020-05-24 17:28   ` Jonathan Cameron
2020-05-08 13:53 ` [RFC PATCH 14/14] iio: buffer: convert single buffer to list of buffers Alexandru Ardelean
2020-05-09  8:52 ` [RFC PATCH 00/14] iio: buffer: add support for multiple buffers Lars-Peter Clausen
2020-05-10 10:09   ` Jonathan Cameron
2020-05-11 10:33     ` Ardelean, Alexandru
2020-05-11 10:37       ` Lars-Peter Clausen
2020-05-11 13:03         ` Ardelean, Alexandru
2020-05-11 13:24           ` Ardelean, Alexandru
2020-05-11 13:58             ` Lars-Peter Clausen
2020-05-11 14:56               ` Ardelean, Alexandru
2020-05-11 19:56                 ` Lars-Peter Clausen
2020-05-12  6:26                   ` Ardelean, Alexandru
2020-05-16 13:08                     ` Ardelean, Alexandru
2020-05-16 16:24                       ` Jonathan Cameron
2020-05-17  6:26                         ` Ardelean, Alexandru
2020-05-17 13:40                           ` Jonathan Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200508135348.15229-12-alexandru.ardelean@analog.com \
    --to=alexandru.ardelean@analog.com \
    --cc=jic23@kernel.org \
    --cc=lars@metafoo.de \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.