aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/of/platform.c32
-rw-r--r--include/linux/of.h1
-rw-r--r--include/linux/of_platform.h7
3 files changed, 12 insertions, 28 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 500436f9be7f..0197725e033a 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -422,6 +422,7 @@ static int of_platform_bus_create(struct device_node *bus,
422 break; 422 break;
423 } 423 }
424 } 424 }
425 of_node_set_flag(bus, OF_POPULATED_BUS);
425 return rc; 426 return rc;
426} 427}
427 428
@@ -508,19 +509,13 @@ EXPORT_SYMBOL_GPL(of_platform_populate);
508 509
509static int of_platform_device_destroy(struct device *dev, void *data) 510static int of_platform_device_destroy(struct device *dev, void *data)
510{ 511{
511 bool *children_left = data;
512
513 /* Do not touch devices not populated from the device tree */ 512 /* Do not touch devices not populated from the device tree */
514 if (!dev->of_node || !of_node_check_flag(dev->of_node, OF_POPULATED)) { 513 if (!dev->of_node || !of_node_check_flag(dev->of_node, OF_POPULATED))
515 *children_left = true;
516 return 0; 514 return 0;
517 }
518 515
519 /* Recurse, but don't touch this device if it has any children left */ 516 /* Recurse for any nodes that were treated as busses */
520 if (of_platform_depopulate(dev) != 0) { 517 if (of_node_check_flag(dev->of_node, OF_POPULATED_BUS))
521 *children_left = true; 518 device_for_each_child(dev, NULL, of_platform_device_destroy);
522 return 0;
523 }
524 519
525 if (dev->bus == &platform_bus_type) 520 if (dev->bus == &platform_bus_type)
526 platform_device_unregister(to_platform_device(dev)); 521 platform_device_unregister(to_platform_device(dev));
@@ -528,19 +523,15 @@ static int of_platform_device_destroy(struct device *dev, void *data)
528 else if (dev->bus == &amba_bustype) 523 else if (dev->bus == &amba_bustype)
529 amba_device_unregister(to_amba_device(dev)); 524 amba_device_unregister(to_amba_device(dev));
530#endif 525#endif
531 else {
532 *children_left = true;
533 return 0;
534 }
535 526
536 of_node_clear_flag(dev->of_node, OF_POPULATED); 527 of_node_clear_flag(dev->of_node, OF_POPULATED);
537 528 of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
538 return 0; 529 return 0;
539} 530}
540 531
541/** 532/**
542 * of_platform_depopulate() - Remove devices populated from device tree 533 * of_platform_depopulate() - Remove devices populated from device tree
543 * @parent: device which childred will be removed 534 * @parent: device which children will be removed
544 * 535 *
545 * Complementary to of_platform_populate(), this function removes children 536 * Complementary to of_platform_populate(), this function removes children
546 * of the given device (and, recurrently, their children) that have been 537 * of the given device (and, recurrently, their children) that have been
@@ -550,14 +541,9 @@ static int of_platform_device_destroy(struct device *dev, void *data)
550 * Returns 0 when all children devices have been removed or 541 * Returns 0 when all children devices have been removed or
551 * -EBUSY when some children remained. 542 * -EBUSY when some children remained.
552 */ 543 */
553int of_platform_depopulate(struct device *parent) 544void of_platform_depopulate(struct device *parent)
554{ 545{
555 bool children_left = false; 546 device_for_each_child(parent, NULL, of_platform_device_destroy);
556
557 device_for_each_child(parent, &children_left,
558 of_platform_device_destroy);
559
560 return children_left ? -EBUSY : 0;
561} 547}
562EXPORT_SYMBOL_GPL(of_platform_depopulate); 548EXPORT_SYMBOL_GPL(of_platform_depopulate);
563 549
diff --git a/include/linux/of.h b/include/linux/of.h
index 196b34c1ef4e..abf829a1f150 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -204,6 +204,7 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
204#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ 204#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
205#define OF_DETACHED 2 /* node has been detached from the device tree */ 205#define OF_DETACHED 2 /* node has been detached from the device tree */
206#define OF_POPULATED 3 /* device already created for the node */ 206#define OF_POPULATED 3 /* device already created for the node */
207#define OF_POPULATED_BUS 4 /* of_platform_populate recursed to children of this node */
207 208
208#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) 209#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
209#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) 210#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index d96e1badbee0..c2b0627a2317 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -72,7 +72,7 @@ extern int of_platform_populate(struct device_node *root,
72 const struct of_device_id *matches, 72 const struct of_device_id *matches,
73 const struct of_dev_auxdata *lookup, 73 const struct of_dev_auxdata *lookup,
74 struct device *parent); 74 struct device *parent);
75extern int of_platform_depopulate(struct device *parent); 75extern void of_platform_depopulate(struct device *parent);
76#else 76#else
77static inline int of_platform_populate(struct device_node *root, 77static inline int of_platform_populate(struct device_node *root,
78 const struct of_device_id *matches, 78 const struct of_device_id *matches,
@@ -81,10 +81,7 @@ static inline int of_platform_populate(struct device_node *root,
81{ 81{
82 return -ENODEV; 82 return -ENODEV;
83} 83}
84static inline int of_platform_depopulate(struct device *parent) 84static inline void of_platform_depopulate(struct device *parent) { }
85{
86 return -ENODEV;
87}
88#endif 85#endif
89 86
90#endif /* _LINUX_OF_PLATFORM_H */ 87#endif /* _LINUX_OF_PLATFORM_H */