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> 82e7d35d2SSimon Glass #include <dm.h> 92e7d35d2SSimon Glass #include <errno.h> 102e7d35d2SSimon Glass #include <fdtdec.h> 112e7d35d2SSimon Glass #include <malloc.h> 122e7d35d2SSimon Glass #include <asm/io.h> 132e7d35d2SSimon Glass #include <dm/test.h> 142e7d35d2SSimon Glass #include <dm/root.h> 152e7d35d2SSimon Glass #include <dm/ut.h> 162e7d35d2SSimon Glass #include <dm/uclass-internal.h> 172e7d35d2SSimon Glass #include <dm/util.h> 182e7d35d2SSimon Glass 192e7d35d2SSimon Glass DECLARE_GLOBAL_DATA_PTR; 202e7d35d2SSimon Glass 2154c5d08aSHeiko Schocher static int testfdt_drv_ping(struct udevice *dev, int pingval, int *pingret) 222e7d35d2SSimon Glass { 232e7d35d2SSimon Glass const struct dm_test_pdata *pdata = dev->platdata; 242e7d35d2SSimon Glass struct dm_test_priv *priv = dev_get_priv(dev); 252e7d35d2SSimon Glass 262e7d35d2SSimon Glass *pingret = pingval + pdata->ping_add; 272e7d35d2SSimon Glass priv->ping_total += *pingret; 282e7d35d2SSimon Glass 292e7d35d2SSimon Glass return 0; 302e7d35d2SSimon Glass } 312e7d35d2SSimon Glass 322e7d35d2SSimon Glass static const struct test_ops test_ops = { 332e7d35d2SSimon Glass .ping = testfdt_drv_ping, 342e7d35d2SSimon Glass }; 352e7d35d2SSimon Glass 3654c5d08aSHeiko Schocher static int testfdt_ofdata_to_platdata(struct udevice *dev) 372e7d35d2SSimon Glass { 382e7d35d2SSimon Glass struct dm_test_pdata *pdata = dev_get_platdata(dev); 392e7d35d2SSimon Glass 402e7d35d2SSimon Glass pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev->of_offset, 412e7d35d2SSimon Glass "ping-add", -1); 422e7d35d2SSimon Glass pdata->base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg"); 432e7d35d2SSimon Glass 442e7d35d2SSimon Glass return 0; 452e7d35d2SSimon Glass } 462e7d35d2SSimon Glass 4754c5d08aSHeiko Schocher static int testfdt_drv_probe(struct udevice *dev) 482e7d35d2SSimon Glass { 492e7d35d2SSimon Glass struct dm_test_priv *priv = dev_get_priv(dev); 502e7d35d2SSimon Glass 512e7d35d2SSimon Glass priv->ping_total += DM_TEST_START_TOTAL; 522e7d35d2SSimon Glass 532e7d35d2SSimon Glass return 0; 542e7d35d2SSimon Glass } 552e7d35d2SSimon Glass 56*ae7f4513SSimon Glass static const struct udevice_id testfdt_ids[] = { 572e7d35d2SSimon Glass { 582e7d35d2SSimon Glass .compatible = "denx,u-boot-fdt-test", 592e7d35d2SSimon Glass .data = DM_TEST_TYPE_FIRST }, 602e7d35d2SSimon Glass { 612e7d35d2SSimon Glass .compatible = "google,another-fdt-test", 622e7d35d2SSimon Glass .data = DM_TEST_TYPE_SECOND }, 632e7d35d2SSimon Glass { } 642e7d35d2SSimon Glass }; 652e7d35d2SSimon Glass 662e7d35d2SSimon Glass U_BOOT_DRIVER(testfdt_drv) = { 672e7d35d2SSimon Glass .name = "testfdt_drv", 682e7d35d2SSimon Glass .of_match = testfdt_ids, 692e7d35d2SSimon Glass .id = UCLASS_TEST_FDT, 702e7d35d2SSimon Glass .ofdata_to_platdata = testfdt_ofdata_to_platdata, 712e7d35d2SSimon Glass .probe = testfdt_drv_probe, 722e7d35d2SSimon Glass .ops = &test_ops, 732e7d35d2SSimon Glass .priv_auto_alloc_size = sizeof(struct dm_test_priv), 742e7d35d2SSimon Glass .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), 752e7d35d2SSimon Glass }; 762e7d35d2SSimon Glass 772e7d35d2SSimon Glass /* From here is the testfdt uclass code */ 7854c5d08aSHeiko Schocher int testfdt_ping(struct udevice *dev, int pingval, int *pingret) 792e7d35d2SSimon Glass { 802e7d35d2SSimon Glass const struct test_ops *ops = device_get_ops(dev); 812e7d35d2SSimon Glass 822e7d35d2SSimon Glass if (!ops->ping) 832e7d35d2SSimon Glass return -ENOSYS; 842e7d35d2SSimon Glass 852e7d35d2SSimon Glass return ops->ping(dev, pingval, pingret); 862e7d35d2SSimon Glass } 872e7d35d2SSimon Glass 882e7d35d2SSimon Glass UCLASS_DRIVER(testfdt) = { 892e7d35d2SSimon Glass .name = "testfdt", 902e7d35d2SSimon Glass .id = UCLASS_TEST_FDT, 912e7d35d2SSimon Glass }; 922e7d35d2SSimon Glass 932e7d35d2SSimon Glass /* Test that FDT-based binding works correctly */ 942e7d35d2SSimon Glass static int dm_test_fdt(struct dm_test_state *dms) 952e7d35d2SSimon Glass { 962e7d35d2SSimon Glass const int num_drivers = 3; 9754c5d08aSHeiko Schocher struct udevice *dev; 982e7d35d2SSimon Glass struct uclass *uc; 992e7d35d2SSimon Glass int ret; 1002e7d35d2SSimon Glass int i; 1012e7d35d2SSimon Glass 1022e7d35d2SSimon Glass ret = dm_scan_fdt(gd->fdt_blob); 1032e7d35d2SSimon Glass ut_assert(!ret); 1042e7d35d2SSimon Glass 1052e7d35d2SSimon Glass ret = uclass_get(UCLASS_TEST_FDT, &uc); 1062e7d35d2SSimon Glass ut_assert(!ret); 1072e7d35d2SSimon Glass 1082e7d35d2SSimon Glass /* These are num_drivers compatible root-level device tree nodes */ 1092e7d35d2SSimon Glass ut_asserteq(num_drivers, list_count_items(&uc->dev_head)); 1102e7d35d2SSimon Glass 1112e7d35d2SSimon Glass /* Each should have no platdata / priv */ 1122e7d35d2SSimon Glass for (i = 0; i < num_drivers; i++) { 1132e7d35d2SSimon Glass ret = uclass_find_device(UCLASS_TEST_FDT, i, &dev); 1142e7d35d2SSimon Glass ut_assert(!ret); 1152e7d35d2SSimon Glass ut_assert(!dev_get_priv(dev)); 1162e7d35d2SSimon Glass ut_assert(!dev->platdata); 1172e7d35d2SSimon Glass } 1182e7d35d2SSimon Glass 1192e7d35d2SSimon Glass /* 1202e7d35d2SSimon Glass * Now check that the ping adds are what we expect. This is using the 1212e7d35d2SSimon Glass * ping-add property in each node. 1222e7d35d2SSimon Glass */ 1232e7d35d2SSimon Glass for (i = 0; i < num_drivers; i++) { 1242e7d35d2SSimon Glass uint32_t base; 1252e7d35d2SSimon Glass 1262e7d35d2SSimon Glass ret = uclass_get_device(UCLASS_TEST_FDT, i, &dev); 1272e7d35d2SSimon Glass ut_assert(!ret); 1282e7d35d2SSimon Glass 1292e7d35d2SSimon Glass /* 1302e7d35d2SSimon Glass * Get the 'reg' property, which tells us what the ping add 1312e7d35d2SSimon Glass * should be. We don't use the platdata because we want 1322e7d35d2SSimon Glass * to test the code that sets that up (testfdt_drv_probe()). 1332e7d35d2SSimon Glass */ 1342e7d35d2SSimon Glass base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg"); 1352e7d35d2SSimon Glass debug("dev=%d, base=%d: %s\n", i, base, 1362e7d35d2SSimon Glass fdt_get_name(gd->fdt_blob, dev->of_offset, NULL)); 1372e7d35d2SSimon Glass 1382e7d35d2SSimon Glass ut_assert(!dm_check_operations(dms, dev, base, 1392e7d35d2SSimon Glass dev_get_priv(dev))); 1402e7d35d2SSimon Glass } 1412e7d35d2SSimon Glass 1422e7d35d2SSimon Glass return 0; 1432e7d35d2SSimon Glass } 1442e7d35d2SSimon Glass DM_TEST(dm_test_fdt, 0); 145