aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r--arch/powerpc/kernel/prom.c90
1 files changed, 88 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 02e2115323e4..70057b63de21 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1627,6 +1627,11 @@ static void of_node_release(struct kref *kref)
1627 kfree(prop->value); 1627 kfree(prop->value);
1628 kfree(prop); 1628 kfree(prop);
1629 prop = next; 1629 prop = next;
1630
1631 if (!prop) {
1632 prop = node->deadprops;
1633 node->deadprops = NULL;
1634 }
1630 } 1635 }
1631 kfree(node->intrs); 1636 kfree(node->intrs);
1632 kfree(node->full_name); 1637 kfree(node->full_name);
@@ -1783,13 +1788,16 @@ unsigned char *get_property(struct device_node *np, const char *name,
1783{ 1788{
1784 struct property *pp; 1789 struct property *pp;
1785 1790
1791 read_lock(&devtree_lock);
1786 for (pp = np->properties; pp != 0; pp = pp->next) 1792 for (pp = np->properties; pp != 0; pp = pp->next)
1787 if (strcmp(pp->name, name) == 0) { 1793 if (strcmp(pp->name, name) == 0) {
1788 if (lenp != 0) 1794 if (lenp != 0)
1789 *lenp = pp->length; 1795 *lenp = pp->length;
1790 return pp->value; 1796 break;
1791 } 1797 }
1792 return NULL; 1798 read_unlock(&devtree_lock);
1799
1800 return pp ? pp->value : NULL;
1793} 1801}
1794EXPORT_SYMBOL(get_property); 1802EXPORT_SYMBOL(get_property);
1795 1803
@@ -1823,4 +1831,82 @@ int prom_add_property(struct device_node* np, struct property* prop)
1823 return 0; 1831 return 0;
1824} 1832}
1825 1833
1834/*
1835 * Remove a property from a node. Note that we don't actually
1836 * remove it, since we have given out who-knows-how-many pointers
1837 * to the data using get-property. Instead we just move the property
1838 * to the "dead properties" list, so it won't be found any more.
1839 */
1840int prom_remove_property(struct device_node *np, struct property *prop)
1841{
1842 struct property **next;
1843 int found = 0;
1844
1845 write_lock(&devtree_lock);
1846 next = &np->properties;
1847 while (*next) {
1848 if (*next == prop) {
1849 /* found the node */
1850 *next = prop->next;
1851 prop->next = np->deadprops;
1852 np->deadprops = prop;
1853 found = 1;
1854 break;
1855 }
1856 next = &(*next)->next;
1857 }
1858 write_unlock(&devtree_lock);
1859
1860 if (!found)
1861 return -ENODEV;
1862
1863#ifdef CONFIG_PROC_DEVICETREE
1864 /* try to remove the proc node as well */
1865 if (np->pde)
1866 proc_device_tree_remove_prop(np->pde, prop);
1867#endif /* CONFIG_PROC_DEVICETREE */
1868
1869 return 0;
1870}
1871
1872/*
1873 * Update a property in a node. Note that we don't actually
1874 * remove it, since we have given out who-knows-how-many pointers
1875 * to the data using get-property. Instead we just move the property
1876 * to the "dead properties" list, and add the new property to the
1877 * property list
1878 */
1879int prom_update_property(struct device_node *np,
1880 struct property *newprop,
1881 struct property *oldprop)
1882{
1883 struct property **next;
1884 int found = 0;
1885
1886 write_lock(&devtree_lock);
1887 next = &np->properties;
1888 while (*next) {
1889 if (*next == oldprop) {
1890 /* found the node */
1891 newprop->next = oldprop->next;
1892 *next = newprop;
1893 oldprop->next = np->deadprops;
1894 np->deadprops = oldprop;
1895 found = 1;
1896 break;
1897 }
1898 next = &(*next)->next;
1899 }
1900 write_unlock(&devtree_lock);
1901
1902 if (!found)
1903 return -ENODEV;
1826 1904
1905#ifdef CONFIG_PROC_DEVICETREE
1906 /* try to add to proc as well if it was initialized */
1907 if (np->pde)
1908 proc_device_tree_update_prop(np->pde, newprop, oldprop);
1909#endif /* CONFIG_PROC_DEVICETREE */
1910
1911 return 0;
1912}