uboot/test/dm/core.c
<<
>>
Prefs
   1/*
   2 * Tests for the core driver model code
   3 *
   4 * Copyright (c) 2013 Google, Inc
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <common.h>
  10#include <errno.h>
  11#include <dm.h>
  12#include <fdtdec.h>
  13#include <malloc.h>
  14#include <dm/device-internal.h>
  15#include <dm/root.h>
  16#include <dm/util.h>
  17#include <dm/test.h>
  18#include <dm/uclass-internal.h>
  19#include <test/ut.h>
  20
  21DECLARE_GLOBAL_DATA_PTR;
  22
  23enum {
  24        TEST_INTVAL1            = 0,
  25        TEST_INTVAL2            = 3,
  26        TEST_INTVAL3            = 6,
  27        TEST_INTVAL_MANUAL      = 101112,
  28        TEST_INTVAL_PRE_RELOC   = 7,
  29};
  30
  31static const struct dm_test_pdata test_pdata[] = {
  32        { .ping_add             = TEST_INTVAL1, },
  33        { .ping_add             = TEST_INTVAL2, },
  34        { .ping_add             = TEST_INTVAL3, },
  35};
  36
  37static const struct dm_test_pdata test_pdata_manual = {
  38        .ping_add               = TEST_INTVAL_MANUAL,
  39};
  40
  41static const struct dm_test_pdata test_pdata_pre_reloc = {
  42        .ping_add               = TEST_INTVAL_PRE_RELOC,
  43};
  44
  45U_BOOT_DEVICE(dm_test_info1) = {
  46        .name = "test_drv",
  47        .platdata = &test_pdata[0],
  48};
  49
  50U_BOOT_DEVICE(dm_test_info2) = {
  51        .name = "test_drv",
  52        .platdata = &test_pdata[1],
  53};
  54
  55U_BOOT_DEVICE(dm_test_info3) = {
  56        .name = "test_drv",
  57        .platdata = &test_pdata[2],
  58};
  59
  60static struct driver_info driver_info_manual = {
  61        .name = "test_manual_drv",
  62        .platdata = &test_pdata_manual,
  63};
  64
  65static struct driver_info driver_info_pre_reloc = {
  66        .name = "test_pre_reloc_drv",
  67        .platdata = &test_pdata_pre_reloc,
  68};
  69
  70void dm_leak_check_start(struct unit_test_state *uts)
  71{
  72        uts->start = mallinfo();
  73        if (!uts->start.uordblks)
  74                puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n");
  75}
  76
  77int dm_leak_check_end(struct unit_test_state *uts)
  78{
  79        struct mallinfo end;
  80        int id, diff;
  81
  82        /* Don't delete the root class, since we started with that */
  83        for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) {
  84                struct uclass *uc;
  85
  86                uc = uclass_find(id);
  87                if (!uc)
  88                        continue;
  89                ut_assertok(uclass_destroy(uc));
  90        }
  91
  92        end = mallinfo();
  93        diff = end.uordblks - uts->start.uordblks;
  94        if (diff > 0)
  95                printf("Leak: lost %#xd bytes\n", diff);
  96        else if (diff < 0)
  97                printf("Leak: gained %#xd bytes\n", -diff);
  98        ut_asserteq(uts->start.uordblks, end.uordblks);
  99
 100        return 0;
 101}
 102
 103/* Test that binding with platdata occurs correctly */
 104static int dm_test_autobind(struct unit_test_state *uts)
 105{
 106        struct dm_test_state *dms = uts->priv;
 107        struct udevice *dev;
 108
 109        /*
 110         * We should have a single class (UCLASS_ROOT) and a single root
 111         * device with no children.
 112         */
 113        ut_assert(dms->root);
 114        ut_asserteq(1, list_count_items(&gd->uclass_root));
 115        ut_asserteq(0, list_count_items(&gd->dm_root->child_head));
 116        ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]);
 117
 118        ut_assertok(dm_scan_platdata(false));
 119
 120        /* We should have our test class now at least, plus more children */
 121        ut_assert(1 < list_count_items(&gd->uclass_root));
 122        ut_assert(0 < list_count_items(&gd->dm_root->child_head));
 123
 124        /* Our 3 dm_test_infox children should be bound to the test uclass */
 125        ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]);
 126
 127        /* No devices should be probed */
 128        list_for_each_entry(dev, &gd->dm_root->child_head, sibling_node)
 129                ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
 130
 131        /* Our test driver should have been bound 3 times */
 132        ut_assert(dm_testdrv_op_count[DM_TEST_OP_BIND] == 3);
 133
 134        return 0;
 135}
 136DM_TEST(dm_test_autobind, 0);
 137
 138/* Test that binding with uclass platdata allocation occurs correctly */
 139static int dm_test_autobind_uclass_pdata_alloc(struct unit_test_state *uts)
 140{
 141        struct dm_test_perdev_uc_pdata *uc_pdata;
 142        struct udevice *dev;
 143        struct uclass *uc;
 144
 145        ut_assertok(uclass_get(UCLASS_TEST, &uc));
 146        ut_assert(uc);
 147
 148        /**
 149         * Test if test uclass driver requires allocation for the uclass
 150         * platform data and then check the dev->uclass_platdata pointer.
 151         */
 152        ut_assert(uc->uc_drv->per_device_platdata_auto_alloc_size);
 153
 154        for (uclass_find_first_device(UCLASS_TEST, &dev);
 155             dev;
 156             uclass_find_next_device(&dev)) {
 157                ut_assert(dev);
 158
 159                uc_pdata = dev_get_uclass_platdata(dev);
 160                ut_assert(uc_pdata);
 161        }
 162
 163        return 0;
 164}
 165DM_TEST(dm_test_autobind_uclass_pdata_alloc, DM_TESTF_SCAN_PDATA);
 166
 167/* Test that binding with uclass platdata setting occurs correctly */
 168static int dm_test_autobind_uclass_pdata_valid(struct unit_test_state *uts)
 169{
 170        struct dm_test_perdev_uc_pdata *uc_pdata;
 171        struct udevice *dev;
 172
 173        /**
 174         * In the test_postbind() method of test uclass driver, the uclass
 175         * platform data should be set to three test int values - test it.
 176         */
 177        for (uclass_find_first_device(UCLASS_TEST, &dev);
 178             dev;
 179             uclass_find_next_device(&dev)) {
 180                ut_assert(dev);
 181
 182                uc_pdata = dev_get_uclass_platdata(dev);
 183                ut_assert(uc_pdata);
 184                ut_assert(uc_pdata->intval1 == TEST_UC_PDATA_INTVAL1);
 185                ut_assert(uc_pdata->intval2 == TEST_UC_PDATA_INTVAL2);
 186                ut_assert(uc_pdata->intval3 == TEST_UC_PDATA_INTVAL3);
 187        }
 188
 189        return 0;
 190}
 191DM_TEST(dm_test_autobind_uclass_pdata_valid, DM_TESTF_SCAN_PDATA);
 192
 193/* Test that autoprobe finds all the expected devices */
 194static int dm_test_autoprobe(struct unit_test_state *uts)
 195{
 196        struct dm_test_state *dms = uts->priv;
 197        int expected_base_add;
 198        struct udevice *dev;
 199        struct uclass *uc;
 200        int i;
 201
 202        ut_assertok(uclass_get(UCLASS_TEST, &uc));
 203        ut_assert(uc);
 204
 205        ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
 206        ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]);
 207        ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
 208
 209        /* The root device should not be activated until needed */
 210        ut_assert(dms->root->flags & DM_FLAG_ACTIVATED);
 211
 212        /*
 213         * We should be able to find the three test devices, and they should
 214         * all be activated as they are used (lazy activation, required by
 215         * U-Boot)
 216         */
 217        for (i = 0; i < 3; i++) {
 218                ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
 219                ut_assert(dev);
 220                ut_assertf(!(dev->flags & DM_FLAG_ACTIVATED),
 221                           "Driver %d/%s already activated", i, dev->name);
 222
 223                /* This should activate it */
 224                ut_assertok(uclass_get_device(UCLASS_TEST, i, &dev));
 225                ut_assert(dev);
 226                ut_assert(dev->flags & DM_FLAG_ACTIVATED);
 227
 228                /* Activating a device should activate the root device */
 229                if (!i)
 230                        ut_assert(dms->root->flags & DM_FLAG_ACTIVATED);
 231        }
 232
 233        /*
 234         * Our 3 dm_test_info children should be passed to pre_probe and
 235         * post_probe
 236         */
 237        ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
 238        ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]);
 239
 240        /* Also we can check the per-device data */
 241        expected_base_add = 0;
 242        for (i = 0; i < 3; i++) {
 243                struct dm_test_uclass_perdev_priv *priv;
 244                struct dm_test_pdata *pdata;
 245
 246                ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
 247                ut_assert(dev);
 248
 249                priv = dev_get_uclass_priv(dev);
 250                ut_assert(priv);
 251                ut_asserteq(expected_base_add, priv->base_add);
 252
 253                pdata = dev->platdata;
 254                expected_base_add += pdata->ping_add;
 255        }
 256
 257        return 0;
 258}
 259DM_TEST(dm_test_autoprobe, DM_TESTF_SCAN_PDATA);
 260
 261/* Check that we see the correct platdata in each device */
 262static int dm_test_platdata(struct unit_test_state *uts)
 263{
 264        const struct dm_test_pdata *pdata;
 265        struct udevice *dev;
 266        int i;
 267
 268        for (i = 0; i < 3; i++) {
 269                ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
 270                ut_assert(dev);
 271                pdata = dev->platdata;
 272                ut_assert(pdata->ping_add == test_pdata[i].ping_add);
 273        }
 274
 275        return 0;
 276}
 277DM_TEST(dm_test_platdata, DM_TESTF_SCAN_PDATA);
 278
 279/* Test that we can bind, probe, remove, unbind a driver */
 280static int dm_test_lifecycle(struct unit_test_state *uts)
 281{
 282        struct dm_test_state *dms = uts->priv;
 283        int op_count[DM_TEST_OP_COUNT];
 284        struct udevice *dev, *test_dev;
 285        int pingret;
 286        int ret;
 287
 288        memcpy(op_count, dm_testdrv_op_count, sizeof(op_count));
 289
 290        ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
 291                                        &dev));
 292        ut_assert(dev);
 293        ut_assert(dm_testdrv_op_count[DM_TEST_OP_BIND]
 294                        == op_count[DM_TEST_OP_BIND] + 1);
 295        ut_assert(!dev->priv);
 296
 297        /* Probe the device - it should fail allocating private data */
 298        dms->force_fail_alloc = 1;
 299        ret = device_probe(dev);
 300        ut_assert(ret == -ENOMEM);
 301        ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE]
 302                        == op_count[DM_TEST_OP_PROBE] + 1);
 303        ut_assert(!dev->priv);
 304
 305        /* Try again without the alloc failure */
 306        dms->force_fail_alloc = 0;
 307        ut_assertok(device_probe(dev));
 308        ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE]
 309                        == op_count[DM_TEST_OP_PROBE] + 2);
 310        ut_assert(dev->priv);
 311
 312        /* This should be device 3 in the uclass */
 313        ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev));
 314        ut_assert(dev == test_dev);
 315
 316        /* Try ping */
 317        ut_assertok(test_ping(dev, 100, &pingret));
 318        ut_assert(pingret == 102);
 319
 320        /* Now remove device 3 */
 321        ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);
 322        ut_assertok(device_remove(dev));
 323        ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);
 324
 325        ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
 326        ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);
 327        ut_assertok(device_unbind(dev));
 328        ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
 329        ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);
 330
 331        return 0;
 332}
 333DM_TEST(dm_test_lifecycle, DM_TESTF_SCAN_PDATA | DM_TESTF_PROBE_TEST);
 334
 335/* Test that we can bind/unbind and the lists update correctly */
 336static int dm_test_ordering(struct unit_test_state *uts)
 337{
 338        struct dm_test_state *dms = uts->priv;
 339        struct udevice *dev, *dev_penultimate, *dev_last, *test_dev;
 340        int pingret;
 341
 342        ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
 343                                        &dev));
 344        ut_assert(dev);
 345
 346        /* Bind two new devices (numbers 4 and 5) */
 347        ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
 348                                        &dev_penultimate));
 349        ut_assert(dev_penultimate);
 350        ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
 351                                        &dev_last));
 352        ut_assert(dev_last);
 353
 354        /* Now remove device 3 */
 355        ut_assertok(device_remove(dev));
 356        ut_assertok(device_unbind(dev));
 357
 358        /* The device numbering should have shifted down one */
 359        ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev));
 360        ut_assert(dev_penultimate == test_dev);
 361        ut_assertok(uclass_find_device(UCLASS_TEST, 4, &test_dev));
 362        ut_assert(dev_last == test_dev);
 363
 364        /* Add back the original device 3, now in position 5 */
 365        ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
 366                                        &dev));
 367        ut_assert(dev);
 368
 369        /* Try ping */
 370        ut_assertok(test_ping(dev, 100, &pingret));
 371        ut_assert(pingret == 102);
 372
 373        /* Remove 3 and 4 */
 374        ut_assertok(device_remove(dev_penultimate));
 375        ut_assertok(device_unbind(dev_penultimate));
 376        ut_assertok(device_remove(dev_last));
 377        ut_assertok(device_unbind(dev_last));
 378
 379        /* Our device should now be in position 3 */
 380        ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev));
 381        ut_assert(dev == test_dev);
 382
 383        /* Now remove device 3 */
 384        ut_assertok(device_remove(dev));
 385        ut_assertok(device_unbind(dev));
 386
 387        return 0;
 388}
 389DM_TEST(dm_test_ordering, DM_TESTF_SCAN_PDATA);
 390
 391/* Check that we can perform operations on a device (do a ping) */
 392int dm_check_operations(struct unit_test_state *uts, struct udevice *dev,
 393                        uint32_t base, struct dm_test_priv *priv)
 394{
 395        int expected;
 396        int pingret;
 397
 398        /* Getting the child device should allocate platdata / priv */
 399        ut_assertok(testfdt_ping(dev, 10, &pingret));
 400        ut_assert(dev->priv);
 401        ut_assert(dev->platdata);
 402
 403        expected = 10 + base;
 404        ut_asserteq(expected, pingret);
 405
 406        /* Do another ping */
 407        ut_assertok(testfdt_ping(dev, 20, &pingret));
 408        expected = 20 + base;
 409        ut_asserteq(expected, pingret);
 410
 411        /* Now check the ping_total */
 412        priv = dev->priv;
 413        ut_asserteq(DM_TEST_START_TOTAL + 10 + 20 + base * 2,
 414                    priv->ping_total);
 415
 416        return 0;
 417}
 418
 419/* Check that we can perform operations on devices */
 420static int dm_test_operations(struct unit_test_state *uts)
 421{
 422        struct udevice *dev;
 423        int i;
 424
 425        /*
 426         * Now check that the ping adds are what we expect. This is using the
 427         * ping-add property in each node.
 428         */
 429        for (i = 0; i < ARRAY_SIZE(test_pdata); i++) {
 430                uint32_t base;
 431
 432                ut_assertok(uclass_get_device(UCLASS_TEST, i, &dev));
 433
 434                /*
 435                 * Get the 'reg' property, which tells us what the ping add
 436                 * should be. We don't use the platdata because we want
 437                 * to test the code that sets that up (testfdt_drv_probe()).
 438                 */
 439                base = test_pdata[i].ping_add;
 440                debug("dev=%d, base=%d\n", i, base);
 441
 442                ut_assert(!dm_check_operations(uts, dev, base, dev->priv));
 443        }
 444
 445        return 0;
 446}
 447DM_TEST(dm_test_operations, DM_TESTF_SCAN_PDATA);
 448
 449/* Remove all drivers and check that things work */
 450static int dm_test_remove(struct unit_test_state *uts)
 451{
 452        struct udevice *dev;
 453        int i;
 454
 455        for (i = 0; i < 3; i++) {
 456                ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
 457                ut_assert(dev);
 458                ut_assertf(dev->flags & DM_FLAG_ACTIVATED,
 459                           "Driver %d/%s not activated", i, dev->name);
 460                ut_assertok(device_remove(dev));
 461                ut_assertf(!(dev->flags & DM_FLAG_ACTIVATED),
 462                           "Driver %d/%s should have deactivated", i,
 463                           dev->name);
 464                ut_assert(!dev->priv);
 465        }
 466
 467        return 0;
 468}
 469DM_TEST(dm_test_remove, DM_TESTF_SCAN_PDATA | DM_TESTF_PROBE_TEST);
 470
 471/* Remove and recreate everything, check for memory leaks */
 472static int dm_test_leak(struct unit_test_state *uts)
 473{
 474        int i;
 475
 476        for (i = 0; i < 2; i++) {
 477                struct udevice *dev;
 478                int ret;
 479                int id;
 480
 481                dm_leak_check_start(uts);
 482
 483                ut_assertok(dm_scan_platdata(false));
 484                ut_assertok(dm_scan_fdt(gd->fdt_blob, false));
 485
 486                /* Scanning the uclass is enough to probe all the devices */
 487                for (id = UCLASS_ROOT; id < UCLASS_COUNT; id++) {
 488                        for (ret = uclass_first_device(UCLASS_TEST, &dev);
 489                             dev;
 490                             ret = uclass_next_device(&dev))
 491                                ;
 492                        ut_assertok(ret);
 493                }
 494
 495                ut_assertok(dm_leak_check_end(uts));
 496        }
 497
 498        return 0;
 499}
 500DM_TEST(dm_test_leak, 0);
 501
 502/* Test uclass init/destroy methods */
 503static int dm_test_uclass(struct unit_test_state *uts)
 504{
 505        struct uclass *uc;
 506
 507        ut_assertok(uclass_get(UCLASS_TEST, &uc));
 508        ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
 509        ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
 510        ut_assert(uc->priv);
 511
 512        ut_assertok(uclass_destroy(uc));
 513        ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
 514        ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
 515
 516        return 0;
 517}
 518DM_TEST(dm_test_uclass, 0);
 519
 520/**
 521 * create_children() - Create children of a parent node
 522 *
 523 * @dms:        Test system state
 524 * @parent:     Parent device
 525 * @count:      Number of children to create
 526 * @key:        Key value to put in first child. Subsequence children
 527 *              receive an incrementing value
 528 * @child:      If not NULL, then the child device pointers are written into
 529 *              this array.
 530 * @return 0 if OK, -ve on error
 531 */
 532static int create_children(struct unit_test_state *uts, struct udevice *parent,
 533                           int count, int key, struct udevice *child[])
 534{
 535        struct udevice *dev;
 536        int i;
 537
 538        for (i = 0; i < count; i++) {
 539                struct dm_test_pdata *pdata;
 540
 541                ut_assertok(device_bind_by_name(parent, false,
 542                                                &driver_info_manual, &dev));
 543                pdata = calloc(1, sizeof(*pdata));
 544                pdata->ping_add = key + i;
 545                dev->platdata = pdata;
 546                if (child)
 547                        child[i] = dev;
 548        }
 549
 550        return 0;
 551}
 552
 553#define NODE_COUNT      10
 554
 555static int dm_test_children(struct unit_test_state *uts)
 556{
 557        struct dm_test_state *dms = uts->priv;
 558        struct udevice *top[NODE_COUNT];
 559        struct udevice *child[NODE_COUNT];
 560        struct udevice *grandchild[NODE_COUNT];
 561        struct udevice *dev;
 562        int total;
 563        int ret;
 564        int i;
 565
 566        /* We don't care about the numbering for this test */
 567        dms->skip_post_probe = 1;
 568
 569        ut_assert(NODE_COUNT > 5);
 570
 571        /* First create 10 top-level children */
 572        ut_assertok(create_children(uts, dms->root, NODE_COUNT, 0, top));
 573
 574        /* Now a few have their own children */
 575        ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL));
 576        ut_assertok(create_children(uts, top[5], NODE_COUNT, 5, child));
 577
 578        /* And grandchildren */
 579        for (i = 0; i < NODE_COUNT; i++)
 580                ut_assertok(create_children(uts, child[i], NODE_COUNT, 50 * i,
 581                                            i == 2 ? grandchild : NULL));
 582
 583        /* Check total number of devices */
 584        total = NODE_COUNT * (3 + NODE_COUNT);
 585        ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_BIND]);
 586
 587        /* Try probing one of the grandchildren */
 588        ut_assertok(uclass_get_device(UCLASS_TEST,
 589                                      NODE_COUNT * 3 + 2 * NODE_COUNT, &dev));
 590        ut_asserteq_ptr(grandchild[0], dev);
 591
 592        /*
 593         * This should have probed the child and top node also, for a total
 594         * of 3 nodes.
 595         */
 596        ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
 597
 598        /* Probe the other grandchildren */
 599        for (i = 1; i < NODE_COUNT; i++)
 600                ut_assertok(device_probe(grandchild[i]));
 601
 602        ut_asserteq(2 + NODE_COUNT, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
 603
 604        /* Probe everything */
 605        for (ret = uclass_first_device(UCLASS_TEST, &dev);
 606             dev;
 607             ret = uclass_next_device(&dev))
 608                ;
 609        ut_assertok(ret);
 610
 611        ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
 612
 613        /* Remove a top-level child and check that the children are removed */
 614        ut_assertok(device_remove(top[2]));
 615        ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_REMOVE]);
 616        dm_testdrv_op_count[DM_TEST_OP_REMOVE] = 0;
 617
 618        /* Try one with grandchildren */
 619        ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev));
 620        ut_asserteq_ptr(dev, top[5]);
 621        ut_assertok(device_remove(dev));
 622        ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT),
 623                    dm_testdrv_op_count[DM_TEST_OP_REMOVE]);
 624
 625        /* Try the same with unbind */
 626        ut_assertok(device_unbind(top[2]));
 627        ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
 628        dm_testdrv_op_count[DM_TEST_OP_UNBIND] = 0;
 629
 630        /* Try one with grandchildren */
 631        ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev));
 632        ut_asserteq_ptr(dev, top[6]);
 633        ut_assertok(device_unbind(top[5]));
 634        ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT),
 635                    dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
 636
 637        return 0;
 638}
 639DM_TEST(dm_test_children, 0);
 640
 641/* Test that pre-relocation devices work as expected */
 642static int dm_test_pre_reloc(struct unit_test_state *uts)
 643{
 644        struct dm_test_state *dms = uts->priv;
 645        struct udevice *dev;
 646
 647        /* The normal driver should refuse to bind before relocation */
 648        ut_asserteq(-EPERM, device_bind_by_name(dms->root, true,
 649                                                &driver_info_manual, &dev));
 650
 651        /* But this one is marked pre-reloc */
 652        ut_assertok(device_bind_by_name(dms->root, true,
 653                                        &driver_info_pre_reloc, &dev));
 654
 655        return 0;
 656}
 657DM_TEST(dm_test_pre_reloc, 0);
 658
 659static int dm_test_uclass_before_ready(struct unit_test_state *uts)
 660{
 661        struct uclass *uc;
 662
 663        ut_assertok(uclass_get(UCLASS_TEST, &uc));
 664
 665        gd->dm_root = NULL;
 666        gd->dm_root_f = NULL;
 667        memset(&gd->uclass_root, '\0', sizeof(gd->uclass_root));
 668
 669        ut_asserteq_ptr(NULL, uclass_find(UCLASS_TEST));
 670
 671        return 0;
 672}
 673DM_TEST(dm_test_uclass_before_ready, 0);
 674
 675static int dm_test_uclass_devices_find(struct unit_test_state *uts)
 676{
 677        struct udevice *dev;
 678        int ret;
 679
 680        for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
 681             dev;
 682             ret = uclass_find_next_device(&dev)) {
 683                ut_assert(!ret);
 684                ut_assert(dev);
 685        }
 686
 687        return 0;
 688}
 689DM_TEST(dm_test_uclass_devices_find, DM_TESTF_SCAN_PDATA);
 690
 691static int dm_test_uclass_devices_find_by_name(struct unit_test_state *uts)
 692{
 693        struct udevice *finddev;
 694        struct udevice *testdev;
 695        int findret, ret;
 696
 697        /*
 698         * For each test device found in fdt like: "a-test", "b-test", etc.,
 699         * use its name and try to find it by uclass_find_device_by_name().
 700         * Then, on success check if:
 701         * - current 'testdev' name is equal to the returned 'finddev' name
 702         * - current 'testdev' pointer is equal to the returned 'finddev'
 703         *
 704         * We assume that, each uclass's device name is unique, so if not, then
 705         * this will fail on checking condition: testdev == finddev, since the
 706         * uclass_find_device_by_name(), returns the first device by given name.
 707        */
 708        for (ret = uclass_find_first_device(UCLASS_TEST_FDT, &testdev);
 709             testdev;
 710             ret = uclass_find_next_device(&testdev)) {
 711                ut_assertok(ret);
 712                ut_assert(testdev);
 713
 714                findret = uclass_find_device_by_name(UCLASS_TEST_FDT,
 715                                                     testdev->name,
 716                                                     &finddev);
 717
 718                ut_assertok(findret);
 719                ut_assert(testdev);
 720                ut_asserteq_str(testdev->name, finddev->name);
 721                ut_asserteq_ptr(testdev, finddev);
 722        }
 723
 724        return 0;
 725}
 726DM_TEST(dm_test_uclass_devices_find_by_name, DM_TESTF_SCAN_FDT);
 727
 728static int dm_test_uclass_devices_get(struct unit_test_state *uts)
 729{
 730        struct udevice *dev;
 731        int ret;
 732
 733        for (ret = uclass_first_device(UCLASS_TEST, &dev);
 734             dev;
 735             ret = uclass_next_device(&dev)) {
 736                ut_assert(!ret);
 737                ut_assert(dev);
 738                ut_assert(device_active(dev));
 739        }
 740
 741        return 0;
 742}
 743DM_TEST(dm_test_uclass_devices_get, DM_TESTF_SCAN_PDATA);
 744
 745static int dm_test_uclass_devices_get_by_name(struct unit_test_state *uts)
 746{
 747        struct udevice *finddev;
 748        struct udevice *testdev;
 749        int ret, findret;
 750
 751        /*
 752         * For each test device found in fdt like: "a-test", "b-test", etc.,
 753         * use its name and try to get it by uclass_get_device_by_name().
 754         * On success check if:
 755         * - returned finddev' is active
 756         * - current 'testdev' name is equal to the returned 'finddev' name
 757         * - current 'testdev' pointer is equal to the returned 'finddev'
 758         *
 759         * We asserts that the 'testdev' is active on each loop entry, so we
 760         * could be sure that the 'finddev' is activated too, but for sure
 761         * we check it again.
 762         *
 763         * We assume that, each uclass's device name is unique, so if not, then
 764         * this will fail on checking condition: testdev == finddev, since the
 765         * uclass_get_device_by_name(), returns the first device by given name.
 766        */
 767        for (ret = uclass_first_device(UCLASS_TEST_FDT, &testdev);
 768             testdev;
 769             ret = uclass_next_device(&testdev)) {
 770                ut_assertok(ret);
 771                ut_assert(testdev);
 772                ut_assert(device_active(testdev));
 773
 774                findret = uclass_get_device_by_name(UCLASS_TEST_FDT,
 775                                                    testdev->name,
 776                                                    &finddev);
 777
 778                ut_assertok(findret);
 779                ut_assert(finddev);
 780                ut_assert(device_active(finddev));
 781                ut_asserteq_str(testdev->name, finddev->name);
 782                ut_asserteq_ptr(testdev, finddev);
 783        }
 784
 785        return 0;
 786}
 787DM_TEST(dm_test_uclass_devices_get_by_name, DM_TESTF_SCAN_FDT);
 788
 789static int dm_test_device_get_uclass_id(struct unit_test_state *uts)
 790{
 791        struct udevice *dev;
 792
 793        ut_assertok(uclass_get_device(UCLASS_TEST, 0, &dev));
 794        ut_asserteq(UCLASS_TEST, device_get_uclass_id(dev));
 795
 796        return 0;
 797}
 798DM_TEST(dm_test_device_get_uclass_id, DM_TESTF_SCAN_PDATA);
 799