[PATCH v2 2/7] fdt: Add function to allow aliases to refer to multiple nodes

Subsystems: library code, the rest

STALE5287d

5 messages, 2 authors, 2012-01-20 · open the first message on its own page

[PATCH v2 2/7] fdt: Add function to allow aliases to refer to multiple nodes

From: Simon Glass <sjg@chromium.org>
Date: 2012-01-12 19:00:13

Some devices can deal with multiple compatible properties. The devices
need to know which nodes to bind to which features. For example an
I2C driver which supports two different controller types will want to
know which type it is dealing with in each case.

The new fdtdec_add_aliases_for_id() function deals with this by allowing
the driver to search for additional compatible nodes for a different ID.
It can then detect the new ones and perform appropriate processing.

Another option considered was to return a tuple (node offset, compat id)
and have the function be passed a list of compatible IDs. This is more
overhead for the common case though. We may add such a function later if
more drivers in U-Boot require it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/fdtdec.h |   15 +++++++++++++++
 lib/fdtdec.c     |   16 ++++++++++++----
 2 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/include/fdtdec.h b/include/fdtdec.h
index bd2222c..e6d63f9 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -200,6 +200,21 @@ int fdtdec_find_aliases_for_id(const void *blob, const char *name,
 			enum fdt_compat_id id, int *node_list, int maxcount);
 
 /*
+ * This function is similar to fdtdec_find_aliases_for_id() except that it
+ * adds to the node_list that is passed in. Any 0 elements are considered
+ * available for allocation - others are considered already used and are
+ * skipped.
+ *
+ * You can use this by calling fdtdec_find_aliases_for_id() with an
+ * uninitialised array, then setting the elements that are returned to -1,
+ * say, then calling this function, perhaps with a different compat id.
+ * Any elements you get back that are >0 are new nodes added by the call
+ * to this function.
+ */
+int fdtdec_add_aliases_for_id(const void *blob, const char *name,
+			enum fdt_compat_id id, int *node_list, int maxcount);
+
+/*
  * Get the name for a compatible ID
  *
  * @param id		Compatible ID to look for
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index daf2c7e..ddd56b9 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -151,10 +151,18 @@ int fdtdec_next_alias(const void *blob, const char *name,
 	return node;
 }
 
-/* TODO: Can we tighten this code up a little? */
 int fdtdec_find_aliases_for_id(const void *blob, const char *name,
 			enum fdt_compat_id id, int *node_list, int maxcount)
 {
+	memset(node_list, '\0', sizeof(*node_list) * maxcount);
+
+	return fdtdec_add_aliases_for_id(blob, name, id, node_list, maxcount);
+}
+
+/* TODO: Can we tighten this code up a little? */
+int fdtdec_add_aliases_for_id(const void *blob, const char *name,
+			enum fdt_compat_id id, int *node_list, int maxcount)
+{
 	int name_len = strlen(name);
 	int nodes[maxcount];
 	int num_found = 0;
@@ -184,8 +192,6 @@ int fdtdec_find_aliases_for_id(const void *blob, const char *name,
 		       __func__, name);
 
 	/* Now find all the aliases */
-	memset(node_list, '\0', sizeof(*node_list) * maxcount);
-
 	for (offset = fdt_first_property_offset(blob, alias_node);
 			offset > 0;
 			offset = fdt_next_property_offset(blob, offset)) {
@@ -232,11 +238,13 @@ int fdtdec_find_aliases_for_id(const void *blob, const char *name,
 		 * it as done.
 		 */
 		if (fdtdec_get_is_enabled(blob, node)) {
+			if (node_list[number])
+				continue;
 			node_list[number] = node;
 			if (number >= num_found)
 				num_found = number + 1;
 		}
-		nodes[j] = 0;
+		nodes[found] = 0;
 	}
 
 	/* Add any nodes not mentioned by an alias */
-- 
1.7.7.3

Re: [PATCH v2 2/7] fdt: Add function to allow aliases to refer to multiple nodes

From: Stephen Warren <hidden>
Date: 2012-01-19 20:49:01

On 01/12/2012 12:00 PM, Simon Glass wrote:
Some devices can deal with multiple compatible properties. The devices
need to know which nodes to bind to which features. For example an
I2C driver which supports two different controller types will want to
know which type it is dealing with in each case.

The new fdtdec_add_aliases_for_id() function deals with this by allowing
the driver to search for additional compatible nodes for a different ID.
It can then detect the new ones and perform appropriate processing.

Another option considered was to return a tuple (node offset, compat id)
and have the function be passed a list of compatible IDs. This is more
overhead for the common case though. We may add such a function later if
more drivers in U-Boot require it.
+int fdtdec_add_aliases_for_id(const void *blob, const char *name,
+			enum fdt_compat_id id, int *node_list, int maxcount)
...
quoted hunk
@@ -232,11 +238,13 @@ int fdtdec_find_aliases_for_id(const void *blob, const char *name,
 		 * it as done.
 		 */
 		if (fdtdec_get_is_enabled(blob, node)) {
+			if (node_list[number])
+				continue;
 			node_list[number] = node;
 			if (number >= num_found)
 				num_found = number + 1;
 		}
-		nodes[j] = 0;
+		nodes[found] = 0;
 	}
 
 	/* Add any nodes not mentioned by an alias */
Aren't those two changes really bug-fixes to the underlying patch rather
than part of this enhancement?

I'm not convinced this patch is correct in all cases. It'll probably
work fine for simply device-trees though. Consider the following case:

4 device nodes
A: compat=i2c alias for usb0
B: compat=i2c no alias
C: compat=i2c alias for usb2
D: compat=i2cx alias for usb1

First, we search for all compat=i2c, the list comes back:

0=A
1=B
2=C

Then we search for all compat=i2cx, the list comes back:

-1
-1
-1
D

So D's alias of 1 isn't honored even though if both IDs were searched
for together, it would have been.

Also, what about the scenario where a driver searches for both
nvidia,tegra20-i2c then later nvidia,tegra30-i2c, given that all the DT
nodes are probably compatible with both?

-- 
nvpublic

Re: [PATCH v2 2/7] fdt: Add function to allow aliases to refer to multiple nodes

From: Simon Glass <sjg@chromium.org>
Date: 2012-01-19 23:45:29

Hi Stephen,

On Thu, Jan 19, 2012 at 12:49 PM, Stephen Warren [off-list ref] wrote:
On 01/12/2012 12:00 PM, Simon Glass wrote:
quoted
Some devices can deal with multiple compatible properties. The devices
need to know which nodes to bind to which features. For example an
I2C driver which supports two different controller types will want to
know which type it is dealing with in each case.

The new fdtdec_add_aliases_for_id() function deals with this by allowing
the driver to search for additional compatible nodes for a different ID.
It can then detect the new ones and perform appropriate processing.

Another option considered was to return a tuple (node offset, compat id)
and have the function be passed a list of compatible IDs. This is more
overhead for the common case though. We may add such a function later if
more drivers in U-Boot require it.
quoted
+int fdtdec_add_aliases_for_id(const void *blob, const char *name,
+                     enum fdt_compat_id id, int *node_list, int maxcount)
...
quoted
@@ -232,11 +238,13 @@ int fdtdec_find_aliases_for_id(const void *blob, const char *name,
               * it as done.
               */
              if (fdtdec_get_is_enabled(blob, node)) {
+                     if (node_list[number])
+                             continue;
                      node_list[number] = node;
                      if (number >= num_found)
                              num_found = number + 1;
              }
-             nodes[j] = 0;
+             nodes[found] = 0;
      }

      /* Add any nodes not mentioned by an alias */
Aren't those two changes really bug-fixes to the underlying patch rather
than part of this enhancement?
Clean-ups maybe. The first change can change behaviour when someone
has two aliases the same. The second is equivalent (j == found) but
nicer I think.
I'm not convinced this patch is correct in all cases. It'll probably
work fine for simply device-trees though. Consider the following case:

4 device nodes
A: compat=i2c alias for usb0
B: compat=i2c no alias
C: compat=i2c alias for usb2
D: compat=i2cx alias for usb1

First, we search for all compat=i2c, the list comes back:

0=A
1=B
2=C

Then we search for all compat=i2cx, the list comes back:

-1
-1
-1
D

So D's alias of 1 isn't honored even though if both IDs were searched
for together, it would have been.
Do we really want that behaviour? Overall I think it is a bit odd to
have devices with no aliases if you actually care about the ordering.
At least in U-Boot ordering is important. The simple fix above is to
provide an alias for everything, which is what we do. If we do want
the behaviour you suggest then I will need the change to doing it in
one pass.
Also, what about the scenario where a driver searches for both
nvidia,tegra20-i2c then later nvidia,tegra30-i2c, given that all the DT
nodes are probably compatible with both?
If all DT notes are compatible with both, why are you searching for
one and then the other? Why not just search for one?

It sounds like a decision here as to whether we want a one-pass
algorithm with a list of compatible nodes, or the current additive
priorty-based approach.

Regards,
Simon
--
nvpublic

Re: [PATCH v2 2/7] fdt: Add function to allow aliases to refer to multiple nodes

From: Stephen Warren <hidden>
Date: 2012-01-20 00:17:16

On 01/19/2012 04:45 PM, Simon Glass wrote:
Hi Stephen,

On Thu, Jan 19, 2012 at 12:49 PM, Stephen Warren [off-list ref] wrote:
quoted
On 01/12/2012 12:00 PM, Simon Glass wrote:
quoted
Some devices can deal with multiple compatible properties. The devices
need to know which nodes to bind to which features. For example an
I2C driver which supports two different controller types will want to
know which type it is dealing with in each case.

The new fdtdec_add_aliases_for_id() function deals with this by allowing
the driver to search for additional compatible nodes for a different ID.
It can then detect the new ones and perform appropriate processing.

Another option considered was to return a tuple (node offset, compat id)
and have the function be passed a list of compatible IDs. This is more
overhead for the common case though. We may add such a function later if
more drivers in U-Boot require it.
...
quoted
I'm not convinced this patch is correct in all cases. It'll probably
work fine for simply device-trees though. Consider the following case:

4 device nodes
A: compat=i2c alias for usb0
B: compat=i2c no alias
C: compat=i2c alias for usb2
D: compat=i2cx alias for usb1

First, we search for all compat=i2c, the list comes back:

0=A
1=B
2=C

Then we search for all compat=i2cx, the list comes back:

-1
-1
-1
D

So D's alias of 1 isn't honored even though if both IDs were searched
for together, it would have been.
Do we really want that behaviour? Overall I think it is a bit odd to
have devices with no aliases if you actually care about the ordering.
At least in U-Boot ordering is important. The simple fix above is to
provide an alias for everything, which is what we do. If we do want
the behaviour you suggest then I will need the change to doing it in
one pass.
I think that behaviour is the intended given that DT content. Despite
the fact that content is admittedly a little twisted and perhaps not
commonly useful, since this is user-supplied content in general, I don't
think we can simply not accept it or not implement the fairly obvious
intent.
quoted
Also, what about the scenario where a driver searches for both
nvidia,tegra20-i2c then later nvidia,tegra30-i2c, given that all the DT
nodes are probably compatible with both?
If all DT notes are compatible with both, why are you searching for
one and then the other? Why not just search for one?
I suppose one /shouldn't/ need to.

I was thinking of supporting the case where somebody only wrote
compatible = "nvidia,tegra30-i2c" and left out the Tegra20 variant.
Still, is arguably a bug, and that won't work in the kernel either since
we're not going around adding all the new compatible values into the
drivers when the devices are compatible with the existing HW anyway.

I guess if we do get some legitimate case that trips this issue, we can
just fix it then, since it's entirely isolated to the code and doesn't
impact anything externally visible etc.

-- 
nvpublic

Re: [PATCH v2 2/7] fdt: Add function to allow aliases to refer to multiple nodes

From: Simon Glass <sjg@chromium.org>
Date: 2012-01-20 00:31:43

Hi Stephen,

On Thu, Jan 19, 2012 at 4:17 PM, Stephen Warren [off-list ref] wrote:
On 01/19/2012 04:45 PM, Simon Glass wrote:
quoted
Hi Stephen,

On Thu, Jan 19, 2012 at 12:49 PM, Stephen Warren [off-list ref] wrote:
quoted
On 01/12/2012 12:00 PM, Simon Glass wrote:
quoted
Some devices can deal with multiple compatible properties. The devices
need to know which nodes to bind to which features. For example an
I2C driver which supports two different controller types will want to
know which type it is dealing with in each case.

The new fdtdec_add_aliases_for_id() function deals with this by allowing
the driver to search for additional compatible nodes for a different ID.
It can then detect the new ones and perform appropriate processing.

Another option considered was to return a tuple (node offset, compat id)
and have the function be passed a list of compatible IDs. This is more
overhead for the common case though. We may add such a function later if
more drivers in U-Boot require it.
...
quoted
quoted
I'm not convinced this patch is correct in all cases. It'll probably
work fine for simply device-trees though. Consider the following case:

4 device nodes
A: compat=i2c alias for usb0
B: compat=i2c no alias
C: compat=i2c alias for usb2
D: compat=i2cx alias for usb1

First, we search for all compat=i2c, the list comes back:

0=A
1=B
2=C

Then we search for all compat=i2cx, the list comes back:

-1
-1
-1
D

So D's alias of 1 isn't honored even though if both IDs were searched
for together, it would have been.
Do we really want that behaviour? Overall I think it is a bit odd to
have devices with no aliases if you actually care about the ordering.
At least in U-Boot ordering is important. The simple fix above is to
provide an alias for everything, which is what we do. If we do want
the behaviour you suggest then I will need the change to doing it in
one pass.
I think that behaviour is the intended given that DT content. Despite
the fact that content is admittedly a little twisted and perhaps not
commonly useful, since this is user-supplied content in general, I don't
think we can simply not accept it or not implement the fairly obvious
intent.
quoted
quoted
Also, what about the scenario where a driver searches for both
nvidia,tegra20-i2c then later nvidia,tegra30-i2c, given that all the DT
nodes are probably compatible with both?
If all DT notes are compatible with both, why are you searching for
one and then the other? Why not just search for one?
I suppose one /shouldn't/ need to.

I was thinking of supporting the case where somebody only wrote
compatible = "nvidia,tegra30-i2c" and left out the Tegra20 variant.
Still, is arguably a bug, and that won't work in the kernel either since
we're not going around adding all the new compatible values into the
drivers when the devices are compatible with the existing HW anyway.

I guess if we do get some legitimate case that trips this issue, we can
just fix it then, since it's entirely isolated to the code and doesn't
impact anything externally visible etc.
Hmmm well perhaps I should add a code comment and see how we go. It
would be nice if this situation could be spotted. I am concerned about
anything that is non-obvious here. Will take a look but otherwise it
sounds like we can punt this until later (unless we decide to move to
the one-pass option).

Anyway this is in a place by itself with unit tests so we should be
able to fiddle if needed.

Regards,
Simon
--
nvpublic
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help