devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* dynamic device tree char driver
@ 2012-08-16 19:43 Alan Tull
       [not found] ` <1345146226-32675-1-git-send-email-atull-EIB2kfCEclfQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Alan Tull @ 2012-08-16 19:43 UTC (permalink / raw)
  To: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ; +Cc: Rob Herring


Hello,

I'm Alan Tull, interested in dynamic features of device trees.

The following patch adds a char driver to add or remove device tree
nodes dynamically.  Its ioctl passes a struct with:
 - size of the blob
 - pointer to the blob

The path to add the nodes under is coded in the blob with dummy nodes.
For example the following can be compiled into a blob and sent to this
driver adding a single node under /soc/apb_periphs:

/dts-v1/;
/ {
        soc {
                apb_periphs {
                        i2c1: i2c@ffc05000 {
                                compatible = "snps,designware-i2c";
                                reg = <0xffc05000 0x1000>;
                                interrupts = <0 159 4>;
                                emptyfifo_hold_master = <1>;
                        };
                };
        };
};

I wanted to get feeback early before I went too far down this particular
path.  As such, this code doesn't do any notification for drivers yet.
Also it won't properly add nested nodes yet.  It can add/remove a single
node and see it show up properly under /proc/device-tree.

Alan Tull
Altera

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/1] dynamic device tree char driver
       [not found] ` <1345146226-32675-1-git-send-email-atull-EIB2kfCEclfQT0dZR+AlfA@public.gmane.org>
@ 2012-08-16 19:43   ` Alan Tull
  2012-08-18 15:45   ` Rob Herring
  1 sibling, 0 replies; 6+ messages in thread
From: Alan Tull @ 2012-08-16 19:43 UTC (permalink / raw)
  To: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ; +Cc: Rob Herring

 * Add a ioctls for adding/removing nodes using binary blobs.

Signed-off-by: Alan Tull <atull-EIB2kfCEclfQT0dZR+AlfA@public.gmane.org>
---
 drivers/of/Makefile  |    1 +
 drivers/of/dynamic.c |  287 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/of/dynamic.h |   26 +++++
 3 files changed, 314 insertions(+), 0 deletions(-)
 create mode 100644 drivers/of/dynamic.c
 create mode 100644 drivers/of/dynamic.h

diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index e027f44..5c08045 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_OF_PROMTREE) += pdt.o
 obj-$(CONFIG_OF_ADDRESS)  += address.o
 obj-$(CONFIG_OF_IRQ)    += irq.o
 obj-$(CONFIG_OF_DEVICE) += device.o platform.o
