Commit 610d9151 authored by Dave C Boutcher's avatar Dave C Boutcher Committed by Paul Mackerras

[PATCH] powerpc: Add support for changing properties from userspace

Add support to reconfigure the device tree through the existing
proc filesystem interface.  Add "add_property", "remove_property",
and "update_property" commands to the existing interface.
Signed-off-by: default avatarDave Boutcher <sleddog@us.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent ecaa8b0f
...@@ -350,6 +350,100 @@ static int do_remove_node(char *buf) ...@@ -350,6 +350,100 @@ static int do_remove_node(char *buf)
return rv; 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 * ofdt_write - perform operations on the Open Firmware device tree
* *
...@@ -392,6 +486,12 @@ static ssize_t ofdt_write(struct file *file, const char __user *buf, size_t coun ...@@ -392,6 +486,12 @@ static ssize_t ofdt_write(struct file *file, const char __user *buf, size_t coun
rv = do_add_node(tmp, count - (tmp - kbuf)); rv = do_add_node(tmp, count - (tmp - kbuf));
else if (!strcmp(kbuf, "remove_node")) else if (!strcmp(kbuf, "remove_node"))
rv = do_remove_node(tmp); 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 else
rv = -EINVAL; rv = -EINVAL;
out: out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment