[PATCH 5/5] powerpc: add reconfigure intefaces for updating properties

Dave C Boutcher sleddog at us.ibm.com
Wed Jan 11 21:04:44 EST 2006


Add support to reconfigure the device tree through the existing
proc filesystem interface.  Add "add_property", "remove_property",
and "update_property" interfaces.

Signed-off-by: Dave Boutcher <sleddog at us.ibm.com>

 arch/powerpc/platforms/pseries/reconfig.c |  101 ++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)

Files linux-2.6.15-patched/arch/powerpc/boot/zImage.vmode and linux-2.6.15-patched2/arch/powerpc/boot/zImage.vmode differ
diff -uNr -X exclude-files linux-2.6.15-patched/arch/powerpc/platforms/pseries/reconfig.c linux-2.6.15-patched2/arch/powerpc/platforms/pseries/reconfig.c
--- linux-2.6.15-patched/arch/powerpc/platforms/pseries/reconfig.c	2006-01-11 01:52:07.000000000 -0600
+++ linux-2.6.15-patched2/arch/powerpc/platforms/pseries/reconfig.c	2006-01-11 03:17:19.000000000 -0600
@@ -350,6 +350,101 @@
 	return rv;
 }
 
+static char *parse_node(char *buf, size_t bufsize, struct device_node **npp)
+{
+	char *handle_str;
+	phandle handle;
+	*npp = NULL;
+
+	handle_str = buf;
+
+	buf = strchr(buf, ' ');
+	if (!buf)
+		return NULL;
+	*buf = '\0';
+	buf++;
+
+	handle = simple_strtoul(handle_str, NULL, 10);
+
+	*npp = of_find_node_by_phandle(handle);
+	return buf;
+}
+
+static int do_add_property(char *buf, size_t bufsize)
+{
+	struct property *prop = NULL;
+	struct device_node *np;
+	unsigned char* value;
+	char *name, *end;
+	int length;
+	end = buf + bufsize;
+	buf = parse_node(buf,bufsize,&np);
+	
+	if (!np)
+		return -ENODEV;
+
+	if (parse_next_property(buf, end, &name, &length, &value) == NULL)
+		return -EINVAL;
+	
+	prop = new_property(name, length, value, NULL);
+	if (!prop) 
+		return -ENOMEM;
+
+	prom_add_property(np, 
+			  prop);
+
+	return 0;
+}
+
+static int do_remove_property(char *buf, size_t bufsize)
+{
+	struct device_node *np;
+	char *tmp;
+	struct property *prop;
+	buf = parse_node(buf,bufsize,&np);
+
+	if (!np)
+		return -ENODEV;
+
+	tmp = strchr(buf,' ');
+	if (tmp)
+		*tmp = '\0';
+
+	if (strlen(buf) == 0)
+		return -EINVAL;
+
+	prop = of_find_property(np, buf, NULL);
+
+	return prom_remove_property(np, prop);
+}
+
+static int do_update_property(char *buf, size_t bufsize)
+{
+	struct device_node *np;
+	unsigned char* value;
+	char *name, *end;
+	int length;
+	struct property *newprop, *oldprop;
+	buf = parse_node(buf,bufsize,&np);
+	end = buf + bufsize;
+
+	if (!np)
+		return -ENODEV;
+
+	if (parse_next_property(buf, end, &name, &length, &value) == NULL)
+		return -EINVAL;
+	
+	newprop = new_property(name, length, value, NULL);
+	if (!newprop) 
+		return -ENOMEM;
+
+	oldprop = of_find_property(np, name,NULL);
+	if (!oldprop)
+		return -ENODEV;
+
+	return prom_update_property(np, newprop, oldprop);
+}
+
 /**
  * ofdt_write - perform operations on the Open Firmware device tree
  *
@@ -392,6 +487,12 @@
 		rv = do_add_node(tmp, count - (tmp - kbuf));
 	else if (!strcmp(kbuf, "remove_node"))
 		rv = do_remove_node(tmp);
+	else if (!strcmp(kbuf, "add_property"))
+		rv = do_add_property(tmp, count - (tmp - kbuf));
+	else if (!strcmp(kbuf, "remove_property"))
+		rv = do_remove_property(tmp, count - (tmp - kbuf));
+	else if (!strcmp(kbuf, "update_property"))
+		rv = do_update_property(tmp, count - (tmp - kbuf));
 	else
 		rv = -EINVAL;
 out:

-- 
Dave Boutcher



More information about the Linuxppc64-dev mailing list