summaryrefslogtreecommitdiffstats
path: root/drivers/of/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r--drivers/of/base.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d9bfd49b1935..d4a1c9a043e1 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -173,9 +173,9 @@ struct property *of_find_property(const struct device_node *np,
173 return NULL; 173 return NULL;
174 174
175 read_lock(&devtree_lock); 175 read_lock(&devtree_lock);
176 for (pp = np->properties; pp != 0; pp = pp->next) { 176 for (pp = np->properties; pp; pp = pp->next) {
177 if (of_prop_cmp(pp->name, name) == 0) { 177 if (of_prop_cmp(pp->name, name) == 0) {
178 if (lenp != 0) 178 if (lenp)
179 *lenp = pp->length; 179 *lenp = pp->length;
180 break; 180 break;
181 } 181 }
@@ -364,6 +364,33 @@ struct device_node *of_get_next_child(const struct device_node *node,
364EXPORT_SYMBOL(of_get_next_child); 364EXPORT_SYMBOL(of_get_next_child);
365 365
366/** 366/**
367 * of_get_next_available_child - Find the next available child node
368 * @node: parent node
369 * @prev: previous child of the parent node, or NULL to get first
370 *
371 * This function is like of_get_next_child(), except that it
372 * automatically skips any disabled nodes (i.e. status = "disabled").
373 */
374struct device_node *of_get_next_available_child(const struct device_node *node,
375 struct device_node *prev)
376{
377 struct device_node *next;
378
379 read_lock(&devtree_lock);
380 next = prev ? prev->sibling : node->child;
381 for (; next; next = next->sibling) {
382 if (!of_device_is_available(next))
383 continue;
384 if (of_node_get(next))
385 break;
386 }
387 of_node_put(prev);
388 read_unlock(&devtree_lock);
389 return next;
390}
391EXPORT_SYMBOL(of_get_next_available_child);
392
393/**
367 * of_find_node_by_path - Find a node matching a full OF path 394 * of_find_node_by_path - Find a node matching a full OF path
368 * @path: The full path to match 395 * @path: The full path to match
369 * 396 *
@@ -497,7 +524,7 @@ struct device_node *of_find_node_with_property(struct device_node *from,
497 read_lock(&devtree_lock); 524 read_lock(&devtree_lock);
498 np = from ? from->allnext : allnodes; 525 np = from ? from->allnext : allnodes;
499 for (; np; np = np->allnext) { 526 for (; np; np = np->allnext) {
500 for (pp = np->properties; pp != 0; pp = pp->next) { 527 for (pp = np->properties; pp; pp = pp->next) {
501 if (of_prop_cmp(pp->name, prop_name) == 0) { 528 if (of_prop_cmp(pp->name, prop_name) == 0) {
502 of_node_get(np); 529 of_node_get(np);
503 goto out; 530 goto out;
@@ -902,7 +929,7 @@ int of_parse_phandle_with_args(struct device_node *np, const char *list_name,
902 /* Retrieve the phandle list property */ 929 /* Retrieve the phandle list property */
903 list = of_get_property(np, list_name, &size); 930 list = of_get_property(np, list_name, &size);
904 if (!list) 931 if (!list)
905 return -EINVAL; 932 return -ENOENT;
906 list_end = list + size / sizeof(*list); 933 list_end = list + size / sizeof(*list);
907 934
908 /* Loop over the phandles until all the requested entry is found */ 935 /* Loop over the phandles until all the requested entry is found */
@@ -1051,7 +1078,8 @@ int prom_remove_property(struct device_node *np, struct property *prop)
1051} 1078}
1052 1079
1053/* 1080/*
1054 * prom_update_property - Update a property in a node. 1081 * prom_update_property - Update a property in a node, if the property does
1082 * not exist, add it.
1055 * 1083 *
1056 * Note that we don't actually remove it, since we have given out 1084 * Note that we don't actually remove it, since we have given out
1057 * who-knows-how-many pointers to the data using get-property. 1085 * who-knows-how-many pointers to the data using get-property.
@@ -1059,13 +1087,19 @@ int prom_remove_property(struct device_node *np, struct property *prop)
1059 * and add the new property to the property list 1087 * and add the new property to the property list
1060 */ 1088 */
1061int prom_update_property(struct device_node *np, 1089int prom_update_property(struct device_node *np,
1062 struct property *newprop, 1090 struct property *newprop)
1063 struct property *oldprop)
1064{ 1091{
1065 struct property **next; 1092 struct property **next, *oldprop;
1066 unsigned long flags; 1093 unsigned long flags;
1067 int found = 0; 1094 int found = 0;
1068 1095
1096 if (!newprop->name)
1097 return -EINVAL;
1098
1099 oldprop = of_find_property(np, newprop->name, NULL);
1100 if (!oldprop)
1101 return prom_add_property(np, newprop);
1102
1069 write_lock_irqsave(&devtree_lock, flags); 1103 write_lock_irqsave(&devtree_lock, flags);
1070 next = &np->properties; 1104 next = &np->properties;
1071 while (*next) { 1105 while (*next) {
@@ -1173,7 +1207,7 @@ static void of_alias_add(struct alias_prop *ap, struct device_node *np,
1173 ap->stem[stem_len] = 0; 1207 ap->stem[stem_len] = 0;
1174 list_add_tail(&ap->link, &aliases_lookup); 1208 list_add_tail(&ap->link, &aliases_lookup);
1175 pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n", 1209 pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
1176 ap->alias, ap->stem, ap->id, np ? np->full_name : NULL); 1210 ap->alias, ap->stem, ap->id, of_node_full_name(np));
1177} 1211}
1178 1212
1179/** 1213/**