+obj-$(CONFIG_OF_DYNAMIC) += dynamic.o
 obj-$(CONFIG_OF_I2C)	+= of_i2c.o
 obj-$(CONFIG_OF_NET)	+= of_net.o
 obj-$(CONFIG_OF_SELFTEST) += selftest.o
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
new file mode 100644
index 0000000..0dce177
--- /dev/null
+++ b/drivers/of/dynamic.c
@@ -0,0 +1,287 @@
+/*
+ * Dynamic Device Tree support
+ *
+ * Copyright (C) 2012 Altera Corporation
+ * Author: Alan Tull <atull-EIB2kfCEclfQT0dZR+AlfA@public.gmane.org>
+ *
+ * Some code taken from reconfig.c
+ * Copyright (C) 2005 Nathan Lynch
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/uaccess.h>
+#include <linux/mutex.h>
+#include "dynamic.h"
+
+static int major;
+module_param(major, int, 0);
+MODULE_PARM_DESC(major, "Major device number");
+
+static DEFINE_MUTEX(of_dynamic_ioctl_mutex);
+
+/*
+ * Routines for "runtime" addition and removal of device tree nodes.
+ */
+#ifdef CONFIG_PROC_DEVICETREE
+/*
+ * Add a node to /proc/device-tree.
+ */
+static void add_node_proc_entries(struct device_node *np)
+{
+	struct proc_dir_entry *ent;
+
+	pr_debug("%s parent........... %s\n", __func__, np->parent->name);
+	pr_debug("%s full_name........ %s\n", __func__, np->full_name);
+
+	ent = proc_mkdir(strrchr(np->full_name, '/') + 1, np->parent->pde);
+	if (ent)
+		proc_device_tree_add_node(np, ent);
+}
+
+static void remove_node_proc_entries(struct device_node *np)
+{
+	struct property *pp = np->properties;
+	struct device_node *parent = np->parent;
+
+	while (pp) {
+		remove_proc_entry(pp->name, np->pde);
+		pp = pp->next;
+	}
+	if (np->pde)
+		remove_proc_entry(np->pde->name, parent->pde);
+}
+#else /* !CONFIG_PROC_DEVICETREE */
+static void add_node_proc_entries(struct device_node *np)
+{
+	return;
+}
+
+static void remove_node_proc_entries(struct device_node *np)
+{
+	return;
+}
+#endif /* CONFIG_PROC_DEVICETREE */
+
+/*
+ *	derive_parent - basically like dirname(1)
+ *	@path:  the full_name of a node to be added to the tree
+ *
+ *	Returns the node which should be the parent of the node
+ *	described by path.  E.g., for path = "/foo/bar", returns
+ *	the node with full_name = "/foo".
+ */
+static struct device_node *derive_parent(const char *path)
+{
+	struct device_node *parent = NULL;
+	char *parent_path = "/";
+	size_t parent_path_len = strrchr(path, '/') - path + 1;
+
+	/* reject if path is "/" */
+	if (!strcmp(path, "/"))
+		return ERR_PTR(-EINVAL);
+
+	if (strrchr(path, '/') != path) {
+		parent_path = kmalloc(parent_path_len, GFP_KERNEL);
+		if (!parent_path)
+			return ERR_PTR(-ENOMEM);
+		strlcpy(parent_path, path, parent_path_len);
+	}
+	parent = of_find_node_by_path(parent_path);
+	if (!parent)
+		return ERR_PTR(-EINVAL);
+	if (strcmp(parent_path, "/"))
+		kfree(parent_path);
+	return parent;
+}
+
+static void next_real_node(struct device_node **npp)
+{
+	/* The blob to be added is not a complete device tree. Some nodes'
+	   parents are only there to indicate the path to add the node
+	   in the existing tree. Look for nodes that have real properties
+	   besides name (i.e. compatible) and add those recursively. */
+
+	/* Mark the nodes we don't attach for removal */
+	while ((*npp) && !of_get_property(*npp, "compatible", NULL)) {
+		of_node_set_flag(*npp, OF_DETACHED);
+		*npp = (*npp)->next;
+	}
+}
+
+static int add_nodes_to_tree(struct device_node *np)
+{
+	struct device_node *tree_node;
+
+	while (np) {
+		next_real_node(&np);
+		if (np) {
+			tree_node = of_find_node_by_path(np->full_name);
+			if (tree_node) {
+				pr_err("%s Error: node %s exists in device tree\n",
+					__func__, np->full_name);
+				of_node_put(tree_node);
+				return -EEXIST;
+			}
+
+			np->parent = derive_parent(np->full_name);
+			if (IS_ERR(np->parent))
+				return -EINVAL;
+			of_attach_node(np);
+			add_node_proc_entries(np);
+
+			of_node_put(np->parent);
+			np = np->next;
+		}
+	}
+
+	return 0;
+}
+
+static int remove_nodes_from_tree(struct device_node *np)
+{
+	struct device_node *tree_node;
+
+	while (np) {
+		next_real_node(&np);
+		if (np) {
+			tree_node = of_find_node_by_path(np->full_name);
+			if (!tree_node) {
+				pr_err("%s Error: node %s does not exist in device tree\n",
+					__func__, np->full_name);
+				return -ENOENT;
+			}
+
+			remove_node_proc_entries(tree_node);
+			of_detach_node(tree_node);
+			of_node_put(tree_node);
+
+			of_node_put(np->parent);
+			np = np->next;
+		}
+	}
+
+	return 0;
+}
+
+static long of_dynamic_unlocked_ioctl(struct file *file, unsigned int cmd,
+				      unsigned long arg)
+{
+	int ret = 0;
+	void *blob = NULL;
+	struct device_node *np;
+	void __user *user_arg = (void __user *)arg;
+	struct of_dynamic_blob_info blob_info;
+
+	pr_debug("%s\n", __func__);
+
+	mutex_lock(&of_dynamic_ioctl_mutex);
+
+	if (copy_from_user(&blob_info, user_arg, sizeof(blob_info))) {
+		pr_err("%s copy_from_user error\n", __func__);
+		ret = -EINVAL;
+		goto ioctl_out;
+	}
+
+	blob = kmalloc(blob_info.size, GFP_KERNEL);
+	if (!blob) {
+		ret = -ENOMEM;
+		goto ioctl_out;
+	}
+
+	if (copy_from_user(blob, blob_info.blob, blob_info.size)) {
+		ret = -EFAULT;
+		goto ioctl_out;
+	}
+
+	of_fdt_unflatten_tree(blob, &np);
+
+	switch (cmd) {
+	case OF_DYNAMIC_ADD_NODE:
+		pr_debug("%s : cmd = OF_DYNAMIC_ADD_NODE  size = %d\n",
+			__func__, blob_info.size);
+		ret = add_nodes_to_tree(np);
+		break;
+
+	case OF_DYNAMIC_REMOVE_NODE:
+		pr_debug("%s : cmd = OF_DYNAMIC_REMOVE_NODE\n", __func__);
+		ret = remove_nodes_from_tree(np);
+		break;
+
+	default:
+		pr_debug("%s : unknown ioctl %d  blob size = %d\n",
+			__func__, cmd, blob_info.size);
+		ret = -EINVAL;
+		break;
+	}
+
+ioctl_out:
+	kfree(blob);
+	mutex_unlock(&of_dynamic_ioctl_mutex);
+	return ret;
+}
+
+static const struct file_operations of_dynamic_fops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.unlocked_ioctl = of_dynamic_unlocked_ioctl,
+};
+
+static struct cdev of_dynamic_dev;
+
+static int __init of_dynamic_init(void)
+{
+	int rc;
+	dev_t dev;
+
+	if (major) {
+		dev = MKDEV(major, 0);
+		rc = register_chrdev_region(dev, 1, "of_dynamic");
+	} else {
+		rc = alloc_chrdev_region(&dev, 0, 1, "of_dynamic");
+		major = MAJOR(dev);
+	}
+	if (rc < 0) {
+		pr_err("of_dynamic chrdev_region err: %d\n", rc);
+		return rc;
+	}
+
+	cdev_init(&of_dynamic_dev, &of_dynamic_fops);
+	rc = cdev_add(&of_dynamic_dev, dev, 1);
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
+static void __exit of_dynamic_exit(void)
+{
+	unregister_chrdev_region(MKDEV(major, 0), 1);
+}
+
+module_init(of_dynamic_init);
+module_exit(of_dynamic_exit);
+
+MODULE_AUTHOR("Alan Tull <atull-EIB2kfCEclfQT0dZR+AlfA@public.gmane.org>");
+MODULE_DESCRIPTION("Dynamic device tree");
+MODULE_LICENSE("GPL");
diff --git a/drivers/of/dynamic.h b/drivers/of/dynamic.h
new file mode 100644
index 0000000..4ee4e96
--- /dev/null
+++ b/drivers/of/dynamic.h
@@ -0,0 +1,26 @@
+/*
+ * Dynamic Device Tree support
+ *
+ * Copyrignt (C) 2012 Altera Corporation
+ *
+ */
+
+#ifndef __OF_DYNAMIC_H
+#define __OF_DYNAMIC_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+struct of_dynamic_blob_info {
+	__u32 size;
+	__u8 *blob;
+};
+
+/*
+ * TODO pick some unused ioctls (see Documentation/ioctl/ioctl-number-txt)
+ * and ask mec to register them
+ */
+#define OF_DYNAMIC_ADD_NODE	_IOW('W', 0, struct of_dynamic_blob_info *)
+#define OF_DYNAMIC_REMOVE_NODE	_IOW('W', 1, struct of_dynamic_blob_info *)
+
+#endif /* __OF_DYNAMIC_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: dynamic device tree char driver
       [not found] ` <1345146226-32675-1-git-send-email-atull-EIB2kfCEclfQT0dZR+AlfA@public.gmane.org>
  2012-08-16 19:43   ` [PATCH 1/1] " Alan Tull
@ 2012-08-18 15:45   ` Rob Herring
       [not found]     ` <502FB8A9.4030907-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  1 sibling, 1 reply; 6+ messages in thread
From: Rob Herring @ 2012-08-18 15:45 UTC (permalink / raw)
  To: Alan Tull; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On 08/16/2012 02:43 PM, Alan Tull wrote:
> 
> Hello,
> 
> I'm Alan Tull, interested in dynamic features of device trees.

Hey Alan. How are you doing?

> The following patch adds a char driver to add or remove device tree
> nodes dynamically.  Its ioctl passes a struct with:
>  - size of the blob
>  - pointer to the blob
> 
> The path to add the nodes under is coded in the blob with dummy nodes.
> For example the following can be compiled into a blob and sent to this
> driver adding a single node under /soc/apb_periphs:
> 
> /dts-v1/;
> / {
>         soc {
>                 apb_periphs {
>                         i2c1: i2c@ffc05000 {
>                                 compatible = "snps,designware-i2c";
>                                 reg = <0xffc05000 0x1000>;
>                                 interrupts = <0 159 4>;
>                                 emptyfifo_hold_master = <1>;
>                         };
>                 };
>         };
> };
> 
> I wanted to get feeback early before I went too far down this particular
> path.  As such, this code doesn't do any notification for drivers yet.
> Also it won't properly add nested nodes yet.  It can add/remove a single
> node and see it show up properly under /proc/device-tree.

Have you looked at arch/powerpc/platforms/pseries/reconfig.c?

There was also a recent discussion titled "OF_DYNAMIC usage" that you
should look at.

I don't think a char driver and ioctls will fly...

Another option could be kexecing with a new DTB if you can live with a
reboot.

Rob

> 
> Alan Tull
> Altera
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: dynamic device tree char driver
       [not found]     ` <502FB8A9.4030907-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2012-08-21 14:38       ` Alan Tull
  2012-08-21 16:51         ` Rob Herring
  0 siblings, 1 reply; 6+ messages in thread
From: Alan Tull @ 2012-08-21 14:38 UTC (permalink / raw)
  To: Rob Herring; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On Sat, 2012-08-18 at 10:45 -0500, Rob Herring wrote:
> On 08/16/2012 02:43 PM, Alan Tull wrote:
> > 
> > Hello,
> > 
> > I'm Alan Tull, interested in dynamic features of device trees.
> 
> Hey Alan. How are you doing?
Doing good! Nice to hear from you.

> 
> > The following patch adds a char driver to add or remove device tree
> > nodes dynamically.  Its ioctl passes a struct with:
> >  - size of the blob
> >  - pointer to the blob
> > 
> > The path to add the nodes under is coded in the blob with dummy nodes.
> > For example the following can be compiled into a blob and sent to this
> > driver adding a single node under /soc/apb_periphs:
> > 
> > /dts-v1/;
> > / {
> >         soc {
> >                 apb_periphs {
> >                         i2c1: i2c@ffc05000 {
> >                                 compatible = "snps,designware-i2c";
> >                                 reg = <0xffc05000 0x1000>;
> >                                 interrupts = <0 159 4>;
> >                                 emptyfifo_hold_master = <1>;
> >                         };
> >                 };
> >         };
> > };
> > 
> > I wanted to get feeback early before I went too far down this particular
> > path.  As such, this code doesn't do any notification for drivers yet.
> > Also it won't properly add nested nodes yet.  It can add/remove a single
> > node and see it show up properly under /proc/device-tree.
> 
> Have you looked at arch/powerpc/platforms/pseries/reconfig.c?
Yes.  In fact I borrowed a three functions from it and gave credit in
the patch.  I'm trying to do something that is architecture independent
and that uses the same type of device tree files (blobs) as are used
during bootup. In my case it will run on an ARM which will have soft
peripherals instantiated in a FPGA.  So after bootup we want to be able
to reconfigure the IP in the FPGA dynamically, then reconfigure the
device tree and load some drivers.  Pretty cool stuff.That's why I'm
interested in doing this dynamically without a reboot.


> There was also a recent discussion titled "OF_DYNAMIC usage" that you
> should look at.
> 
> I don't think a char driver and ioctls will fly...
Doh!  Yes, I know the thread.  For some reason, I thought it would be
better to post a patch as a new thread rather than posting a patch to
the "OF_DYNAMIC usage" thread but perhaps not.  Sorry for forking the
discussion.

That is where I got the idea of doing ioctls.  I am assuming that
there's only going to be one proper place in the tree for each blob to
get inserted, so I leave that path information in the blob rather than
storing it passing it as a separate parameter of the ioctl.

reconfig.c's interface is pretty bad.  It uses /proc as the place for
the user to write commands.  The commands are broken up such that the
userspace has to 'add _node', then do 'add_property' a few times.  Also
it had to introduce a flag "OF_DYNAMIC" (not to be confused with
"CONFIG_OF_DYNAMIC") to keep of_node_release from releasing the nodes
that are allocated in reconfig.c.  Seems messy.

With an ioctl, the userspace can just send a single command to add a
blob.  The blob can contain one node or many nodes as long as they all
end up under the same path.  Removing nodes is just as straightforward
and clean.

> 
> Another option could be kexecing with a new DTB if you can live with a
> reboot.
We are looking at reconfiguring soft peripheral in a FPGA on the fly.
So a reboot won't work here.

> 
> Rob
> 
> > 
> > Alan Tull
> > Altera
> > 
> > _______________________________________________
> > devicetree-discuss mailing list
> > devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> > https://lists.ozlabs.org/listinfo/devicetree-discuss
> > 
> 
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: dynamic device tree char driver
  2012-08-21 14:38       ` Alan Tull
