diff options
Diffstat (limited to 'drivers/core/of_access.c')
-rw-r--r-- | drivers/core/of_access.c | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index c20b19cb50f..a52f5a6b18b 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -343,24 +343,30 @@ static struct device_node *__of_find_node_by_path(struct device_node *parent, #define for_each_property_of_node(dn, pp) \ for (pp = dn->properties; pp != NULL; pp = pp->next) -struct device_node *of_find_node_opts_by_path(const char *path, +struct device_node *of_find_node_opts_by_path(struct device_node *root, + const char *path, const char **opts) { struct device_node *np = NULL; struct property *pp; const char *separator = strchr(path, ':'); + if (!root) + root = gd->of_root; if (opts) *opts = separator ? separator + 1 : NULL; if (strcmp(path, "/") == 0) - return of_node_get(gd->of_root); + return of_node_get(root); /* The path could begin with an alias */ if (*path != '/') { int len; const char *p = separator; + /* Only allow alias processing on the control FDT */ + if (root != gd->of_root) + return NULL; if (!p) p = strchrnul(path, '/'); len = p - path; @@ -383,7 +389,7 @@ struct device_node *of_find_node_opts_by_path(const char *path, /* Step down the tree matching path components */ if (!np) - np = of_node_get(gd->of_root); + np = of_node_get(root); while (np && *path == '/') { struct device_node *tmp = np; @@ -791,7 +797,7 @@ int of_alias_scan(void) name = of_get_property(of_chosen, "stdout-path", NULL); if (name) - of_stdout = of_find_node_opts_by_path(name, + of_stdout = of_find_node_opts_by_path(NULL, name, &of_stdout_options); } @@ -881,3 +887,46 @@ struct device_node *of_get_stdout(void) { return of_stdout; } + +int of_write_prop(struct device_node *np, const char *propname, int len, + const void *value) +{ + struct property *pp; + struct property *pp_last = NULL; + struct property *new; + + if (!np) + return -EINVAL; + + for (pp = np->properties; pp; pp = pp->next) { + if (strcmp(pp->name, propname) == 0) { + /* Property exists -> change value */ + pp->value = (void *)value; + pp->length = len; + return 0; + } + pp_last = pp; + } + + if (!pp_last) + return -ENOENT; + + /* Property does not exist -> append new property */ + new = malloc(sizeof(struct property)); + if (!new) + return -ENOMEM; + + new->name = strdup(propname); + if (!new->name) { + free(new); + return -ENOMEM; + } + + new->value = (void *)value; + new->length = len; + new->next = NULL; + + pp_last->next = new; + + return 0; +} |