12e7d35d2SSimon Glass /* 22e7d35d2SSimon Glass * Tests for the core driver model code 32e7d35d2SSimon Glass * 42e7d35d2SSimon Glass * Copyright (c) 2013 Google, Inc 52e7d35d2SSimon Glass * 62e7d35d2SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 72e7d35d2SSimon Glass */ 82e7d35d2SSimon Glass 92e7d35d2SSimon Glass #include <common.h> 102e7d35d2SSimon Glass #include <errno.h> 112e7d35d2SSimon Glass #include <dm.h> 122e7d35d2SSimon Glass #include <fdtdec.h> 132e7d35d2SSimon Glass #include <malloc.h> 142e7d35d2SSimon Glass #include <dm/device-internal.h> 152e7d35d2SSimon Glass #include <dm/root.h> 162e7d35d2SSimon Glass #include <dm/util.h> 172e7d35d2SSimon Glass #include <dm/test.h> 182e7d35d2SSimon Glass #include <dm/uclass-internal.h> 19e721b882SJoe Hershberger #include <test/ut.h> 202e7d35d2SSimon Glass 212e7d35d2SSimon Glass DECLARE_GLOBAL_DATA_PTR; 222e7d35d2SSimon Glass 232e7d35d2SSimon Glass enum { 242e7d35d2SSimon Glass TEST_INTVAL1 = 0, 252e7d35d2SSimon Glass TEST_INTVAL2 = 3, 262e7d35d2SSimon Glass TEST_INTVAL3 = 6, 272e7d35d2SSimon Glass TEST_INTVAL_MANUAL = 101112, 2800606d7eSSimon Glass TEST_INTVAL_PRE_RELOC = 7, 292e7d35d2SSimon Glass }; 302e7d35d2SSimon Glass 312e7d35d2SSimon Glass static const struct dm_test_pdata test_pdata[] = { 322e7d35d2SSimon Glass { .ping_add = TEST_INTVAL1, }, 332e7d35d2SSimon Glass { .ping_add = TEST_INTVAL2, }, 342e7d35d2SSimon Glass { .ping_add = TEST_INTVAL3, }, 352e7d35d2SSimon Glass }; 362e7d35d2SSimon Glass 372e7d35d2SSimon Glass static const struct dm_test_pdata test_pdata_manual = { 382e7d35d2SSimon Glass .ping_add = TEST_INTVAL_MANUAL, 392e7d35d2SSimon Glass }; 402e7d35d2SSimon Glass 4100606d7eSSimon Glass static const struct dm_test_pdata test_pdata_pre_reloc = { 4200606d7eSSimon Glass .ping_add = TEST_INTVAL_PRE_RELOC, 4300606d7eSSimon Glass }; 4400606d7eSSimon Glass 452e7d35d2SSimon Glass U_BOOT_DEVICE(dm_test_info1) = { 462e7d35d2SSimon Glass .name = "test_drv", 472e7d35d2SSimon Glass .platdata = &test_pdata[0], 482e7d35d2SSimon Glass }; 492e7d35d2SSimon Glass 502e7d35d2SSimon Glass U_BOOT_DEVICE(dm_test_info2) = { 512e7d35d2SSimon Glass .name = "test_drv", 522e7d35d2SSimon Glass .platdata = &test_pdata[1], 532e7d35d2SSimon Glass }; 542e7d35d2SSimon Glass 552e7d35d2SSimon Glass U_BOOT_DEVICE(dm_test_info3) = { 562e7d35d2SSimon Glass .name = "test_drv", 572e7d35d2SSimon Glass .platdata = &test_pdata[2], 582e7d35d2SSimon Glass }; 592e7d35d2SSimon Glass 602e7d35d2SSimon Glass static struct driver_info driver_info_manual = { 612e7d35d2SSimon Glass .name = "test_manual_drv", 622e7d35d2SSimon Glass .platdata = &test_pdata_manual, 632e7d35d2SSimon Glass }; 642e7d35d2SSimon Glass 6500606d7eSSimon Glass static struct driver_info driver_info_pre_reloc = { 6600606d7eSSimon Glass .name = "test_pre_reloc_drv", 67f09144a2STom Rini .platdata = &test_pdata_pre_reloc, 6800606d7eSSimon Glass }; 6900606d7eSSimon Glass 7024f927c5SStefan Roese static struct driver_info driver_info_act_dma = { 7124f927c5SStefan Roese .name = "test_act_dma_drv", 7224f927c5SStefan Roese }; 7324f927c5SStefan Roese 74e721b882SJoe Hershberger void dm_leak_check_start(struct unit_test_state *uts) 75756ac0bbSSimon Glass { 76e721b882SJoe Hershberger uts->start = mallinfo(); 77e721b882SJoe Hershberger if (!uts->start.uordblks) 78756ac0bbSSimon Glass puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n"); 79756ac0bbSSimon Glass } 80756ac0bbSSimon Glass 81e721b882SJoe Hershberger int dm_leak_check_end(struct unit_test_state *uts) 82756ac0bbSSimon Glass { 83756ac0bbSSimon Glass struct mallinfo end; 84cbfc2ff9SSimon Glass int id, diff; 85756ac0bbSSimon Glass 86756ac0bbSSimon Glass /* Don't delete the root class, since we started with that */ 87756ac0bbSSimon Glass for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) { 88756ac0bbSSimon Glass struct uclass *uc; 89756ac0bbSSimon Glass 90756ac0bbSSimon Glass uc = uclass_find(id); 91756ac0bbSSimon Glass if (!uc) 92756ac0bbSSimon Glass continue; 93756ac0bbSSimon Glass ut_assertok(uclass_destroy(uc)); 94756ac0bbSSimon Glass } 95756ac0bbSSimon Glass 96756ac0bbSSimon Glass end = mallinfo(); 97cbfc2ff9SSimon Glass diff = end.uordblks - uts->start.uordblks; 98cbfc2ff9SSimon Glass if (diff > 0) 99cbfc2ff9SSimon Glass printf("Leak: lost %#xd bytes\n", diff); 100cbfc2ff9SSimon Glass else if (diff < 0) 101cbfc2ff9SSimon Glass printf("Leak: gained %#xd bytes\n", -diff); 102e721b882SJoe Hershberger ut_asserteq(uts->start.uordblks, end.uordblks); 103756ac0bbSSimon Glass 104756ac0bbSSimon Glass return 0; 105756ac0bbSSimon Glass } 106756ac0bbSSimon Glass 1072e7d35d2SSimon Glass /* Test that binding with platdata occurs correctly */ 108e721b882SJoe Hershberger static int dm_test_autobind(struct unit_test_state *uts) 1092e7d35d2SSimon Glass { 110e721b882SJoe Hershberger struct dm_test_state *dms = uts->priv; 11154c5d08aSHeiko Schocher struct udevice *dev; 1122e7d35d2SSimon Glass 1132e7d35d2SSimon Glass /* 1142e7d35d2SSimon Glass * We should have a single class (UCLASS_ROOT) and a single root 1152e7d35d2SSimon Glass * device with no children. 1162e7d35d2SSimon Glass */ 1172e7d35d2SSimon Glass ut_assert(dms->root); 1182e7d35d2SSimon Glass ut_asserteq(1, list_count_items(&gd->uclass_root)); 1192e7d35d2SSimon Glass ut_asserteq(0, list_count_items(&gd->dm_root->child_head)); 1202e7d35d2SSimon Glass ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]); 1212e7d35d2SSimon Glass 12200606d7eSSimon Glass ut_assertok(dm_scan_platdata(false)); 1232e7d35d2SSimon Glass 1242e7d35d2SSimon Glass /* We should have our test class now at least, plus more children */ 1252e7d35d2SSimon Glass ut_assert(1 < list_count_items(&gd->uclass_root)); 1262e7d35d2SSimon Glass ut_assert(0 < list_count_items(&gd->dm_root->child_head)); 1272e7d35d2SSimon Glass 1282e7d35d2SSimon Glass /* Our 3 dm_test_infox children should be bound to the test uclass */ 1292e7d35d2SSimon Glass ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]); 1302e7d35d2SSimon Glass 1312e7d35d2SSimon Glass /* No devices should be probed */ 1322e7d35d2SSimon Glass list_for_each_entry(dev, &gd->dm_root->child_head, sibling_node) 1332e7d35d2SSimon Glass ut_assert(!(dev->flags & DM_FLAG_ACTIVATED)); 1342e7d35d2SSimon Glass 1352e7d35d2SSimon Glass /* Our test driver should have been bound 3 times */ 1362e7d35d2SSimon Glass ut_assert(dm_testdrv_op_count[DM_TEST_OP_BIND] == 3); 1372e7d35d2SSimon Glass 1382e7d35d2SSimon Glass return 0; 1392e7d35d2SSimon Glass } 1402e7d35d2SSimon Glass DM_TEST(dm_test_autobind, 0); 1412e7d35d2SSimon Glass 142754e71e8SPrzemyslaw Marczak /* Test that binding with uclass platdata allocation occurs correctly */ 143e721b882SJoe Hershberger static int dm_test_autobind_uclass_pdata_alloc(struct unit_test_state *uts) 144754e71e8SPrzemyslaw Marczak { 145754e71e8SPrzemyslaw Marczak struct dm_test_perdev_uc_pdata *uc_pdata; 146754e71e8SPrzemyslaw Marczak struct udevice *dev; 147754e71e8SPrzemyslaw Marczak struct uclass *uc; 148754e71e8SPrzemyslaw Marczak 149754e71e8SPrzemyslaw Marczak ut_assertok(uclass_get(UCLASS_TEST, &uc)); 150754e71e8SPrzemyslaw Marczak ut_assert(uc); 151754e71e8SPrzemyslaw Marczak 152754e71e8SPrzemyslaw Marczak /** 153754e71e8SPrzemyslaw Marczak * Test if test uclass driver requires allocation for the uclass 154754e71e8SPrzemyslaw Marczak * platform data and then check the dev->uclass_platdata pointer. 155754e71e8SPrzemyslaw Marczak */ 156754e71e8SPrzemyslaw Marczak ut_assert(uc->uc_drv->per_device_platdata_auto_alloc_size); 157754e71e8SPrzemyslaw Marczak 158754e71e8SPrzemyslaw Marczak for (uclass_find_first_device(UCLASS_TEST, &dev); 159754e71e8SPrzemyslaw Marczak dev; 160754e71e8SPrzemyslaw Marczak uclass_find_next_device(&dev)) { 161754e71e8SPrzemyslaw Marczak ut_assert(dev); 162754e71e8SPrzemyslaw Marczak 163754e71e8SPrzemyslaw Marczak uc_pdata = dev_get_uclass_platdata(dev); 164754e71e8SPrzemyslaw Marczak ut_assert(uc_pdata); 165754e71e8SPrzemyslaw Marczak } 166754e71e8SPrzemyslaw Marczak 167754e71e8SPrzemyslaw Marczak return 0; 168754e71e8SPrzemyslaw Marczak } 169754e71e8SPrzemyslaw Marczak DM_TEST(dm_test_autobind_uclass_pdata_alloc, DM_TESTF_SCAN_PDATA); 170754e71e8SPrzemyslaw Marczak 171754e71e8SPrzemyslaw Marczak /* Test that binding with uclass platdata setting occurs correctly */ 172e721b882SJoe Hershberger static int dm_test_autobind_uclass_pdata_valid(struct unit_test_state *uts) 173754e71e8SPrzemyslaw Marczak { 174754e71e8SPrzemyslaw Marczak struct dm_test_perdev_uc_pdata *uc_pdata; 175754e71e8SPrzemyslaw Marczak struct udevice *dev; 176754e71e8SPrzemyslaw Marczak 177754e71e8SPrzemyslaw Marczak /** 178754e71e8SPrzemyslaw Marczak * In the test_postbind() method of test uclass driver, the uclass 179754e71e8SPrzemyslaw Marczak * platform data should be set to three test int values - test it. 180754e71e8SPrzemyslaw Marczak */ 181754e71e8SPrzemyslaw Marczak for (uclass_find_first_device(UCLASS_TEST, &dev); 182754e71e8SPrzemyslaw Marczak dev; 183754e71e8SPrzemyslaw Marczak uclass_find_next_device(&dev)) { 184754e71e8SPrzemyslaw Marczak ut_assert(dev); 185754e71e8SPrzemyslaw Marczak 186754e71e8SPrzemyslaw Marczak uc_pdata = dev_get_uclass_platdata(dev); 187754e71e8SPrzemyslaw Marczak ut_assert(uc_pdata); 188754e71e8SPrzemyslaw Marczak ut_assert(uc_pdata->intval1 == TEST_UC_PDATA_INTVAL1); 189754e71e8SPrzemyslaw Marczak ut_assert(uc_pdata->intval2 == TEST_UC_PDATA_INTVAL2); 190754e71e8SPrzemyslaw Marczak ut_assert(uc_pdata->intval3 == TEST_UC_PDATA_INTVAL3); 191754e71e8SPrzemyslaw Marczak } 192754e71e8SPrzemyslaw Marczak 193754e71e8SPrzemyslaw Marczak return 0; 194754e71e8SPrzemyslaw Marczak } 195754e71e8SPrzemyslaw Marczak DM_TEST(dm_test_autobind_uclass_pdata_valid, DM_TESTF_SCAN_PDATA); 196754e71e8SPrzemyslaw Marczak 1972e7d35d2SSimon Glass /* Test that autoprobe finds all the expected devices */ 198e721b882SJoe Hershberger static int dm_test_autoprobe(struct unit_test_state *uts) 1992e7d35d2SSimon Glass { 200e721b882SJoe Hershberger struct dm_test_state *dms = uts->priv; 2012e7d35d2SSimon Glass int expected_base_add; 20254c5d08aSHeiko Schocher struct udevice *dev; 2032e7d35d2SSimon Glass struct uclass *uc; 2042e7d35d2SSimon Glass int i; 2052e7d35d2SSimon Glass 2062e7d35d2SSimon Glass ut_assertok(uclass_get(UCLASS_TEST, &uc)); 2072e7d35d2SSimon Glass ut_assert(uc); 2082e7d35d2SSimon Glass 2092e7d35d2SSimon Glass ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]); 21002c07b37SSimon Glass ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]); 2112e7d35d2SSimon Glass ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]); 2122e7d35d2SSimon Glass 2132e7d35d2SSimon Glass /* The root device should not be activated until needed */ 2147497812dSSimon Glass ut_assert(dms->root->flags & DM_FLAG_ACTIVATED); 2152e7d35d2SSimon Glass 2162e7d35d2SSimon Glass /* 2172e7d35d2SSimon Glass * We should be able to find the three test devices, and they should 2182e7d35d2SSimon Glass * all be activated as they are used (lazy activation, required by 2192e7d35d2SSimon Glass * U-Boot) 2202e7d35d2SSimon Glass */ 2212e7d35d2SSimon Glass for (i = 0; i < 3; i++) { 2222e7d35d2SSimon Glass ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev)); 2232e7d35d2SSimon Glass ut_assert(dev); 2242e7d35d2SSimon Glass ut_assertf(!(dev->flags & DM_FLAG_ACTIVATED), 2252e7d35d2SSimon Glass "Driver %d/%s already activated", i, dev->name); 2262e7d35d2SSimon Glass 2272e7d35d2SSimon Glass /* This should activate it */ 2282e7d35d2SSimon Glass ut_assertok(uclass_get_device(UCLASS_TEST, i, &dev)); 2292e7d35d2SSimon Glass ut_assert(dev); 2302e7d35d2SSimon Glass ut_assert(dev->flags & DM_FLAG_ACTIVATED); 2312e7d35d2SSimon Glass 2322e7d35d2SSimon Glass /* Activating a device should activate the root device */ 2332e7d35d2SSimon Glass if (!i) 2342e7d35d2SSimon Glass ut_assert(dms->root->flags & DM_FLAG_ACTIVATED); 2352e7d35d2SSimon Glass } 2362e7d35d2SSimon Glass 23702c07b37SSimon Glass /* 23802c07b37SSimon Glass * Our 3 dm_test_info children should be passed to pre_probe and 23902c07b37SSimon Glass * post_probe 24002c07b37SSimon Glass */ 2412e7d35d2SSimon Glass ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]); 24202c07b37SSimon Glass ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]); 2432e7d35d2SSimon Glass 2442e7d35d2SSimon Glass /* Also we can check the per-device data */ 2452e7d35d2SSimon Glass expected_base_add = 0; 2462e7d35d2SSimon Glass for (i = 0; i < 3; i++) { 2472e7d35d2SSimon Glass struct dm_test_uclass_perdev_priv *priv; 2482e7d35d2SSimon Glass struct dm_test_pdata *pdata; 2492e7d35d2SSimon Glass 2502e7d35d2SSimon Glass ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev)); 2512e7d35d2SSimon Glass ut_assert(dev); 2522e7d35d2SSimon Glass 253e564f054SSimon Glass priv = dev_get_uclass_priv(dev); 2542e7d35d2SSimon Glass ut_assert(priv); 2552e7d35d2SSimon Glass ut_asserteq(expected_base_add, priv->base_add); 2562e7d35d2SSimon Glass 2572e7d35d2SSimon Glass pdata = dev->platdata; 2582e7d35d2SSimon Glass expected_base_add += pdata->ping_add; 2592e7d35d2SSimon Glass } 2602e7d35d2SSimon Glass 2612e7d35d2SSimon Glass return 0; 2622e7d35d2SSimon Glass } 2632e7d35d2SSimon Glass DM_TEST(dm_test_autoprobe, DM_TESTF_SCAN_PDATA); 2642e7d35d2SSimon Glass 2652e7d35d2SSimon Glass /* Check that we see the correct platdata in each device */ 266e721b882SJoe Hershberger static int dm_test_platdata(struct unit_test_state *uts) 2672e7d35d2SSimon Glass { 2682e7d35d2SSimon Glass const struct dm_test_pdata *pdata; 26954c5d08aSHeiko Schocher struct udevice *dev; 2702e7d35d2SSimon Glass int i; 2712e7d35d2SSimon Glass 2722e7d35d2SSimon Glass for (i = 0; i < 3; i++) { 2732e7d35d2SSimon Glass ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev)); 2742e7d35d2SSimon Glass ut_assert(dev); 2752e7d35d2SSimon Glass pdata = dev->platdata; 2762e7d35d2SSimon Glass ut_assert(pdata->ping_add == test_pdata[i].ping_add); 2772e7d35d2SSimon Glass } 2782e7d35d2SSimon Glass 2792e7d35d2SSimon Glass return 0; 2802e7d35d2SSimon Glass } 2812e7d35d2SSimon Glass DM_TEST(dm_test_platdata, DM_TESTF_SCAN_PDATA); 2822e7d35d2SSimon Glass 2832e7d35d2SSimon Glass /* Test that we can bind, probe, remove, unbind a driver */ 284e721b882SJoe Hershberger static int dm_test_lifecycle(struct unit_test_state *uts) 2852e7d35d2SSimon Glass { 286e721b882SJoe Hershberger struct dm_test_state *dms = uts->priv; 2872e7d35d2SSimon Glass int op_count[DM_TEST_OP_COUNT]; 28854c5d08aSHeiko Schocher struct udevice *dev, *test_dev; 2892e7d35d2SSimon Glass int pingret; 2902e7d35d2SSimon Glass int ret; 2912e7d35d2SSimon Glass 2922e7d35d2SSimon Glass memcpy(op_count, dm_testdrv_op_count, sizeof(op_count)); 2932e7d35d2SSimon Glass 29400606d7eSSimon Glass ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual, 2952e7d35d2SSimon Glass &dev)); 2962e7d35d2SSimon Glass ut_assert(dev); 2972e7d35d2SSimon Glass ut_assert(dm_testdrv_op_count[DM_TEST_OP_BIND] 2982e7d35d2SSimon Glass == op_count[DM_TEST_OP_BIND] + 1); 2992e7d35d2SSimon Glass ut_assert(!dev->priv); 3002e7d35d2SSimon Glass 3012e7d35d2SSimon Glass /* Probe the device - it should fail allocating private data */ 3022e7d35d2SSimon Glass dms->force_fail_alloc = 1; 3032e7d35d2SSimon Glass ret = device_probe(dev); 3042e7d35d2SSimon Glass ut_assert(ret == -ENOMEM); 3052e7d35d2SSimon Glass ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE] 3062e7d35d2SSimon Glass == op_count[DM_TEST_OP_PROBE] + 1); 3072e7d35d2SSimon Glass ut_assert(!dev->priv); 3082e7d35d2SSimon Glass 3092e7d35d2SSimon Glass /* Try again without the alloc failure */ 3102e7d35d2SSimon Glass dms->force_fail_alloc = 0; 3112e7d35d2SSimon Glass ut_assertok(device_probe(dev)); 3122e7d35d2SSimon Glass ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE] 3132e7d35d2SSimon Glass == op_count[DM_TEST_OP_PROBE] + 2); 3142e7d35d2SSimon Glass ut_assert(dev->priv); 3152e7d35d2SSimon Glass 3162e7d35d2SSimon Glass /* This should be device 3 in the uclass */ 3172e7d35d2SSimon Glass ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev)); 3182e7d35d2SSimon Glass ut_assert(dev == test_dev); 3192e7d35d2SSimon Glass 3202e7d35d2SSimon Glass /* Try ping */ 3212e7d35d2SSimon Glass ut_assertok(test_ping(dev, 100, &pingret)); 3222e7d35d2SSimon Glass ut_assert(pingret == 102); 3232e7d35d2SSimon Glass 3242e7d35d2SSimon Glass /* Now remove device 3 */ 3252e7d35d2SSimon Glass ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]); 326706865afSStefan Roese ut_assertok(device_remove(dev, DM_REMOVE_NORMAL)); 3272e7d35d2SSimon Glass ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]); 3282e7d35d2SSimon Glass 3292e7d35d2SSimon Glass ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_UNBIND]); 3302e7d35d2SSimon Glass ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]); 3312e7d35d2SSimon Glass ut_assertok(device_unbind(dev)); 3322e7d35d2SSimon Glass ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]); 3332e7d35d2SSimon Glass ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]); 3342e7d35d2SSimon Glass 3352e7d35d2SSimon Glass return 0; 3362e7d35d2SSimon Glass } 3372e7d35d2SSimon Glass DM_TEST(dm_test_lifecycle, DM_TESTF_SCAN_PDATA | DM_TESTF_PROBE_TEST); 3382e7d35d2SSimon Glass 3392e7d35d2SSimon Glass /* Test that we can bind/unbind and the lists update correctly */ 340e721b882SJoe Hershberger static int dm_test_ordering(struct unit_test_state *uts) 3412e7d35d2SSimon Glass { 342e721b882SJoe Hershberger struct dm_test_state *dms = uts->priv; 34354c5d08aSHeiko Schocher struct udevice *dev, *dev_penultimate, *dev_last, *test_dev; 3442e7d35d2SSimon Glass int pingret; 3452e7d35d2SSimon Glass 34600606d7eSSimon Glass ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual, 3472e7d35d2SSimon Glass &dev)); 3482e7d35d2SSimon Glass ut_assert(dev); 3492e7d35d2SSimon Glass 3502e7d35d2SSimon Glass /* Bind two new devices (numbers 4 and 5) */ 35100606d7eSSimon Glass ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual, 3522e7d35d2SSimon Glass &dev_penultimate)); 3532e7d35d2SSimon Glass ut_assert(dev_penultimate); 35400606d7eSSimon Glass ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual, 3552e7d35d2SSimon Glass &dev_last)); 3562e7d35d2SSimon Glass ut_assert(dev_last); 3572e7d35d2SSimon Glass 3582e7d35d2SSimon Glass /* Now remove device 3 */ 359706865afSStefan Roese ut_assertok(device_remove(dev, DM_REMOVE_NORMAL)); 3602e7d35d2SSimon Glass ut_assertok(device_unbind(dev)); 3612e7d35d2SSimon Glass 3622e7d35d2SSimon Glass /* The device numbering should have shifted down one */ 3632e7d35d2SSimon Glass ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev)); 3642e7d35d2SSimon Glass ut_assert(dev_penultimate == test_dev); 3652e7d35d2SSimon Glass ut_assertok(uclass_find_device(UCLASS_TEST, 4, &test_dev)); 3662e7d35d2SSimon Glass ut_assert(dev_last == test_dev); 3672e7d35d2SSimon Glass 3682e7d35d2SSimon Glass /* Add back the original device 3, now in position 5 */ 36900606d7eSSimon Glass ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual, 37000606d7eSSimon Glass &dev)); 3712e7d35d2SSimon Glass ut_assert(dev); 3722e7d35d2SSimon Glass 3732e7d35d2SSimon Glass /* Try ping */ 3742e7d35d2SSimon Glass ut_assertok(test_ping(dev, 100, &pingret)); 3752e7d35d2SSimon Glass ut_assert(pingret == 102); 3762e7d35d2SSimon Glass 3772e7d35d2SSimon Glass /* Remove 3 and 4 */ 378706865afSStefan Roese ut_assertok(device_remove(dev_penultimate, DM_REMOVE_NORMAL)); 3792e7d35d2SSimon Glass ut_assertok(device_unbind(dev_penultimate)); 380706865afSStefan Roese ut_assertok(device_remove(dev_last, DM_REMOVE_NORMAL)); 3812e7d35d2SSimon Glass ut_assertok(device_unbind(dev_last)); 3822e7d35d2SSimon Glass 3832e7d35d2SSimon Glass /* Our device should now be in position 3 */ 3842e7d35d2SSimon Glass ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev)); 3852e7d35d2SSimon Glass ut_assert(dev == test_dev); 3862e7d35d2SSimon Glass 3872e7d35d2SSimon Glass /* Now remove device 3 */ 388706865afSStefan Roese ut_assertok(device_remove(dev, DM_REMOVE_NORMAL)); 3892e7d35d2SSimon Glass ut_assertok(device_unbind(dev)); 3902e7d35d2SSimon Glass 3912e7d35d2SSimon Glass return 0; 3922e7d35d2SSimon Glass } 3932e7d35d2SSimon Glass DM_TEST(dm_test_ordering, DM_TESTF_SCAN_PDATA); 3942e7d35d2SSimon Glass 3952e7d35d2SSimon Glass /* Check that we can perform operations on a device (do a ping) */ 396e721b882SJoe Hershberger int dm_check_operations(struct unit_test_state *uts, struct udevice *dev, 3972e7d35d2SSimon Glass uint32_t base, struct dm_test_priv *priv) 3982e7d35d2SSimon Glass { 3992e7d35d2SSimon Glass int expected; 4002e7d35d2SSimon Glass int pingret; 4012e7d35d2SSimon Glass 4022e7d35d2SSimon Glass /* Getting the child device should allocate platdata / priv */ 4032e7d35d2SSimon Glass ut_assertok(testfdt_ping(dev, 10, &pingret)); 4042e7d35d2SSimon Glass ut_assert(dev->priv); 4052e7d35d2SSimon Glass ut_assert(dev->platdata); 4062e7d35d2SSimon Glass 4072e7d35d2SSimon Glass expected = 10 + base; 4082e7d35d2SSimon Glass ut_asserteq(expected, pingret); 4092e7d35d2SSimon Glass 4102e7d35d2SSimon Glass /* Do another ping */ 4112e7d35d2SSimon Glass ut_assertok(testfdt_ping(dev, 20, &pingret)); 4122e7d35d2SSimon Glass expected = 20 + base; 4132e7d35d2SSimon Glass ut_asserteq(expected, pingret); 4142e7d35d2SSimon Glass 4152e7d35d2SSimon Glass /* Now check the ping_total */ 4162e7d35d2SSimon Glass priv = dev->priv; 4172e7d35d2SSimon Glass ut_asserteq(DM_TEST_START_TOTAL + 10 + 20 + base * 2, 4182e7d35d2SSimon Glass priv->ping_total); 4192e7d35d2SSimon Glass 4202e7d35d2SSimon Glass return 0; 4212e7d35d2SSimon Glass } 4222e7d35d2SSimon Glass 4232e7d35d2SSimon Glass /* Check that we can perform operations on devices */ 424e721b882SJoe Hershberger static int dm_test_operations(struct unit_test_state *uts) 4252e7d35d2SSimon Glass { 42654c5d08aSHeiko Schocher struct udevice *dev; 4272e7d35d2SSimon Glass int i; 4282e7d35d2SSimon Glass 4292e7d35d2SSimon Glass /* 4302e7d35d2SSimon Glass * Now check that the ping adds are what we expect. This is using the 4312e7d35d2SSimon Glass * ping-add property in each node. 4322e7d35d2SSimon Glass */ 4332e7d35d2SSimon Glass for (i = 0; i < ARRAY_SIZE(test_pdata); i++) { 4342e7d35d2SSimon Glass uint32_t base; 4352e7d35d2SSimon Glass 4362e7d35d2SSimon Glass ut_assertok(uclass_get_device(UCLASS_TEST, i, &dev)); 4372e7d35d2SSimon Glass 4382e7d35d2SSimon Glass /* 4392e7d35d2SSimon Glass * Get the 'reg' property, which tells us what the ping add 4402e7d35d2SSimon Glass * should be. We don't use the platdata because we want 4412e7d35d2SSimon Glass * to test the code that sets that up (testfdt_drv_probe()). 4422e7d35d2SSimon Glass */ 4432e7d35d2SSimon Glass base = test_pdata[i].ping_add; 4442e7d35d2SSimon Glass debug("dev=%d, base=%d\n", i, base); 4452e7d35d2SSimon Glass 446e721b882SJoe Hershberger ut_assert(!dm_check_operations(uts, dev, base, dev->priv)); 4472e7d35d2SSimon Glass } 4482e7d35d2SSimon Glass 4492e7d35d2SSimon Glass return 0; 4502e7d35d2SSimon Glass } 4512e7d35d2SSimon Glass DM_TEST(dm_test_operations, DM_TESTF_SCAN_PDATA); 4522e7d35d2SSimon Glass 4532e7d35d2SSimon Glass /* Remove all drivers and check that things work */ 454e721b882SJoe Hershberger static int dm_test_remove(struct unit_test_state *uts) 4552e7d35d2SSimon Glass { 45654c5d08aSHeiko Schocher struct udevice *dev; 4572e7d35d2SSimon Glass int i; 4582e7d35d2SSimon Glass 4592e7d35d2SSimon Glass for (i = 0; i < 3; i++) { 4602e7d35d2SSimon Glass ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev)); 4612e7d35d2SSimon Glass ut_assert(dev); 4622e7d35d2SSimon Glass ut_assertf(dev->flags & DM_FLAG_ACTIVATED, 4632e7d35d2SSimon Glass "Driver %d/%s not activated", i, dev->name); 464706865afSStefan Roese ut_assertok(device_remove(dev, DM_REMOVE_NORMAL)); 4652e7d35d2SSimon Glass ut_assertf(!(dev->flags & DM_FLAG_ACTIVATED), 4662e7d35d2SSimon Glass "Driver %d/%s should have deactivated", i, 4672e7d35d2SSimon Glass dev->name); 4682e7d35d2SSimon Glass ut_assert(!dev->priv); 4692e7d35d2SSimon Glass } 4702e7d35d2SSimon Glass 4712e7d35d2SSimon Glass return 0; 4722e7d35d2SSimon Glass } 4732e7d35d2SSimon Glass DM_TEST(dm_test_remove, DM_TESTF_SCAN_PDATA | DM_TESTF_PROBE_TEST); 4742e7d35d2SSimon Glass 4752e7d35d2SSimon Glass /* Remove and recreate everything, check for memory leaks */ 476e721b882SJoe Hershberger static int dm_test_leak(struct unit_test_state *uts) 4772e7d35d2SSimon Glass { 4782e7d35d2SSimon Glass int i; 4792e7d35d2SSimon Glass 4802e7d35d2SSimon Glass for (i = 0; i < 2; i++) { 48154c5d08aSHeiko Schocher struct udevice *dev; 4822e7d35d2SSimon Glass int ret; 4832e7d35d2SSimon Glass int id; 4842e7d35d2SSimon Glass 485e721b882SJoe Hershberger dm_leak_check_start(uts); 4862e7d35d2SSimon Glass 48700606d7eSSimon Glass ut_assertok(dm_scan_platdata(false)); 48800606d7eSSimon Glass ut_assertok(dm_scan_fdt(gd->fdt_blob, false)); 4892e7d35d2SSimon Glass 4902e7d35d2SSimon Glass /* Scanning the uclass is enough to probe all the devices */ 4912e7d35d2SSimon Glass for (id = UCLASS_ROOT; id < UCLASS_COUNT; id++) { 4922e7d35d2SSimon Glass for (ret = uclass_first_device(UCLASS_TEST, &dev); 4932e7d35d2SSimon Glass dev; 4942e7d35d2SSimon Glass ret = uclass_next_device(&dev)) 4952e7d35d2SSimon Glass ; 4962e7d35d2SSimon Glass ut_assertok(ret); 4972e7d35d2SSimon Glass } 4982e7d35d2SSimon Glass 499e721b882SJoe Hershberger ut_assertok(dm_leak_check_end(uts)); 5002e7d35d2SSimon Glass } 5012e7d35d2SSimon Glass 5022e7d35d2SSimon Glass return 0; 5032e7d35d2SSimon Glass } 5042e7d35d2SSimon Glass DM_TEST(dm_test_leak, 0); 5052e7d35d2SSimon Glass 5062e7d35d2SSimon Glass /* Test uclass init/destroy methods */ 507e721b882SJoe Hershberger static int dm_test_uclass(struct unit_test_state *uts) 5082e7d35d2SSimon Glass { 5092e7d35d2SSimon Glass struct uclass *uc; 5102e7d35d2SSimon Glass 5112e7d35d2SSimon Glass ut_assertok(uclass_get(UCLASS_TEST, &uc)); 5122e7d35d2SSimon Glass ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]); 5132e7d35d2SSimon Glass ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_DESTROY]); 5142e7d35d2SSimon Glass ut_assert(uc->priv); 5152e7d35d2SSimon Glass 5162e7d35d2SSimon Glass ut_assertok(uclass_destroy(uc)); 5172e7d35d2SSimon Glass ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]); 5182e7d35d2SSimon Glass ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_DESTROY]); 5192e7d35d2SSimon Glass 5202e7d35d2SSimon Glass return 0; 5212e7d35d2SSimon Glass } 5222e7d35d2SSimon Glass DM_TEST(dm_test_uclass, 0); 5232e7d35d2SSimon Glass 5242e7d35d2SSimon Glass /** 5252e7d35d2SSimon Glass * create_children() - Create children of a parent node 5262e7d35d2SSimon Glass * 5272e7d35d2SSimon Glass * @dms: Test system state 5282e7d35d2SSimon Glass * @parent: Parent device 5292e7d35d2SSimon Glass * @count: Number of children to create 5302e7d35d2SSimon Glass * @key: Key value to put in first child. Subsequence children 5312e7d35d2SSimon Glass * receive an incrementing value 5322e7d35d2SSimon Glass * @child: If not NULL, then the child device pointers are written into 5332e7d35d2SSimon Glass * this array. 5342e7d35d2SSimon Glass * @return 0 if OK, -ve on error 5352e7d35d2SSimon Glass */ 536e721b882SJoe Hershberger static int create_children(struct unit_test_state *uts, struct udevice *parent, 53754c5d08aSHeiko Schocher int count, int key, struct udevice *child[]) 5382e7d35d2SSimon Glass { 53954c5d08aSHeiko Schocher struct udevice *dev; 5402e7d35d2SSimon Glass int i; 5412e7d35d2SSimon Glass 5422e7d35d2SSimon Glass for (i = 0; i < count; i++) { 5432e7d35d2SSimon Glass struct dm_test_pdata *pdata; 5442e7d35d2SSimon Glass 54500606d7eSSimon Glass ut_assertok(device_bind_by_name(parent, false, 54600606d7eSSimon Glass &driver_info_manual, &dev)); 5472e7d35d2SSimon Glass pdata = calloc(1, sizeof(*pdata)); 5482e7d35d2SSimon Glass pdata->ping_add = key + i; 5492e7d35d2SSimon Glass dev->platdata = pdata; 5502e7d35d2SSimon Glass if (child) 5512e7d35d2SSimon Glass child[i] = dev; 5522e7d35d2SSimon Glass } 5532e7d35d2SSimon Glass 5542e7d35d2SSimon Glass return 0; 5552e7d35d2SSimon Glass } 5562e7d35d2SSimon Glass 5572e7d35d2SSimon Glass #define NODE_COUNT 10 5582e7d35d2SSimon Glass 559e721b882SJoe Hershberger static int dm_test_children(struct unit_test_state *uts) 5602e7d35d2SSimon Glass { 561e721b882SJoe Hershberger struct dm_test_state *dms = uts->priv; 56254c5d08aSHeiko Schocher struct udevice *top[NODE_COUNT]; 56354c5d08aSHeiko Schocher struct udevice *child[NODE_COUNT]; 56454c5d08aSHeiko Schocher struct udevice *grandchild[NODE_COUNT]; 56554c5d08aSHeiko Schocher struct udevice *dev; 5662e7d35d2SSimon Glass int total; 5672e7d35d2SSimon Glass int ret; 5682e7d35d2SSimon Glass int i; 5692e7d35d2SSimon Glass 5702e7d35d2SSimon Glass /* We don't care about the numbering for this test */ 5712e7d35d2SSimon Glass dms->skip_post_probe = 1; 5722e7d35d2SSimon Glass 5732e7d35d2SSimon Glass ut_assert(NODE_COUNT > 5); 5742e7d35d2SSimon Glass 5752e7d35d2SSimon Glass /* First create 10 top-level children */ 576e721b882SJoe Hershberger ut_assertok(create_children(uts, dms->root, NODE_COUNT, 0, top)); 5772e7d35d2SSimon Glass 5782e7d35d2SSimon Glass /* Now a few have their own children */ 579e721b882SJoe Hershberger ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL)); 580e721b882SJoe Hershberger ut_assertok(create_children(uts, top[5], NODE_COUNT, 5, child)); 5812e7d35d2SSimon Glass 5822e7d35d2SSimon Glass /* And grandchildren */ 5832e7d35d2SSimon Glass for (i = 0; i < NODE_COUNT; i++) 584e721b882SJoe Hershberger ut_assertok(create_children(uts, child[i], NODE_COUNT, 50 * i, 5852e7d35d2SSimon Glass i == 2 ? grandchild : NULL)); 5862e7d35d2SSimon Glass 5872e7d35d2SSimon Glass /* Check total number of devices */ 5882e7d35d2SSimon Glass total = NODE_COUNT * (3 + NODE_COUNT); 5892e7d35d2SSimon Glass ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_BIND]); 5902e7d35d2SSimon Glass 5912e7d35d2SSimon Glass /* Try probing one of the grandchildren */ 5922e7d35d2SSimon Glass ut_assertok(uclass_get_device(UCLASS_TEST, 5932e7d35d2SSimon Glass NODE_COUNT * 3 + 2 * NODE_COUNT, &dev)); 5942e7d35d2SSimon Glass ut_asserteq_ptr(grandchild[0], dev); 5952e7d35d2SSimon Glass 5962e7d35d2SSimon Glass /* 5972e7d35d2SSimon Glass * This should have probed the child and top node also, for a total 5982e7d35d2SSimon Glass * of 3 nodes. 5992e7d35d2SSimon Glass */ 6002e7d35d2SSimon Glass ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PROBE]); 6012e7d35d2SSimon Glass 6022e7d35d2SSimon Glass /* Probe the other grandchildren */ 6032e7d35d2SSimon Glass for (i = 1; i < NODE_COUNT; i++) 6042e7d35d2SSimon Glass ut_assertok(device_probe(grandchild[i])); 6052e7d35d2SSimon Glass 6062e7d35d2SSimon Glass ut_asserteq(2 + NODE_COUNT, dm_testdrv_op_count[DM_TEST_OP_PROBE]); 6072e7d35d2SSimon Glass 6082e7d35d2SSimon Glass /* Probe everything */ 6092e7d35d2SSimon Glass for (ret = uclass_first_device(UCLASS_TEST, &dev); 6102e7d35d2SSimon Glass dev; 6112e7d35d2SSimon Glass ret = uclass_next_device(&dev)) 6122e7d35d2SSimon Glass ; 6132e7d35d2SSimon Glass ut_assertok(ret); 6142e7d35d2SSimon Glass 6152e7d35d2SSimon Glass ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_PROBE]); 6162e7d35d2SSimon Glass 6172e7d35d2SSimon Glass /* Remove a top-level child and check that the children are removed */ 618706865afSStefan Roese ut_assertok(device_remove(top[2], DM_REMOVE_NORMAL)); 6192e7d35d2SSimon Glass ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_REMOVE]); 6202e7d35d2SSimon Glass dm_testdrv_op_count[DM_TEST_OP_REMOVE] = 0; 6212e7d35d2SSimon Glass 6222e7d35d2SSimon Glass /* Try one with grandchildren */ 6232e7d35d2SSimon Glass ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev)); 6242e7d35d2SSimon Glass ut_asserteq_ptr(dev, top[5]); 625706865afSStefan Roese ut_assertok(device_remove(dev, DM_REMOVE_NORMAL)); 6262e7d35d2SSimon Glass ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT), 6272e7d35d2SSimon Glass dm_testdrv_op_count[DM_TEST_OP_REMOVE]); 6282e7d35d2SSimon Glass 6292e7d35d2SSimon Glass /* Try the same with unbind */ 6302e7d35d2SSimon Glass ut_assertok(device_unbind(top[2])); 6312e7d35d2SSimon Glass ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]); 6322e7d35d2SSimon Glass dm_testdrv_op_count[DM_TEST_OP_UNBIND] = 0; 6332e7d35d2SSimon Glass 6342e7d35d2SSimon Glass /* Try one with grandchildren */ 6352e7d35d2SSimon Glass ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev)); 6362e7d35d2SSimon Glass ut_asserteq_ptr(dev, top[6]); 6372e7d35d2SSimon Glass ut_assertok(device_unbind(top[5])); 6382e7d35d2SSimon Glass ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT), 6392e7d35d2SSimon Glass dm_testdrv_op_count[DM_TEST_OP_UNBIND]); 6402e7d35d2SSimon Glass 6412e7d35d2SSimon Glass return 0; 6422e7d35d2SSimon Glass } 6432e7d35d2SSimon Glass DM_TEST(dm_test_children, 0); 64400606d7eSSimon Glass 64500606d7eSSimon Glass /* Test that pre-relocation devices work as expected */ 646e721b882SJoe Hershberger static int dm_test_pre_reloc(struct unit_test_state *uts) 64700606d7eSSimon Glass { 648e721b882SJoe Hershberger struct dm_test_state *dms = uts->priv; 64900606d7eSSimon Glass struct udevice *dev; 65000606d7eSSimon Glass 65100606d7eSSimon Glass /* The normal driver should refuse to bind before relocation */ 65200606d7eSSimon Glass ut_asserteq(-EPERM, device_bind_by_name(dms->root, true, 65300606d7eSSimon Glass &driver_info_manual, &dev)); 65400606d7eSSimon Glass 65500606d7eSSimon Glass /* But this one is marked pre-reloc */ 65600606d7eSSimon Glass ut_assertok(device_bind_by_name(dms->root, true, 65700606d7eSSimon Glass &driver_info_pre_reloc, &dev)); 65800606d7eSSimon Glass 65900606d7eSSimon Glass return 0; 66000606d7eSSimon Glass } 66100606d7eSSimon Glass DM_TEST(dm_test_pre_reloc, 0); 662c910e2e2SSimon Glass 66324f927c5SStefan Roese /* 66424f927c5SStefan Roese * Test that removal of devices, either via the "normal" device_remove() 66524f927c5SStefan Roese * API or via the device driver selective flag works as expected 66624f927c5SStefan Roese */ 66724f927c5SStefan Roese static int dm_test_remove_active_dma(struct unit_test_state *uts) 66824f927c5SStefan Roese { 66924f927c5SStefan Roese struct dm_test_state *dms = uts->priv; 67024f927c5SStefan Roese struct udevice *dev; 67124f927c5SStefan Roese 67224f927c5SStefan Roese ut_assertok(device_bind_by_name(dms->root, false, &driver_info_act_dma, 67324f927c5SStefan Roese &dev)); 67424f927c5SStefan Roese ut_assert(dev); 67524f927c5SStefan Roese 67624f927c5SStefan Roese /* Probe the device */ 67724f927c5SStefan Roese ut_assertok(device_probe(dev)); 67824f927c5SStefan Roese 67924f927c5SStefan Roese /* Test if device is active right now */ 68024f927c5SStefan Roese ut_asserteq(true, device_active(dev)); 68124f927c5SStefan Roese 68224f927c5SStefan Roese /* Remove the device via selective remove flag */ 68324f927c5SStefan Roese dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL); 68424f927c5SStefan Roese 68524f927c5SStefan Roese /* Test if device is inactive right now */ 68624f927c5SStefan Roese ut_asserteq(false, device_active(dev)); 68724f927c5SStefan Roese 68824f927c5SStefan Roese /* Probe the device again */ 68924f927c5SStefan Roese ut_assertok(device_probe(dev)); 69024f927c5SStefan Roese 69124f927c5SStefan Roese /* Test if device is active right now */ 69224f927c5SStefan Roese ut_asserteq(true, device_active(dev)); 69324f927c5SStefan Roese 69424f927c5SStefan Roese /* Remove the device via "normal" remove API */ 69524f927c5SStefan Roese ut_assertok(device_remove(dev, DM_REMOVE_NORMAL)); 69624f927c5SStefan Roese 69724f927c5SStefan Roese /* Test if device is inactive right now */ 69824f927c5SStefan Roese ut_asserteq(false, device_active(dev)); 69924f927c5SStefan Roese 70024f927c5SStefan Roese /* 70124f927c5SStefan Roese * Test if a device without the active DMA flags is not removed upon 70224f927c5SStefan Roese * the active DMA remove call 70324f927c5SStefan Roese */ 70424f927c5SStefan Roese ut_assertok(device_unbind(dev)); 70524f927c5SStefan Roese ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual, 70624f927c5SStefan Roese &dev)); 70724f927c5SStefan Roese ut_assert(dev); 70824f927c5SStefan Roese 70924f927c5SStefan Roese /* Probe the device */ 71024f927c5SStefan Roese ut_assertok(device_probe(dev)); 71124f927c5SStefan Roese 71224f927c5SStefan Roese /* Test if device is active right now */ 71324f927c5SStefan Roese ut_asserteq(true, device_active(dev)); 71424f927c5SStefan Roese 71524f927c5SStefan Roese /* Remove the device via selective remove flag */ 71624f927c5SStefan Roese dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL); 71724f927c5SStefan Roese 71824f927c5SStefan Roese /* Test if device is still active right now */ 71924f927c5SStefan Roese ut_asserteq(true, device_active(dev)); 72024f927c5SStefan Roese 72124f927c5SStefan Roese return 0; 72224f927c5SStefan Roese } 72324f927c5SStefan Roese DM_TEST(dm_test_remove_active_dma, 0); 72424f927c5SStefan Roese 725e721b882SJoe Hershberger static int dm_test_uclass_before_ready(struct unit_test_state *uts) 726c910e2e2SSimon Glass { 727c910e2e2SSimon Glass struct uclass *uc; 728c910e2e2SSimon Glass 729c910e2e2SSimon Glass ut_assertok(uclass_get(UCLASS_TEST, &uc)); 730c910e2e2SSimon Glass 731f9fd4558SSimon Glass gd->dm_root = NULL; 732f9fd4558SSimon Glass gd->dm_root_f = NULL; 733f9fd4558SSimon Glass memset(&gd->uclass_root, '\0', sizeof(gd->uclass_root)); 734f9fd4558SSimon Glass 735c910e2e2SSimon Glass ut_asserteq_ptr(NULL, uclass_find(UCLASS_TEST)); 736c910e2e2SSimon Glass 737c910e2e2SSimon Glass return 0; 738c910e2e2SSimon Glass } 739c910e2e2SSimon Glass DM_TEST(dm_test_uclass_before_ready, 0); 740b3670531SSimon Glass 741e721b882SJoe Hershberger static int dm_test_uclass_devices_find(struct unit_test_state *uts) 7429e85f13dSPrzemyslaw Marczak { 7439e85f13dSPrzemyslaw Marczak struct udevice *dev; 7449e85f13dSPrzemyslaw Marczak int ret; 7459e85f13dSPrzemyslaw Marczak 7469e85f13dSPrzemyslaw Marczak for (ret = uclass_find_first_device(UCLASS_TEST, &dev); 7479e85f13dSPrzemyslaw Marczak dev; 7489e85f13dSPrzemyslaw Marczak ret = uclass_find_next_device(&dev)) { 7499e85f13dSPrzemyslaw Marczak ut_assert(!ret); 7509e85f13dSPrzemyslaw Marczak ut_assert(dev); 7519e85f13dSPrzemyslaw Marczak } 7529e85f13dSPrzemyslaw Marczak 7539e85f13dSPrzemyslaw Marczak return 0; 7549e85f13dSPrzemyslaw Marczak } 7559e85f13dSPrzemyslaw Marczak DM_TEST(dm_test_uclass_devices_find, DM_TESTF_SCAN_PDATA); 7569e85f13dSPrzemyslaw Marczak 757e721b882SJoe Hershberger static int dm_test_uclass_devices_find_by_name(struct unit_test_state *uts) 7586e0c4880SPrzemyslaw Marczak { 7596e0c4880SPrzemyslaw Marczak struct udevice *finddev; 7606e0c4880SPrzemyslaw Marczak struct udevice *testdev; 7616e0c4880SPrzemyslaw Marczak int findret, ret; 7626e0c4880SPrzemyslaw Marczak 7636e0c4880SPrzemyslaw Marczak /* 7646e0c4880SPrzemyslaw Marczak * For each test device found in fdt like: "a-test", "b-test", etc., 7656e0c4880SPrzemyslaw Marczak * use its name and try to find it by uclass_find_device_by_name(). 7666e0c4880SPrzemyslaw Marczak * Then, on success check if: 7676e0c4880SPrzemyslaw Marczak * - current 'testdev' name is equal to the returned 'finddev' name 7686e0c4880SPrzemyslaw Marczak * - current 'testdev' pointer is equal to the returned 'finddev' 7696e0c4880SPrzemyslaw Marczak * 7706e0c4880SPrzemyslaw Marczak * We assume that, each uclass's device name is unique, so if not, then 7716e0c4880SPrzemyslaw Marczak * this will fail on checking condition: testdev == finddev, since the 7726e0c4880SPrzemyslaw Marczak * uclass_find_device_by_name(), returns the first device by given name. 7736e0c4880SPrzemyslaw Marczak */ 7746e0c4880SPrzemyslaw Marczak for (ret = uclass_find_first_device(UCLASS_TEST_FDT, &testdev); 7756e0c4880SPrzemyslaw Marczak testdev; 7766e0c4880SPrzemyslaw Marczak ret = uclass_find_next_device(&testdev)) { 7776e0c4880SPrzemyslaw Marczak ut_assertok(ret); 7786e0c4880SPrzemyslaw Marczak ut_assert(testdev); 7796e0c4880SPrzemyslaw Marczak 7806e0c4880SPrzemyslaw Marczak findret = uclass_find_device_by_name(UCLASS_TEST_FDT, 7816e0c4880SPrzemyslaw Marczak testdev->name, 7826e0c4880SPrzemyslaw Marczak &finddev); 7836e0c4880SPrzemyslaw Marczak 7846e0c4880SPrzemyslaw Marczak ut_assertok(findret); 7856e0c4880SPrzemyslaw Marczak ut_assert(testdev); 7866e0c4880SPrzemyslaw Marczak ut_asserteq_str(testdev->name, finddev->name); 7876e0c4880SPrzemyslaw Marczak ut_asserteq_ptr(testdev, finddev); 7886e0c4880SPrzemyslaw Marczak } 7896e0c4880SPrzemyslaw Marczak 7906e0c4880SPrzemyslaw Marczak return 0; 7916e0c4880SPrzemyslaw Marczak } 7926e0c4880SPrzemyslaw Marczak DM_TEST(dm_test_uclass_devices_find_by_name, DM_TESTF_SCAN_FDT); 7936e0c4880SPrzemyslaw Marczak 794e721b882SJoe Hershberger static int dm_test_uclass_devices_get(struct unit_test_state *uts) 7959e85f13dSPrzemyslaw Marczak { 7969e85f13dSPrzemyslaw Marczak struct udevice *dev; 7979e85f13dSPrzemyslaw Marczak int ret; 7989e85f13dSPrzemyslaw Marczak 799*1f383ee4SMichal Suchanek for (ret = uclass_first_device_check(UCLASS_TEST, &dev); 8009e85f13dSPrzemyslaw Marczak dev; 801*1f383ee4SMichal Suchanek ret = uclass_next_device_check(&dev)) { 8029e85f13dSPrzemyslaw Marczak ut_assert(!ret); 8039e85f13dSPrzemyslaw Marczak ut_assert(device_active(dev)); 8049e85f13dSPrzemyslaw Marczak } 8059e85f13dSPrzemyslaw Marczak 8069e85f13dSPrzemyslaw Marczak return 0; 8079e85f13dSPrzemyslaw Marczak } 8089e85f13dSPrzemyslaw Marczak DM_TEST(dm_test_uclass_devices_get, DM_TESTF_SCAN_PDATA); 8099e85f13dSPrzemyslaw Marczak 810e721b882SJoe Hershberger static int dm_test_uclass_devices_get_by_name(struct unit_test_state *uts) 8116e0c4880SPrzemyslaw Marczak { 8126e0c4880SPrzemyslaw Marczak struct udevice *finddev; 8136e0c4880SPrzemyslaw Marczak struct udevice *testdev; 8146e0c4880SPrzemyslaw Marczak int ret, findret; 8156e0c4880SPrzemyslaw Marczak 8166e0c4880SPrzemyslaw Marczak /* 8176e0c4880SPrzemyslaw Marczak * For each test device found in fdt like: "a-test", "b-test", etc., 8186e0c4880SPrzemyslaw Marczak * use its name and try to get it by uclass_get_device_by_name(). 8196e0c4880SPrzemyslaw Marczak * On success check if: 8206e0c4880SPrzemyslaw Marczak * - returned finddev' is active 8216e0c4880SPrzemyslaw Marczak * - current 'testdev' name is equal to the returned 'finddev' name 8226e0c4880SPrzemyslaw Marczak * - current 'testdev' pointer is equal to the returned 'finddev' 8236e0c4880SPrzemyslaw Marczak * 8246e0c4880SPrzemyslaw Marczak * We asserts that the 'testdev' is active on each loop entry, so we 8256e0c4880SPrzemyslaw Marczak * could be sure that the 'finddev' is activated too, but for sure 8266e0c4880SPrzemyslaw Marczak * we check it again. 8276e0c4880SPrzemyslaw Marczak * 8286e0c4880SPrzemyslaw Marczak * We assume that, each uclass's device name is unique, so if not, then 8296e0c4880SPrzemyslaw Marczak * this will fail on checking condition: testdev == finddev, since the 8306e0c4880SPrzemyslaw Marczak * uclass_get_device_by_name(), returns the first device by given name. 8316e0c4880SPrzemyslaw Marczak */ 832*1f383ee4SMichal Suchanek for (ret = uclass_first_device_check(UCLASS_TEST_FDT, &testdev); 8336e0c4880SPrzemyslaw Marczak testdev; 834*1f383ee4SMichal Suchanek ret = uclass_next_device_check(&testdev)) { 8356e0c4880SPrzemyslaw Marczak ut_assertok(ret); 8366e0c4880SPrzemyslaw Marczak ut_assert(device_active(testdev)); 8376e0c4880SPrzemyslaw Marczak 8386e0c4880SPrzemyslaw Marczak findret = uclass_get_device_by_name(UCLASS_TEST_FDT, 8396e0c4880SPrzemyslaw Marczak testdev->name, 8406e0c4880SPrzemyslaw Marczak &finddev); 8416e0c4880SPrzemyslaw Marczak 8426e0c4880SPrzemyslaw Marczak ut_assertok(findret); 8436e0c4880SPrzemyslaw Marczak ut_assert(finddev); 8446e0c4880SPrzemyslaw Marczak ut_assert(device_active(finddev)); 8456e0c4880SPrzemyslaw Marczak ut_asserteq_str(testdev->name, finddev->name); 8466e0c4880SPrzemyslaw Marczak ut_asserteq_ptr(testdev, finddev); 8476e0c4880SPrzemyslaw Marczak } 8486e0c4880SPrzemyslaw Marczak 8496e0c4880SPrzemyslaw Marczak return 0; 8506e0c4880SPrzemyslaw Marczak } 8516e0c4880SPrzemyslaw Marczak DM_TEST(dm_test_uclass_devices_get_by_name, DM_TESTF_SCAN_FDT); 8526e0c4880SPrzemyslaw Marczak 853e721b882SJoe Hershberger static int dm_test_device_get_uclass_id(struct unit_test_state *uts) 854b3670531SSimon Glass { 855b3670531SSimon Glass struct udevice *dev; 856b3670531SSimon Glass 857b3670531SSimon Glass ut_assertok(uclass_get_device(UCLASS_TEST, 0, &dev)); 858b3670531SSimon Glass ut_asserteq(UCLASS_TEST, device_get_uclass_id(dev)); 859b3670531SSimon Glass 860b3670531SSimon Glass return 0; 861b3670531SSimon Glass } 862b3670531SSimon Glass DM_TEST(dm_test_device_get_uclass_id, DM_TESTF_SCAN_PDATA); 863440e24d7SSimon Glass 864440e24d7SSimon Glass static int dm_test_uclass_names(struct unit_test_state *uts) 865440e24d7SSimon Glass { 866440e24d7SSimon Glass ut_asserteq_str("test", uclass_get_name(UCLASS_TEST)); 867440e24d7SSimon Glass ut_asserteq(UCLASS_TEST, uclass_get_by_name("test")); 868440e24d7SSimon Glass 869440e24d7SSimon Glass return 0; 870440e24d7SSimon Glass } 871440e24d7SSimon Glass DM_TEST(dm_test_uclass_names, DM_TESTF_SCAN_PDATA); 872