diff options
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r-- | arch/powerpc/kernel/prom.c | 90 |
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 | } |
1794 | EXPORT_SYMBOL(get_property); | 1802 | EXPORT_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 | */ | ||
1840 | int 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 | */ | ||
1879 | int 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 | } | ||