@ 2012-08-21 16:51         ` Rob Herring
       [not found]           ` <5033BCAE.6080902-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Rob Herring @ 2012-08-21 16:51 UTC (permalink / raw)
  To: Alan Tull; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On 08/21/2012 09:38 AM, Alan Tull wrote:
> On Sat, 2012-08-18 at 10:45 -0500, Rob Herring wrote:
>> On 08/16/2012 02:43 PM, Alan Tull wrote:
>>>
>>> Hello,
>>>
>>> I'm Alan Tull, interested in dynamic features of device trees.
>>
>> Hey Alan. How are you doing?
> Doing good! Nice to hear from you.
> 
>>
>>> The following patch adds a char driver to add or remove device tree
>>> nodes dynamically.  Its ioctl passes a struct with:
>>>  - size of the blob
>>>  - pointer to the blob
>>>
>>> The path to add the nodes under is coded in the blob with dummy nodes.
>>> For example the following can be compiled into a blob and sent to this
>>> driver adding a single node under /soc/apb_periphs:
>>>
>>> /dts-v1/;
>>> / {
>>>         soc {
>>>                 apb_periphs {
>>>                         i2c1: i2c@ffc05000 {
>>>                                 compatible = "snps,designware-i2c";
>>>                                 reg = <0xffc05000 0x1000>;
>>>                                 interrupts = <0 159 4>;
>>>                                 emptyfifo_hold_master = <1>;
>>>                         };
>>>                 };
>>>         };
>>> };
>>>
>>> I wanted to get feeback early before I went too far down this particular
>>> path.  As such, this code doesn't do any notification for drivers yet.
>>> Also it won't properly add nested nodes yet.  It can add/remove a single
>>> node and see it show up properly under /proc/device-tree.
>>
>> Have you looked at arch/powerpc/platforms/pseries/reconfig.c?
> Yes.  In fact I borrowed a three functions from it and gave credit in
> the patch.  I'm trying to do something that is architecture independent
> and that uses the same type of device tree files (blobs) as are used
> during bootup. In my case it will run on an ARM which will have soft
> peripherals instantiated in a FPGA.  So after bootup we want to be able
> to reconfigure the IP in the FPGA dynamically, then reconfigure the
> device tree and load some drivers.  Pretty cool stuff.That's why I'm
> interested in doing this dynamically without a reboot.
> 
> 
>> There was also a recent discussion titled "OF_DYNAMIC usage" that you
>> should look at.
>>
>> I don't think a char driver and ioctls will fly...
> Doh!  Yes, I know the thread.  For some reason, I thought it would be
> better to post a patch as a new thread rather than posting a patch to
> the "OF_DYNAMIC usage" thread but perhaps not.  Sorry for forking the
> discussion.

