1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2014 Google, Inc 4 */ 5 6 #include <common.h> 7 #ifdef CONFIG_SANDBOX 8 #include <os.h> 9 #endif 10 #include <dm.h> 11 #include <dm/device-internal.h> 12 #include <dm/test.h> 13 #include <dm/uclass-internal.h> 14 #include <dm/util.h> 15 #include <test/ut.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 struct dm_test_parent_platdata { 20 int count; 21 int bind_flag; 22 int uclass_bind_flag; 23 }; 24 25 enum { 26 FLAG_CHILD_PROBED = 10, 27 FLAG_CHILD_REMOVED = -7, 28 }; 29 30 static struct dm_test_state *test_state; 31 32 static int testbus_drv_probe(struct udevice *dev) 33 { 34 return dm_scan_fdt_dev(dev); 35 } 36 37 static int testbus_child_post_bind(struct udevice *dev) 38 { 39 struct dm_test_parent_platdata *plat; 40 41 plat = dev_get_parent_platdata(dev); 42 plat->bind_flag = 1; 43 plat->uclass_bind_flag = 2; 44 45 return 0; 46 } 47 48 static int testbus_child_pre_probe(struct udevice *dev) 49 { 50 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev); 51 52 parent_data->flag += FLAG_CHILD_PROBED; 53 54 return 0; 55 } 56 57 static int testbus_child_pre_probe_uclass(struct udevice *dev) 58 { 59 struct dm_test_priv *priv = dev_get_priv(dev); 60 61 priv->uclass_flag++; 62 63 return 0; 64 } 65 66 static int testbus_child_post_probe_uclass(struct udevice *dev) 67 { 68 struct dm_test_priv *priv = dev_get_priv(dev); 69 70 priv->uclass_postp++; 71 72 return 0; 73 } 74 75 static int testbus_child_post_remove(struct udevice *dev) 76 { 77 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev); 78 struct dm_test_state *dms = test_state; 79 80 parent_data->flag += FLAG_CHILD_REMOVED; 81 if (dms) 82 dms->removed = dev; 83 84 return 0; 85 } 86 87 static const struct udevice_id testbus_ids[] = { 88 { 89 .compatible = "denx,u-boot-test-bus", 90 .data = DM_TEST_TYPE_FIRST }, 91 { } 92 }; 93 94 U_BOOT_DRIVER(testbus_drv) = { 95 .name = "testbus_drv", 96 .of_match = testbus_ids, 97 .id = UCLASS_TEST_BUS, 98 .probe = testbus_drv_probe, 99 .child_post_bind = testbus_child_post_bind, 100 .priv_auto_alloc_size = sizeof(struct dm_test_priv), 101 .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), 102 .per_child_auto_alloc_size = sizeof(struct dm_test_parent_data), 103 .per_child_platdata_auto_alloc_size = 104 sizeof(struct dm_test_parent_platdata), 105 .child_pre_probe = testbus_child_pre_probe, 106 .child_post_remove = testbus_child_post_remove, 107 }; 108 109 UCLASS_DRIVER(testbus) = { 110 .name = "testbus", 111 .id = UCLASS_TEST_BUS, 112 .flags = DM_UC_FLAG_SEQ_ALIAS, 113 .child_pre_probe = testbus_child_pre_probe_uclass, 114 .child_post_probe = testbus_child_post_probe_uclass, 115 }; 116 117 /* Test that we can probe for children */ 118 static int dm_test_bus_children(struct unit_test_state *uts) 119 { 120 int num_devices = 8; 121 struct udevice *bus; 122 struct uclass *uc; 123 124 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc)); 125 ut_asserteq(num_devices, list_count_items(&uc->dev_head)); 126 127 /* Probe the bus, which should yield 3 more devices */ 128 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); 129 num_devices += 3; 130 131 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc)); 132 ut_asserteq(num_devices, list_count_items(&uc->dev_head)); 133 134 ut_assert(!dm_check_devices(uts, num_devices)); 135 136 return 0; 137 } 138 DM_TEST(dm_test_bus_children, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 139 140 /* Test our functions for accessing children */ 141 static int dm_test_bus_children_funcs(struct unit_test_state *uts) 142 { 143 const void *blob = gd->fdt_blob; 144 struct udevice *bus, *dev; 145 int node; 146 147 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); 148 149 /* device_get_child() */ 150 ut_assertok(device_get_child(bus, 0, &dev)); 151 ut_asserteq(-ENODEV, device_get_child(bus, 4, &dev)); 152 ut_assertok(device_get_child_by_seq(bus, 5, &dev)); 153 ut_assert(dev->flags & DM_FLAG_ACTIVATED); 154 ut_asserteq_str("c-test@5", dev->name); 155 156 /* Device with sequence number 0 should be accessible */ 157 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, true, &dev)); 158 ut_assertok(device_find_child_by_seq(bus, 0, true, &dev)); 159 ut_assert(!(dev->flags & DM_FLAG_ACTIVATED)); 160 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 0, false, &dev)); 161 ut_assertok(device_get_child_by_seq(bus, 0, &dev)); 162 ut_assert(dev->flags & DM_FLAG_ACTIVATED); 163 164 /* There is no device with sequence number 2 */ 165 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, false, &dev)); 166 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, true, &dev)); 167 ut_asserteq(-ENODEV, device_get_child_by_seq(bus, 2, &dev)); 168 169 /* Looking for something that is not a child */ 170 node = fdt_path_offset(blob, "/junk"); 171 ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev)); 172 node = fdt_path_offset(blob, "/d-test"); 173 ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev)); 174 175 return 0; 176 } 177 DM_TEST(dm_test_bus_children_funcs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 178 179 static int dm_test_bus_children_of_offset(struct unit_test_state *uts) 180 { 181 const void *blob = gd->fdt_blob; 182 struct udevice *bus, *dev; 183 int node; 184 185 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); 186 ut_assertnonnull(bus); 187 188 /* Find a valid child */ 189 node = fdt_path_offset(blob, "/some-bus/c-test@1"); 190 ut_assert(node > 0); 191 ut_assertok(device_find_child_by_of_offset(bus, node, &dev)); 192 ut_assertnonnull(dev); 193 ut_assert(!(dev->flags & DM_FLAG_ACTIVATED)); 194 ut_assertok(device_get_child_by_of_offset(bus, node, &dev)); 195 ut_assertnonnull(dev); 196 ut_assert(dev->flags & DM_FLAG_ACTIVATED); 197 198 return 0; 199 } 200 DM_TEST(dm_test_bus_children_of_offset, 201 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE); 202 203 /* Test that we can iterate through children */ 204 static int dm_test_bus_children_iterators(struct unit_test_state *uts) 205 { 206 struct udevice *bus, *dev, *child; 207 208 /* Walk through the children one by one */ 209 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); 210 ut_assertok(device_find_first_child(bus, &dev)); 211 ut_asserteq_str("c-test@5", dev->name); 212 ut_assertok(device_find_next_child(&dev)); 213 ut_asserteq_str("c-test@0", dev->name); 214 ut_assertok(device_find_next_child(&dev)); 215 ut_asserteq_str("c-test@1", dev->name); 216 ut_assertok(device_find_next_child(&dev)); 217 ut_asserteq_ptr(dev, NULL); 218 219 /* Move to the next child without using device_find_first_child() */ 220 ut_assertok(device_find_child_by_seq(bus, 5, true, &dev)); 221 ut_asserteq_str("c-test@5", dev->name); 222 ut_assertok(device_find_next_child(&dev)); 223 ut_asserteq_str("c-test@0", dev->name); 224 225 /* Try a device with no children */ 226 ut_assertok(device_find_first_child(dev, &child)); 227 ut_asserteq_ptr(child, NULL); 228 229 return 0; 230 } 231 DM_TEST(dm_test_bus_children_iterators, 232 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 233 234 /* Test that the bus can store data about each child */ 235 static int test_bus_parent_data(struct unit_test_state *uts) 236 { 237 struct dm_test_parent_data *parent_data; 238 struct udevice *bus, *dev; 239 struct uclass *uc; 240 int value; 241 242 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); 243 244 /* Check that parent data is allocated */ 245 ut_assertok(device_find_child_by_seq(bus, 0, true, &dev)); 246 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); 247 ut_assertok(device_get_child_by_seq(bus, 0, &dev)); 248 parent_data = dev_get_parent_priv(dev); 249 ut_assert(NULL != parent_data); 250 251 /* Check that it starts at 0 and goes away when device is removed */ 252 parent_data->sum += 5; 253 ut_asserteq(5, parent_data->sum); 254 device_remove(dev, DM_REMOVE_NORMAL); 255 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); 256 257 /* Check that we can do this twice */ 258 ut_assertok(device_get_child_by_seq(bus, 0, &dev)); 259 parent_data = dev_get_parent_priv(dev); 260 ut_assert(NULL != parent_data); 261 parent_data->sum += 5; 262 ut_asserteq(5, parent_data->sum); 263 264 /* Add parent data to all children */ 265 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc)); 266 value = 5; 267 uclass_foreach_dev(dev, uc) { 268 /* Ignore these if they are not on this bus */ 269 if (dev->parent != bus) { 270 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); 271 continue; 272 } 273 ut_assertok(device_probe(dev)); 274 parent_data = dev_get_parent_priv(dev); 275 276 parent_data->sum = value; 277 value += 5; 278 } 279 280 /* Check it is still there */ 281 value = 5; 282 uclass_foreach_dev(dev, uc) { 283 /* Ignore these if they are not on this bus */ 284 if (dev->parent != bus) 285 continue; 286 parent_data = dev_get_parent_priv(dev); 287 288 ut_asserteq(value, parent_data->sum); 289 value += 5; 290 } 291 292 return 0; 293 } 294 /* Test that the bus can store data about each child */ 295 static int dm_test_bus_parent_data(struct unit_test_state *uts) 296 { 297 return test_bus_parent_data(uts); 298 } 299 DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 300 301 /* As above but the size is controlled by the uclass */ 302 static int dm_test_bus_parent_data_uclass(struct unit_test_state *uts) 303 { 304 struct driver *drv; 305 struct udevice *bus; 306 int size; 307 int ret; 308 309 /* Set the driver size to 0 so that the uclass size is used */ 310 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); 311 drv = (struct driver *)bus->driver; 312 size = drv->per_child_auto_alloc_size; 313 314 #ifdef CONFIG_SANDBOX 315 os_mprotect_allow(bus->uclass->uc_drv, sizeof(*bus->uclass->uc_drv)); 316 os_mprotect_allow(drv, sizeof(*drv)); 317 #endif 318 bus->uclass->uc_drv->per_child_auto_alloc_size = size; 319 drv->per_child_auto_alloc_size = 0; 320 ret = test_bus_parent_data(uts); 321 if (ret) 322 return ret; 323 bus->uclass->uc_drv->per_child_auto_alloc_size = 0; 324 drv->per_child_auto_alloc_size = size; 325 326 return 0; 327 } 328 DM_TEST(dm_test_bus_parent_data_uclass, 329 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 330 331 /* Test that the bus ops are called when a child is probed/removed */ 332 static int dm_test_bus_parent_ops(struct unit_test_state *uts) 333 { 334 struct dm_test_parent_data *parent_data; 335 struct dm_test_state *dms = uts->priv; 336 struct udevice *bus, *dev; 337 struct uclass *uc; 338 339 test_state = dms; 340 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); 341 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc)); 342 343 uclass_foreach_dev(dev, uc) { 344 /* Ignore these if they are not on this bus */ 345 if (dev->parent != bus) 346 continue; 347 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); 348 349 ut_assertok(device_probe(dev)); 350 parent_data = dev_get_parent_priv(dev); 351 ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag); 352 } 353 354 uclass_foreach_dev(dev, uc) { 355 /* Ignore these if they are not on this bus */ 356 if (dev->parent != bus) 357 continue; 358 parent_data = dev_get_parent_priv(dev); 359 ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag); 360 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL)); 361 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); 362 ut_asserteq_ptr(dms->removed, dev); 363 } 364 test_state = NULL; 365 366 return 0; 367 } 368 DM_TEST(dm_test_bus_parent_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 369 370 static int test_bus_parent_platdata(struct unit_test_state *uts) 371 { 372 struct dm_test_parent_platdata *plat; 373 struct udevice *bus, *dev; 374 int child_count; 375 376 /* Check that the bus has no children */ 377 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); 378 device_find_first_child(bus, &dev); 379 ut_asserteq_ptr(NULL, dev); 380 381 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); 382 383 for (device_find_first_child(bus, &dev), child_count = 0; 384 dev; 385 device_find_next_child(&dev)) { 386 /* Check that platform data is allocated */ 387 plat = dev_get_parent_platdata(dev); 388 ut_assert(plat != NULL); 389 390 /* 391 * Check that it is not affected by the device being 392 * probed/removed 393 */ 394 plat->count++; 395 ut_asserteq(1, plat->count); 396 device_probe(dev); 397 device_remove(dev, DM_REMOVE_NORMAL); 398 399 ut_asserteq_ptr(plat, dev_get_parent_platdata(dev)); 400 ut_asserteq(1, plat->count); 401 ut_assertok(device_probe(dev)); 402 child_count++; 403 } 404 ut_asserteq(3, child_count); 405 406 /* Removing the bus should also have no effect (it is still bound) */ 407 device_remove(bus, DM_REMOVE_NORMAL); 408 for (device_find_first_child(bus, &dev), child_count = 0; 409 dev; 410 device_find_next_child(&dev)) { 411 /* Check that platform data is allocated */ 412 plat = dev_get_parent_platdata(dev); 413 ut_assert(plat != NULL); 414 ut_asserteq(1, plat->count); 415 child_count++; 416 } 417 ut_asserteq(3, child_count); 418 419 /* Unbind all the children */ 420 do { 421 device_find_first_child(bus, &dev); 422 if (dev) 423 device_unbind(dev); 424 } while (dev); 425 426 /* Now the child platdata should be removed and re-added */ 427 device_probe(bus); 428 for (device_find_first_child(bus, &dev), child_count = 0; 429 dev; 430 device_find_next_child(&dev)) { 431 /* Check that platform data is allocated */ 432 plat = dev_get_parent_platdata(dev); 433 ut_assert(plat != NULL); 434 ut_asserteq(0, plat->count); 435 child_count++; 436 } 437 ut_asserteq(3, child_count); 438 439 return 0; 440 } 441 442 /* Test that the bus can store platform data about each child */ 443 static int dm_test_bus_parent_platdata(struct unit_test_state *uts) 444 { 445 return test_bus_parent_platdata(uts); 446 } 447 DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 448 449 /* As above but the size is controlled by the uclass */ 450 static int dm_test_bus_parent_platdata_uclass(struct unit_test_state *uts) 451 { 452 struct udevice *bus; 453 struct driver *drv; 454 int size; 455 int ret; 456 457 /* Set the driver size to 0 so that the uclass size is used */ 458 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); 459 drv = (struct driver *)bus->driver; 460 size = drv->per_child_platdata_auto_alloc_size; 461 #ifdef CONFIG_SANDBOX 462 os_mprotect_allow(bus->uclass->uc_drv, sizeof(*bus->uclass->uc_drv)); 463 os_mprotect_allow(drv, sizeof(*drv)); 464 #endif 465 bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size; 466 drv->per_child_platdata_auto_alloc_size = 0; 467 ret = test_bus_parent_platdata(uts); 468 if (ret) 469 return ret; 470 bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0; 471 drv->per_child_platdata_auto_alloc_size = size; 472 473 return 0; 474 } 475 DM_TEST(dm_test_bus_parent_platdata_uclass, 476 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 477 478 /* Test that the child post_bind method is called */ 479 static int dm_test_bus_child_post_bind(struct unit_test_state *uts) 480 { 481 struct dm_test_parent_platdata *plat; 482 struct udevice *bus, *dev; 483 int child_count; 484 485 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); 486 for (device_find_first_child(bus, &dev), child_count = 0; 487 dev; 488 device_find_next_child(&dev)) { 489 /* Check that platform data is allocated */ 490 plat = dev_get_parent_platdata(dev); 491 ut_assert(plat != NULL); 492 ut_asserteq(1, plat->bind_flag); 493 child_count++; 494 } 495 ut_asserteq(3, child_count); 496 497 return 0; 498 } 499 DM_TEST(dm_test_bus_child_post_bind, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 500 501 /* Test that the child post_bind method is called */ 502 static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts) 503 { 504 struct dm_test_parent_platdata *plat; 505 struct udevice *bus, *dev; 506 int child_count; 507 508 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); 509 for (device_find_first_child(bus, &dev), child_count = 0; 510 dev; 511 device_find_next_child(&dev)) { 512 /* Check that platform data is allocated */ 513 plat = dev_get_parent_platdata(dev); 514 ut_assert(plat != NULL); 515 ut_asserteq(2, plat->uclass_bind_flag); 516 child_count++; 517 } 518 ut_asserteq(3, child_count); 519 520 return 0; 521 } 522 DM_TEST(dm_test_bus_child_post_bind_uclass, 523 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 524 525 /* 526 * Test that the bus' uclass' child_pre_probe() is called before the 527 * device's probe() method 528 */ 529 static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts) 530 { 531 struct udevice *bus, *dev; 532 int child_count; 533 534 /* 535 * See testfdt_drv_probe() which effectively checks that the uclass 536 * flag is set before that method is called 537 */ 538 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); 539 for (device_find_first_child(bus, &dev), child_count = 0; 540 dev; 541 device_find_next_child(&dev)) { 542 struct dm_test_priv *priv = dev_get_priv(dev); 543 544 /* Check that things happened in the right order */ 545 ut_asserteq_ptr(NULL, priv); 546 ut_assertok(device_probe(dev)); 547 548 priv = dev_get_priv(dev); 549 ut_assert(priv != NULL); 550 ut_asserteq(1, priv->uclass_flag); 551 ut_asserteq(1, priv->uclass_total); 552 child_count++; 553 } 554 ut_asserteq(3, child_count); 555 556 return 0; 557 } 558 DM_TEST(dm_test_bus_child_pre_probe_uclass, 559 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 560 561 /* 562 * Test that the bus' uclass' child_post_probe() is called after the 563 * device's probe() method 564 */ 565 static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts) 566 { 567 struct udevice *bus, *dev; 568 int child_count; 569 570 /* 571 * See testfdt_drv_probe() which effectively initializes that 572 * the uclass postp flag is set to a value 573 */ 574 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); 575 for (device_find_first_child(bus, &dev), child_count = 0; 576 dev; 577 device_find_next_child(&dev)) { 578 struct dm_test_priv *priv = dev_get_priv(dev); 579 580 /* Check that things happened in the right order */ 581 ut_asserteq_ptr(NULL, priv); 582 ut_assertok(device_probe(dev)); 583 584 priv = dev_get_priv(dev); 585 ut_assert(priv != NULL); 586 ut_asserteq(0, priv->uclass_postp); 587 child_count++; 588 } 589 ut_asserteq(3, child_count); 590 591 return 0; 592 } 593 DM_TEST(dm_test_bus_child_post_probe_uclass, 594 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 595