12e7d35d2SSimon Glass /* 22e7d35d2SSimon Glass * Copyright (c) 2013 Google, Inc 32e7d35d2SSimon Glass * 42e7d35d2SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 52e7d35d2SSimon Glass */ 62e7d35d2SSimon Glass 72e7d35d2SSimon Glass #include <common.h> 82e7d35d2SSimon Glass #include <dm.h> 92e7d35d2SSimon Glass #include <errno.h> 102e7d35d2SSimon Glass #include <fdtdec.h> 112e7d35d2SSimon Glass #include <malloc.h> 122e7d35d2SSimon Glass #include <asm/io.h> 132e7d35d2SSimon Glass #include <dm/test.h> 142e7d35d2SSimon Glass #include <dm/root.h> 1598561572SSimon Glass #include <dm/device-internal.h> 162e7d35d2SSimon Glass #include <dm/uclass-internal.h> 172e7d35d2SSimon Glass #include <dm/util.h> 18e721b882SJoe Hershberger #include <test/ut.h> 192e7d35d2SSimon Glass 202e7d35d2SSimon Glass DECLARE_GLOBAL_DATA_PTR; 212e7d35d2SSimon Glass 2254c5d08aSHeiko Schocher static int testfdt_drv_ping(struct udevice *dev, int pingval, int *pingret) 232e7d35d2SSimon Glass { 242e7d35d2SSimon Glass const struct dm_test_pdata *pdata = dev->platdata; 252e7d35d2SSimon Glass struct dm_test_priv *priv = dev_get_priv(dev); 262e7d35d2SSimon Glass 272e7d35d2SSimon Glass *pingret = pingval + pdata->ping_add; 282e7d35d2SSimon Glass priv->ping_total += *pingret; 292e7d35d2SSimon Glass 302e7d35d2SSimon Glass return 0; 312e7d35d2SSimon Glass } 322e7d35d2SSimon Glass 332e7d35d2SSimon Glass static const struct test_ops test_ops = { 342e7d35d2SSimon Glass .ping = testfdt_drv_ping, 352e7d35d2SSimon Glass }; 362e7d35d2SSimon Glass 3754c5d08aSHeiko Schocher static int testfdt_ofdata_to_platdata(struct udevice *dev) 382e7d35d2SSimon Glass { 392e7d35d2SSimon Glass struct dm_test_pdata *pdata = dev_get_platdata(dev); 402e7d35d2SSimon Glass 41e160f7d4SSimon Glass pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), 422e7d35d2SSimon Glass "ping-add", -1); 43e160f7d4SSimon Glass pdata->base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), 44eb9ef5feSSimon Glass "ping-expect"); 452e7d35d2SSimon Glass 462e7d35d2SSimon Glass return 0; 472e7d35d2SSimon Glass } 482e7d35d2SSimon Glass 4954c5d08aSHeiko Schocher static int testfdt_drv_probe(struct udevice *dev) 502e7d35d2SSimon Glass { 512e7d35d2SSimon Glass struct dm_test_priv *priv = dev_get_priv(dev); 522e7d35d2SSimon Glass 532e7d35d2SSimon Glass priv->ping_total += DM_TEST_START_TOTAL; 542e7d35d2SSimon Glass 5583c7e434SSimon Glass /* 5683c7e434SSimon Glass * If this device is on a bus, the uclass_flag will be set before 5783c7e434SSimon Glass * calling this function. This is used by 5883c7e434SSimon Glass * dm_test_bus_child_pre_probe_uclass(). 5983c7e434SSimon Glass */ 6083c7e434SSimon Glass priv->uclass_total += priv->uclass_flag; 6183c7e434SSimon Glass 622e7d35d2SSimon Glass return 0; 632e7d35d2SSimon Glass } 642e7d35d2SSimon Glass 65ae7f4513SSimon Glass static const struct udevice_id testfdt_ids[] = { 662e7d35d2SSimon Glass { 672e7d35d2SSimon Glass .compatible = "denx,u-boot-fdt-test", 682e7d35d2SSimon Glass .data = DM_TEST_TYPE_FIRST }, 692e7d35d2SSimon Glass { 702e7d35d2SSimon Glass .compatible = "google,another-fdt-test", 712e7d35d2SSimon Glass .data = DM_TEST_TYPE_SECOND }, 722e7d35d2SSimon Glass { } 732e7d35d2SSimon Glass }; 742e7d35d2SSimon Glass 752e7d35d2SSimon Glass U_BOOT_DRIVER(testfdt_drv) = { 762e7d35d2SSimon Glass .name = "testfdt_drv", 772e7d35d2SSimon Glass .of_match = testfdt_ids, 782e7d35d2SSimon Glass .id = UCLASS_TEST_FDT, 792e7d35d2SSimon Glass .ofdata_to_platdata = testfdt_ofdata_to_platdata, 802e7d35d2SSimon Glass .probe = testfdt_drv_probe, 812e7d35d2SSimon Glass .ops = &test_ops, 822e7d35d2SSimon Glass .priv_auto_alloc_size = sizeof(struct dm_test_priv), 832e7d35d2SSimon Glass .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), 842e7d35d2SSimon Glass }; 852e7d35d2SSimon Glass 862e7d35d2SSimon Glass /* From here is the testfdt uclass code */ 8754c5d08aSHeiko Schocher int testfdt_ping(struct udevice *dev, int pingval, int *pingret) 882e7d35d2SSimon Glass { 892e7d35d2SSimon Glass const struct test_ops *ops = device_get_ops(dev); 902e7d35d2SSimon Glass 912e7d35d2SSimon Glass if (!ops->ping) 922e7d35d2SSimon Glass return -ENOSYS; 932e7d35d2SSimon Glass 942e7d35d2SSimon Glass return ops->ping(dev, pingval, pingret); 952e7d35d2SSimon Glass } 962e7d35d2SSimon Glass 972e7d35d2SSimon Glass UCLASS_DRIVER(testfdt) = { 982e7d35d2SSimon Glass .name = "testfdt", 992e7d35d2SSimon Glass .id = UCLASS_TEST_FDT, 1009cc36a2bSSimon Glass .flags = DM_UC_FLAG_SEQ_ALIAS, 1012e7d35d2SSimon Glass }; 1022e7d35d2SSimon Glass 10398561572SSimon Glass struct dm_testprobe_pdata { 10498561572SSimon Glass int probe_err; 10598561572SSimon Glass }; 10698561572SSimon Glass 10798561572SSimon Glass static int testprobe_drv_probe(struct udevice *dev) 10898561572SSimon Glass { 10998561572SSimon Glass struct dm_testprobe_pdata *pdata = dev_get_platdata(dev); 11098561572SSimon Glass 11198561572SSimon Glass return pdata->probe_err; 11298561572SSimon Glass } 11398561572SSimon Glass 11498561572SSimon Glass static const struct udevice_id testprobe_ids[] = { 11598561572SSimon Glass { .compatible = "denx,u-boot-probe-test" }, 11698561572SSimon Glass { } 11798561572SSimon Glass }; 11898561572SSimon Glass 11998561572SSimon Glass U_BOOT_DRIVER(testprobe_drv) = { 12098561572SSimon Glass .name = "testprobe_drv", 12198561572SSimon Glass .of_match = testprobe_ids, 12298561572SSimon Glass .id = UCLASS_TEST_PROBE, 12398561572SSimon Glass .probe = testprobe_drv_probe, 12498561572SSimon Glass .platdata_auto_alloc_size = sizeof(struct dm_testprobe_pdata), 12598561572SSimon Glass }; 12698561572SSimon Glass 12798561572SSimon Glass UCLASS_DRIVER(testprobe) = { 12898561572SSimon Glass .name = "testprobe", 12998561572SSimon Glass .id = UCLASS_TEST_PROBE, 13098561572SSimon Glass .flags = DM_UC_FLAG_SEQ_ALIAS, 13198561572SSimon Glass }; 13298561572SSimon Glass 133e721b882SJoe Hershberger int dm_check_devices(struct unit_test_state *uts, int num_devices) 1342e7d35d2SSimon Glass { 13554c5d08aSHeiko Schocher struct udevice *dev; 1362e7d35d2SSimon Glass int ret; 1372e7d35d2SSimon Glass int i; 1382e7d35d2SSimon Glass 1392e7d35d2SSimon Glass /* 1402e7d35d2SSimon Glass * Now check that the ping adds are what we expect. This is using the 1412e7d35d2SSimon Glass * ping-add property in each node. 1422e7d35d2SSimon Glass */ 1431ca7e206SSimon Glass for (i = 0; i < num_devices; i++) { 1442e7d35d2SSimon Glass uint32_t base; 1452e7d35d2SSimon Glass 1462e7d35d2SSimon Glass ret = uclass_get_device(UCLASS_TEST_FDT, i, &dev); 1472e7d35d2SSimon Glass ut_assert(!ret); 1482e7d35d2SSimon Glass 1492e7d35d2SSimon Glass /* 150eb9ef5feSSimon Glass * Get the 'ping-expect' property, which tells us what the 151eb9ef5feSSimon Glass * ping add should be. We don't use the platdata because we 152eb9ef5feSSimon Glass * want to test the code that sets that up 153eb9ef5feSSimon Glass * (testfdt_drv_probe()). 1542e7d35d2SSimon Glass */ 155e160f7d4SSimon Glass base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), 156eb9ef5feSSimon Glass "ping-expect"); 1572e7d35d2SSimon Glass debug("dev=%d, base=%d: %s\n", i, base, 158e160f7d4SSimon Glass fdt_get_name(gd->fdt_blob, dev_of_offset(dev), NULL)); 1592e7d35d2SSimon Glass 160e721b882SJoe Hershberger ut_assert(!dm_check_operations(uts, dev, base, 1612e7d35d2SSimon Glass dev_get_priv(dev))); 1622e7d35d2SSimon Glass } 1632e7d35d2SSimon Glass 1642e7d35d2SSimon Glass return 0; 1652e7d35d2SSimon Glass } 1661ca7e206SSimon Glass 1671ca7e206SSimon Glass /* Test that FDT-based binding works correctly */ 168e721b882SJoe Hershberger static int dm_test_fdt(struct unit_test_state *uts) 1691ca7e206SSimon Glass { 1709cc36a2bSSimon Glass const int num_devices = 6; 1711ca7e206SSimon Glass struct udevice *dev; 1721ca7e206SSimon Glass struct uclass *uc; 1731ca7e206SSimon Glass int ret; 1741ca7e206SSimon Glass int i; 1751ca7e206SSimon Glass 1761ca7e206SSimon Glass ret = dm_scan_fdt(gd->fdt_blob, false); 1771ca7e206SSimon Glass ut_assert(!ret); 1781ca7e206SSimon Glass 1791ca7e206SSimon Glass ret = uclass_get(UCLASS_TEST_FDT, &uc); 1801ca7e206SSimon Glass ut_assert(!ret); 1811ca7e206SSimon Glass 1821ca7e206SSimon Glass /* These are num_devices compatible root-level device tree nodes */ 1831ca7e206SSimon Glass ut_asserteq(num_devices, list_count_items(&uc->dev_head)); 1841ca7e206SSimon Glass 185f8a85449SSimon Glass /* Each should have platform data but no private data */ 1861ca7e206SSimon Glass for (i = 0; i < num_devices; i++) { 1871ca7e206SSimon Glass ret = uclass_find_device(UCLASS_TEST_FDT, i, &dev); 1881ca7e206SSimon Glass ut_assert(!ret); 1891ca7e206SSimon Glass ut_assert(!dev_get_priv(dev)); 190f8a85449SSimon Glass ut_assert(dev->platdata); 1911ca7e206SSimon Glass } 1921ca7e206SSimon Glass 193e721b882SJoe Hershberger ut_assertok(dm_check_devices(uts, num_devices)); 1941ca7e206SSimon Glass 1951ca7e206SSimon Glass return 0; 1961ca7e206SSimon Glass } 1972e7d35d2SSimon Glass DM_TEST(dm_test_fdt, 0); 19800606d7eSSimon Glass 199e721b882SJoe Hershberger static int dm_test_fdt_pre_reloc(struct unit_test_state *uts) 20000606d7eSSimon Glass { 20100606d7eSSimon Glass struct uclass *uc; 20200606d7eSSimon Glass int ret; 20300606d7eSSimon Glass 20400606d7eSSimon Glass ret = dm_scan_fdt(gd->fdt_blob, true); 20500606d7eSSimon Glass ut_assert(!ret); 20600606d7eSSimon Glass 20700606d7eSSimon Glass ret = uclass_get(UCLASS_TEST_FDT, &uc); 20800606d7eSSimon Glass ut_assert(!ret); 20900606d7eSSimon Glass 21000606d7eSSimon Glass /* These is only one pre-reloc device */ 21100606d7eSSimon Glass ut_asserteq(1, list_count_items(&uc->dev_head)); 21200606d7eSSimon Glass 21300606d7eSSimon Glass return 0; 21400606d7eSSimon Glass } 21500606d7eSSimon Glass DM_TEST(dm_test_fdt_pre_reloc, 0); 2165a66a8ffSSimon Glass 2175a66a8ffSSimon Glass /* Test that sequence numbers are allocated properly */ 218e721b882SJoe Hershberger static int dm_test_fdt_uclass_seq(struct unit_test_state *uts) 2195a66a8ffSSimon Glass { 2205a66a8ffSSimon Glass struct udevice *dev; 2215a66a8ffSSimon Glass 2225a66a8ffSSimon Glass /* A few basic santiy tests */ 2235a66a8ffSSimon Glass ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 3, true, &dev)); 2245a66a8ffSSimon Glass ut_asserteq_str("b-test", dev->name); 2255a66a8ffSSimon Glass 2269cc36a2bSSimon Glass ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 8, true, &dev)); 2275a66a8ffSSimon Glass ut_asserteq_str("a-test", dev->name); 2285a66a8ffSSimon Glass 2295a66a8ffSSimon Glass ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 5, 2305a66a8ffSSimon Glass true, &dev)); 2315a66a8ffSSimon Glass ut_asserteq_ptr(NULL, dev); 2325a66a8ffSSimon Glass 2335a66a8ffSSimon Glass /* Test aliases */ 2345a66a8ffSSimon Glass ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 6, &dev)); 2355a66a8ffSSimon Glass ut_asserteq_str("e-test", dev->name); 2365a66a8ffSSimon Glass 2375a66a8ffSSimon Glass ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 7, 2385a66a8ffSSimon Glass true, &dev)); 2395a66a8ffSSimon Glass 2401ca7e206SSimon Glass /* 2411ca7e206SSimon Glass * Note that c-test nodes are not probed since it is not a top-level 2421ca7e206SSimon Glass * node 2431ca7e206SSimon Glass */ 2445a66a8ffSSimon Glass ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 3, &dev)); 2455a66a8ffSSimon Glass ut_asserteq_str("b-test", dev->name); 2465a66a8ffSSimon Glass 2475a66a8ffSSimon Glass /* 2485a66a8ffSSimon Glass * d-test wants sequence number 3 also, but it can't have it because 2495a66a8ffSSimon Glass * b-test gets it first. 2505a66a8ffSSimon Glass */ 2515a66a8ffSSimon Glass ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 2, &dev)); 2525a66a8ffSSimon Glass ut_asserteq_str("d-test", dev->name); 2535a66a8ffSSimon Glass 2545a66a8ffSSimon Glass /* d-test actually gets 0 */ 2555a66a8ffSSimon Glass ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 0, &dev)); 2565a66a8ffSSimon Glass ut_asserteq_str("d-test", dev->name); 2575a66a8ffSSimon Glass 2585a66a8ffSSimon Glass /* initially no one wants seq 1 */ 2595a66a8ffSSimon Glass ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, 2605a66a8ffSSimon Glass &dev)); 2615a66a8ffSSimon Glass ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); 2629cc36a2bSSimon Glass ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 4, &dev)); 2635a66a8ffSSimon Glass 2645a66a8ffSSimon Glass /* But now that it is probed, we can find it */ 2655a66a8ffSSimon Glass ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, &dev)); 2669cc36a2bSSimon Glass ut_asserteq_str("f-test", dev->name); 2675a66a8ffSSimon Glass 2685a66a8ffSSimon Glass return 0; 2695a66a8ffSSimon Glass } 2705a66a8ffSSimon Glass DM_TEST(dm_test_fdt_uclass_seq, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 271f4cdead2SSimon Glass 272f4cdead2SSimon Glass /* Test that we can find a device by device tree offset */ 273e721b882SJoe Hershberger static int dm_test_fdt_offset(struct unit_test_state *uts) 274f4cdead2SSimon Glass { 275f4cdead2SSimon Glass const void *blob = gd->fdt_blob; 276f4cdead2SSimon Glass struct udevice *dev; 277f4cdead2SSimon Glass int node; 278f4cdead2SSimon Glass 279f4cdead2SSimon Glass node = fdt_path_offset(blob, "/e-test"); 280f4cdead2SSimon Glass ut_assert(node > 0); 281f4cdead2SSimon Glass ut_assertok(uclass_get_device_by_of_offset(UCLASS_TEST_FDT, node, 282f4cdead2SSimon Glass &dev)); 283f4cdead2SSimon Glass ut_asserteq_str("e-test", dev->name); 284f4cdead2SSimon Glass 285f4cdead2SSimon Glass /* This node should not be bound */ 286f4cdead2SSimon Glass node = fdt_path_offset(blob, "/junk"); 287f4cdead2SSimon Glass ut_assert(node > 0); 288f4cdead2SSimon Glass ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT, 289f4cdead2SSimon Glass node, &dev)); 290f4cdead2SSimon Glass 291f4cdead2SSimon Glass /* This is not a top level node so should not be probed */ 2921ca7e206SSimon Glass node = fdt_path_offset(blob, "/some-bus/c-test@5"); 293f4cdead2SSimon Glass ut_assert(node > 0); 294f4cdead2SSimon Glass ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT, 295f4cdead2SSimon Glass node, &dev)); 296f4cdead2SSimon Glass 297f4cdead2SSimon Glass return 0; 298f4cdead2SSimon Glass } 29986b54eceSSimon Glass DM_TEST(dm_test_fdt_offset, 30086b54eceSSimon Glass DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE); 30198561572SSimon Glass 30298561572SSimon Glass /** 30398561572SSimon Glass * Test various error conditions with uclass_first_device() and 30498561572SSimon Glass * uclass_next_device() 30598561572SSimon Glass */ 30698561572SSimon Glass static int dm_test_first_next_device(struct unit_test_state *uts) 30798561572SSimon Glass { 30898561572SSimon Glass struct dm_testprobe_pdata *pdata; 30998561572SSimon Glass struct udevice *dev, *parent = NULL; 31098561572SSimon Glass int count; 31198561572SSimon Glass int ret; 31298561572SSimon Glass 31398561572SSimon Glass /* There should be 4 devices */ 31498561572SSimon Glass for (ret = uclass_first_device(UCLASS_TEST_PROBE, &dev), count = 0; 31598561572SSimon Glass dev; 31698561572SSimon Glass ret = uclass_next_device(&dev)) { 31798561572SSimon Glass count++; 31898561572SSimon Glass parent = dev_get_parent(dev); 31998561572SSimon Glass } 32098561572SSimon Glass ut_assertok(ret); 32198561572SSimon Glass ut_asserteq(4, count); 32298561572SSimon Glass 32398561572SSimon Glass /* Remove them and try again, with an error on the second one */ 32498561572SSimon Glass ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 1, &dev)); 32598561572SSimon Glass pdata = dev_get_platdata(dev); 32698561572SSimon Glass pdata->probe_err = -ENOMEM; 32798561572SSimon Glass device_remove(parent, DM_REMOVE_NORMAL); 32898561572SSimon Glass ut_assertok(uclass_first_device(UCLASS_TEST_PROBE, &dev)); 32998561572SSimon Glass ut_asserteq(-ENOMEM, uclass_next_device(&dev)); 33098561572SSimon Glass ut_asserteq_ptr(dev, NULL); 33198561572SSimon Glass 33298561572SSimon Glass /* Now an error on the first one */ 33398561572SSimon Glass ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 0, &dev)); 33498561572SSimon Glass pdata = dev_get_platdata(dev); 33598561572SSimon Glass pdata->probe_err = -ENOENT; 33698561572SSimon Glass device_remove(parent, DM_REMOVE_NORMAL); 33798561572SSimon Glass ut_asserteq(-ENOENT, uclass_first_device(UCLASS_TEST_PROBE, &dev)); 33898561572SSimon Glass 33998561572SSimon Glass return 0; 34098561572SSimon Glass } 34198561572SSimon Glass DM_TEST(dm_test_first_next_device, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 34295ce385aSSimon Glass 343*2c3c84fcSSimon Glass /* Test iteration through devices in a uclass */ 344*2c3c84fcSSimon Glass static int dm_test_uclass_foreach(struct unit_test_state *uts) 345*2c3c84fcSSimon Glass { 346*2c3c84fcSSimon Glass struct udevice *dev; 347*2c3c84fcSSimon Glass struct uclass *uc; 348*2c3c84fcSSimon Glass int count; 349*2c3c84fcSSimon Glass 350*2c3c84fcSSimon Glass count = 0; 351*2c3c84fcSSimon Glass uclass_id_foreach_dev(UCLASS_TEST_FDT, dev, uc) 352*2c3c84fcSSimon Glass count++; 353*2c3c84fcSSimon Glass ut_asserteq(8, count); 354*2c3c84fcSSimon Glass 355*2c3c84fcSSimon Glass count = 0; 356*2c3c84fcSSimon Glass uclass_foreach_dev(dev, uc) 357*2c3c84fcSSimon Glass count++; 358*2c3c84fcSSimon Glass ut_asserteq(8, count); 359*2c3c84fcSSimon Glass 360*2c3c84fcSSimon Glass return 0; 361*2c3c84fcSSimon Glass } 362*2c3c84fcSSimon Glass DM_TEST(dm_test_uclass_foreach, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 363*2c3c84fcSSimon Glass 36495ce385aSSimon Glass /** 36595ce385aSSimon Glass * check_devices() - Check return values and pointers 36695ce385aSSimon Glass * 36795ce385aSSimon Glass * This runs through a full sequence of uclass_first_device_check()... 36895ce385aSSimon Glass * uclass_next_device_check() checking that the return values and devices 36995ce385aSSimon Glass * are correct. 37095ce385aSSimon Glass * 37195ce385aSSimon Glass * @uts: Test state 37295ce385aSSimon Glass * @devlist: List of expected devices 37395ce385aSSimon Glass * @mask: Indicates which devices should return an error. Device n should 37495ce385aSSimon Glass * return error (-NOENT - n) if bit n is set, or no error (i.e. 0) if 37595ce385aSSimon Glass * bit n is clear. 37695ce385aSSimon Glass */ 37795ce385aSSimon Glass static int check_devices(struct unit_test_state *uts, 37895ce385aSSimon Glass struct udevice *devlist[], int mask) 37995ce385aSSimon Glass { 38095ce385aSSimon Glass int expected_ret; 38195ce385aSSimon Glass struct udevice *dev; 38295ce385aSSimon Glass int i; 38395ce385aSSimon Glass 38495ce385aSSimon Glass expected_ret = (mask & 1) ? -ENOENT : 0; 38595ce385aSSimon Glass mask >>= 1; 38695ce385aSSimon Glass ut_asserteq(expected_ret, 38795ce385aSSimon Glass uclass_first_device_check(UCLASS_TEST_PROBE, &dev)); 38895ce385aSSimon Glass for (i = 0; i < 4; i++) { 38995ce385aSSimon Glass ut_asserteq_ptr(devlist[i], dev); 39095ce385aSSimon Glass expected_ret = (mask & 1) ? -ENOENT - (i + 1) : 0; 39195ce385aSSimon Glass mask >>= 1; 39295ce385aSSimon Glass ut_asserteq(expected_ret, uclass_next_device_check(&dev)); 39395ce385aSSimon Glass } 39495ce385aSSimon Glass ut_asserteq_ptr(NULL, dev); 39595ce385aSSimon Glass 39695ce385aSSimon Glass return 0; 39795ce385aSSimon Glass } 39895ce385aSSimon Glass 39995ce385aSSimon Glass /* Test uclass_first_device_check() and uclass_next_device_check() */ 40095ce385aSSimon Glass static int dm_test_first_next_ok_device(struct unit_test_state *uts) 40195ce385aSSimon Glass { 40295ce385aSSimon Glass struct dm_testprobe_pdata *pdata; 40395ce385aSSimon Glass struct udevice *dev, *parent = NULL, *devlist[4]; 40495ce385aSSimon Glass int count; 40595ce385aSSimon Glass int ret; 40695ce385aSSimon Glass 40795ce385aSSimon Glass /* There should be 4 devices */ 40895ce385aSSimon Glass count = 0; 40995ce385aSSimon Glass for (ret = uclass_first_device_check(UCLASS_TEST_PROBE, &dev); 41095ce385aSSimon Glass dev; 41195ce385aSSimon Glass ret = uclass_next_device_check(&dev)) { 41295ce385aSSimon Glass ut_assertok(ret); 41395ce385aSSimon Glass devlist[count++] = dev; 41495ce385aSSimon Glass parent = dev_get_parent(dev); 41595ce385aSSimon Glass } 41695ce385aSSimon Glass ut_asserteq(4, count); 41795ce385aSSimon Glass ut_assertok(uclass_first_device_check(UCLASS_TEST_PROBE, &dev)); 41895ce385aSSimon Glass ut_assertok(check_devices(uts, devlist, 0)); 41995ce385aSSimon Glass 42095ce385aSSimon Glass /* Remove them and try again, with an error on the second one */ 42195ce385aSSimon Glass pdata = dev_get_platdata(devlist[1]); 42295ce385aSSimon Glass pdata->probe_err = -ENOENT - 1; 42395ce385aSSimon Glass device_remove(parent, DM_REMOVE_NORMAL); 42495ce385aSSimon Glass ut_assertok(check_devices(uts, devlist, 1 << 1)); 42595ce385aSSimon Glass 42695ce385aSSimon Glass /* Now an error on the first one */ 42795ce385aSSimon Glass pdata = dev_get_platdata(devlist[0]); 42895ce385aSSimon Glass pdata->probe_err = -ENOENT - 0; 42995ce385aSSimon Glass device_remove(parent, DM_REMOVE_NORMAL); 43095ce385aSSimon Glass ut_assertok(check_devices(uts, devlist, 3 << 0)); 43195ce385aSSimon Glass 43295ce385aSSimon Glass /* Now errors on all */ 43395ce385aSSimon Glass pdata = dev_get_platdata(devlist[2]); 43495ce385aSSimon Glass pdata->probe_err = -ENOENT - 2; 43595ce385aSSimon Glass pdata = dev_get_platdata(devlist[3]); 43695ce385aSSimon Glass pdata->probe_err = -ENOENT - 3; 43795ce385aSSimon Glass device_remove(parent, DM_REMOVE_NORMAL); 43895ce385aSSimon Glass ut_assertok(check_devices(uts, devlist, 0xf << 0)); 43995ce385aSSimon Glass 44095ce385aSSimon Glass return 0; 44195ce385aSSimon Glass } 44295ce385aSSimon Glass DM_TEST(dm_test_first_next_ok_device, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 443