devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dong Aisheng <b29396@freescale.com>
To: devicetree-discuss@lists.ozlabs.org, linux-kernel@vger.kernel.org
Cc: grant.likely@linaro.org, rob.herring@calxeda.com,
	rob@landley.net, linux-arm-kernel@lists.infradead.org
Subject: [PATCH 3/3] of: add node status update via name format with cmdline
Date: Thu, 15 Aug 2013 18:55:33 +0800	[thread overview]
Message-ID: <1376564133-11286-4-git-send-email-b29396@freescale.com> (raw)
In-Reply-To: <1376564133-11286-1-git-send-email-b29396@freescale.com>

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 <b29396@freescale.com>
---
 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.<enable|disable>=<path>[,<path>]
+			Format: fdt.<enable|disable>=<path|node>[,<path|node>]
 			enable    := update the device node to a enabled state
 			disable   := update the device node to a disabled state
 			<path>    := node path or node full name in device tree
+			<node>	  := 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 <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
@@ -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, &reg))
+		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.<enable|disable>=<path>[,<path>]
+ * fdt.<enable|disable>=<path|node>[,<path|node>]
  * enable    := update the device node to a enabled state
  * disable   := update the device node to a disabled state
  * <path>    := node path or node full name in device tree
+ * <node>    := 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;
-- 
1.7.1

  parent reply	other threads:[~2013-08-15 10:55 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-15 10:55 [PATCH 0/3] of: add update device node status via cmdline feature Dong Aisheng
2013-08-15 10:55 ` [PATCH 1/3] of: add device node status update APIs Dong Aisheng
2013-08-15 10:55 ` [PATCH 2/3] of: add update device node status via cmdline feature Dong Aisheng
2013-08-15 10:55 ` Dong Aisheng [this message]
2013-08-15 12:37 ` [PATCH 0/3] " Rob Herring
2013-08-15 12:46   ` Grant Likely
2013-08-21 12:47   ` Dong Aisheng
2013-08-21 13:23     ` Rob Herring
2013-08-23  7:13       ` Dong Aisheng
2013-08-15 12:45 ` Grant Likely
2013-08-21 12:37   ` Dong Aisheng
2013-08-23  7:09     ` Dong Aisheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1376564133-11286-4-git-send-email-b29396@freescale.com \
    --to=b29396@freescale.com \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=grant.likely@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rob.herring@calxeda.com \
    --cc=rob@landley.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).