All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
To: Bjorn Andersson <bjorn.andersson@linaro.org>,
	Ohad Ben-Cohen <ohad@wizery.com>,
	Mathieu Poirier <mathieu.poirier@linaro.org>,
	Andy Gross <agross@kernel.org>
Cc: <linux-remoteproc@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>,
	<linux-stm32@st-md-mailman.stormreply.com>,
	<linux-arm-msm@vger.kernel.org>, <arnaud.pouliquen@foss.st.com>
Subject: [PATCH v2 01/16] rpmsg: introduce RPMsg control driver for channel creation
Date: Tue, 22 Dec 2020 11:57:11 +0100	[thread overview]
Message-ID: <20201222105726.16906-2-arnaud.pouliquen@foss.st.com> (raw)
In-Reply-To: <20201222105726.16906-1-arnaud.pouliquen@foss.st.com>

The RPMsg_ctrl driver is a duplication of the ioctrl part of the
rpmsg_char driver to make generic the ioctl to manage channels by
the userspace applications.

As a first step, this driver just creates the /dev/rpmsg_ctl<x>
( <x> is the instance value). The ioctl is not implemented.

Notice that this driver is associated to a RPMsg device with no endpoint.
Instantiating this device as an RPMsg device allows to retrieve the
associated RPMsg backend.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
---
 drivers/rpmsg/Kconfig      |   8 ++
 drivers/rpmsg/Makefile     |   1 +
 drivers/rpmsg/rpmsg_ctrl.c | 208 +++++++++++++++++++++++++++++++++++++
 3 files changed, 217 insertions(+)
 create mode 100644 drivers/rpmsg/rpmsg_ctrl.c

diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
index 0b4407abdf13..c9e602016c3b 100644
--- a/drivers/rpmsg/Kconfig
+++ b/drivers/rpmsg/Kconfig
@@ -23,6 +23,14 @@ config RPMSG_NS
 	  channel that probes the associated RPMsg device on remote endpoint
 	  service announcement.
 
+config RPMSG_CTRL
+	tristate "RPMSG control interface"
+	depends on RPMSG
+	help
+	  Say Y here to enable the support of the /dev/rpmsg_ctl API. this API
+	  allows user-space programs to create channels with specific name,
+	  source and destination addresses.
+
 config RPMSG_MTK_SCP
 	tristate "MediaTek SCP"
 	depends on MTK_SCP
diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
index 8d452656f0ee..3c1bce9d0228 100644
--- a/drivers/rpmsg/Makefile
+++ b/drivers/rpmsg/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_RPMSG)		+= rpmsg_core.o
 obj-$(CONFIG_RPMSG_CHAR)	+= rpmsg_char.o
 obj-$(CONFIG_RPMSG_NS)		+= rpmsg_ns.o
+obj-$(CONFIG_RPMSG_CTRL)	+= rpmsg_ctrl.o
 obj-$(CONFIG_RPMSG_MTK_SCP)	+= mtk_rpmsg.o
 qcom_glink-objs			:= qcom_glink_native.o qcom_glink_ssr.o
 obj-$(CONFIG_RPMSG_QCOM_GLINK) += qcom_glink.o