The fork is fine. Just making sure you were aware of it.

> That is where I got the idea of doing ioctls.  I am assuming that
> there's only going to be one proper place in the tree for each blob to
> get inserted, so I leave that path information in the blob rather than
> storing it passing it as a separate parameter of the ioctl.

ioctls simply won't fly. So I would start by extending the current
interface to do blobs. From a user standpoint, something like this is
certainly easier to use than an ioctl:

echo "add blob" > /proc/devicetree/ofdt
cat blob.dtb > /proc/devicetree/ofdt

> reconfig.c's interface is pretty bad.  It uses /proc as the place for
> the user to write commands.  The commands are broken up such that the
> userspace has to 'add _node', then do 'add_property' a few times.  Also
> it had to introduce a flag "OF_DYNAMIC" (not to be confused with
> "CONFIG_OF_DYNAMIC") to keep of_node_release from releasing the nodes
> that are allocated in reconfig.c.  Seems messy.
> 
> With an ioctl, the userspace can just send a single command to add a
> blob.  The blob can contain one node or many nodes as long as they all
> end up under the same path.  Removing nodes is just as straightforward
> and clean.

Whether paths are part of the blob are debatable. I'm sure you and your
competitors can put your heads together and come up with something. :)

Rob

>>
>> Another option could be kexecing with a new DTB if you can live with a
>> reboot.
> We are looking at reconfiguring soft peripheral in a FPGA on the fly.
> So a reboot won't work here.
> 
>>
>> Rob
>>
>>>
>>> Alan Tull
>>> Altera
>>>
>>> _______________________________________________
>>> devicetree-discuss mailing list
>>> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
>>> https://lists.ozlabs.org/listinfo/devicetree-discuss
>>>
>>
>>
> 
> 
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: dynamic device tree char driver
       [not found]           ` <5033BCAE.6080902-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2012-08-21 18:55             ` Alan Tull
  0 siblings, 0 replies; 6+ messages in thread
From: Alan Tull @ 2012-08-21 18:55 UTC (permalink / raw)
  To: robherring2-Re5JQEeQqe8AvxtiuMwx3w
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On Tue, 2012-08-21 at 11:51 -0500, Rob Herring wrote:
> On 08/21/2012 09:38 AM, Alan Tull wrote:
> > On Sat, 2012-08-18 at 10:45 -0500, Rob Herring wrote:
> >> On 08/16/2012 02:43 PM, Alan Tull wrote:
> >>>
> >>> Hello,
> >>>
> >>> I'm Alan Tull, interested in dynamic features of device trees.
> >>
> >> Hey Alan. How are you doing?
> > Doing good! Nice to hear from you.
> >
> >>
> >>> The following patch adds a char driver to add or remove device tree
> >>> nodes dynamically.  Its ioctl passes a struct with:
> >>>  - size of the blob
> >>>  - pointer to the blob
> >>>
> >>> The path to add the nodes under is coded in the blob with dummy nodes.
> >>> For example the following can be compiled into a blob and sent to this
> >>> driver adding a single node under /soc/apb_periphs:
> >>>
> >>> /dts-v1/;
> >>> / {
> >>>         soc {
> >>>                 apb_periphs {
> >>>                         i2c1: i2c@ffc05000 {
> >>>                                 compatible = "snps,designware-i2c";
> >>>                                 reg = <0xffc05000 0x1000>;
> >>>                                 interrupts = <0 159 4>;
> >>>                                 emptyfifo_hold_master = <1>;
> >>>                         };
> >>>                 };
> >>>         };
> >>> };
> >>>
> >>> I wanted to get feeback early before I went too far down this particular
> >>> path.  As such, this code doesn't do any notification for drivers yet.
> >>> Also it won't properly add nested nodes yet.  It can add/remove a single
> >>> node and see it show up properly under /proc/device-tree.
> >>
> >> Have you looked at arch/powerpc/platforms/pseries/reconfig.c?
> > Yes.  In fact I borrowed a three functions from it and gave credit in
> > the patch.  I'm trying to do something that is architecture independent
> > and that uses the same type of device tree files (blobs) as are used
> > during bootup. In my case it will run on an ARM which will have soft
> > peripherals instantiated in a FPGA.  So after bootup we want to be able
> > to reconfigure the IP in the FPGA dynamically, then reconfigure the
> > device tree and load some drivers.  Pretty cool stuff.That's why I'm
> > interested in doing this dynamically without a reboot.
> >
> >
> >> There was also a recent discussion titled "OF_DYNAMIC usage" that you
> >> should look at.
> >>
> >> I don't think a char driver and ioctls will fly...
> > Doh!  Yes, I know the thread.  For some reason, I thought it would be
> > better to post a patch as a new thread rather than posting a patch to
> > the "OF_DYNAMIC usage" thread but perhaps not.  Sorry for forking the
> > discussion.
>
> The fork is fine. Just making sure you were aware of it.
>
> > That is where I got the idea of doing ioctls.  I am assuming that
> > there's only going to be one proper place in the tree for each blob to
> > get inserted, so I leave that path information in the blob rather than
> > storing it passing it as a separate parameter of the ioctl.
>
> ioctls simply won't fly. So I would start by extending the current
> interface to do blobs. From a user standpoint, something like this is
> certainly easier to use than an ioctl:
>
> echo "add blob" > /proc/devicetree/ofdt
> cat blob.dtb > /proc/devicetree/ofdt

That does have the advantage of not needing a userspace app.  But
something could write to /proc/devicetree/ofdt between the echo and the
cat.  A way to prevent that would be

echo "add blob" > add.txt
cat add.txt blob.dtb > /proc/devicetree/ofdt

In real world use, there would be a set of dtb's and a userspace app
that would prepend the "add blob" command when sending it to proc.

I am a bit surprised that it is considered fine to cat a binary file
to /proc.  I'm used to thinking that as all being readable text.

>
> > reconfig.c's interface is pretty bad.  It uses /proc as the place for
> > the user to write commands.  The commands are broken up such that the
> > userspace has to 'add _node', then do 'add_property' a few times.  Also
> > it had to introduce a flag "OF_DYNAMIC" (not to be confused with
> > "CONFIG_OF_DYNAMIC") to keep of_node_release from releasing the nodes
> > that are allocated in reconfig.c.  Seems messy.
> >
> > With an ioctl, the userspace can just send a single command to add a
> > blob.  The blob can contain one node or many nodes as long as they all
> > end up under the same path.  Removing nodes is just as straightforward
> > and clean.
>
> Whether paths are part of the blob are debatable. I'm sure you and your
> competitors can put your heads together and come up with something. :)
>
> Rob
>
> >>
> >> Another option could be kexecing with a new DTB if you can live with a
> >> reboot.
> > We are looking at reconfiguring soft peripheral in a FPGA on the fly.
> > So a reboot won't work here.
> >
> >>
> >> Rob
> >>
> >>>
> >>> Alan Tull
> >>> Altera
> >>>
> >>> _______________________________________________
> >>> devicetree-discuss mailing list
> >>> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> >>> https://lists.ozlabs.org/listinfo/devicetree-discuss
> >>>
> >>
> >>
> >
> >
> >
>
>


Confidentiality Notice.
This message may contain information that is confidential or otherwise protected from disclosure. If you are not the intended recipient, you are hereby notified that any use, disclosure, dissemination, distribution,  or copying  of this message, or any attachments, is strictly prohibited.  If you have received this message in error, please advise the sender by reply e-mail, and delete the message and any attachments.  Thank you.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-08-21 18:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-16 19:43 dynamic device tree char driver Alan Tull
     [not found] ` <1345146226-32675-1-git-send-email-atull-EIB2kfCEclfQT0dZR+AlfA@public.gmane.org>
2012-08-16 19:43   ` [PATCH 1/1] " Alan Tull
2012-08-18 15:45   ` Rob Herring
     [not found]     ` <502FB8A9.4030907-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2012-08-21 14:38       ` Alan Tull
2012-08-21 16:51         ` Rob Herring
     [not found]           ` <5033BCAE.6080902-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2012-08-21 18:55             ` Alan Tull

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).