1*2e7d35d2SSimon Glass /* 2*2e7d35d2SSimon Glass * Copyright (c) 2013 Google, Inc 3*2e7d35d2SSimon Glass * 4*2e7d35d2SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 5*2e7d35d2SSimon Glass */ 6*2e7d35d2SSimon Glass 7*2e7d35d2SSimon Glass #include <common.h> 8*2e7d35d2SSimon Glass #include <dm.h> 9*2e7d35d2SSimon Glass #include <errno.h> 10*2e7d35d2SSimon Glass #include <fdtdec.h> 11*2e7d35d2SSimon Glass #include <malloc.h> 12*2e7d35d2SSimon Glass #include <asm/io.h> 13*2e7d35d2SSimon Glass #include <dm/test.h> 14*2e7d35d2SSimon Glass #include <dm/root.h> 15*2e7d35d2SSimon Glass #include <dm/ut.h> 16*2e7d35d2SSimon Glass #include <dm/uclass-internal.h> 17*2e7d35d2SSimon Glass #include <dm/util.h> 18*2e7d35d2SSimon Glass 19*2e7d35d2SSimon Glass DECLARE_GLOBAL_DATA_PTR; 20*2e7d35d2SSimon Glass 21*2e7d35d2SSimon Glass static int testfdt_drv_ping(struct device *dev, int pingval, int *pingret) 22*2e7d35d2SSimon Glass { 23*2e7d35d2SSimon Glass const struct dm_test_pdata *pdata = dev->platdata; 24*2e7d35d2SSimon Glass struct dm_test_priv *priv = dev_get_priv(dev); 25*2e7d35d2SSimon Glass 26*2e7d35d2SSimon Glass *pingret = pingval + pdata->ping_add; 27*2e7d35d2SSimon Glass priv->ping_total += *pingret; 28*2e7d35d2SSimon Glass 29*2e7d35d2SSimon Glass return 0; 30*2e7d35d2SSimon Glass } 31*2e7d35d2SSimon Glass 32*2e7d35d2SSimon Glass static const struct test_ops test_ops = { 33*2e7d35d2SSimon Glass .ping = testfdt_drv_ping, 34*2e7d35d2SSimon Glass }; 35*2e7d35d2SSimon Glass 36*2e7d35d2SSimon Glass static int testfdt_ofdata_to_platdata(struct device *dev) 37*2e7d35d2SSimon Glass { 38*2e7d35d2SSimon Glass struct dm_test_pdata *pdata = dev_get_platdata(dev); 39*2e7d35d2SSimon Glass 40*2e7d35d2SSimon Glass pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev->of_offset, 41*2e7d35d2SSimon Glass "ping-add", -1); 42*2e7d35d2SSimon Glass pdata->base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg"); 43*2e7d35d2SSimon Glass 44*2e7d35d2SSimon Glass return 0; 45*2e7d35d2SSimon Glass } 46*2e7d35d2SSimon Glass 47*2e7d35d2SSimon Glass static int testfdt_drv_probe(struct device *dev) 48*2e7d35d2SSimon Glass { 49*2e7d35d2SSimon Glass struct dm_test_priv *priv = dev_get_priv(dev); 50*2e7d35d2SSimon Glass 51*2e7d35d2SSimon Glass priv->ping_total += DM_TEST_START_TOTAL; 52*2e7d35d2SSimon Glass 53*2e7d35d2SSimon Glass return 0; 54*2e7d35d2SSimon Glass } 55*2e7d35d2SSimon Glass 56*2e7d35d2SSimon Glass static const struct device_id testfdt_ids[] = { 57*2e7d35d2SSimon Glass { 58*2e7d35d2SSimon Glass .compatible = "denx,u-boot-fdt-test", 59*2e7d35d2SSimon Glass .data = DM_TEST_TYPE_FIRST }, 60*2e7d35d2SSimon Glass { 61*2e7d35d2SSimon Glass .compatible = "google,another-fdt-test", 62*2e7d35d2SSimon Glass .data = DM_TEST_TYPE_SECOND }, 63*2e7d35d2SSimon Glass { } 64*2e7d35d2SSimon Glass }; 65*2e7d35d2SSimon Glass 66*2e7d35d2SSimon Glass U_BOOT_DRIVER(testfdt_drv) = { 67*2e7d35d2SSimon Glass .name = "testfdt_drv", 68*2e7d35d2SSimon Glass .of_match = testfdt_ids, 69*2e7d35d2SSimon Glass .id = UCLASS_TEST_FDT, 70*2e7d35d2SSimon Glass .ofdata_to_platdata = testfdt_ofdata_to_platdata, 71*2e7d35d2SSimon Glass .probe = testfdt_drv_probe, 72*2e7d35d2SSimon Glass .ops = &test_ops, 73*2e7d35d2SSimon Glass .priv_auto_alloc_size = sizeof(struct dm_test_priv), 74*2e7d35d2SSimon Glass .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), 75*2e7d35d2SSimon Glass }; 76*2e7d35d2SSimon Glass 77*2e7d35d2SSimon Glass /* From here is the testfdt uclass code */ 78*2e7d35d2SSimon Glass int testfdt_ping(struct device *dev, int pingval, int *pingret) 79*2e7d35d2SSimon Glass { 80*2e7d35d2SSimon Glass const struct test_ops *ops = device_get_ops(dev); 81*2e7d35d2SSimon Glass 82*2e7d35d2SSimon Glass if (!ops->ping) 83*2e7d35d2SSimon Glass return -ENOSYS; 84*2e7d35d2SSimon Glass 85*2e7d35d2SSimon Glass return ops->ping(dev, pingval, pingret); 86*2e7d35d2SSimon Glass } 87*2e7d35d2SSimon Glass 88*2e7d35d2SSimon Glass UCLASS_DRIVER(testfdt) = { 89*2e7d35d2SSimon Glass .name = "testfdt", 90*2e7d35d2SSimon Glass .id = UCLASS_TEST_FDT, 91*2e7d35d2SSimon Glass }; 92*2e7d35d2SSimon Glass 93*2e7d35d2SSimon Glass /* Test that FDT-based binding works correctly */ 94*2e7d35d2SSimon Glass static int dm_test_fdt(struct dm_test_state *dms) 95*2e7d35d2SSimon Glass { 96*2e7d35d2SSimon Glass const int num_drivers = 3; 97*2e7d35d2SSimon Glass struct device *dev; 98*2e7d35d2SSimon Glass struct uclass *uc; 99*2e7d35d2SSimon Glass int ret; 100*2e7d35d2SSimon Glass int i; 101*2e7d35d2SSimon Glass 102*2e7d35d2SSimon Glass ret = dm_scan_fdt(gd->fdt_blob); 103*2e7d35d2SSimon Glass ut_assert(!ret); 104*2e7d35d2SSimon Glass 105*2e7d35d2SSimon Glass ret = uclass_get(UCLASS_TEST_FDT, &uc); 106*2e7d35d2SSimon Glass ut_assert(!ret); 107*2e7d35d2SSimon Glass 108*2e7d35d2SSimon Glass /* These are num_drivers compatible root-level device tree nodes */ 109*2e7d35d2SSimon Glass ut_asserteq(num_drivers, list_count_items(&uc->dev_head)); 110*2e7d35d2SSimon Glass 111*2e7d35d2SSimon Glass /* Each should have no platdata / priv */ 112*2e7d35d2SSimon Glass for (i = 0; i < num_drivers; i++) { 113*2e7d35d2SSimon Glass ret = uclass_find_device(UCLASS_TEST_FDT, i, &dev); 114*2e7d35d2SSimon Glass ut_assert(!ret); 115*2e7d35d2SSimon Glass ut_assert(!dev_get_priv(dev)); 116*2e7d35d2SSimon Glass ut_assert(!dev->platdata); 117*2e7d35d2SSimon Glass } 118*2e7d35d2SSimon Glass 119*2e7d35d2SSimon Glass /* 120*2e7d35d2SSimon Glass * Now check that the ping adds are what we expect. This is using the 121*2e7d35d2SSimon Glass * ping-add property in each node. 122*2e7d35d2SSimon Glass */ 123*2e7d35d2SSimon Glass for (i = 0; i < num_drivers; i++) { 124*2e7d35d2SSimon Glass uint32_t base; 125*2e7d35d2SSimon Glass 126*2e7d35d2SSimon Glass ret = uclass_get_device(UCLASS_TEST_FDT, i, &dev); 127*2e7d35d2SSimon Glass ut_assert(!ret); 128*2e7d35d2SSimon Glass 129*2e7d35d2SSimon Glass /* 130*2e7d35d2SSimon Glass * Get the 'reg' property, which tells us what the ping add 131*2e7d35d2SSimon Glass * should be. We don't use the platdata because we want 132*2e7d35d2SSimon Glass * to test the code that sets that up (testfdt_drv_probe()). 133*2e7d35d2SSimon Glass */ 134*2e7d35d2SSimon Glass base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg"); 135*2e7d35d2SSimon Glass debug("dev=%d, base=%d: %s\n", i, base, 136*2e7d35d2SSimon Glass fdt_get_name(gd->fdt_blob, dev->of_offset, NULL)); 137*2e7d35d2SSimon Glass 138*2e7d35d2SSimon Glass ut_assert(!dm_check_operations(dms, dev, base, 139*2e7d35d2SSimon Glass dev_get_priv(dev))); 140*2e7d35d2SSimon Glass } 141*2e7d35d2SSimon Glass 142*2e7d35d2SSimon Glass return 0; 143*2e7d35d2SSimon Glass } 144*2e7d35d2SSimon Glass DM_TEST(dm_test_fdt, 0); 145