On Wed, Jun 08, 2016 at 11:53:26AM -0400, Rhyland Klein wrote: >On 6/8/2016 2:50 AM, Gavin Shan wrote: >> The function is unflattening device sub-tree blob if @dad passed to >> the function is valid. Currently, this functionality is used by PPC >> PowerNV PCI hotplug driver only. There are possibly multiple nodes >> in the first level of depth, fdt_next_node() bails immediately when >> @depth becomes negative before the second device node can be probed >> successfully. It leads to the device nodes except the first one won't >> be unflattened successfully. >> >> This fixes the issue by setting the initial depth (@inital_depth) to >> 1 when this function is called to unflatten device sub-tree blob. No >> logic changes when this function is used to unflatten non-sub-tree >> blob. >> >> Cc: Rhyland Klein <rklein@xxxxxxxxxx> >> Fixes: 78c44d910 ("drivers/of: Fix depth when unflattening devicetree") >> Signed-off-by: Gavin Shan <gwshan@xxxxxxxxxxxxxxxxxx> >> --- >> drivers/of/fdt.c | 15 +++++++++++++-- >> 1 file changed, 13 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c >> index 14f2f8c..9d70316 100644 >> --- a/drivers/of/fdt.c >> +++ b/drivers/of/fdt.c >> @@ -395,7 +395,7 @@ static int unflatten_dt_nodes(const void *blob, >> struct device_node **nodepp) >> { >> struct device_node *root; >> - int offset = 0, depth = 0; >> + int offset = 0, depth = 0, initial_depth = 0; >> #define FDT_MAX_DEPTH 64 >> unsigned int fpsizes[FDT_MAX_DEPTH]; >> struct device_node *nps[FDT_MAX_DEPTH]; >> @@ -408,8 +408,19 @@ static int unflatten_dt_nodes(const void *blob, >> root = dad; >> fpsizes[depth] = dad ? strlen(of_node_full_name(dad)) : 0; >> nps[depth] = dad; >> + >> + /* >> + * We're unflattening device sub-tree if @dad is valid. There are >> + * possibly multiple nodes in the first level of depth. We need >> + * set @depth to 1 to make fdt_next_node() happy as it bails >> + * immediately when negative @depth is found. Otherwise, the device >> + * nodes except the first one won't be unflattened successfully. >> + */ >> + if (dad) >> + depth = initial_depth = 1; >> + >> for (offset = 0; >> - offset >= 0 && depth >= 0; >> + offset >= 0 && depth >= initial_depth; >> offset = fdt_next_node(blob, offset, &depth)) { >> if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH)) >> continue; >> > >I tested this and it seems to be working fine for me. > >Tested-by: Rhyland Klein <rklein@xxxxxxxxxx> > Rhyland, thanks for your testing. I need send a v2 to adjust the @depth before @fpsizes[depth] and @nps[depth] are initialized, which doesn't affect your case and v2 should work for you. Your tested-by will be included in v2. Thanks, Gavin >-rhyland > >-- >nvpublic > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html