mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-04-01 03:51:31 +00:00
dm: core: Add a way to iterate through children, probing each
It is sometimes useful to process all children, making sure they are probed first. Add functions to help with this and a macro to make it more convenient. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
f262d4ca4b
commit
903e83ee84
3 changed files with 80 additions and 0 deletions
|
@ -792,6 +792,28 @@ int device_find_child_by_name(const struct udevice *parent, const char *name,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int device_first_child_err(struct udevice *parent, struct udevice **devp)
|
||||||
|
{
|
||||||
|
struct udevice *dev;
|
||||||
|
|
||||||
|
device_find_first_child(parent, &dev);
|
||||||
|
if (!dev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
return device_get_device_tail(dev, 0, devp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int device_next_child_err(struct udevice **devp)
|
||||||
|
{
|
||||||
|
struct udevice *dev = *devp;
|
||||||
|
|
||||||
|
device_find_next_child(&dev);
|
||||||
|
if (!dev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
return device_get_device_tail(dev, 0, devp);
|
||||||
|
}
|
||||||
|
|
||||||
int device_first_child_ofdata_err(struct udevice *parent, struct udevice **devp)
|
int device_first_child_ofdata_err(struct udevice *parent, struct udevice **devp)
|
||||||
{
|
{
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
|
|
|
@ -602,6 +602,28 @@ int device_first_child_ofdata_err(struct udevice *parent,
|
||||||
*/
|
*/
|
||||||
int device_next_child_ofdata_err(struct udevice **devp);
|
int device_next_child_ofdata_err(struct udevice **devp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* device_first_child_err() - Get the first child of a device
|
||||||
|
*
|
||||||
|
* The device returned is probed if necessary, and ready for use
|
||||||
|
*
|
||||||
|
* @parent: Parent device to search
|
||||||
|
* @devp: Returns device found, if any
|
||||||
|
* @return 0 if found, -ENODEV if not, -ve error if device failed to probe
|
||||||
|
*/
|
||||||
|
int device_first_child_err(struct udevice *parent, struct udevice **devp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* device_next_child_err() - Get the next child of a parent device
|
||||||
|
*
|
||||||
|
* The device returned is probed if necessary, and ready for use
|
||||||
|
*
|
||||||
|
* @devp: On entry, pointer to device to lookup. On exit, returns pointer
|
||||||
|
* to the next sibling if no error occurred
|
||||||
|
* @return 0 if found, -ENODEV if not, -ve error if device failed to probe
|
||||||
|
*/
|
||||||
|
int device_next_child_err(struct udevice **devp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* device_has_children() - check if a device has any children
|
* device_has_children() - check if a device has any children
|
||||||
*
|
*
|
||||||
|
@ -748,6 +770,23 @@ static inline bool device_is_on_pci_bus(const struct udevice *dev)
|
||||||
for (int _ret = device_first_child_ofdata_err(parent, &dev); !_ret; \
|
for (int _ret = device_first_child_ofdata_err(parent, &dev); !_ret; \
|
||||||
_ret = device_next_child_ofdata_err(&dev))
|
_ret = device_next_child_ofdata_err(&dev))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* device_foreach_child_probe() - iterate through children, probing them
|
||||||
|
*
|
||||||
|
* This creates a for() loop which works through the available children of
|
||||||
|
* a device in order from start to end. Devices are probed if necessary,
|
||||||
|
* and ready for use.
|
||||||
|
*
|
||||||
|
* This stops when it gets an error, with @pos set to the device that failed to
|
||||||
|
* probe
|
||||||
|
*
|
||||||
|
* @pos: struct udevice * for the current device
|
||||||
|
* @parent: parent device to scan
|
||||||
|
*/
|
||||||
|
#define device_foreach_child_probe(pos, parent) \
|
||||||
|
for (int _ret = device_first_child_err(parent, &dev); !_ret; \
|
||||||
|
_ret = device_next_child_err(&dev))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dm_scan_fdt_dev() - Bind child device in a the device tree
|
* dm_scan_fdt_dev() - Bind child device in a the device tree
|
||||||
*
|
*
|
||||||
|
|
|
@ -891,3 +891,22 @@ static int dm_test_child_ofdata(struct unit_test_state *uts)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DM_TEST(dm_test_child_ofdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
DM_TEST(dm_test_child_ofdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
|
||||||
|
/* Test device_first_child_err(), etc. */
|
||||||
|
static int dm_test_first_child_probe(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct udevice *bus, *dev;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
ut_assertok(uclass_first_device_err(UCLASS_TEST_BUS, &bus));
|
||||||
|
count = 0;
|
||||||
|
device_foreach_child_probe(dev, bus) {
|
||||||
|
ut_assert(dev->flags & DM_FLAG_PLATDATA_VALID);
|
||||||
|
ut_assert(dev->flags & DM_FLAG_ACTIVATED);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
ut_asserteq(3, count);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_first_child_probe, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
|
Loading…
Add table
Reference in a new issue