On 22/11/20 4:37 am, Simon Glass wrote:
> Hi,
> 
> On Wed, 18 Nov 2020 at 10:55, Vignesh Raghavendra <vigne...@ti.com> wrote:
>>
>>
>>
>> On 11/18/20 8:44 PM, Aswath Govindraju wrote:
>>> Hi Simon,
>>>
>>> On 18/11/20 8:07 pm, Simon Glass wrote:
>>>> Hi Aswath,
>>>>
>>>> On Mon, 16 Nov 2020 at 07:29, Aswath Govindraju <a-govindr...@ti.com> 
>>>> wrote:
>>>>>
>>>>> While assigning the sequence number to subsystem instances by reading the
>>>>> aliases property, only DT nodes names are compared and not the complete
>>>>> path. This causes a problem when there are two DT nodes with same name but
>>>>> have different paths.
>>>>>
>>>>> Fix it by comparing the phandles of DT nodes after the node names match.
>>>>>
>>>>> Signed-off-by: Aswath Govindraju <a-govindr...@ti.com>
>>>>> ---
>>>>>
>>>>> Resending this patch as it was held awaiting for moderator approval 
>>>>> because
>>>>> patch was sent by non-member.
>>>>>
>>>>>  lib/fdtdec.c | 5 +++++
>>>>>  1 file changed, 5 insertions(+)
>>>>>
>>>>> diff --git a/lib/fdtdec.c b/lib/fdtdec.c
>>>>> index 2015907dee7d..9e1bfe0b519e 100644
>>>>> --- a/lib/fdtdec.c
>>>>> +++ b/lib/fdtdec.c
>>>>> @@ -478,6 +478,11 @@ int fdtdec_get_alias_seq(const void *blob, const 
>>>>> char *base, int offset,
>>>>>                 slash = strrchr(prop, '/');
>>>>>                 if (strcmp(slash + 1, find_name))
>>>>>                         continue;
>>>>> +
>>>>> +               if (fdt_get_phandle(blob, offset) !=
>>>>> +                   fdt_get_phandle(blob, fdt_path_offset(blob, prop)))
>>>>> +                       continue;
>>>>
>>>> The call to fdt_path_offset() is very slow. Perhaps we can do this
>>>> check only with livetree? What situation is causing a problem for you?
>>>> What are the node / alias names?
>>>
>>> In the case of live tree for getting the sequence number the node
>>> pointers are compared. So, I don't think this problem would come up.
>>>
>>> As for the use case,
>>>
>>> In AM654 Device tree there are two instances of USB controllers and both
>>> the controller nodes have the same name usb@10000
>>>
>>> If dfu is performed through the port connected to second controller.
>>> Then based on the dr_mode of first controller the instance number to be
>>> used in dfu command will vary. In order to make the instance number for
>>> dfu command to be independent, aliases can be used(If aliases are
>>> defined then the sequence number is assigned as the alias number.).
>>>
>>> The problem with current method for acquiring sequence number using
>>> aliases is that only the name of the node is compared with node name
>>> from the aliases property. So in the above case both the controllers
>>> will have the same name. This leads to the first alias number being used
>>> for the both the controllers to assign sequence number.
>>>
>>>
>>> aliases {
>>>                 serial2 = &main_uart0;
>>>                 ethernet0 = &cpsw_port1;
>>>                 usb0 = &usb0;            // This property being used to
>>>                                       //alias both the controllers
>>>                 usb1 = &usb1;
>>>         };
>>
>>
>> To explain a bit more, here is the DT snippet around usb0 and usb1
>>
>>         dwc3_0: dwc3@4000000 {
>>                 compatible = "ti,am654-dwc3";
>>                 reg = <0x0 0x4000000 0x0 0x4000>;
>>                 #address-cells = <1>;
>>                 #size-cells = <1>;
>>                 ranges = <0x0 0x0 0x4000000 0x20000>;
>>                 ...
>>
>>                 usb0: usb@10000 {
>>                         compatible = "snps,dwc3";
>>                         reg = <0x10000 0x10000>;
>>                         ...
>>                 };
>>         };
>>
>>         dwc3_1: dwc3@4020000 {
>>                 compatible = "ti,am654-dwc3";
>>                 reg = <0x0 0x4020000 0x0 0x4000>;
>>                 #address-cells = <1>;
>>                 #size-cells = <1>;
>>                 ranges = <0x0 0x0 0x4020000 0x20000>;
>>                 ...
>>
>>                 usb1: usb@10000 {
>>                         compatible = "snps,dwc3";
>>                         reg = <0x10000 0x10000>;
>>                         ...
>>                 };
>>         };
>>
>> In above case, (with CONFIG_OF_LIVE disabled),
>> fdtdec_get_alias_seq() fails to pick the correct instance for USB
>> controller for a given index. This is because fdtdec_get_alias_seq()
>> only compares the leaf node name (usb@10000) with alias path and thus
>> both usb instances match to usb0.
>>
>>>
>>> So, to distinguish nodes with same name, phandles can be used while
>>> assigning sequence numbers.
> 

I apologize for the delay in response.


> Thank you both for the detai. I understand it and in fact I think this
> has come up before.
> 
> Would it be OK to use livetree?
> 
Currently live tree has not been enabled in the configurations of the
AM65 board and there are some issues that I am facing after enabling it.

> If not, can we put this code behind a Kconfig so the extra time
> penalty is only incurred on boards that need it?
> 

I think putting it under Kconfig is a good idea and I think I will do that.

Also, I have alternate method to implement the comparison that does not
use fdt_path_offset(), compares by getting the path name. I have
attached it to this mail. I think it is slightly better in terms of time
penalty. Can you please look at it and suggest if it is better to implement.

Thanks,
Aswath


> Regards,
> Simon
> 

>From 9effa3d192aca526d3c37a76ded011bdd21a92ca Mon Sep 17 00:00:00 2001
From: Aswath Govindraju <a-govindr...@ti.com>
Date: Tue, 24 Nov 2020 01:00:12 +0530
Subject: [PATCH] Check the complete path after node names match

Signed-off-by: Aswath Govindraju <a-govindr...@ti.com>
---
 lib/fdtdec.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index ee1bd41b0818..529e9aff6f92 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -479,6 +479,10 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
 	int prop_offset;
 	int aliases;
 
+	int parent_offset;
+	const char *parent_name;
+	int parent_namelen;
+
 	find_name = fdt_get_name(blob, offset, &find_namelen);
 	debug("Looking for '%s' at %d, name %s\n", base, offset, find_name);
 
@@ -491,6 +495,9 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
 		const char *slash;
 		int len, val;
 
+		bool flag = false;
+		const char *p;
+
 		prop = fdt_getprop_by_offset(blob, prop_offset, &name, &len);
 		debug("   - %s, %s\n", name, prop);
 		if (len < find_namelen || *prop != '/' || prop[len - 1] ||
@@ -500,6 +507,22 @@ int fdtdec_get_alias_seq(const void *blob, const char *base, int offset,
 		slash = strrchr(prop, '/');
 		if (strcmp(slash + 1, find_name))
 			continue;
+
+		parent_offset = fdt_parent_offset(blob, offset);
+		while ((parent_offset > 0) && (!flag)) {
+			parent_name = fdt_get_name(blob, parent_offset, &parent_namelen);
+			p = parent_name + parent_namelen - 1;
+			do {
+				if (*(--slash) != *p)
+					flag = true;
+			} while ((--p >= parent_name) && (!flag));
+			parent_offset = fdt_parent_offset(blob, parent_offset);
+			--slash;
+		}
+
+		if (flag)
+			continue;
+
 		val = trailing_strtol(name);
 		if (val != -1) {
 			*seqp = val;
-- 
2.17.1

Reply via email to