From patchwork Thu Aug 6 04:11:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Shan X-Patchwork-Id: 6955791 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 6F4B4C05AD for ; Thu, 6 Aug 2015 04:14:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C5FEB203E3 for ; Thu, 6 Aug 2015 04:14:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BAA1D20638 for ; Thu, 6 Aug 2015 04:14:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754272AbbHFEOG (ORCPT ); Thu, 6 Aug 2015 00:14:06 -0400 Received: from e23smtp03.au.ibm.com ([202.81.31.145]:36758 "EHLO e23smtp03.au.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752466AbbHFENR (ORCPT ); Thu, 6 Aug 2015 00:13:17 -0400 Received: from /spool/local by e23smtp03.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 6 Aug 2015 14:13:15 +1000 Received: from d23dlp02.au.ibm.com (202.81.31.213) by e23smtp03.au.ibm.com (202.81.31.209) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 6 Aug 2015 14:13:13 +1000 X-Helo: d23dlp02.au.ibm.com X-MailFrom: gwshan@linux.vnet.ibm.com X-RcptTo: linux-pci@vger.kernel.org Received: from d23relay09.au.ibm.com (d23relay09.au.ibm.com [9.185.63.181]) by d23dlp02.au.ibm.com (Postfix) with ESMTP id 3A2142BB0066; Thu, 6 Aug 2015 14:13:12 +1000 (EST) Received: from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.234.97]) by d23relay09.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t764D4GC29294668; Thu, 6 Aug 2015 14:13:12 +1000 Received: from d23av03.au.ibm.com (localhost [127.0.0.1]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t764CctR002879; Thu, 6 Aug 2015 14:12:39 +1000 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t764CbON002252; Thu, 6 Aug 2015 14:12:38 +1000 Received: from bran.ozlabs.ibm.com (unknown [9.192.254.114]) by ozlabs.au.ibm.com (Postfix) with ESMTP id 84EFAA0414; Thu, 6 Aug 2015 14:12:12 +1000 (AEST) Received: from gwshan (shangw.ozlabs.ibm.com [10.61.2.199]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 78E66E38F9; Thu, 6 Aug 2015 14:12:12 +1000 (AEST) Received: by gwshan (Postfix, from userid 1000) id 5EE8B94222F; Thu, 6 Aug 2015 14:12:12 +1000 (AEST) From: Gavin Shan To: linuxppc-dev@lists.ozlabs.org Cc: linux-pci@vger.kernel.org, devicetree@vger.kernel.org, benh@kernel.crashing.org, mpe@ellerman.id.au, bhelgaas@google.com, grant.likely@linaro.org, robherring2@gmail.com, panto@antoniou-consulting.com, aik@ozlabs.ru, Gavin Shan Subject: [PATCH v6 38/42] drivers/of: Unflatten subordinate nodes after specified level Date: Thu, 6 Aug 2015 14:11:43 +1000 Message-Id: <1438834307-26960-39-git-send-email-gwshan@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1438834307-26960-1-git-send-email-gwshan@linux.vnet.ibm.com> References: <1438834307-26960-1-git-send-email-gwshan@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15080604-0009-0000-0000-000001DABBFA Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP unflatten_dt_node() is called recursively to unflatten FDT nodes with the assumption that FDT blob has only one root node, which isn't true when the FDT blob represents device sub-tree. This improves the function to supporting device sub-tree that have multiple nodes in the first level: * Rename original unflatten_dt_node() to __unflatten_dt_node(). * Wrapper unflatten_dt_node() calls __unflatten_dt_node() with adjusted current node depth to 1 to avoid underflow. Signed-off-by: Gavin Shan Acked-by: Rob Herring --- drivers/of/fdt.c | 53 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 0749656..a18a2ce 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -161,7 +161,7 @@ static void *unflatten_dt_alloc(void **mem, unsigned long size, } /** - * unflatten_dt_node - Alloc and populate a device_node from the flat tree + * __unflatten_dt_node - Alloc and populate a device_node from the flat tree * @blob: The parent device tree blob * @mem: Memory chunk to use for allocating device nodes and properties * @poffset: pointer to node in flat tree @@ -171,20 +171,20 @@ static void *unflatten_dt_alloc(void **mem, unsigned long size, * @dryrun: If true, do not allocate device nodes but still calculate needed * memory size */ -static void * unflatten_dt_node(const void *blob, +static void *__unflatten_dt_node(const void *blob, void *mem, int *poffset, struct device_node *dad, struct device_node **nodepp, unsigned long fpsize, - bool dryrun) + bool dryrun, + int *depth) { const __be32 *p; struct device_node *np; struct property *pp, **prev_pp = NULL; const char *pathp; unsigned int l, allocl; - static int depth = 0; int old_depth; int offset; int has_name = 0; @@ -337,13 +337,25 @@ static void * unflatten_dt_node(const void *blob, np->type = ""; } - old_depth = depth; - *poffset = fdt_next_node(blob, *poffset, &depth); - if (depth < 0) - depth = 0; - while (*poffset > 0 && depth > old_depth) - mem = unflatten_dt_node(blob, mem, poffset, np, NULL, - fpsize, dryrun); + /* Multiple nodes might be in the first depth level if + * the device tree is sub-tree. All nodes in current + * or deeper depth are unflattened after it returns. + */ + old_depth = *depth; + *poffset = fdt_next_node(blob, *poffset, depth); + while (*poffset > 0) { + if (*depth < old_depth) + break; + + if (*depth == old_depth) + mem = __unflatten_dt_node(blob, mem, poffset, + dad, NULL, fpsize, + dryrun, depth); + else if (*depth > old_depth) + mem = __unflatten_dt_node(blob, mem, poffset, + np, NULL, fpsize, + dryrun, depth); + } if (*poffset < 0 && *poffset != -FDT_ERR_NOTFOUND) pr_err("unflatten: error %d processing FDT\n", *poffset); @@ -369,6 +381,20 @@ static void * unflatten_dt_node(const void *blob, return mem; } +static void *unflatten_dt_node(const void *blob, + void *mem, + int *poffset, + struct device_node *dad, + struct device_node **nodepp, + bool dryrun) +{ + int depth = 1; + + return __unflatten_dt_node(blob, mem, poffset, + dad, nodepp, 0, + dryrun, &depth); +} + /** * __unflatten_device_tree - create tree of device_nodes from flat blob * @@ -408,7 +434,8 @@ static void __unflatten_device_tree(const void *blob, /* First pass, scan for size */ start = 0; - size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL, 0, true); + size = (unsigned long)unflatten_dt_node(blob, NULL, &start, + NULL, NULL, true); size = ALIGN(size, 4); pr_debug(" size is %lx, allocating...\n", size); @@ -423,7 +450,7 @@ static void __unflatten_device_tree(const void *blob, /* Second pass, do actual unflattening */ start = 0; - unflatten_dt_node(blob, mem, &start, NULL, mynodes, 0, false); + unflatten_dt_node(blob, mem, &start, NULL, mynodes, false); if (be32_to_cpup(mem + size) != 0xdeadbeef) pr_warning("End of tree marker overwritten: %08x\n", be32_to_cpup(mem + size));