diff --git a/drivers/rpmsg/rpmsg_ctrl.c b/drivers/rpmsg/rpmsg_ctrl.c
new file mode 100644
index 000000000000..425c3e32ada4
--- /dev/null
+++ b/drivers/rpmsg/rpmsg_ctrl.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2020
+ */
+
+#include <linux/cdev.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "rpmsg_internal.h"
+#include <uapi/linux/rpmsg.h>
+
+#define RPMSG_DEV_MAX	(MINORMASK + 1)
+
+#define dev_to_ctrldev(dev) container_of(dev, struct rpmsg_ctrl_dev, dev)
+#define cdev_to_ctrldev(i_cdev) container_of(i_cdev, struct rpmsg_ctrl_dev, cdev)
+
+/**
+ * struct rpmsg_ctrl_dev - control device for instantiating endpoint devices
+ * @rpdev:	underlaying rpmsg device
+ * @cdev:	cdev for the ctrl device
+ * @dev:	device for the ctrl device
+ */
+struct rpmsg_ctrl_dev {
+	struct rpmsg_device *rpdev;
+	struct cdev cdev;
+	struct device dev;
+};
+
+static DEFINE_IDA(rpmsg_ctrl_ida);
+static DEFINE_IDA(rpmsg_minor_ida);
+
+static dev_t rpmsg_major;
+
+static int rpmsg_ctrl_dev_open(struct inode *inode, struct file *filp)
+{
+	struct rpmsg_ctrl_dev *ctrldev = cdev_to_ctrldev(inode->i_cdev);
+
+	get_device(&ctrldev->dev);
+	filp->private_data = ctrldev;
+
+	return 0;
+}
+
+static long rpmsg_ctrl_dev_ioctl(struct file *fp, unsigned int cmd,
+				 unsigned long arg)
+{
+	struct rpmsg_ctrl_dev *ctrldev = fp->private_data;
+
+	dev_info(&ctrldev->dev, "Control not yet implemented\n");
+
+	return 0;
+};
+
+static int rpmsg_ctrl_dev_release(struct inode *inode, struct file *filp)
+{
+	struct rpmsg_ctrl_dev *ctrldev = cdev_to_ctrldev(inode->i_cdev);
+
+	put_device(&ctrldev->dev);
+
+	return 0;
+}
+
+static void rpmsg_ctrl_dev_release_device(struct device *dev)
+{
+	struct rpmsg_ctrl_dev *ctrldev = dev_to_ctrldev(dev);
+
+	dev_err(dev, "%s\n", __func__);
+
+	ida_simple_remove(&rpmsg_ctrl_ida, dev->id);
+	ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt));
+	cdev_del(&ctrldev->cdev);
+	kfree(ctrldev);
+}
+
+static const struct file_operations rpmsg_ctrl_fops = {
+	.owner = THIS_MODULE,
+	.open = rpmsg_ctrl_dev_open,
+	.release = rpmsg_ctrl_dev_release,
+	.unlocked_ioctl = rpmsg_ctrl_dev_ioctl,
+	.compat_ioctl = compat_ptr_ioctl,
+};
+
+static int rpmsg_ctrl_add_control(struct rpmsg_ctrl_dev *ctrldev)
+{
+	struct device *dev = &ctrldev->dev;
+	int ret;
+
+	cdev_init(&ctrldev->cdev, &rpmsg_ctrl_fops);
+	ctrldev->cdev.owner = THIS_MODULE;
+
+	ret = ida_simple_get(&rpmsg_minor_ida, 0, RPMSG_DEV_MAX, GFP_KERNEL);
+	if (ret < 0)
+		return ret;
+	dev->devt = MKDEV(MAJOR(rpmsg_major), ret);
+
+	dev_set_name(dev, "rpmsg_ctrl%d", dev->id);
+
+	ret = cdev_add(&ctrldev->cdev, dev->devt, 1);
+	if (ret)
+		goto free_minor_ida;
+
+	dev_info(dev, "add %s control for %s driver\n",
+		 dev_name(dev),  dev_name(dev->parent));
+
+	return 0;
+
+free_minor_ida:
+	ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt));
+
+	return ret;
+}
+
+static int rpmsg_ctrl_probe(struct rpmsg_device *rpdev)
+{
+	struct rpmsg_ctrl_dev *ctrldev;
+	struct device *dev;
+	int ret;
+
+	ctrldev = kzalloc(sizeof(*ctrldev), GFP_KERNEL);
+	if (!ctrldev)
+		return -ENOMEM;
+
+	ctrldev->rpdev = rpdev;
+
+	dev = &ctrldev->dev;
+	device_initialize(dev);
+	dev->parent = &rpdev->dev;
+
+	ret = ida_simple_get(&rpmsg_ctrl_ida, 0, 0, GFP_KERNEL);
+	if (ret < 0)
+		goto free_ctrldev;
+
+	dev->id = ret;
+
+	ret = rpmsg_ctrl_add_control(ctrldev);
+	if (ret < 0)
+		goto free_ctrl_ida;
+
+	/* We can now rely on the release function for cleanup */
+	dev->release = rpmsg_ctrl_dev_release_device;
+
+	ret = device_add(dev);
+	if (ret) {
+		dev_err(&rpdev->dev, "device_add failed: %d\n", ret);
+		put_device(dev);
+		goto free_ctrl_ida;
+	}
+
+	dev_set_drvdata(dev, ctrldev);
+	dev_set_drvdata(&rpdev->dev, ctrldev);
+
+	return 0;
+
+free_ctrl_ida:
+	ida_simple_remove(&rpmsg_ctrl_ida, dev->id);
+free_ctrldev:
+	put_device(dev);
+	kfree(ctrldev);
+
+	return ret;
+}
+
+static void rpmsg_ctrl_remove(struct rpmsg_device *rpdev)
+{
+	struct rpmsg_ctrl_dev *ctrldev = dev_get_drvdata(&rpdev->dev);
+
+	device_del(&ctrldev->dev);
+	put_device(&ctrldev->dev);
+}
+
+static struct rpmsg_driver rpmsg_ctrl_driver = {
+	.drv.name = KBUILD_MODNAME,
+	.probe = rpmsg_ctrl_probe,
+	.remove = rpmsg_ctrl_remove,
+};
+
+static int rpmsg_ctrl_init(void)
+{
+	int ret;
+
+	ret = alloc_chrdev_region(&rpmsg_major, 0, RPMSG_DEV_MAX, "rpmsg");
+	if (ret < 0) {
+		pr_err("rpmsg_ctrl: failed to allocate char dev region\n");
+		return ret;
+	}
+
+	ret = register_rpmsg_driver(&rpmsg_ctrl_driver);
+	if (ret < 0) {
+		pr_err("rpmsg_ctrl: failed to register rpmsg driver\n");
+		unregister_chrdev_region(rpmsg_major, RPMSG_DEV_MAX);
+	}
+
+	return ret;
+}
+postcore_initcall(rpmsg_ctrl_init);
+
+static void rpmsg_ctrl_exit(void)
+{
+	unregister_rpmsg_driver(&rpmsg_ctrl_driver);
+	unregister_chrdev_region(rpmsg_major, RPMSG_DEV_MAX);
+}
+module_exit(rpmsg_ctrl_exit);
+
+MODULE_DESCRIPTION("ioctl rpmsg driver");
+MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>");
+MODULE_ALIAS("rpmsg:" KBUILD_MODNAME);
+MODULE_LICENSE("GPL v2");
-- 
2.17.1


  reply	other threads:[~2020-12-22 11:00 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-22 10:57 [PATCH v2 00/16] introduce generic IOCTL interface for RPMsg channels management Arnaud Pouliquen
2020-12-22 10:57 ` Arnaud Pouliquen [this message]
2020-12-22 16:45   ` [PATCH v2 01/16] rpmsg: introduce RPMsg control driver for channel creation Randy Dunlap
2021-01-05  0:21   ` Bjorn Andersson
2021-01-21 23:31   ` Mathieu Poirier
2020-12-22 10:57 ` [PATCH v2 02/16] rpmsg: add RPMsg control API to register service Arnaud Pouliquen
2021-01-05  0:34   ` Bjorn Andersson
2021-01-05 16:53     ` Arnaud POULIQUEN
2021-01-21 23:46   ` Mathieu Poirier
2020-12-22 10:57 ` [PATCH v2 03/16] rpmsg: add override field in channel info Arnaud Pouliquen
2020-12-22 10:57 ` [PATCH v2 04/16] rpmsg: ctrl: implement the ioctl function to create device Arnaud Pouliquen
2021-01-05  1:33   ` Bjorn Andersson
2021-01-05 18:07     ` Arnaud POULIQUEN
2021-01-21 23:52   ` Mathieu Poirier
2021-01-22 13:05     ` Arnaud POULIQUEN
2021-01-22 20:59       ` Mathieu Poirier
2021-01-25 10:52         ` Arnaud POULIQUEN
2021-01-29  0:13         ` Mathieu Poirier
2021-01-29  9:45           ` Arnaud POULIQUEN
2020-12-22 10:57 ` [PATCH v2 05/16] rpmsg: ns: initialize channel info override field Arnaud Pouliquen
2021-01-05  0:38   ` Bjorn Andersson
2021-01-05 17:02     ` Arnaud POULIQUEN
2020-12-22 10:57 ` [PATCH v2 06/16] rpmsg: add helper to register the rpmsg ctrl device Arnaud Pouliquen
2020-12-22 10:57 ` [PATCH v2 07/16] rpmsg: char: clean up rpmsg class Arnaud Pouliquen
2021-01-05  0:47   ` Bjorn Andersson
2021-01-05  0:54     ` Bjorn Andersson
2021-01-05 17:03       ` Arnaud POULIQUEN
2020-12-22 10:57 ` [PATCH v2 08/16] rpmsg: char: make char rpmsg a rpmsg device without the control part Arnaud Pouliquen
2020-12-22 10:57 ` [PATCH v2 09/16] rpmsg: char: register RPMsg raw service to the ioctl interface Arnaud Pouliquen
2020-12-22 10:57 ` [PATCH v2 10/16] rpmsg: char: allow only one endpoint per device Arnaud Pouliquen
2021-01-05  0:59   ` Bjorn Andersson
2021-01-05 17:05     ` Arnaud POULIQUEN
2020-12-22 10:57 ` [PATCH v2 11/16] rpmsg: char: check destination address is not null Arnaud Pouliquen
2021-01-05  1:03   ` Bjorn Andersson
2021-01-05 17:08     ` Arnaud POULIQUEN
2020-12-22 10:57 ` [PATCH v2 12/16] rpmsg: virtio: use the driver_override in channel creation ops Arnaud Pouliquen
2020-12-22 10:57 ` [PATCH v2 13/16] rpmsg: virtio: probe the rpmsg_ctl device Arnaud Pouliquen
2020-12-29  4:16   ` kernel test robot
2020-12-29  4:16     ` kernel test robot
2021-01-04 12:59   ` Dan Carpenter
2021-01-04 12:59     ` Dan Carpenter
2021-01-04 12:59     ` Dan Carpenter
2020-12-22 10:57 ` [PATCH v2 14/16] rpmsg: glink: add create and release rpmsg channel ops Arnaud Pouliquen
2021-01-05  1:08   ` Bjorn Andersson
2021-01-05 17:29     ` Arnaud POULIQUEN
2020-12-22 10:57 ` [PATCH v2 15/16] rpmsg: smd: " Arnaud Pouliquen
2020-12-22 10:57 ` [PATCH v2 16/16] rpmsg: replace rpmsg_chrdev_register_device use Arnaud Pouliquen
2021-01-05  1:10   ` Bjorn Andersson
2021-01-04 23:03 ` [PATCH v2 00/16] introduce generic IOCTL interface for RPMsg channels management Bjorn Andersson
2021-01-05 16:59   ` Arnaud POULIQUEN
2021-01-13 20:31 ` Mathieu Poirier
2021-01-14  9:05   ` Arnaud POULIQUEN

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=20201222105726.16906-2-arnaud.pouliquen@foss.st.com \
    --to=arnaud.pouliquen@foss.st.com \
    --cc=agross@kernel.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-remoteproc@vger.kernel.org \
    --cc=linux-stm32@st-md-mailman.stormreply.com \
    --cc=mathieu.poirier@linaro.org \
    --cc=ohad@wizery.com \
    /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.