diff options
-rw-r--r-- | arch/powerpc/kernel/prom.c | 11 | ||||
-rw-r--r-- | include/asm-powerpc/prom.h | 1 |
2 files changed, 12 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index bcd1c5ed44a..6d5e601097a 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1375,8 +1375,17 @@ static void of_node_release(struct kref *kref) struct device_node *node = kref_to_device_node(kref); struct property *prop = node->properties; + /* We should never be releasing nodes that haven't been detached. */ + if (!of_node_check_flag(node, OF_DETACHED)) { + printk("WARNING: Bad of_node_put() on %s\n", node->full_name); + dump_stack(); + kref_init(&node->kref); + return; + } + if (!of_node_check_flag(node, OF_DYNAMIC)) return; + while (prop) { struct property *next = prop->next; kfree(prop->name); @@ -1457,6 +1466,8 @@ void of_detach_node(const struct device_node *np) prevsib->sibling = np->sibling; } + of_node_set_flag(np, OF_DETACHED); + out_unlock: write_unlock(&devtree_lock); } diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h index f1006b91bd1..1632baa17dc 100644 --- a/include/asm-powerpc/prom.h +++ b/include/asm-powerpc/prom.h @@ -99,6 +99,7 @@ extern struct device_node *of_chosen; /* flag descriptions */ #define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ +#define OF_DETACHED 2 /* node has been detached from the device tree */ static inline int of_node_check_flag(struct device_node *n, unsigned long flag) { |