From patchwork Tue Mar 22 17:58:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joerg Roedel X-Patchwork-Id: 8644541 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 49AD69F6E1 for ; Tue, 22 Mar 2016 18:01:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 326C820386 for ; Tue, 22 Mar 2016 18:01:42 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5055120131 for ; Tue, 22 Mar 2016 18:01:40 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aiQav-0006B9-DQ; Tue, 22 Mar 2016 17:59:53 +0000 Received: from 8bytes.org ([2a01:238:4383:600:38bc:a715:4b6d:a889] helo=theia.8bytes.org) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aiQa9-0005i0-5E for linux-arm-kernel@lists.infradead.org; Tue, 22 Mar 2016 17:59:09 +0000 Received: by theia.8bytes.org (Postfix, from userid 1000) id 4B6441B1; Tue, 22 Mar 2016 18:58:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=8bytes.org; s=mail-1; t=1458669515; bh=RJ7C55UWMO1b1FAMwPXm8rlJA1eL9rrjRle+9BYsA68=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AWRp8Y7ujJhpPopn6WmPMaMtXMoKcuiFjZu1X7zOvWH6lbkBXv+I9xSWLEZsdFnbQ PqvK2pdlKLt+yo2K5gOA8Tp0FzKZUY+pWpM6E2JiBpygPK1omqfTzaI0cnoJkfIyUN REGxSA00Et3GOPNx7w23DgI74GTTtBE2DH61BmkLn9WvAwrK/YXB+Fu4NyGSolo83c kUFMxelxM0+LxYH7qYwO9CPULILE7bF8AlR8ApY8IcvFSKkfFXLAbZcddOoNOnME/T 2mLW14R5p7ENoTJZha8liQsgy/ec7h5jH9+7SsQnum+X+47W5QvsD0aHsVkrLXQNO+ XWCOL5aBWPPrQ== From: Joerg Roedel To: Rob Herring , grant.likely@linaro.org Subject: [PATCH 1/6] of: Introduce struct of_phandle_iterator Date: Tue, 22 Mar 2016 18:58:24 +0100 Message-Id: <1458669509-7178-2-git-send-email-joro@8bytes.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1458669509-7178-1-git-send-email-joro@8bytes.org> References: <1458669509-7178-1-git-send-email-joro@8bytes.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160322_105905_691591_FFE582F9 X-CRM114-Status: GOOD ( 20.60 ) X-Spam-Score: -2.0 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, jroedel@suse.de, Will Deacon , linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_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 From: Joerg Roedel This struct carrys all necessary information to iterate over a list of phandles and extract the arguments. Add an init-function for the iterator and make use of it in __of_parse_phandle_with_args(). Signed-off-by: Joerg Roedel --- drivers/of/base.c | 99 +++++++++++++++++++++++++++++++++--------------------- include/linux/of.h | 33 ++++++++++++++++++ 2 files changed, 93 insertions(+), 39 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 017dd94..bfdb09b 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1439,35 +1439,56 @@ void of_print_phandle_args(const char *msg, const struct of_phandle_args *args) printk("\n"); } +int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, + const char *list_name, + const char *cells_name, + int cell_count) +{ + const __be32 *list; + int size; + + memset(it, 0, sizeof(*it)); + + list = of_get_property(np, list_name, &size); + if (!list) + return -ENOENT; + + it->cells_name = cells_name; + it->cell_count = cell_count; + it->parent = np; + it->list_end = list + size / sizeof(*list); + it->phandle_end = list; + it->cur = list; + + return 0; +} + static int __of_parse_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name, int cell_count, int index, struct of_phandle_args *out_args) { - const __be32 *list, *list_end; - int rc = 0, size, cur_index = 0; - uint32_t count = 0; - struct device_node *node = NULL; - phandle phandle; + struct of_phandle_iterator it; + int rc, cur_index = 0; - /* Retrieve the phandle list property */ - list = of_get_property(np, list_name, &size); - if (!list) - return -ENOENT; - list_end = list + size / sizeof(*list); + rc = of_phandle_iterator_init(&it, np, list_name, + cells_name, cell_count); + if (rc) + return rc; /* Loop over the phandles until all the requested entry is found */ - while (list < list_end) { + while (it.cur < it.list_end) { rc = -EINVAL; - count = 0; + it.cur_count = 0; /* * If phandle is 0, then it is an empty entry with no * arguments. Skip forward to the next entry. */ - phandle = be32_to_cpup(list++); - if (phandle) { + it.phandle = be32_to_cpup(it.cur++); + if (it.phandle) { /* * Find the provider node and parse the #*-cells * property to determine the argument length. @@ -1477,34 +1498,34 @@ static int __of_parse_phandle_with_args(const struct device_node *np, * except when we're going to return the found node * below. */ - if (cells_name || cur_index == index) { - node = of_find_node_by_phandle(phandle); - if (!node) { + if (it.cells_name || cur_index == index) { + it.node = of_find_node_by_phandle(it.phandle); + if (!it.node) { pr_err("%s: could not find phandle\n", - np->full_name); + it.parent->full_name); goto err; } } - if (cells_name) { - if (of_property_read_u32(node, cells_name, - &count)) { + if (it.cells_name) { + if (of_property_read_u32(it.node, it.cells_name, + &it.cur_count)) { pr_err("%s: could not get %s for %s\n", - np->full_name, cells_name, - node->full_name); + it.parent->full_name, it.cells_name, + it.node->full_name); goto err; } } else { - count = cell_count; + it.cur_count = it.cell_count; } /* * Make sure that the arguments actually fit in the * remaining property data length */ - if (list + count > list_end) { + if (it.cur + it.cur_count > it.list_end) { pr_err("%s: arguments longer than property\n", - np->full_name); + it.parent->full_name); goto err; } } @@ -1517,28 +1538,28 @@ static int __of_parse_phandle_with_args(const struct device_node *np, */ rc = -ENOENT; if (cur_index == index) { - if (!phandle) + if (!it.phandle) goto err; if (out_args) { int i; - if (WARN_ON(count > MAX_PHANDLE_ARGS)) - count = MAX_PHANDLE_ARGS; - out_args->np = node; - out_args->args_count = count; - for (i = 0; i < count; i++) - out_args->args[i] = be32_to_cpup(list++); + if (WARN_ON(it.cur_count > MAX_PHANDLE_ARGS)) + it.cur_count = MAX_PHANDLE_ARGS; + out_args->np = it.node; + out_args->args_count = it.cur_count; + for (i = 0; i < it.cur_count; i++) + out_args->args[i] = be32_to_cpup(it.cur++); } else { - of_node_put(node); + of_node_put(it.node); } /* Found it! return success */ return 0; } - of_node_put(node); - node = NULL; - list += count; + of_node_put(it.node); + it.node = NULL; + it.cur += it.cur_count; cur_index++; } @@ -1550,8 +1571,8 @@ static int __of_parse_phandle_with_args(const struct device_node *np, */ rc = index < 0 ? cur_index : -ENOENT; err: - if (node) - of_node_put(node); + if (it.node) + of_node_put(it.node); return rc; } diff --git a/include/linux/of.h b/include/linux/of.h index dc6e396..70c2bdb 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -75,6 +75,23 @@ struct of_phandle_args { uint32_t args[MAX_PHANDLE_ARGS]; }; +struct of_phandle_iterator { + /* Common iterator information */ + const char *cells_name; + int cell_count; + const struct device_node *parent; + + /* List size information */ + const __be32 *list_end; + const __be32 *phandle_end; + + /* Current position state */ + const __be32 *cur; + uint32_t cur_count; + phandle phandle; + struct device_node *node; +}; + struct of_reconfig_data { struct device_node *dn; struct property *prop; @@ -334,6 +351,13 @@ extern int of_parse_phandle_with_fixed_args(const struct device_node *np, extern int of_count_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name); +/* phandle iterator functions */ +extern int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, + const char *list_name, + const char *cells_name, + int cell_count); + extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)); extern int of_alias_get_id(struct device_node *np, const char *stem); extern int of_alias_get_highest_id(const char *stem); @@ -608,6 +632,15 @@ static inline int of_count_phandle_with_args(struct device_node *np, return -ENOSYS; } +static inline int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, + const char *list_name, + const char *cells_name, + int cell_count) +{ + return -ENOSYS; +} + static inline int of_alias_get_id(struct device_node *np, const char *stem) { return -ENOSYS;