From e3963fd60a83967573f6330c9db134bd581da746 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Fri, 8 Nov 2013 17:03:57 +0200 Subject: of: Clear detach flag on attach When attaching a node always clear the detach flag. Without this change the sequence detach, attach fails. Signed-off-by: Pantelis Antoniou Signed-off-by: Grant Likely --- drivers/of/base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/of/base.c') diff --git a/drivers/of/base.c b/drivers/of/base.c index ff85450d5683..87038d80b473 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1692,6 +1692,7 @@ int of_attach_node(struct device_node *np) np->allnext = of_allnodes; np->parent->child = np; of_allnodes = np; + of_node_clear_flag(np, OF_DETACHED); raw_spin_unlock_irqrestore(&devtree_lock, flags); of_add_proc_dt_entry(np); -- cgit v1.2.1 From 62664f67775fad840cf6f68d6b5f428817bef6c5 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 22 Jan 2014 13:57:39 +0800 Subject: of: add __of_add_property() without lock operations There two places will use the same code for adding one new property to the DT node. Adding __of_add_property() and prepare for fixing of_update_property()'s bug. Signed-off-by: Xiubo Li Signed-off-by: Grant Likely --- drivers/of/base.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'drivers/of/base.c') diff --git a/drivers/of/base.c b/drivers/of/base.c index 87038d80b473..6ad3dc976b18 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1492,12 +1492,32 @@ static int of_property_notify(int action, struct device_node *np, } #endif +/** + * __of_add_property - Add a property to a node without lock operations + */ +static int __of_add_property(struct device_node *np, struct property *prop) +{ + struct property **next; + + prop->next = NULL; + next = &np->properties; + while (*next) { + if (strcmp(prop->name, (*next)->name) == 0) + /* duplicate ! don't insert it */ + return -EEXIST; + + next = &(*next)->next; + } + *next = prop; + + return 0; +} + /** * of_add_property - Add a property to a node */ int of_add_property(struct device_node *np, struct property *prop) { - struct property **next; unsigned long flags; int rc; @@ -1505,27 +1525,17 @@ int of_add_property(struct device_node *np, struct property *prop) if (rc) return rc; - prop->next = NULL; raw_spin_lock_irqsave(&devtree_lock, flags); - next = &np->properties; - while (*next) { - if (strcmp(prop->name, (*next)->name) == 0) { - /* duplicate ! don't insert it */ - raw_spin_unlock_irqrestore(&devtree_lock, flags); - return -1; - } - next = &(*next)->next; - } - *next = prop; + rc = __of_add_property(np, prop); raw_spin_unlock_irqrestore(&devtree_lock, flags); #ifdef CONFIG_PROC_DEVICETREE /* try to add to proc as well if it was initialized */ - if (np->pde) + if (!rc && np->pde) proc_device_tree_add_prop(np->pde, prop); #endif /* CONFIG_PROC_DEVICETREE */ - return 0; + return rc; } /** -- cgit v1.2.1 From 02ed594e7113644c06ae3a89bc9215d839510efc Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 22 Jan 2014 13:57:40 +0800 Subject: 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 Cc: Pantelis Antoniou Signed-off-by: Grant Likely --- drivers/of/base.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) (limited to 'drivers/of/base.c') 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) { struct property **next, *oldprop; unsigned long flags; - int rc, found = 0; + int rc = 0; rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop); if (rc) @@ -1606,36 +1606,28 @@ int of_update_property(struct device_node *np, struct property *newprop) if (!newprop->name) return -EINVAL; - oldprop = of_find_property(np, newprop->name, NULL); - if (!oldprop) - return of_add_property(np, newprop); - raw_spin_lock_irqsave(&devtree_lock, flags); - next = &np->properties; - while (*next) { - if (*next == oldprop) { - /* found the node */ - newprop->next = oldprop->next; - *next = newprop; - oldprop->next = np->deadprops; - np->deadprops = oldprop; - found = 1; - break; - } - next = &(*next)->next; + oldprop = __of_find_property(np, newprop->name, NULL); + if (!oldprop) { + /* add the node */ + rc = __of_add_property(np, newprop); + } else { + /* replace the node */ + next = &oldprop; + newprop->next = oldprop->next; + *next = newprop; + oldprop->next = np->deadprops; + np->deadprops = oldprop; } raw_spin_unlock_irqrestore(&devtree_lock, flags); - if (!found) - return -ENODEV; - #ifdef CONFIG_PROC_DEVICETREE /* try to add to proc as well if it was initialized */ - if (np->pde) + if (!rc && np->pde) proc_device_tree_update_prop(np->pde, newprop, oldprop); #endif /* CONFIG_PROC_DEVICETREE */ - return 0; + return rc; } #if defined(CONFIG_OF_DYNAMIC) -- cgit v1.2.1 From a3dbeb5b45af5b6113385db89fce2a8279278e8b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 4 Mar 2014 16:07:17 +0800 Subject: Revert "of: fix of_update_property()" This reverts commit 02ed594e7113644c06ae3a89bc9215d839510efc. The change is completely broken. It attempt to get the previous item in a linked list by grabbing the address of a stack variable. Outright wrong. Signed-off-by: Grant Likely --- drivers/of/base.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'drivers/of/base.c') diff --git a/drivers/of/base.c b/drivers/of/base.c index 239e3da9e728..a63e77694d0f 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) { struct property **next, *oldprop; unsigned long flags; - int rc = 0; + int rc, found = 0; rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop); if (rc) @@ -1606,28 +1606,36 @@ int of_update_property(struct device_node *np, struct property *newprop) if (!newprop->name) return -EINVAL; + oldprop = of_find_property(np, newprop->name, NULL); + if (!oldprop) + return of_add_property(np, newprop); + raw_spin_lock_irqsave(&devtree_lock, flags); - oldprop = __of_find_property(np, newprop->name, NULL); - if (!oldprop) { - /* add the node */ - rc = __of_add_property(np, newprop); - } else { - /* replace the node */ - next = &oldprop; - newprop->next = oldprop->next; - *next = newprop; - oldprop->next = np->deadprops; - np->deadprops = oldprop; + next = &np->properties; + while (*next) { + if (*next == oldprop) { + /* found the node */ + newprop->next = oldprop->next; + *next = newprop; + oldprop->next = np->deadprops; + np->deadprops = oldprop; + found = 1; + break; + } + next = &(*next)->next; } raw_spin_unlock_irqrestore(&devtree_lock, flags); + if (!found) + return -ENODEV; + #ifdef CONFIG_PROC_DEVICETREE /* try to add to proc as well if it was initialized */ if (!rc && np->pde) proc_device_tree_update_prop(np->pde, newprop, oldprop); #endif /* CONFIG_PROC_DEVICETREE */ - return rc; + return 0; } #if defined(CONFIG_OF_DYNAMIC) -- cgit v1.2.1 From 75b57ecf9d1d1e17d099ab13b8f48e6e038676be Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 20 Feb 2014 18:02:11 +0000 Subject: of: Make device nodes kobjects so they show up in sysfs Device tree nodes are already treated as objects, and we already want to expose them to userspace which is done using the /proc filesystem today. Right now the kernel has to do a lot of work to keep the /proc view in sync with the in-kernel representation. If device_nodes are switched to be kobjects then the device tree code can be a whole lot simpler. It also turns out that switching to using /sysfs from /proc results in smaller code and data size, and the userspace ABI won't change if /proc/device-tree symlinks to /sys/firmware/devicetree/base. v7: Add missing sysfs_bin_attr_init() v6: Add __of_add_property() early init fixes from Pantelis v5: Rename firmware/ofw to firmware/devicetree Fix updating property values in sysfs v4: Fixed build error on Powerpc Fixed handling of dynamic nodes on powerpc v3: Fixed handling of duplicate attribute and child node names v2: switch to using sysfs bin_attributes which solve the problem of reporting incorrect property size. Signed-off-by: Grant Likely Tested-by: Sascha Hauer Cc: Rob Herring Cc: Benjamin Herrenschmidt Cc: David S. Miller Cc: Nathan Fontenot Cc: Pantelis Antoniou --- drivers/of/base.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 166 insertions(+), 8 deletions(-) (limited to 'drivers/of/base.c') diff --git a/drivers/of/base.c b/drivers/of/base.c index 48594f334151..3b70a468c8ab 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "of_private.h" @@ -35,6 +36,12 @@ struct device_node *of_chosen; struct device_node *of_aliases; static struct device_node *of_stdout; +static struct kset *of_kset; + +/* + * Used to protect the of_aliases; but also overloaded to hold off addition of + * nodes to sysfs + */ DEFINE_MUTEX(of_aliases_mutex); /* use when traversing tree through the allnext, child, sibling, @@ -92,14 +99,14 @@ int __weak of_node_to_nid(struct device_node *np) struct device_node *of_node_get(struct device_node *node) { if (node) - kref_get(&node->kref); + kobject_get(&node->kobj); return node; } EXPORT_SYMBOL(of_node_get); -static inline struct device_node *kref_to_device_node(struct kref *kref) +static inline struct device_node *kobj_to_device_node(struct kobject *kobj) { - return container_of(kref, struct device_node, kref); + return container_of(kobj, struct device_node, kobj); } /** @@ -109,16 +116,15 @@ static inline struct device_node *kref_to_device_node(struct kref *kref) * In of_node_put() this function is passed to kref_put() * as the destructor. */ -static void of_node_release(struct kref *kref) +static void of_node_release(struct kobject *kobj) { - struct device_node *node = kref_to_device_node(kref); + struct device_node *node = kobj_to_device_node(kobj); struct property *prop = node->properties; /* We should never be releasing nodes that haven't been detached. */ if (!of_node_check_flag(node, OF_DETACHED)) { pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name); dump_stack(); - kref_init(&node->kref); return; } @@ -151,11 +157,140 @@ static void of_node_release(struct kref *kref) void of_node_put(struct device_node *node) { if (node) - kref_put(&node->kref, of_node_release); + kobject_put(&node->kobj); } EXPORT_SYMBOL(of_node_put); +#else +static void of_node_release(struct kobject *kobj) +{ + /* Without CONFIG_OF_DYNAMIC, no nodes gets freed */ +} #endif /* CONFIG_OF_DYNAMIC */ +struct kobj_type of_node_ktype = { + .release = of_node_release, +}; + +static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t offset, size_t count) +{ + struct property *pp = container_of(bin_attr, struct property, attr); + return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length); +} + +static const char *safe_name(struct kobject *kobj, const char *orig_name) +{ + const char *name = orig_name; + struct kernfs_node *kn; + int i = 0; + + /* don't be a hero. After 16 tries give up */ + while (i < 16 && (kn = sysfs_get_dirent(kobj->sd, name))) { + sysfs_put(kn); + if (name != orig_name) + kfree(name); + name = kasprintf(GFP_KERNEL, "%s#%i", orig_name, ++i); + } + + if (name != orig_name) + pr_warn("device-tree: Duplicate name in %s, renamed to \"%s\"\n", + kobject_name(kobj), name); + return name; +} + +static int __of_add_property_sysfs(struct device_node *np, struct property *pp) +{ + int rc; + + /* Important: Don't leak passwords */ + bool secure = strncmp(pp->name, "security-", 9) == 0; + + sysfs_bin_attr_init(&pp->attr); + pp->attr.attr.name = safe_name(&np->kobj, pp->name); + pp->attr.attr.mode = secure ? S_IRUSR : S_IRUGO; + pp->attr.size = secure ? 0 : pp->length; + pp->attr.read = of_node_property_read; + + rc = sysfs_create_bin_file(&np->kobj, &pp->attr); + WARN(rc, "error adding attribute %s to node %s\n", pp->name, np->full_name); + return rc; +} + +static int __of_node_add(struct device_node *np) +{ + const char *name; + struct property *pp; + int rc; + + np->kobj.kset = of_kset; + if (!np->parent) { + /* Nodes without parents are new top level trees */ + rc = kobject_add(&np->kobj, NULL, safe_name(&of_kset->kobj, "base")); + } else { + name = safe_name(&np->parent->kobj, kbasename(np->full_name)); + if (!name || !name[0]) + return -EINVAL; + + rc = kobject_add(&np->kobj, &np->parent->kobj, "%s", name); + } + if (rc) + return rc; + + for_each_property_of_node(np, pp) + __of_add_property_sysfs(np, pp); + + return 0; +} + +int of_node_add(struct device_node *np) +{ + int rc = 0; + kobject_init(&np->kobj, &of_node_ktype); + mutex_lock(&of_aliases_mutex); + if (of_kset) + rc = __of_node_add(np); + mutex_unlock(&of_aliases_mutex); + return rc; +} + +#if defined(CONFIG_OF_DYNAMIC) +static void of_node_remove(struct device_node *np) +{ + struct property *pp; + + for_each_property_of_node(np, pp) + sysfs_remove_bin_file(&np->kobj, &pp->attr); + + kobject_del(&np->kobj); +} +#endif + +static int __init of_init(void) +{ + struct device_node *np; + + /* Create the kset, and register existing nodes */ + mutex_lock(&of_aliases_mutex); + of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj); + if (!of_kset) { + mutex_unlock(&of_aliases_mutex); + return -ENOMEM; + } + for_each_of_allnodes(np) + __of_node_add(np); + mutex_unlock(&of_aliases_mutex); + +#if !defined(CONFIG_PROC_DEVICETREE) + /* Symlink to the new tree when PROC_DEVICETREE is disabled */ + if (of_allnodes) + proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); +#endif /* CONFIG_PROC_DEVICETREE */ + + return 0; +} +core_initcall(of_init); + static struct property *__of_find_property(const struct device_node *np, const char *name, int *lenp) { @@ -1546,6 +1681,14 @@ int of_add_property(struct device_node *np, struct property *prop) raw_spin_lock_irqsave(&devtree_lock, flags); rc = __of_add_property(np, prop); raw_spin_unlock_irqrestore(&devtree_lock, flags); + if (rc) + return rc; + + /* at early boot, bail hear and defer setup to of_init() */ + if (!of_kset) + return 0; + + __of_add_property_sysfs(np, prop); #ifdef CONFIG_PROC_DEVICETREE /* try to add to proc as well if it was initialized */ @@ -1593,6 +1736,12 @@ int of_remove_property(struct device_node *np, struct property *prop) if (!found) return -ENODEV; + /* at early boot, bail hear and defer setup to of_init() */ + if (!of_kset) + return 0; + + sysfs_remove_bin_file(&np->kobj, &prop->attr); + #ifdef CONFIG_PROC_DEVICETREE /* try to remove the proc node as well */ if (np->pde) @@ -1643,13 +1792,20 @@ int of_update_property(struct device_node *np, struct property *newprop) next = &(*next)->next; } raw_spin_unlock_irqrestore(&devtree_lock, flags); + if (rc) + return rc; + + /* Update the sysfs attribute */ + if (oldprop) + sysfs_remove_bin_file(&np->kobj, &oldprop->attr); + __of_add_property_sysfs(np, newprop); if (!found) return -ENODEV; #ifdef CONFIG_PROC_DEVICETREE /* try to add to proc as well if it was initialized */ - if (!rc && np->pde) + if (np->pde) proc_device_tree_update_prop(np->pde, newprop, oldprop); #endif /* CONFIG_PROC_DEVICETREE */ @@ -1723,6 +1879,7 @@ int of_attach_node(struct device_node *np) of_node_clear_flag(np, OF_DETACHED); raw_spin_unlock_irqrestore(&devtree_lock, flags); + of_node_add(np); of_add_proc_dt_entry(np); return 0; } @@ -1795,6 +1952,7 @@ int of_detach_node(struct device_node *np) raw_spin_unlock_irqrestore(&devtree_lock, flags); of_remove_proc_dt_entry(np); + of_node_remove(np); return rc; } #endif /* defined(CONFIG_OF_DYNAMIC) */ -- cgit v1.2.1 From 8357041a69b368991d1b04d9f1d297f8d71e1314 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 6 Nov 2012 21:03:27 +0000 Subject: of: remove /proc/device-tree The same data is now available in sysfs, so we can remove the code that exports it in /proc and replace it with a symlink to the sysfs version. Tested on versatile qemu model and mpc5200 eval board. More testing would be appreciated. v5: Fixed up conflicts with mainline changes Signed-off-by: Grant Likely Cc: Rob Herring Cc: Benjamin Herrenschmidt Cc: David S. Miller Cc: Nathan Fontenot Cc: Pantelis Antoniou --- drivers/of/base.c | 52 +--------------------------------------------------- 1 file changed, 1 insertion(+), 51 deletions(-) (limited to 'drivers/of/base.c') diff --git a/drivers/of/base.c b/drivers/of/base.c index 3b70a468c8ab..ed3e70b84957 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -281,11 +281,9 @@ static int __init of_init(void) __of_node_add(np); mutex_unlock(&of_aliases_mutex); -#if !defined(CONFIG_PROC_DEVICETREE) - /* Symlink to the new tree when PROC_DEVICETREE is disabled */ + /* Symlink in /proc as required by userspace ABI */ if (of_allnodes) proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); -#endif /* CONFIG_PROC_DEVICETREE */ return 0; } @@ -1690,12 +1688,6 @@ int of_add_property(struct device_node *np, struct property *prop) __of_add_property_sysfs(np, prop); -#ifdef CONFIG_PROC_DEVICETREE - /* try to add to proc as well if it was initialized */ - if (!rc && np->pde) - proc_device_tree_add_prop(np->pde, prop); -#endif /* CONFIG_PROC_DEVICETREE */ - return rc; } @@ -1742,12 +1734,6 @@ int of_remove_property(struct device_node *np, struct property *prop) sysfs_remove_bin_file(&np->kobj, &prop->attr); -#ifdef CONFIG_PROC_DEVICETREE - /* try to remove the proc node as well */ - if (np->pde) - proc_device_tree_remove_prop(np->pde, prop); -#endif /* CONFIG_PROC_DEVICETREE */ - return 0; } @@ -1803,12 +1789,6 @@ int of_update_property(struct device_node *np, struct property *newprop) if (!found) return -ENODEV; -#ifdef CONFIG_PROC_DEVICETREE - /* try to add to proc as well if it was initialized */ - if (np->pde) - proc_device_tree_update_prop(np->pde, newprop, oldprop); -#endif /* CONFIG_PROC_DEVICETREE */ - return 0; } @@ -1843,22 +1823,6 @@ int of_reconfig_notify(unsigned long action, void *p) return notifier_to_errno(rc); } -#ifdef CONFIG_PROC_DEVICETREE -static void of_add_proc_dt_entry(struct device_node *dn) -{ - struct proc_dir_entry *ent; - - ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde); - if (ent) - proc_device_tree_add_node(dn, ent); -} -#else -static void of_add_proc_dt_entry(struct device_node *dn) -{ - return; -} -#endif - /** * of_attach_node - Plug a device node into the tree and global list. */ @@ -1880,22 +1844,9 @@ int of_attach_node(struct device_node *np) raw_spin_unlock_irqrestore(&devtree_lock, flags); of_node_add(np); - of_add_proc_dt_entry(np); return 0; } -#ifdef CONFIG_PROC_DEVICETREE -static void of_remove_proc_dt_entry(struct device_node *dn) -{ - proc_remove(dn->pde); -} -#else -static void of_remove_proc_dt_entry(struct device_node *dn) -{ - return; -} -#endif - /** * of_detach_node - "Unplug" a node from the device tree. * @@ -1951,7 +1902,6 @@ int of_detach_node(struct device_node *np) of_node_set_flag(np, OF_DETACHED); raw_spin_unlock_irqrestore(&devtree_lock, flags); - of_remove_proc_dt_entry(np); of_node_remove(np); return rc; } -- cgit v1.2.1 From 0829f6d1f69e4f2fae4062987ae6531a9af1a2e3 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Fri, 13 Dec 2013 20:08:59 +0200 Subject: of: device_node kobject lifecycle fixes After the move to having device nodes be proper kobjects the lifecycle of the node needs to be controlled better. At first convert of_add_node() in the unflattened functions to of_init_node() which initializes the kobject so that of_node_get/put work correctly even before of_init is called. Afterwards introduce of_node_is_initialized & of_node_is_attached that query the underlying kobject about the state (attached means kobj is visible in sysfs) Using that make sure the lifecycle of the tree is correct at all times. Signed-off-by: Pantelis Antoniou [grant.likely: moved of_node_init() calls, fixed up locking, and dropped __of_populate() hunks] Signed-off-by: Grant Likely --- drivers/of/base.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'drivers/of/base.c') diff --git a/drivers/of/base.c b/drivers/of/base.c index ed3e70b84957..418a4ff9d97c 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -246,10 +246,19 @@ static int __of_node_add(struct device_node *np) int of_node_add(struct device_node *np) { int rc = 0; - kobject_init(&np->kobj, &of_node_ktype); + + BUG_ON(!of_node_is_initialized(np)); + + /* + * Grab the mutex here so that in a race condition between of_init() and + * of_node_add(), node addition will still be consistent. + */ mutex_lock(&of_aliases_mutex); if (of_kset) rc = __of_node_add(np); + else + /* This scenario may be perfectly valid, but report it anyway */ + pr_info("of_node_add(%s) before of_init()\n", np->full_name); mutex_unlock(&of_aliases_mutex); return rc; } @@ -259,10 +268,17 @@ static void of_node_remove(struct device_node *np) { struct property *pp; - for_each_property_of_node(np, pp) - sysfs_remove_bin_file(&np->kobj, &pp->attr); + BUG_ON(!of_node_is_initialized(np)); + + /* only remove properties if on sysfs */ + if (of_node_is_attached(np)) { + for_each_property_of_node(np, pp) + sysfs_remove_bin_file(&np->kobj, &pp->attr); + kobject_del(&np->kobj); + } - kobject_del(&np->kobj); + /* finally remove the kobj_init ref */ + of_node_put(np); } #endif @@ -1631,6 +1647,10 @@ static int of_property_notify(int action, struct device_node *np, { struct of_prop_reconfig pr; + /* only call notifiers if the node is attached */ + if (!of_node_is_attached(np)) + return 0; + pr.dn = np; pr.prop = prop; return of_reconfig_notify(action, &pr); @@ -1682,11 +1702,8 @@ int of_add_property(struct device_node *np, struct property *prop) if (rc) return rc; - /* at early boot, bail hear and defer setup to of_init() */ - if (!of_kset) - return 0; - - __of_add_property_sysfs(np, prop); + if (of_node_is_attached(np)) + __of_add_property_sysfs(np, prop); return rc; } -- cgit v1.2.1 From 676e1b2fcd9dbb47a59baac13d089621d22c68b8 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 27 Mar 2014 17:11:23 -0700 Subject: of: Add support for ePAPR "stdout-path" property ePAPR 1.1 defines the "stdout-path" property for specifying the console device, but Linux currently only handles the older "linux,stdout-path" property. This patch adds parsing for the new property name. Signed-off-by: Grant Likely --- drivers/of/base.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/of/base.c') diff --git a/drivers/of/base.c b/drivers/of/base.c index 418a4ff9d97c..be2861d69b02 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1955,9 +1955,9 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) of_chosen = of_find_node_by_path("/chosen@0"); if (of_chosen) { - const char *name; - - name = of_get_property(of_chosen, "linux,stdout-path", NULL); + const char *name = of_get_property(of_chosen, "stdout-path", NULL); + if (!name) + name = of_get_property(of_chosen, "linux,stdout-path", NULL); if (name) of_stdout = of_find_node_by_path(name); } -- cgit v1.2.1