diff options
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r-- | drivers/of/base.c | 91 |
1 files changed, 54 insertions, 37 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c index 0d8955605738..b403f9d98461 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1659,7 +1659,7 @@ EXPORT_SYMBOL(of_count_phandle_with_args); /** * __of_add_property - Add a property to a node without lock operations */ -static int __of_add_property(struct device_node *np, struct property *prop) +int __of_add_property(struct device_node *np, struct property *prop) { struct property **next; @@ -1701,6 +1701,25 @@ int of_add_property(struct device_node *np, struct property *prop) return rc; } +int __of_remove_property(struct device_node *np, struct property *prop) +{ + struct property **next; + + for (next = &np->properties; *next; next = &(*next)->next) { + if (*next == prop) + break; + } + if (*next == NULL) + return -ENODEV; + + /* found the node */ + *next = prop->next; + prop->next = np->deadprops; + np->deadprops = prop; + + return 0; +} + /** * of_remove_property - Remove a property from a node. * @@ -1711,9 +1730,7 @@ int of_add_property(struct device_node *np, struct property *prop) */ int of_remove_property(struct device_node *np, struct property *prop) { - struct property **next; unsigned long flags; - int found = 0; int rc; rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop); @@ -1721,22 +1738,11 @@ int of_remove_property(struct device_node *np, struct property *prop) return rc; raw_spin_lock_irqsave(&devtree_lock, flags); - next = &np->properties; - while (*next) { - if (*next == prop) { - /* found the node */ - *next = prop->next; - prop->next = np->deadprops; - np->deadprops = prop; - found = 1; - break; - } - next = &(*next)->next; - } + rc = __of_remove_property(np, prop); raw_spin_unlock_irqrestore(&devtree_lock, flags); - if (!found) - return -ENODEV; + if (rc) + return rc; /* at early boot, bail hear and defer setup to of_init() */ if (!of_kset) @@ -1747,6 +1753,32 @@ int of_remove_property(struct device_node *np, struct property *prop) return 0; } +int __of_update_property(struct device_node *np, struct property *newprop, + struct property **oldpropp) +{ + struct property **next, *oldprop; + + for (next = &np->properties; *next; next = &(*next)->next) { + if (of_prop_cmp((*next)->name, newprop->name) == 0) + break; + } + *oldpropp = oldprop = *next; + + if (oldprop) { + /* replace the node */ + newprop->next = oldprop->next; + *next = newprop; + oldprop->next = np->deadprops; + np->deadprops = oldprop; + } else { + /* new node */ + newprop->next = NULL; + *next = newprop; + } + + return 0; +} + /* * of_update_property - Update a property in a node, if the property does * not exist, add it. @@ -1758,34 +1790,19 @@ int of_remove_property(struct device_node *np, struct property *prop) */ int of_update_property(struct device_node *np, struct property *newprop) { - struct property **next, *oldprop; + struct property *oldprop; unsigned long flags; int rc; + if (!newprop->name) + return -EINVAL; + rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop); if (rc) return rc; - if (!newprop->name) - return -EINVAL; - raw_spin_lock_irqsave(&devtree_lock, flags); - next = &np->properties; - oldprop = __of_find_property(np, newprop->name, NULL); - if (!oldprop) { - /* add the new node */ - rc = __of_add_property(np, newprop); - } else while (*next) { - /* replace the node */ - if (*next == oldprop) { - newprop->next = oldprop->next; - *next = newprop; - oldprop->next = np->deadprops; - np->deadprops = oldprop; - break; - } - next = &(*next)->next; - } + rc = __of_update_property(np, newprop, &oldprop); raw_spin_unlock_irqrestore(&devtree_lock, flags); if (rc) return rc; |