From patchwork Thu Aug 15 10:55:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aisheng Dong X-Patchwork-Id: 2845083 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2E218BF546 for ; Thu, 15 Aug 2013 11:00:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 580BB203EA for ; Thu, 15 Aug 2013 11:00:52 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 453CD203E8 for ; Thu, 15 Aug 2013 11:00:47 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V9vHH-0006ue-Rj; Thu, 15 Aug 2013 10:59:40 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1V9vGr-0004vM-KU; Thu, 15 Aug 2013 10:59:13 +0000 Received: from co9ehsobe005.messaging.microsoft.com ([207.46.163.28] helo=co9outboundpool.messaging.microsoft.com) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V9vGG-0004qi-Vp for linux-arm-kernel@lists.infradead.org; Thu, 15 Aug 2013 10:58:42 +0000 Received: from mail5-co9-R.bigfish.com (10.236.132.228) by CO9EHSOBE037.bigfish.com (10.236.130.100) with Microsoft SMTP Server id 14.1.225.22; Thu, 15 Aug 2013 10:58:15 +0000 Received: from mail5-co9 (localhost [127.0.0.1]) by mail5-co9-R.bigfish.com (Postfix) with ESMTP id 68CB8120139; Thu, 15 Aug 2013 10:58:15 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 3 X-BigFish: VS3(zzzz1f42h208ch1ee6h1de0h1fdah2073h1202h1e76h1d1ah1d2ah1fc6h1082kzz1de098h8275bh1de097hz2dh2a8h668h839hd24he5bhf0ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1b2fh1fb3h1d0ch1d2eh1d3fh1dfeh1dffh1e23h1fe8h1ff5h1155h) Received: from mail5-co9 (localhost.localdomain [127.0.0.1]) by mail5-co9 (MessageSwitch) id 137656429410198_13781; Thu, 15 Aug 2013 10:58:14 +0000 (UTC) Received: from CO9EHSMHS024.bigfish.com (unknown [10.236.132.252]) by mail5-co9.bigfish.com (Postfix) with ESMTP id E833F18004A; Thu, 15 Aug 2013 10:58:13 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CO9EHSMHS024.bigfish.com (10.236.130.34) with Microsoft SMTP Server (TLS) id 14.16.227.3; Thu, 15 Aug 2013 10:58:13 +0000 Received: from az84smr01.freescale.net (10.64.34.197) by 039-SN1MMR1-002.039d.mgd.msft.net (10.84.1.15) with Microsoft SMTP Server (TLS) id 14.3.136.1; Thu, 15 Aug 2013 10:58:12 +0000 Received: from shlinux2.ap.freescale.net (shlinux2.ap.freescale.net [10.192.224.44]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id r7FAw00A002450; Thu, 15 Aug 2013 03:58:09 -0700 From: Dong Aisheng To: , Subject: [PATCH 3/3] of: add node status update via name format with cmdline Date: Thu, 15 Aug 2013 18:55:33 +0800 Message-ID: <1376564133-11286-4-git-send-email-b29396@freescale.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1376564133-11286-1-git-send-email-b29396@freescale.com> References: <1376564133-11286-1-git-send-email-b29396@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-FOPE-CONNECTOR: Id%0$Dn%*$RO%0$TLS%0$FQDN%$TlsDn% X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130815_065837_775249_B3E5C62D X-CRM114-Status: GOOD ( 21.48 ) X-Spam-Score: -4.2 (----) Cc: grant.likely@linaro.org, rob@landley.net, rob.herring@calxeda.com, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 The node full patch is a bit long to use in the command line to update the device node status, so we add a more convenient way to simply use device node name in device tree. e.g: formerly: fdt.enable=/soc/aips-bus@02100000/i2c@021a8000,/soc/aips-bus@02100000/weim@021b8000 fdt.disable=/soc/aips-bus@02100000/weim@021b8000 now: fdt.enable=i2c@021a8000,weim@021b8000 fdt.disable=weim@021b8000 Signed-off-by: Dong Aisheng --- Documentation/kernel-parameters.txt | 3 +- drivers/of/base.c | 33 +++++++++++++++++ drivers/of/fdt.c | 66 ++++++++++++++++++++++++++++------ include/linux/of.h | 8 ++++ 4 files changed, 97 insertions(+), 13 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 65f3be2..7fbdb86 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -900,10 +900,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. fdt.disable= [KNL,FDT] update device tree node status before populating devices - Format: fdt.=[,] + Format: fdt.=[,] enable := update the device node to a enabled state disable := update the device node to a disabled state := node path or node full name in device tree + := node name in device tree floppy= [HW] See Documentation/blockdev/floppy.txt. diff --git a/drivers/of/base.c b/drivers/of/base.c index f944a54..b072722 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -514,6 +515,38 @@ struct device_node *of_find_node_by_name(struct device_node *from, EXPORT_SYMBOL(of_find_node_by_name); /** + * of_find_node_by_name_and_reg - Find a node by its "name" and "reg" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @name: The name string to match against + * @reg: The reg address to match against + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_name_and_reg(struct device_node *from, + const char *name, resource_size_t reg) +{ + struct device_node *np; + struct resource res; + + while ((np = of_find_node_by_name(from, name)) != NULL) { + if (!of_address_to_resource(np, 0, &res)) + if ((res.start == reg) && of_node_get(np)) { + pr_debug("find node %s 0x%x: %s\n", name, + reg, np->full_name); + break; + } + from = np; + } + + return np; +} +EXPORT_SYMBOL(of_find_node_by_name_and_reg); + +/** * of_find_node_by_type - Find a node by its "device_type" property * @from: The node to start searching from, or NULL to start searching * the entire device tree. The node you pass will not be diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 423624b..27ad6ae 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -718,21 +718,52 @@ void __init unflatten_device_tree(void) of_alias_scan(early_init_dt_alloc_memory_arch); } +static int of_flat_update_node_by_name(const char *s, bool enable) +{ + char node[256]; + char *r, *p; + struct device_node *np; + unsigned long reg; + + if (!s) + return -EINVAL; + + p = strchr(s, '@'); + strncpy(node, s, p - s); + node[p - s] = '\0'; + r = p + 1; + if (kstrtoul(r, 16, ®)) + return -EINVAL; + + np = of_find_node_by_name_and_reg(NULL, node, reg); + if (!np) { + pr_debug("%s: unable to find node %s\n", __func__, s); + return -ENODEV; + } + + return enable ? of_node_status_enable(np) : + of_node_status_disable(np); +} + /* * The format for the command line is as follows: * - * fdt.=[,] + * fdt.=[,] * enable := update the device node to a enabled state * disable := update the device node to a disabled state * := node path or node full name in device tree + * := node name in device tree * * e.g: * fdt.enable=/soc/aips-bus@02100000/i2c@021a8000,/soc/aips-bus@02100000/weim@021b8000 * fdt.disable=/soc/aips-bus@02100000/weim@021b8000 + * or + * fdt.enable=i2c@021a8000,weim@021b8000 + * fdt.disable=weim@021b8000 */ static int __init __of_flat_parse_param(char *s, bool enable) { - char path[256], *p; + char node[256], *p; if (!s) return 0; @@ -742,20 +773,31 @@ static int __init __of_flat_parse_param(char *s, bool enable) p = strchr(s, ','); if (p != NULL) { BUG_ON((p - s) >= 256); - strncpy(path, s, p - s); - path[p - s] = '\0'; - if (enable) - of_node_status_enable_by_path(path); - else - of_node_status_disable_by_path(path); + strncpy(node, s, p - s); + node[p - s] = '\0'; + if (*s != '/') { + /* device tree node name */ + of_flat_update_node_by_name(node, enable); + } else { + /* device tree node full path*/ + if (enable) + of_node_status_enable_by_path(node); + else + of_node_status_disable_by_path(node); + } + /* search for next node */ s = p + 1; } else { /* last node */ - if (enable) - of_node_status_enable_by_path(s); - else - of_node_status_disable_by_path(s); + if (*s != '/') { + of_flat_update_node_by_name(s, enable); + } else { + if (enable) + of_node_status_enable_by_path(s); + else + of_node_status_disable_by_path(s); + } break; } } diff --git a/include/linux/of.h b/include/linux/of.h index 61b35fe..7dd3da0 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -170,6 +170,8 @@ extern struct device_node *of_find_node_by_name(struct device_node *from, #define for_each_node_by_name(dn, name) \ for (dn = of_find_node_by_name(NULL, name); dn; \ dn = of_find_node_by_name(dn, name)) +extern struct device_node *of_find_node_by_name_and_reg(struct device_node *from, + const char *name, resource_size_t reg); extern struct device_node *of_find_node_by_type(struct device_node *from, const char *type); #define for_each_node_by_type(dn, type) \ @@ -361,6 +363,12 @@ static inline struct device_node *of_find_node_by_name(struct device_node *from, return NULL; } +static inline struct device_node *of_find_node_by_name_and_reg( + struct device_node *from, const char *name, resource_size_t reg) +{ + return NULL; +} + static inline struct device_node *of_get_parent(const struct device_node *node) { return NULL;