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; 792e7d35d2SSimon Glass 802e7d35d2SSimon Glass /* 812e7d35d2SSimon Glass * If we have no device tree, or it only has a root node, then these 822e7d35d2SSimon Glass * tests clearly aren't going to work... 832e7d35d2SSimon Glass */ 842e7d35d2SSimon Glass if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) { 852e7d35d2SSimon Glass puts("Please run with test device tree:\n" 86f64000c3SPrzemyslaw Marczak " ./u-boot -d arch/sandbox/dts/test.dtb\n"); 872e7d35d2SSimon Glass ut_assert(gd->fdt_blob); 882e7d35d2SSimon Glass } 892e7d35d2SSimon Glass 9057f54d55SSimon Glass if (!test_name) 912e7d35d2SSimon Glass printf("Running %d driver model tests\n", n_ents); 922e7d35d2SSimon Glass 932e7d35d2SSimon Glass for (test = tests; test < tests + n_ents; test++) { 9457f54d55SSimon Glass if (test_name && strcmp(test_name, test->name)) 9557f54d55SSimon Glass continue; 962e7d35d2SSimon Glass printf("Test: %s\n", test->name); 97e721b882SJoe Hershberger ut_assertok(dm_test_init(uts)); 982e7d35d2SSimon Glass 99e721b882SJoe Hershberger uts->start = mallinfo(); 1002e7d35d2SSimon Glass if (test->flags & DM_TESTF_SCAN_PDATA) 10100606d7eSSimon Glass ut_assertok(dm_scan_platdata(false)); 1022e7d35d2SSimon Glass if (test->flags & DM_TESTF_PROBE_TEST) 103e721b882SJoe Hershberger ut_assertok(do_autoprobe(uts)); 1042e7d35d2SSimon Glass if (test->flags & DM_TESTF_SCAN_FDT) 10500606d7eSSimon Glass ut_assertok(dm_scan_fdt(gd->fdt_blob, false)); 1062e7d35d2SSimon Glass 107*7cccc66aSJoe Hershberger test->func(uts); 1082e7d35d2SSimon Glass 109e721b882SJoe Hershberger ut_assertok(dm_test_destroy(uts)); 1102e7d35d2SSimon Glass } 1112e7d35d2SSimon Glass 112e721b882SJoe Hershberger printf("Failures: %d\n", uts->fail_count); 1132e7d35d2SSimon Glass 114*7cccc66aSJoe Hershberger return uts->fail_count ? CMD_RET_FAILURE : 0; 1152e7d35d2SSimon Glass } 11640441e0bSJoe Hershberger 11740441e0bSJoe Hershberger int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 11840441e0bSJoe Hershberger { 11940441e0bSJoe Hershberger const char *test_name = NULL; 12040441e0bSJoe Hershberger 12140441e0bSJoe Hershberger if (argc > 1) 12240441e0bSJoe Hershberger test_name = argv[1]; 12340441e0bSJoe Hershberger 12440441e0bSJoe Hershberger return dm_test_main(test_name); 12540441e0bSJoe Hershberger } 126