1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2013 Google, Inc
14 #include <dm/device-internal.h>
15 #include <dm/uclass-internal.h>
18 #include <dm/of_access.h>
21 DECLARE_GLOBAL_DATA_PTR;
23 static int testfdt_drv_ping(struct udevice *dev, int pingval, int *pingret)
25 const struct dm_test_pdata *pdata = dev->platdata;
26 struct dm_test_priv *priv = dev_get_priv(dev);
28 *pingret = pingval + pdata->ping_add;
29 priv->ping_total += *pingret;
34 static const struct test_ops test_ops = {
35 .ping = testfdt_drv_ping,
38 static int testfdt_ofdata_to_platdata(struct udevice *dev)
40 struct dm_test_pdata *pdata = dev_get_platdata(dev);
42 pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
44 pdata->base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev),
50 static int testfdt_drv_probe(struct udevice *dev)
52 struct dm_test_priv *priv = dev_get_priv(dev);
54 priv->ping_total += DM_TEST_START_TOTAL;
57 * If this device is on a bus, the uclass_flag will be set before
58 * calling this function. This is used by
59 * dm_test_bus_child_pre_probe_uclass().
61 priv->uclass_total += priv->uclass_flag;
66 static const struct udevice_id testfdt_ids[] = {
68 .compatible = "denx,u-boot-fdt-test",
69 .data = DM_TEST_TYPE_FIRST },
71 .compatible = "google,another-fdt-test",
72 .data = DM_TEST_TYPE_SECOND },
76 U_BOOT_DRIVER(testfdt_drv) = {
77 .name = "testfdt_drv",
78 .of_match = testfdt_ids,
79 .id = UCLASS_TEST_FDT,
80 .ofdata_to_platdata = testfdt_ofdata_to_platdata,
81 .probe = testfdt_drv_probe,
83 .priv_auto_alloc_size = sizeof(struct dm_test_priv),
84 .platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
87 static const struct udevice_id testfdt1_ids[] = {
89 .compatible = "denx,u-boot-fdt-test1",
90 .data = DM_TEST_TYPE_FIRST },
94 U_BOOT_DRIVER(testfdt1_drv) = {
95 .name = "testfdt1_drv",
96 .of_match = testfdt1_ids,
97 .id = UCLASS_TEST_FDT,
98 .ofdata_to_platdata = testfdt_ofdata_to_platdata,
99 .probe = testfdt_drv_probe,
101 .priv_auto_alloc_size = sizeof(struct dm_test_priv),
102 .platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
103 .flags = DM_FLAG_PRE_RELOC,
106 /* From here is the testfdt uclass code */
107 int testfdt_ping(struct udevice *dev, int pingval, int *pingret)
109 const struct test_ops *ops = device_get_ops(dev);
114 return ops->ping(dev, pingval, pingret);
117 UCLASS_DRIVER(testfdt) = {
119 .id = UCLASS_TEST_FDT,
120 .flags = DM_UC_FLAG_SEQ_ALIAS,
123 struct dm_testprobe_pdata {
127 static int testprobe_drv_probe(struct udevice *dev)
129 struct dm_testprobe_pdata *pdata = dev_get_platdata(dev);
131 return pdata->probe_err;
134 static const struct udevice_id testprobe_ids[] = {
135 { .compatible = "denx,u-boot-probe-test" },
139 U_BOOT_DRIVER(testprobe_drv) = {
140 .name = "testprobe_drv",
141 .of_match = testprobe_ids,
142 .id = UCLASS_TEST_PROBE,
143 .probe = testprobe_drv_probe,
144 .platdata_auto_alloc_size = sizeof(struct dm_testprobe_pdata),
147 UCLASS_DRIVER(testprobe) = {
149 .id = UCLASS_TEST_PROBE,
150 .flags = DM_UC_FLAG_SEQ_ALIAS,
153 int dm_check_devices(struct unit_test_state *uts, int num_devices)
160 * Now check that the ping adds are what we expect. This is using the
161 * ping-add property in each node.
163 for (i = 0; i < num_devices; i++) {
166 ret = uclass_get_device(UCLASS_TEST_FDT, i, &dev);
170 * Get the 'ping-expect' property, which tells us what the
171 * ping add should be. We don't use the platdata because we
172 * want to test the code that sets that up
173 * (testfdt_drv_probe()).
175 base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev),
177 debug("dev=%d, base=%d: %s\n", i, base,
178 fdt_get_name(gd->fdt_blob, dev_of_offset(dev), NULL));
180 ut_assert(!dm_check_operations(uts, dev, base,
187 /* Test that FDT-based binding works correctly */
188 static int dm_test_fdt(struct unit_test_state *uts)
190 const int num_devices = 8;
196 ret = dm_scan_fdt(gd->fdt_blob, false);
199 ret = uclass_get(UCLASS_TEST_FDT, &uc);
202 /* These are num_devices compatible root-level device tree nodes */
203 ut_asserteq(num_devices, list_count_items(&uc->dev_head));
205 /* Each should have platform data but no private data */
206 for (i = 0; i < num_devices; i++) {
207 ret = uclass_find_device(UCLASS_TEST_FDT, i, &dev);
209 ut_assert(!dev_get_priv(dev));
210 ut_assert(dev->platdata);
213 ut_assertok(dm_check_devices(uts, num_devices));
217 DM_TEST(dm_test_fdt, 0);
219 static int dm_test_fdt_pre_reloc(struct unit_test_state *uts)
224 ret = dm_scan_fdt(gd->fdt_blob, true);
227 ret = uclass_get(UCLASS_TEST_FDT, &uc);
231 * These are 2 pre-reloc devices:
232 * one with "u-boot,dm-pre-reloc" property (a-test node), and the other
233 * one whose driver marked with DM_FLAG_PRE_RELOC flag (h-test node).
235 ut_asserteq(2, list_count_items(&uc->dev_head));
239 DM_TEST(dm_test_fdt_pre_reloc, 0);
241 /* Test that sequence numbers are allocated properly */
242 static int dm_test_fdt_uclass_seq(struct unit_test_state *uts)
246 /* A few basic santiy tests */
247 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 3, true, &dev));
248 ut_asserteq_str("b-test", dev->name);
250 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 8, true, &dev));
251 ut_asserteq_str("a-test", dev->name);
253 ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 5,
255 ut_asserteq_ptr(NULL, dev);
258 ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 6, &dev));
259 ut_asserteq_str("e-test", dev->name);
261 ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 7,
265 * Note that c-test nodes are not probed since it is not a top-level
268 ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 3, &dev));
269 ut_asserteq_str("b-test", dev->name);
272 * d-test wants sequence number 3 also, but it can't have it because
273 * b-test gets it first.
275 ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 2, &dev));
276 ut_asserteq_str("d-test", dev->name);
278 /* d-test actually gets 0 */
279 ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 0, &dev));
280 ut_asserteq_str("d-test", dev->name);
282 /* initially no one wants seq 1 */
283 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 1,
285 ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
286 ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 4, &dev));
288 /* But now that it is probed, we can find it */
289 ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, &dev));
290 ut_asserteq_str("f-test", dev->name);
294 DM_TEST(dm_test_fdt_uclass_seq, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
296 /* Test that we can find a device by device tree offset */
297 static int dm_test_fdt_offset(struct unit_test_state *uts)
299 const void *blob = gd->fdt_blob;
303 node = fdt_path_offset(blob, "/e-test");
305 ut_assertok(uclass_get_device_by_of_offset(UCLASS_TEST_FDT, node,
307 ut_asserteq_str("e-test", dev->name);
309 /* This node should not be bound */
310 node = fdt_path_offset(blob, "/junk");
312 ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT,
315 /* This is not a top level node so should not be probed */
316 node = fdt_path_offset(blob, "/some-bus/c-test@5");
318 ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT,
323 DM_TEST(dm_test_fdt_offset,
324 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
327 * Test various error conditions with uclass_first_device() and
328 * uclass_next_device()
330 static int dm_test_first_next_device(struct unit_test_state *uts)
332 struct dm_testprobe_pdata *pdata;
333 struct udevice *dev, *parent = NULL;
337 /* There should be 4 devices */
338 for (ret = uclass_first_device(UCLASS_TEST_PROBE, &dev), count = 0;
340 ret = uclass_next_device(&dev)) {
342 parent = dev_get_parent(dev);
345 ut_asserteq(4, count);
347 /* Remove them and try again, with an error on the second one */
348 ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 1, &dev));
349 pdata = dev_get_platdata(dev);
350 pdata->probe_err = -ENOMEM;
351 device_remove(parent, DM_REMOVE_NORMAL);
352 ut_assertok(uclass_first_device(UCLASS_TEST_PROBE, &dev));
353 ut_asserteq(-ENOMEM, uclass_next_device(&dev));
354 ut_asserteq_ptr(dev, NULL);
356 /* Now an error on the first one */
357 ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 0, &dev));
358 pdata = dev_get_platdata(dev);
359 pdata->probe_err = -ENOENT;
360 device_remove(parent, DM_REMOVE_NORMAL);
361 ut_asserteq(-ENOENT, uclass_first_device(UCLASS_TEST_PROBE, &dev));
365 DM_TEST(dm_test_first_next_device, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
368 * check_devices() - Check return values and pointers
370 * This runs through a full sequence of uclass_first_device_check()...
371 * uclass_next_device_check() checking that the return values and devices
375 * @devlist: List of expected devices
376 * @mask: Indicates which devices should return an error. Device n should
377 * return error (-NOENT - n) if bit n is set, or no error (i.e. 0) if
380 static int check_devices(struct unit_test_state *uts,
381 struct udevice *devlist[], int mask)
387 expected_ret = (mask & 1) ? -ENOENT : 0;
389 ut_asserteq(expected_ret,
390 uclass_first_device_check(UCLASS_TEST_PROBE, &dev));
391 for (i = 0; i < 4; i++) {
392 ut_asserteq_ptr(devlist[i], dev);
393 expected_ret = (mask & 1) ? -ENOENT - (i + 1) : 0;
395 ut_asserteq(expected_ret, uclass_next_device_check(&dev));
397 ut_asserteq_ptr(NULL, dev);
402 /* Test uclass_first_device_check() and uclass_next_device_check() */
403 static int dm_test_first_next_ok_device(struct unit_test_state *uts)
405 struct dm_testprobe_pdata *pdata;
406 struct udevice *dev, *parent = NULL, *devlist[4];
410 /* There should be 4 devices */
412 for (ret = uclass_first_device_check(UCLASS_TEST_PROBE, &dev);
414 ret = uclass_next_device_check(&dev)) {
416 devlist[count++] = dev;
417 parent = dev_get_parent(dev);
419 ut_asserteq(4, count);
420 ut_assertok(uclass_first_device_check(UCLASS_TEST_PROBE, &dev));
421 ut_assertok(check_devices(uts, devlist, 0));
423 /* Remove them and try again, with an error on the second one */
424 pdata = dev_get_platdata(devlist[1]);
425 pdata->probe_err = -ENOENT - 1;
426 device_remove(parent, DM_REMOVE_NORMAL);
427 ut_assertok(check_devices(uts, devlist, 1 << 1));
429 /* Now an error on the first one */
430 pdata = dev_get_platdata(devlist[0]);
431 pdata->probe_err = -ENOENT - 0;
432 device_remove(parent, DM_REMOVE_NORMAL);
433 ut_assertok(check_devices(uts, devlist, 3 << 0));
435 /* Now errors on all */
436 pdata = dev_get_platdata(devlist[2]);
437 pdata->probe_err = -ENOENT - 2;
438 pdata = dev_get_platdata(devlist[3]);
439 pdata->probe_err = -ENOENT - 3;
440 device_remove(parent, DM_REMOVE_NORMAL);
441 ut_assertok(check_devices(uts, devlist, 0xf << 0));
445 DM_TEST(dm_test_first_next_ok_device, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
447 static const struct udevice_id fdt_dummy_ids[] = {
448 { .compatible = "denx,u-boot-fdt-dummy", },
452 UCLASS_DRIVER(fdt_dummy) = {
454 .id = UCLASS_TEST_DUMMY,
455 .flags = DM_UC_FLAG_SEQ_ALIAS,
458 U_BOOT_DRIVER(fdt_dummy_drv) = {
459 .name = "fdt_dummy_drv",
460 .of_match = fdt_dummy_ids,
461 .id = UCLASS_TEST_DUMMY,
464 static int dm_test_fdt_translation(struct unit_test_state *uts)
468 /* Some simple translations */
469 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
470 ut_asserteq_str("dev@0,0", dev->name);
471 ut_asserteq(0x8000, dev_read_addr(dev));
473 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 1, true, &dev));
474 ut_asserteq_str("dev@1,100", dev->name);
475 ut_asserteq(0x9000, dev_read_addr(dev));
477 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 2, true, &dev));
478 ut_asserteq_str("dev@2,200", dev->name);
479 ut_asserteq(0xA000, dev_read_addr(dev));
481 /* No translation for busses with #size-cells == 0 */
482 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 3, true, &dev));
483 ut_asserteq_str("dev@42", dev->name);
484 ut_asserteq(0x42, dev_read_addr(dev));
488 DM_TEST(dm_test_fdt_translation, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
490 /* Test devfdt_remap_addr_index() */
491 static int dm_test_fdt_remap_addr_flat(struct unit_test_state *uts)
497 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
499 addr = devfdt_get_addr(dev);
500 ut_asserteq(0x8000, addr);
502 paddr = map_physmem(addr, 0, MAP_NOCACHE);
503 ut_assertnonnull(paddr);
504 ut_asserteq_ptr(paddr, devfdt_remap_addr(dev));
508 DM_TEST(dm_test_fdt_remap_addr_flat,
509 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
511 /* Test dev_remap_addr_index() */
512 static int dm_test_fdt_remap_addr_live(struct unit_test_state *uts)
518 ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
520 addr = dev_read_addr(dev);
521 ut_asserteq(0x8000, addr);
523 paddr = map_physmem(addr, 0, MAP_NOCACHE);
524 ut_assertnonnull(paddr);
525 ut_asserteq_ptr(paddr, dev_remap_addr(dev));
529 DM_TEST(dm_test_fdt_remap_addr_live,
530 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
532 static int dm_test_fdt_livetree_writing(struct unit_test_state *uts)
537 if (!of_live_active()) {
538 printf("Live tree not active; ignore test\n");
542 /* Test enabling devices */
544 node = ofnode_path("/usb@2");
546 ut_assert(!of_device_is_available(ofnode_to_np(node)));
547 ofnode_set_enabled(node, true);
548 ut_assert(of_device_is_available(ofnode_to_np(node)));
550 device_bind_driver_to_node(dm_root(), "usb_sandbox", "usb@2", node,
552 ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, true, &dev));
554 /* Test string property setting */
556 ut_assert(device_is_compatible(dev, "sandbox,usb"));
557 ofnode_write_string(node, "compatible", "gdsys,super-usb");
558 ut_assert(device_is_compatible(dev, "gdsys,super-usb"));
559 ofnode_write_string(node, "compatible", "sandbox,usb");
560 ut_assert(device_is_compatible(dev, "sandbox,usb"));
562 /* Test setting generic properties */
564 /* Non-existent in DTB */
565 ut_asserteq(FDT_ADDR_T_NONE, dev_read_addr(dev));
566 /* reg = 0x42, size = 0x100 */
567 ut_assertok(ofnode_write_prop(node, "reg", 8,
568 "\x00\x00\x00\x42\x00\x00\x01\x00"));
569 ut_asserteq(0x42, dev_read_addr(dev));
571 /* Test disabling devices */
573 device_remove(dev, DM_REMOVE_NORMAL);
576 ut_assert(of_device_is_available(ofnode_to_np(node)));
577 ofnode_set_enabled(node, false);
578 ut_assert(!of_device_is_available(ofnode_to_np(node)));
582 DM_TEST(dm_test_fdt_livetree_writing, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
584 static int dm_test_fdt_disable_enable_by_path(struct unit_test_state *uts)
588 if (!of_live_active()) {
589 printf("Live tree not active; ignore test\n");
593 node = ofnode_path("/usb@2");
595 /* Test enabling devices */
597 ut_assert(!of_device_is_available(ofnode_to_np(node)));
598 dev_enable_by_path("/usb@2");
599 ut_assert(of_device_is_available(ofnode_to_np(node)));
601 /* Test disabling devices */
603 ut_assert(of_device_is_available(ofnode_to_np(node)));
604 dev_disable_by_path("/usb@2");
605 ut_assert(!of_device_is_available(ofnode_to_np(node)));
609 DM_TEST(dm_test_fdt_disable_enable_by_path, DM_TESTF_SCAN_PDATA |