diff mbox

[U-Boot,v4,02/29] dm: core: Add functions for iterating through device children

Message ID 1413265336-9571-3-git-send-email-sjg@chromium.org
State Awaiting Upstream
Delegated to: Simon Glass
Headers show

Commit Message

Simon Glass Oct. 14, 2014, 5:41 a.m. UTC
Buses need to iterate through their children in some situations. Add a few
functions to make this easy.

Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
---

Changes in v4: None
Changes in v3:
- Add new functions to iterate through device children

Changes in v2: None

 doc/driver-model/README.txt |  3 ++-
 drivers/core/device.c       | 27 +++++++++++++++++++++++++++
 include/dm/device.h         | 18 ++++++++++++++++++
 test/dm/bus.c               | 31 +++++++++++++++++++++++++++++++
 4 files changed, 78 insertions(+), 1 deletion(-)

Comments

Simon Glass Oct. 23, 2014, 3:03 a.m. UTC | #1
On 13 October 2014 23:41, Simon Glass <sjg@chromium.org> wrote:
> Buses need to iterate through their children in some situations. Add a few
> functions to make this easy.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Acked-by: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
> ---
>
> Changes in v4: None
> Changes in v3:
> - Add new functions to iterate through device children
>
> Changes in v2: None
>
>  doc/driver-model/README.txt |  3 ++-
>  drivers/core/device.c       | 27 +++++++++++++++++++++++++++
>  include/dm/device.h         | 18 ++++++++++++++++++
>  test/dm/bus.c               | 31 +++++++++++++++++++++++++++++++
>  4 files changed, 78 insertions(+), 1 deletion(-)

Applied to u-boot-dm/master.
diff mbox

Patch

diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt
index f9b68be..c435cdc 100644
--- a/doc/driver-model/README.txt
+++ b/doc/driver-model/README.txt
@@ -95,7 +95,7 @@  are provided in test/dm. To run them, try:
 You should see something like this:
 
     <...U-Boot banner...>
-    Running 21 driver model tests
+    Running 22 driver model tests
     Test: dm_test_autobind
     Test: dm_test_autoprobe
     Test: dm_test_bus_children
@@ -103,6 +103,7 @@  You should see something like this:
     Device 'c-test@0': seq 0 is in use by 'a-test'
     Device 'c-test@1': seq 1 is in use by 'd-test'
     Test: dm_test_bus_children_funcs
+    Test: dm_test_bus_children_iterators
     Test: dm_test_bus_parent_data
     Test: dm_test_bus_parent_ops
     Test: dm_test_children
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 32e80e8..9538874 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -514,3 +514,30 @@  int device_get_child_by_of_offset(struct udevice *parent, int seq,
 	ret = device_find_child_by_of_offset(parent, seq, &dev);
 	return device_get_device_tail(dev, ret, devp);
 }
+
+int device_find_first_child(struct udevice *parent, struct udevice **devp)
+{
+	if (list_empty(&parent->child_head)) {
+		*devp = NULL;
+	} else {
+		*devp = list_first_entry(&parent->child_head, struct udevice,
+					 sibling_node);
+	}
+
+	return 0;
+}
+
+int device_find_next_child(struct udevice **devp)
+{
+	struct udevice *dev = *devp;
+	struct udevice *parent = dev->parent;
+
+	if (list_is_last(&dev->sibling_node, &parent->child_head)) {
+		*devp = NULL;
+	} else {
+		*devp = list_entry(dev->sibling_node.next, struct udevice,
+				   sibling_node);
+	}
+
+	return 0;
+}
diff --git a/include/dm/device.h b/include/dm/device.h
index c8a4072..4d277db 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -274,4 +274,22 @@  int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
 int device_get_child_by_of_offset(struct udevice *parent, int seq,
 				  struct udevice **devp);
 
+/**
+ * device_find_first_child() - Find the first child of a device
+ *
+ * @parent: Parent device to search
+ * @devp: Returns first child device, or NULL if none
+ * @return 0
+ */
+int device_find_first_child(struct udevice *parent, struct udevice **devp);
+
+/**
+ * device_find_first_child() - Find the first child of a device
+ *
+ * @devp: Pointer to previous child device on entry. Returns pointer to next
+ *		child device, or NULL if none
+ * @return 0
+ */
+int device_find_next_child(struct udevice **devp);
+
 #endif
diff --git a/test/dm/bus.c b/test/dm/bus.c
index 873d64e..abbaccf 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -140,6 +140,37 @@  static int dm_test_bus_children_funcs(struct dm_test_state *dms)
 }
 DM_TEST(dm_test_bus_children_funcs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 
+/* Test that we can iterate through children */
+static int dm_test_bus_children_iterators(struct dm_test_state *dms)
+{
+	struct udevice *bus, *dev, *child;
+
+	/* Walk through the children one by one */
+	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
+	ut_assertok(device_find_first_child(bus, &dev));
+	ut_asserteq_str("c-test@5", dev->name);
+	ut_assertok(device_find_next_child(&dev));
+	ut_asserteq_str("c-test@0", dev->name);
+	ut_assertok(device_find_next_child(&dev));
+	ut_asserteq_str("c-test@1", dev->name);
+	ut_assertok(device_find_next_child(&dev));
+	ut_asserteq_ptr(dev, NULL);
+
+	/* Move to the next child without using device_find_first_child() */
+	ut_assertok(device_find_child_by_seq(bus, 5, true, &dev));
+	ut_asserteq_str("c-test@5", dev->name);
+	ut_assertok(device_find_next_child(&dev));
+	ut_asserteq_str("c-test@0", dev->name);
+
+	/* Try a device with no children */
+	ut_assertok(device_find_first_child(dev, &child));
+	ut_asserteq_ptr(child, NULL);
+
+	return 0;
+}
+DM_TEST(dm_test_bus_children_iterators,
+	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
 /* Test that the bus can store data about each child */
 static int dm_test_bus_parent_data(struct dm_test_state *dms)
 {