return 0;
}
+int device_find_first_inactive_child(struct udevice *parent,
+ enum uclass_id uclass_id,
+ struct udevice **devp)
+{
+ struct udevice *dev;
+
+ *devp = NULL;
+ list_for_each_entry(dev, &parent->child_head, sibling_node) {
+ if (!device_active(dev) &&
+ device_get_uclass_id(dev) == uclass_id) {
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
struct udevice *dev_get_parent(const struct udevice *child)
{
return child->parent;
*/
int device_find_next_child(struct udevice **devp);
+/**
+ * device_find_first_inactive_child() - Find the first inactive child
+ *
+ * This is used to locate an existing child of a device which is of a given
+ * uclass.
+ *
+ * @parent: Parent device to search
+ * @uclass_id: Uclass to look for
+ * @devp: Returns device found, if any
+ * @return 0 if found, else -ENODEV
+ */
+int device_find_first_inactive_child(struct udevice *parent,
+ enum uclass_id uclass_id,
+ struct udevice **devp);
+
/**
* device_has_children() - check if a device has any children
*
return 0;
}
DM_TEST(dm_test_uclass_names, DM_TESTF_SCAN_PDATA);
+
+static int dm_test_inactive_child(struct unit_test_state *uts)
+{
+ struct dm_test_state *dms = uts->priv;
+ struct udevice *parent, *dev1, *dev2;
+
+ /* Skip the behaviour in test_post_probe() */
+ dms->skip_post_probe = 1;
+
+ ut_assertok(uclass_first_device_err(UCLASS_TEST, &parent));
+
+ /*
+ * Create a child but do not activate it. Calling the function again
+ * should return the same child.
+ */
+ ut_asserteq(-ENODEV, device_find_first_inactive_child(parent,
+ UCLASS_TEST, &dev1));
+ ut_assertok(device_bind_ofnode(parent, DM_GET_DRIVER(test_drv),
+ "test_child", 0, ofnode_null(), &dev1));
+
+ ut_assertok(device_find_first_inactive_child(parent, UCLASS_TEST,
+ &dev2));
+ ut_asserteq_ptr(dev1, dev2);
+
+ ut_assertok(device_probe(dev1));
+ ut_asserteq(-ENODEV, device_find_first_inactive_child(parent,
+ UCLASS_TEST, &dev2));
+
+ return 0;
+}
+DM_TEST(dm_test_inactive_child, DM_TESTF_SCAN_PDATA);