From patchwork Thu Jun 6 15:47:23 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 2681661 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 3D4363FD4E for ; Thu, 6 Jun 2013 15:47:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751371Ab3FFPrg (ORCPT ); Thu, 6 Jun 2013 11:47:36 -0400 Received: from moutng.kundenserver.de ([212.227.126.171]:58151 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751353Ab3FFPrf (ORCPT ); Thu, 6 Jun 2013 11:47:35 -0400 Received: from axis700.grange (dslb-088-077-167-013.pools.arcor-ip.net [88.77.167.13]) by mrelayeu.kundenserver.de (node=mreu1) with ESMTP (Nemesis) id 0LZjJo-1U5jko06hg-00lm4g; Thu, 06 Jun 2013 17:47:26 +0200 Received: from 6a.grange (6a.grange [192.168.1.11]) by axis700.grange (Postfix) with ESMTPS id B2EE440BB4; Thu, 6 Jun 2013 17:47:25 +0200 (CEST) Received: from lyakh by 6a.grange with local (Exim 4.72) (envelope-from ) id 1UkcPN-0006Aa-JC; Thu, 06 Jun 2013 17:47:25 +0200 From: Guennadi Liakhovetski To: linux-sh@vger.kernel.org Cc: Vinod Koul , devicetree-discuss@lists.ozlabs.org, Rob Herring , Grant Likely , Magnus Damm , Simon Horman , Guennadi Liakhovetski Subject: [PATCH 1/3] OF: add a new phandle parsing function for grouped nodes Date: Thu, 6 Jun 2013 17:47:23 +0200 Message-Id: <1370533645-23690-2-git-send-email-g.liakhovetski@gmx.de> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1370533645-23690-1-git-send-email-g.liakhovetski@gmx.de> References: <1370533645-23690-1-git-send-email-g.liakhovetski@gmx.de> X-Provags-ID: V02:K0:9Ap9OUQJXJfgT8KClaG8ymhfa/qZ6UNmFaNvL/TkPIo huLlZXW2lOTnHbelfcPWoUQPvzzL3Km9ZQ5ZMn8p0772+00LKR I3CMf0jPtteJnku+ULzJTTskSVbYPAzTJ4KFLhmLijiRqsSVU1 eP6ekhGbYZcHuQlxeB3y/UyYnqHxiSOSPrPrfvZnVv5gcPBSp6 ZZtmzEMreKafIOuZPI/63AEEV/X2DQRG8Q/znRyn4Fg0dMSL64 2RDCMNACkqCzzD+HRjbq9VNKFJZEKRqMhuHUA16ZtXCwR04x06 8e572W19B6idbgoDxCyiZ5BmxXP6WXZPbMUw85O9T3wEnEeONv LKZVc0aCju086/gtRVaLhDB/FQgDhp+F1Gw2IEoDEp57CtmPPl B1T+rExE/Lyjw== Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org Sometimes it is useful to group similar DT nodes under a common parent, when a different node can reference the group, meaning, that any subnode will do the job. An example of such a group is a DMA multiplexer, when a DMA slave can be served by any DMA controller from the group. This patch slightly extends an internal __of_parse_phandle_with_args() function to accept one more optional parameter and exports a new API function of_parse_phandle_with_child_args(), which allows the caller to provide a compatibility string for a group. In this case the function returns the first matching node. Once a matching node is found, standard DT iterators can be used to look for further matches. Signed-off-by: Guennadi Liakhovetski Cc: Rob Herring Cc: Grant Likely --- drivers/of/base.c | 28 +++++++++++++++++++++++++--- include/linux/of.h | 16 ++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index f53b992..33d4f3a 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1108,11 +1108,16 @@ EXPORT_SYMBOL(of_parse_phandle); * @cells_name: property name that specifies phandles' arguments count * @index: index of a phandle to parse out * @out_args: optional pointer to output arguments structure (will be filled) + * @parent: optional parent-compatibility string * * This function is useful to parse lists of phandles and their arguments. * Returns 0 on success and fills out_args, on error returns appropriate * errno value. * + * If @parent is specified and the DT node, pointed by the currently iterated + * phandle is compatible with it, it is assumed, that the phandle is a parent of + * DT nodes with equal cell counts. In that case the first child is taken. + * * Caller is responsible to call of_node_put() on the returned out_args->node * pointer. * @@ -1136,7 +1141,8 @@ EXPORT_SYMBOL(of_parse_phandle); static int __of_parse_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name, int index, - struct of_phandle_args *out_args) + struct of_phandle_args *out_args, + const char *parent) { const __be32 *list, *list_end; int rc = 0, size, cur_index = 0; @@ -1171,6 +1177,12 @@ static int __of_parse_phandle_with_args(const struct device_node *np, np->full_name); goto err; } + if (parent && of_device_is_compatible(node, parent)) { + struct device_node *child = + of_get_next_available_child(node, NULL); + of_node_put(node); + node = child; + } if (of_property_read_u32(node, cells_name, &count)) { pr_err("%s: could not get %s for %s\n", np->full_name, cells_name, @@ -1241,10 +1253,20 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na { if (index < 0) return -EINVAL; - return __of_parse_phandle_with_args(np, list_name, cells_name, index, out_args); + return __of_parse_phandle_with_args(np, list_name, cells_name, index, out_args, NULL); } EXPORT_SYMBOL(of_parse_phandle_with_args); +int of_parse_phandle_with_child_args(const struct device_node *np, const char *list_name, + const char *cells_name, int index, + struct of_phandle_args *out_args, const char *parent) +{ + if (index < 0) + return -EINVAL; + return __of_parse_phandle_with_args(np, list_name, cells_name, index, out_args, parent); +} +EXPORT_SYMBOL(of_parse_phandle_with_child_args); + /** * of_count_phandle_with_args() - Find the number of phandles references in a property * @np: pointer to a device tree node containing a list @@ -1263,7 +1285,7 @@ EXPORT_SYMBOL(of_parse_phandle_with_args); int of_count_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name) { - return __of_parse_phandle_with_args(np, list_name, cells_name, -1, NULL); + return __of_parse_phandle_with_args(np, list_name, cells_name, -1, NULL, NULL); } EXPORT_SYMBOL(of_count_phandle_with_args); diff --git a/include/linux/of.h b/include/linux/of.h index 6e10f8f..d3fdce2 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -280,6 +280,12 @@ extern struct device_node *of_parse_phandle(const struct device_node *np, extern int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name, int index, struct of_phandle_args *out_args); +extern int of_parse_phandle_with_child_args(const struct device_node *np, + const char *list_name, + const char *cells_name, + int index, + struct of_phandle_args *out_args, + const char *parent); extern int of_count_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name); @@ -488,6 +494,16 @@ static inline int of_parse_phandle_with_args(const struct device_node *np, return -ENOSYS; } +static inline int of_parse_phandle_with_child_args(const struct device_node *np, + const char *list_name, + const char *cells_name, + int index, + struct of_phandle_args *out_args, + const char *parent) +{ + return -ENOSYS; +} + static inline int of_count_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name)