[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: Dave Boutcher <sleddog@us.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
ecaa8b0ff3
commit
610d91511f
|
@ -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
|
||||||
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:
|
||||||
|
|
Loading…
Reference in New Issue