From 3cf0fba4ff862d833545f82fb2209ff3c79d17b5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 6 Feb 2020 09:54:49 -0700 Subject: dm: core: Allow iterating devices without uclass_get() At present we have uclass_foreach_dev() which requires that uclass_get() be called beforehand to find the uclass. This is good if we suspect that that function might fail, but often we know that the uclass is available. Add a new helper which does this uclass_get() automatically, so that only the uclass ID is needed. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- include/dm/uclass.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include/dm') diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 484d1660135..74b8e2ecb5e 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -365,6 +365,23 @@ int uclass_next_device_check(struct udevice **devp); */ int uclass_resolve_seq(struct udevice *dev); +/** + * uclass_id_foreach_dev() - Helper function to iteration through devices + * + * This creates a for() loop which works through the available devices in + * a uclass ID in order from start to end. + * + * If for some reason the uclass cannot be found, this does nothing. + * + * @id: enum uclass_id ID to use + * @pos: struct udevice * to hold the current device. Set to NULL when there + * are no more devices. + * @uc: temporary uclass variable (struct udevice *) + */ +#define uclass_id_foreach_dev(id, pos, uc) \ + if (!uclass_get(id, &uc)) \ + list_for_each_entry(pos, &uc->dev_head, uclass_node) + /** * uclass_foreach_dev() - Helper function to iteration through devices * -- cgit v1.3.1 From 50162348f0d3b915004733131acd81805e202c76 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 6 Feb 2020 09:54:50 -0700 Subject: dm: core: Add a function to find a device by drvdata It is sometimes useful to find a device in a uclass using only its driver data. The driver data often indicates the 'subtype' of the device, e,g, via its compatible string. Add a function to handle this. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/core/uclass.c | 17 +++++++++++++++++ include/dm/test.h | 2 ++ include/dm/uclass.h | 14 ++++++++++++++ test/dm/test-fdt.c | 21 +++++++++++++++++++++ 4 files changed, 54 insertions(+) (limited to 'include/dm') diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index c520ef113a2..61192d8a9ff 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -629,6 +629,23 @@ int uclass_next_device_check(struct udevice **devp) return device_probe(*devp); } +int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data, + struct udevice **devp) +{ + struct udevice *dev; + struct uclass *uc; + + uclass_id_foreach_dev(id, dev, uc) { + if (dev_get_driver_data(dev) == driver_data) { + *devp = dev; + + return device_probe(dev); + } + } + + return -ENODEV; +} + int uclass_bind_device(struct udevice *dev) { struct uclass *uc; diff --git a/include/dm/test.h b/include/dm/test.h index 07385cd531f..f0f36624ce3 100644 --- a/include/dm/test.h +++ b/include/dm/test.h @@ -56,6 +56,8 @@ enum { enum { DM_TEST_TYPE_FIRST = 0, DM_TEST_TYPE_SECOND, + + DM_TEST_TYPE_COUNT, }; /* The number added to the ping total on each probe */ diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 74b8e2ecb5e..70fca79b449 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -350,6 +350,20 @@ int uclass_first_device_check(enum uclass_id id, struct udevice **devp); */ int uclass_next_device_check(struct udevice **devp); +/** + * uclass_first_device_drvdata() - Find the first device with given driver data + * + * This searches through the devices for a particular uclass looking for one + * that has the given driver data. + * + * @id: Uclass ID to check + * @driver_data: Driver data to search for + * @devp: Returns pointer to the first matching device in that uclass, if found + * @return 0 if found, -ENODEV if not found, other -ve on error + */ +int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data, + struct udevice **devp); + /** * uclass_resolve_seq() - Resolve a device's sequence number * diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 8ea536c3093..698ca0e7cf8 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -893,3 +893,24 @@ static int dm_test_read_int(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_read_int, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test iteration through devices by drvdata */ +static int dm_test_uclass_drvdata(struct unit_test_state *uts) +{ + struct udevice *dev; + + ut_assertok(uclass_first_device_drvdata(UCLASS_TEST_FDT, + DM_TEST_TYPE_FIRST, &dev)); + ut_asserteq_str("a-test", dev->name); + + ut_assertok(uclass_first_device_drvdata(UCLASS_TEST_FDT, + DM_TEST_TYPE_SECOND, &dev)); + ut_asserteq_str("d-test", dev->name); + + ut_asserteq(-ENODEV, uclass_first_device_drvdata(UCLASS_TEST_FDT, + DM_TEST_TYPE_COUNT, + &dev)); + + return 0; +} +DM_TEST(dm_test_uclass_drvdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- cgit v1.3.1