From patchwork Thu Jul 16 08:30:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joerg Roedel X-Patchwork-Id: 6804781 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 A9E0F9F6CE for ; Thu, 16 Jul 2015 08:33:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B74772058E for ; Thu, 16 Jul 2015 08:33:18 +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 AFBDB20751 for ; Thu, 16 Jul 2015 08:33:17 +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 1ZFeZt-0001Mh-FS; Thu, 16 Jul 2015 08:31:37 +0000 Received: from 8bytes.org ([81.169.241.247] helo=theia.8bytes.org) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZFeZd-0001D1-SP for linux-arm-kernel@lists.infradead.org; Thu, 16 Jul 2015 08:31:23 +0000 Received: by theia.8bytes.org (Postfix, from userid 1000) id 7826824; Thu, 16 Jul 2015 10:30:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=8bytes.org; s=mail-1; t=1437035453; bh=Re3pg+suDBU2yh2NXjGJ0l9FIjd/S1SPPICx5Jj+HOc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R5uxlyOd5rWHDvLuTVb6eZQI8Kk8AGwKM4aLaBdckjX1BNogtOF9jgi9lWmSxz43u GqA7kDwHeaJeJqt1t2IkyBKe4JyuRTwqCEy5caVKnZV+nzT0IDXZFsnCH0HK9+5Wty BVAuxewh4a1VsMTj6ykeWGT+JMtGB8IddorHRYkVM8lxMQNdRGeBX+7qvZ4Mc+rJBI hx0CEebompTEx+8pDkov97klWdlXDyUpM8UCmcAuJ+PbnzgnkZ1+u6nlbBHAGIBaUA zN9HcdIFB0X+eXpcVEs3/fFoUYmQg2XMmjZIokP89TSCFxo7ul3J4Xf8k9/abqA0+J fIYTkgIM23OwA== From: Joerg Roedel To: Will Deacon , Grant Likely , Rob Herring Subject: [PATCH 1/2] of: base: Allow more args than MAX_PHANDLE_ARGS if required Date: Thu, 16 Jul 2015 10:30:43 +0200 Message-Id: <1437035444-13867-2-git-send-email-joro@8bytes.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1437035444-13867-1-git-send-email-joro@8bytes.org> References: <1437035444-13867-1-git-send-email-joro@8bytes.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150716_013122_264656_EBBE0B46 X-CRM114-Status: GOOD ( 15.23 ) X-Spam-Score: -3.4 (---) 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, iommu@lists.linux-foundation.org, Joerg Roedel , linux-kernel@vger.kernel.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=-5.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,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 The main use of MAX_PHANDLE_ARGS is to define the number of args elements in 'struct of_phandle_args'. This struct is often declared on the stack and thus it is impractical to increase MAX_PHANDLE_ARGS again and again. To handle situations where more than MAX_PHANDLE_ARGS elements may appear in a device-tree, introduce functions to allocate/free 'struct of_phandle_args' with more than MAX_PHANDLE_ARGS elements and provide the new function of_parse_phandle_with_var_args(), which can handle those variable-size structs. This is necessary for the ARM-SMMU driver, where the number of mmu-masters can be up to 128. Signed-off-by: Joerg Roedel --- drivers/of/base.c | 43 ++++++++++++++++++++++++++++++++++++------- include/linux/of.h | 7 +++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 8b5a187..2b288db 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -54,6 +54,24 @@ DEFINE_MUTEX(of_mutex); */ DEFINE_RAW_SPINLOCK(devtree_lock); +struct of_phandle_args *of_alloc_phandle_args(int size) +{ + struct of_phandle_args *args; + int e = max(0, size - MAX_PHANDLE_ARGS); + + args = kzalloc(sizeof(struct of_phandle_args) + e * sizeof(uint32_t), + GFP_KERNEL); + + return args; +} +EXPORT_SYMBOL(of_alloc_phandle_args); + +void of_free_phandle_args(struct of_phandle_args *args) +{ + kfree(args); +} +EXPORT_SYMBOL(of_free_phandle_args); + int of_n_addr_cells(struct device_node *np) { const __be32 *ip; @@ -1446,7 +1464,8 @@ 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) + struct of_phandle_args *out_args, + int elems) { const __be32 *list, *list_end; int rc = 0, size, cur_index = 0; @@ -1525,8 +1544,8 @@ static int __of_parse_phandle_with_args(const struct device_node *np, if (out_args) { int i; - if (WARN_ON(count > MAX_PHANDLE_ARGS)) - count = MAX_PHANDLE_ARGS; + if (WARN_ON(count > elems)) + count = elems; out_args->np = node; out_args->args_count = count; for (i = 0; i < count; i++) @@ -1577,7 +1596,7 @@ struct device_node *of_parse_phandle(const struct device_node *np, return NULL; if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, - index, &args)) + index, &args, MAX_PHANDLE_ARGS)) return NULL; return args.np; @@ -1623,10 +1642,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, 0, - index, out_args); + index, out_args, MAX_PHANDLE_ARGS); } EXPORT_SYMBOL(of_parse_phandle_with_args); +int of_parse_phandle_with_var_args(const struct device_node *np, const char *list_name, + const char *cells_name, int index, + struct of_phandle_args *out_args, int elems) +{ + if (index < 0) + return -EINVAL; + return __of_parse_phandle_with_args(np, list_name, cells_name, 0, + index, out_args, elems); +} +EXPORT_SYMBOL(of_parse_phandle_with_var_args); /** * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list * @np: pointer to a device tree node containing a list @@ -1664,7 +1693,7 @@ int of_parse_phandle_with_fixed_args(const struct device_node *np, if (index < 0) return -EINVAL; return __of_parse_phandle_with_args(np, list_name, NULL, cell_count, - index, out_args); + index, out_args, MAX_PHANDLE_ARGS); } EXPORT_SYMBOL(of_parse_phandle_with_fixed_args); @@ -1687,7 +1716,7 @@ int of_count_phandle_with_args(const struct device_node *np, const char *list_na const char *cells_name) { return __of_parse_phandle_with_args(np, list_name, cells_name, 0, -1, - NULL); + NULL, MAX_PHANDLE_ARGS); } EXPORT_SYMBOL(of_count_phandle_with_args); diff --git a/include/linux/of.h b/include/linux/of.h index edc068d..cd9f225 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -75,6 +75,10 @@ struct of_phandle_args { uint32_t args[MAX_PHANDLE_ARGS]; }; +/* Use these if you need more that MAX_PHANDLE_ARGS */ +extern struct of_phandle_args *of_alloc_phandle_args(int size); +extern void of_free_phandle_args(struct of_phandle_args *args); + struct of_reconfig_data { struct device_node *dn; struct property *prop; @@ -327,6 +331,9 @@ 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_var_args(const struct device_node *np, + const char *list_name, const char *cells_name, int index, + struct of_phandle_args *out_args, int elems); extern int of_parse_phandle_with_fixed_args(const struct device_node *np, const char *list_name, int cells_count, int index, struct of_phandle_args *out_args);