aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/base.c
diff options
context:
space:
mode:
authorPantelis Antoniou <pantelis.antoniou@konsulko.com>2014-07-04 12:58:46 -0400
committerGrant Likely <grant.likely@linaro.org>2014-07-16 10:16:52 -0400
commitd8c50088417ebf61ad8b132caad20d10f7736034 (patch)
tree40f3105ec3c03601e22301f36d207362e6d1226e /drivers/of/base.c
parent698433963b98d6de7b102c242805c99fda4fa1fb (diff)
of: Create unlocked versions of node and property add/remove functions
The DT overlay code will need to manipulate nodes and properties while already holding the devicetree lock, or on nodes that are not yet attached to the tree, but the current helper functions don't allow that. Extract the core behaviour from the accessors and create the following unlocked variants. The unlocked variants require either the lock to already be held or for the nodes to be detached from the tree. Changes to live nodes will not get updated in sysfs, so the caller must arrange for housekeeping to take place after dropping the lock. The new functions are: __of_add_property(), __of_remove_property(), __of_update_property(), __of_attach_node() and __of_detach_node(). Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> [Remove unnecessary diff hunks and rewrite commit text] Signed-off-by: Grant Likely <grant.likely@linaro.org>
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r--drivers/of/base.c91
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);
1659/** 1659/**
1660 * __of_add_property - Add a property to a node without lock operations 1660 * __of_add_property - Add a property to a node without lock operations
1661 */ 1661 */
1662static int __of_add_property(struct device_node *np, struct property *prop) 1662int __of_add_property(struct device_node *np, struct property *prop)
1663{ 1663{
1664 struct property **next; 1664 struct property **next;
1665 1665
@@ -1701,6 +1701,25 @@ int of_add_property(struct device_node *np, struct property *prop)
1701 return rc; 1701 return rc;
1702} 1702}
1703 1703
1704int __of_remove_property(struct device_node *np, struct property *prop)
1705{
1706 struct property **next;
1707
1708 for (next = &np->properties; *next; next = &(*next)->next) {
1709 if (*next == prop)
1710 break;
1711 }
1712 if (*next == NULL)
1713 return -ENODEV;
1714
1715 /* found the node */
1716 *next = prop->next;
1717 prop->next = np->deadprops;
1718 np->deadprops = prop;
1719
1720 return 0;
1721}
1722
1704/** 1723/**
1705 * of_remove_property - Remove a property from a node. 1724 * of_remove_property - Remove a property from a node.
1706 * 1725 *
@@ -1711,9 +1730,7 @@ int of_add_property(struct device_node *np, struct property *prop)
1711 */ 1730 */
1712int of_remove_property(struct device_node *np, struct property *prop) 1731int of_remove_property(struct device_node *np, struct property *prop)
1713{ 1732{
1714 struct property **next;
1715 unsigned long flags; 1733 unsigned long flags;
1716 int found = 0;
1717 int rc; 1734 int rc;
1718 1735
1719 rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop); 1736 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)
1721 return rc; 1738 return rc;
1722 1739
1723 raw_spin_lock_irqsave(&devtree_lock, flags); 1740 raw_spin_lock_irqsave(&devtree_lock, flags);
1724 next = &np->properties; 1741 rc = __of_remove_property(np, prop);
1725 while (*next) {
1726 if (*next == prop) {
1727 /* found the node */
1728 *next = prop->next;
1729 prop->next = np->deadprops;
1730 np->deadprops = prop;
1731 found = 1;
1732 break;
1733 }
1734 next = &(*next)->next;
1735 }
1736 raw_spin_unlock_irqrestore(&devtree_lock, flags); 1742 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1737 1743
1738 if (!found) 1744 if (rc)
1739 return -ENODEV; 1745 return rc;
1740 1746
1741 /* at early boot, bail hear and defer setup to of_init() */ 1747 /* at early boot, bail hear and defer setup to of_init() */
1742 if (!of_kset) 1748 if (!of_kset)
@@ -1747,6 +1753,32 @@ int of_remove_property(struct device_node *np, struct property *prop)
1747 return 0; 1753 return 0;
1748} 1754}
1749 1755
1756int __of_update_property(struct device_node *np, struct property *newprop,
1757 struct property **oldpropp)
1758{
1759 struct property **next, *oldprop;
1760
1761 for (next = &np->properties; *next; next = &(*next)->next) {
1762 if (of_prop_cmp((*next)->name, newprop->name) == 0)
1763 break;
1764 }
1765 *oldpropp = oldprop = *next;
1766
1767 if (oldprop) {
1768 /* replace the node */
1769 newprop->next = oldprop->next;
1770 *next = newprop;
1771 oldprop->next = np->deadprops;
1772 np->deadprops = oldprop;
1773 } else {
1774 /* new node */
1775 newprop->next = NULL;
1776 *next = newprop;
1777 }
1778
1779 return 0;
1780}
1781
1750/* 1782/*
1751 * of_update_property - Update a property in a node, if the property does 1783 * of_update_property - Update a property in a node, if the property does
1752 * not exist, add it. 1784 * not exist, add it.
@@ -1758,34 +1790,19 @@ int of_remove_property(struct device_node *np, struct property *prop)
1758 */ 1790 */
1759int of_update_property(struct device_node *np, struct property *newprop) 1791int of_update_property(struct device_node *np, struct property *newprop)
1760{ 1792{
1761 struct property **next, *oldprop; 1793 struct property *oldprop;
1762 unsigned long flags; 1794 unsigned long flags;
1763 int rc; 1795 int rc;
1764 1796
1797 if (!newprop->name)
1798 return -EINVAL;
1799
1765 rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop); 1800 rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
1766 if (rc) 1801 if (rc)
1767 return rc; 1802 return rc;
1768 1803
1769 if (!newprop->name)
1770 return -EINVAL;
1771
1772 raw_spin_lock_irqsave(&devtree_lock, flags); 1804 raw_spin_lock_irqsave(&devtree_lock, flags);
1773 next = &np->properties; 1805 rc = __of_update_property(np, newprop, &oldprop);
1774 oldprop = __of_find_property(np, newprop->name, NULL);
1775 if (!oldprop) {
1776 /* add the new node */
1777 rc = __of_add_property(np, newprop);
1778 } else while (*next) {
1779 /* replace the node */
1780 if (*next == oldprop) {
1781 newprop->next = oldprop->next;
1782 *next = newprop;
1783 oldprop->next = np->deadprops;
1784 np->deadprops = oldprop;
1785 break;
1786 }
1787 next = &(*next)->next;
1788 }
1789 raw_spin_unlock_irqrestore(&devtree_lock, flags); 1806 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1790 if (rc) 1807 if (rc)
1791 return rc; 1808 return rc;