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> 840441e0bSJoe Hershberger #include <command.h> 92e7d35d2SSimon Glass #include <dm.h> 102e7d35d2SSimon Glass #include <errno.h> 11756ac0bbSSimon Glass #include <malloc.h> 122e7d35d2SSimon Glass #include <dm/test.h> 132e7d35d2SSimon Glass #include <dm/root.h> 142e7d35d2SSimon Glass #include <dm/uclass-internal.h> 15e721b882SJoe Hershberger #include <test/ut.h> 162e7d35d2SSimon Glass 172e7d35d2SSimon Glass DECLARE_GLOBAL_DATA_PTR; 182e7d35d2SSimon Glass 19e721b882SJoe Hershberger struct unit_test_state global_dm_test_state; 20e721b882SJoe Hershberger static struct dm_test_state _global_priv_dm_test_state; 212e7d35d2SSimon Glass 222e7d35d2SSimon Glass /* Get ready for testing */ 23e721b882SJoe Hershberger static int dm_test_init(struct unit_test_state *uts) 242e7d35d2SSimon Glass { 25e721b882SJoe Hershberger struct dm_test_state *dms = uts->priv; 26e721b882SJoe Hershberger 272e7d35d2SSimon Glass memset(dms, '\0', sizeof(*dms)); 282e7d35d2SSimon Glass gd->dm_root = NULL; 292e7d35d2SSimon Glass memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); 302e7d35d2SSimon Glass 312e7d35d2SSimon Glass ut_assertok(dm_init()); 322e7d35d2SSimon Glass dms->root = dm_root(); 332e7d35d2SSimon Glass 342e7d35d2SSimon Glass return 0; 352e7d35d2SSimon Glass } 362e7d35d2SSimon Glass 372e7d35d2SSimon Glass /* Ensure all the test devices are probed */ 38e721b882SJoe Hershberger static int do_autoprobe(struct unit_test_state *uts) 392e7d35d2SSimon Glass { 4054c5d08aSHeiko Schocher struct udevice *dev; 412e7d35d2SSimon Glass int ret; 422e7d35d2SSimon Glass 432e7d35d2SSimon Glass /* Scanning the uclass is enough to probe all the devices */ 442e7d35d2SSimon Glass for (ret = uclass_first_device(UCLASS_TEST, &dev); 452e7d35d2SSimon Glass dev; 462e7d35d2SSimon Glass ret = uclass_next_device(&dev)) 472e7d35d2SSimon Glass ; 482e7d35d2SSimon Glass 492e7d35d2SSimon Glass return ret; 502e7d35d2SSimon Glass } 512e7d35d2SSimon Glass 52e721b882SJoe Hershberger static int dm_test_destroy(struct unit_test_state *uts) 532e7d35d2SSimon Glass { 542e7d35d2SSimon Glass int id; 552e7d35d2SSimon Glass 562e7d35d2SSimon Glass for (id = 0; id < UCLASS_COUNT; id++) { 572e7d35d2SSimon Glass struct uclass *uc; 582e7d35d2SSimon Glass 592e7d35d2SSimon Glass /* 602e7d35d2SSimon Glass * If the uclass doesn't exist we don't want to create it. So 612e7d35d2SSimon Glass * check that here before we call uclass_find_device()/ 622e7d35d2SSimon Glass */ 632e7d35d2SSimon Glass uc = uclass_find(id); 642e7d35d2SSimon Glass if (!uc) 652e7d35d2SSimon Glass continue; 662e7d35d2SSimon Glass ut_assertok(uclass_destroy(uc)); 672e7d35d2SSimon Glass } 682e7d35d2SSimon Glass 692e7d35d2SSimon Glass return 0; 702e7d35d2SSimon Glass } 712e7d35d2SSimon Glass 7240441e0bSJoe Hershberger static int dm_test_main(const char *test_name) 732e7d35d2SSimon Glass { 74e721b882SJoe Hershberger struct unit_test *tests = ll_entry_start(struct unit_test, dm_test); 75e721b882SJoe Hershberger const int n_ents = ll_entry_count(struct unit_test, dm_test); 76e721b882SJoe Hershberger struct unit_test_state *uts = &global_dm_test_state; 77e721b882SJoe Hershberger uts->priv = &_global_priv_dm_test_state; 78e721b882SJoe Hershberger struct unit_test *test; 79*c02790ceSSimon Glass int run_count; 802e7d35d2SSimon Glass 812e7d35d2SSimon Glass /* 822e7d35d2SSimon Glass * If we have no device tree, or it only has a root node, then these 832e7d35d2SSimon Glass * tests clearly aren't going to work... 842e7d35d2SSimon Glass */ 852e7d35d2SSimon Glass if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) { 862e7d35d2SSimon Glass puts("Please run with test device tree:\n" 87f64000c3SPrzemyslaw Marczak " ./u-boot -d arch/sandbox/dts/test.dtb\n"); 882e7d35d2SSimon Glass ut_assert(gd->fdt_blob); 892e7d35d2SSimon Glass } 902e7d35d2SSimon Glass 9157f54d55SSimon Glass if (!test_name) 922e7d35d2SSimon Glass printf("Running %d driver model tests\n", n_ents); 932e7d35d2SSimon Glass 94*c02790ceSSimon Glass run_count = 0; 952e7d35d2SSimon Glass for (test = tests; test < tests + n_ents; test++) { 96*c02790ceSSimon Glass const char *name = test->name; 97*c02790ceSSimon Glass 98*c02790ceSSimon Glass /* All tests have this prefix */ 99*c02790ceSSimon Glass if (!strncmp(name, "dm_test_", 8)) 100*c02790ceSSimon Glass name += 8; 101*c02790ceSSimon Glass if (test_name && strcmp(test_name, name)) 10257f54d55SSimon Glass continue; 1032e7d35d2SSimon Glass printf("Test: %s\n", test->name); 104*c02790ceSSimon Glass run_count++; 105e721b882SJoe Hershberger ut_assertok(dm_test_init(uts)); 1062e7d35d2SSimon Glass 107e721b882SJoe Hershberger uts->start = mallinfo(); 1082e7d35d2SSimon Glass if (test->flags & DM_TESTF_SCAN_PDATA) 10900606d7eSSimon Glass ut_assertok(dm_scan_platdata(false)); 1102e7d35d2SSimon Glass if (test->flags & DM_TESTF_PROBE_TEST) 111e721b882SJoe Hershberger ut_assertok(do_autoprobe(uts)); 1122e7d35d2SSimon Glass if (test->flags & DM_TESTF_SCAN_FDT) 11300606d7eSSimon Glass ut_assertok(dm_scan_fdt(gd->fdt_blob, false)); 1142e7d35d2SSimon Glass 1157cccc66aSJoe Hershberger test->func(uts); 1162e7d35d2SSimon Glass 117e721b882SJoe Hershberger ut_assertok(dm_test_destroy(uts)); 1182e7d35d2SSimon Glass } 1192e7d35d2SSimon Glass 120*c02790ceSSimon Glass if (test_name && !run_count) 121*c02790ceSSimon Glass printf("Test '%s' not found\n", test_name); 122*c02790ceSSimon Glass else 123e721b882SJoe Hershberger printf("Failures: %d\n", uts->fail_count); 1242e7d35d2SSimon Glass 125b6227d39SJoe Hershberger gd->dm_root = NULL; 126b6227d39SJoe Hershberger ut_assertok(dm_init()); 127b6227d39SJoe Hershberger dm_scan_platdata(false); 128b6227d39SJoe Hershberger dm_scan_fdt(gd->fdt_blob, false); 129b6227d39SJoe Hershberger 1307cccc66aSJoe Hershberger return uts->fail_count ? CMD_RET_FAILURE : 0; 1312e7d35d2SSimon Glass } 13240441e0bSJoe Hershberger 13340441e0bSJoe Hershberger int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 13440441e0bSJoe Hershberger { 13540441e0bSJoe Hershberger const char *test_name = NULL; 13640441e0bSJoe Hershberger 13740441e0bSJoe Hershberger if (argc > 1) 13840441e0bSJoe Hershberger test_name = argv[1]; 13940441e0bSJoe Hershberger 14040441e0bSJoe Hershberger return dm_test_main(test_name); 14140441e0bSJoe Hershberger } 142