Skip to content
Snippets Groups Projects
Commit a8981d4f authored by Simon Glass's avatar Simon Glass
Browse files

dm: core: Add functions for iterating through device children


Buses need to iterate through their children in some situations. Add a few
functions to make this easy.

Signed-off-by: default avatarSimon Glass <sjg@chromium.org>
Acked-by: default avatarJagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
parent 0b304a24
No related branches found
No related tags found
No related merge requests found
...@@ -95,7 +95,7 @@ are provided in test/dm. To run them, try: ...@@ -95,7 +95,7 @@ are provided in test/dm. To run them, try:
You should see something like this: You should see something like this:
<...U-Boot banner...> <...U-Boot banner...>
Running 21 driver model tests Running 22 driver model tests
Test: dm_test_autobind Test: dm_test_autobind
Test: dm_test_autoprobe Test: dm_test_autoprobe
Test: dm_test_bus_children Test: dm_test_bus_children
...@@ -103,6 +103,7 @@ You should see something like this: ...@@ -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@0': seq 0 is in use by 'a-test'
Device 'c-test@1': seq 1 is in use by 'd-test' Device 'c-test@1': seq 1 is in use by 'd-test'
Test: dm_test_bus_children_funcs Test: dm_test_bus_children_funcs
Test: dm_test_bus_children_iterators
Test: dm_test_bus_parent_data Test: dm_test_bus_parent_data
Test: dm_test_bus_parent_ops Test: dm_test_bus_parent_ops
Test: dm_test_children Test: dm_test_children
......
...@@ -514,3 +514,30 @@ int device_get_child_by_of_offset(struct udevice *parent, int seq, ...@@ -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); ret = device_find_child_by_of_offset(parent, seq, &dev);
return device_get_device_tail(dev, ret, devp); 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;
}
...@@ -280,4 +280,22 @@ int device_find_child_by_of_offset(struct udevice *parent, int of_offset, ...@@ -280,4 +280,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, int device_get_child_by_of_offset(struct udevice *parent, int seq,
struct udevice **devp); 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 #endif
...@@ -140,6 +140,37 @@ static int dm_test_bus_children_funcs(struct dm_test_state *dms) ...@@ -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); 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 */ /* Test that the bus can store data about each child */
static int dm_test_bus_parent_data(struct dm_test_state *dms) static int dm_test_bus_parent_data(struct dm_test_state *dms)
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment