aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2016-06-09 01:50:49 -0400
committerRob Herring <robh@kernel.org>2016-06-09 15:36:34 -0400
commit8c237cd0ccb570d13158758af02e11359a4a5b1c (patch)
tree5180e8610b892fd9993e00996adf98df492c3b53
parent5c1d3310d84309330264e2a06e5000eb289a44ad (diff)
drivers/of: Fix depth for sub-tree blob in unflatten_dt_nodes()
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@nvidia.com> Fixes: 78c44d910 ("drivers/of: Fix depth when unflattening devicetree") Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Tested-by: Rhyland Klein <rklein@nvidia.com> Tested-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> Signed-off-by: Rob Herring <robh@kernel.org>
-rw-r--r--drivers/of/fdt.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 14f2f8c7c260..33daffc4392c 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -395,7 +395,7 @@ static int unflatten_dt_nodes(const void *blob,
395 struct device_node **nodepp) 395 struct device_node **nodepp)
396{ 396{
397 struct device_node *root; 397 struct device_node *root;
398 int offset = 0, depth = 0; 398 int offset = 0, depth = 0, initial_depth = 0;
399#define FDT_MAX_DEPTH 64 399#define FDT_MAX_DEPTH 64
400 unsigned int fpsizes[FDT_MAX_DEPTH]; 400 unsigned int fpsizes[FDT_MAX_DEPTH];
401 struct device_node *nps[FDT_MAX_DEPTH]; 401 struct device_node *nps[FDT_MAX_DEPTH];
@@ -405,11 +405,22 @@ static int unflatten_dt_nodes(const void *blob,
405 if (nodepp) 405 if (nodepp)
406 *nodepp = NULL; 406 *nodepp = NULL;
407 407
408 /*
409 * We're unflattening device sub-tree if @dad is valid. There are
410 * possibly multiple nodes in the first level of depth. We need
411 * set @depth to 1 to make fdt_next_node() happy as it bails
412 * immediately when negative @depth is found. Otherwise, the device
413 * nodes except the first one won't be unflattened successfully.
414 */
415 if (dad)
416 depth = initial_depth = 1;
417
408 root = dad; 418 root = dad;
409 fpsizes[depth] = dad ? strlen(of_node_full_name(dad)) : 0; 419 fpsizes[depth] = dad ? strlen(of_node_full_name(dad)) : 0;
410 nps[depth] = dad; 420 nps[depth] = dad;
421
411 for (offset = 0; 422 for (offset = 0;
412 offset >= 0 && depth >= 0; 423 offset >= 0 && depth >= initial_depth;
413 offset = fdt_next_node(blob, offset, &depth)) { 424 offset = fdt_next_node(blob, offset, &depth)) {
414 if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH)) 425 if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH))
415 continue; 426 continue;