test-fdt.c 3.3 KB

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