aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/base.c
diff options
context:
space:
mode:
authorXiubo Li <Li.Xiubo@freescale.com>2014-01-22 00:57:40 -0500
committerGrant Likely <grant.likely@linaro.org>2014-02-04 12:24:25 -0500
commit02ed594e7113644c06ae3a89bc9215d839510efc (patch)
tree446be5e427cc97bf3b4de76cbad996edfd72d005 /drivers/of/base.c
parent62664f67775fad840cf6f68d6b5f428817bef6c5 (diff)
of: fix of_update_property()
The of_update_property() is intented to update a property in a node and if the property does not exist, will add it. The second search of the property is possibly won't be found, that maybe removed by other thread just before the second search begain. Using the __of_find_property() and __of_add_property() instead and move them into lock operations. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> Cc: Pantelis Antoniou <panto@antoniou-consulting.com> Signed-off-by: Grant Likely <grant.likely@linaro.org>
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r--drivers/of/base.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 6ad3dc976b18..239e3da9e728 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1597,7 +1597,7 @@ int of_update_property(struct device_node *np, struct property *newprop)
1597{ 1597{
1598 struct property **next, *oldprop; 1598 struct property **next, *oldprop;
1599 unsigned long flags; 1599 unsigned long flags;
1600 int rc, found = 0; 1600 int rc = 0;
1601 1601
1602 rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop); 1602 rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
1603 if (rc) 1603 if (rc)
@@ -1606,36 +1606,28 @@ int of_update_property(struct device_node *np, struct property *newprop)
1606 if (!newprop->name) 1606 if (!newprop->name)
1607 return -EINVAL; 1607 return -EINVAL;
1608 1608
1609 oldprop = of_find_property(np, newprop->name, NULL);
1610 if (!oldprop)
1611 return of_add_property(np, newprop);
1612
1613 raw_spin_lock_irqsave(&devtree_lock, flags); 1609 raw_spin_lock_irqsave(&devtree_lock, flags);
1614 next = &np->properties; 1610 oldprop = __of_find_property(np, newprop->name, NULL);
1615 while (*next) { 1611 if (!oldprop) {
1616 if (*next == oldprop) { 1612 /* add the node */
1617 /* found the node */ 1613 rc = __of_add_property(np, newprop);
1618 newprop->next = oldprop->next; 1614 } else {
1619 *next = newprop; 1615 /* replace the node */
1620 oldprop->next = np->deadprops; 1616 next = &oldprop;
1621 np->deadprops = oldprop; 1617 newprop->next = oldprop->next;
1622 found = 1; 1618 *next = newprop;
1623 break; 1619 oldprop->next = np->deadprops;
1624 } 1620 np->deadprops = oldprop;
1625 next = &(*next)->next;
1626 } 1621 }
1627 raw_spin_unlock_irqrestore(&devtree_lock, flags); 1622 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1628 1623
1629 if (!found)
1630 return -ENODEV;
1631
1632#ifdef CONFIG_PROC_DEVICETREE 1624#ifdef CONFIG_PROC_DEVICETREE
1633 /* try to add to proc as well if it was initialized */ 1625 /* try to add to proc as well if it was initialized */
1634 if (np->pde) 1626 if (!rc && np->pde)
1635 proc_device_tree_update_prop(np->pde, newprop, oldprop); 1627 proc_device_tree_update_prop(np->pde, newprop, oldprop);
1636#endif /* CONFIG_PROC_DEVICETREE */ 1628#endif /* CONFIG_PROC_DEVICETREE */
1637 1629
1638 return 0; 1630 return rc;
1639} 1631}
1640 1632
1641#if defined(CONFIG_OF_DYNAMIC) 1633#if defined(CONFIG_OF_DYNAMIC)