root.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * Copyright (c) 2013 Google, Inc
  3. *
  4. * (C) Copyright 2012
  5. * Pavel Herrmann <morpheus.ibis@gmail.com>
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <common.h>
  10. #include <errno.h>
  11. #include <fdtdec.h>
  12. #include <malloc.h>
  13. #include <libfdt.h>
  14. #include <dm/device.h>
  15. #include <dm/device-internal.h>
  16. #include <dm/lists.h>
  17. #include <dm/platdata.h>
  18. #include <dm/root.h>
  19. #include <dm/uclass.h>
  20. #include <dm/util.h>
  21. #include <linux/list.h>
  22. DECLARE_GLOBAL_DATA_PTR;
  23. static const struct driver_info root_info = {
  24. .name = "root_driver",
  25. };
  26. struct udevice *dm_root(void)
  27. {
  28. if (!gd->dm_root) {
  29. dm_warn("Virtual root driver does not exist!\n");
  30. return NULL;
  31. }
  32. return gd->dm_root;
  33. }
  34. #if defined(CONFIG_NEEDS_MANUAL_RELOC)
  35. void fix_drivers(void)
  36. {
  37. struct driver *drv =
  38. ll_entry_start(struct driver, driver);
  39. const int n_ents = ll_entry_count(struct driver, driver);
  40. struct driver *entry;
  41. for (entry = drv; entry != drv + n_ents; entry++) {
  42. if (entry->of_match)
  43. entry->of_match = (const struct udevice_id *)
  44. ((u32)entry->of_match + gd->reloc_off);
  45. if (entry->bind)
  46. entry->bind += gd->reloc_off;
  47. if (entry->probe)
  48. entry->probe += gd->reloc_off;
  49. if (entry->remove)
  50. entry->remove += gd->reloc_off;
  51. if (entry->unbind)
  52. entry->unbind += gd->reloc_off;
  53. if (entry->ofdata_to_platdata)
  54. entry->ofdata_to_platdata += gd->reloc_off;
  55. if (entry->child_post_bind)
  56. entry->child_post_bind += gd->reloc_off;
  57. if (entry->child_pre_probe)
  58. entry->child_pre_probe += gd->reloc_off;
  59. if (entry->child_post_remove)
  60. entry->child_post_remove += gd->reloc_off;
  61. /* OPS are fixed in every uclass post_probe function */
  62. if (entry->ops)
  63. entry->ops += gd->reloc_off;
  64. }
  65. }
  66. void fix_uclass(void)
  67. {
  68. struct uclass_driver *uclass =
  69. ll_entry_start(struct uclass_driver, uclass);
  70. const int n_ents = ll_entry_count(struct uclass_driver, uclass);
  71. struct uclass_driver *entry;
  72. for (entry = uclass; entry != uclass + n_ents; entry++) {
  73. if (entry->post_bind)
  74. entry->post_bind += gd->reloc_off;
  75. if (entry->pre_unbind)
  76. entry->pre_unbind += gd->reloc_off;
  77. if (entry->pre_probe)
  78. entry->pre_probe += gd->reloc_off;
  79. if (entry->post_probe)
  80. entry->post_probe += gd->reloc_off;
  81. if (entry->pre_remove)
  82. entry->pre_remove += gd->reloc_off;
  83. if (entry->child_post_bind)
  84. entry->child_post_bind += gd->reloc_off;
  85. if (entry->child_pre_probe)
  86. entry->child_pre_probe += gd->reloc_off;
  87. if (entry->init)
  88. entry->init += gd->reloc_off;
  89. if (entry->destroy)
  90. entry->destroy += gd->reloc_off;
  91. /* FIXME maybe also need to fix these ops */
  92. if (entry->ops)
  93. entry->ops += gd->reloc_off;
  94. }
  95. }
  96. #endif
  97. int dm_init(void)
  98. {
  99. int ret;
  100. if (gd->dm_root) {
  101. dm_warn("Virtual root driver already exists!\n");
  102. return -EINVAL;
  103. }
  104. INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
  105. #if defined(CONFIG_NEEDS_MANUAL_RELOC)
  106. fix_drivers();
  107. fix_uclass();
  108. #endif
  109. ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);
  110. if (ret)
  111. return ret;
  112. #if CONFIG_IS_ENABLED(OF_CONTROL)
  113. DM_ROOT_NON_CONST->of_offset = 0;
  114. #endif
  115. ret = device_probe(DM_ROOT_NON_CONST);
  116. if (ret)
  117. return ret;
  118. return 0;
  119. }
  120. int dm_uninit(void)
  121. {
  122. device_remove(dm_root());
  123. device_unbind(dm_root());
  124. return 0;
  125. }
  126. int dm_scan_platdata(bool pre_reloc_only)
  127. {
  128. int ret;
  129. ret = lists_bind_drivers(DM_ROOT_NON_CONST, pre_reloc_only);
  130. if (ret == -ENOENT) {
  131. dm_warn("Some drivers were not found\n");
  132. ret = 0;
  133. }
  134. return ret;
  135. }
  136. #if CONFIG_IS_ENABLED(OF_CONTROL)
  137. int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
  138. bool pre_reloc_only)
  139. {
  140. int ret = 0, err;
  141. for (offset = fdt_first_subnode(blob, offset);
  142. offset > 0;
  143. offset = fdt_next_subnode(blob, offset)) {
  144. if (pre_reloc_only &&
  145. !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL))
  146. continue;
  147. if (!fdtdec_get_is_enabled(blob, offset)) {
  148. dm_dbg(" - ignoring disabled device\n");
  149. continue;
  150. }
  151. err = lists_bind_fdt(parent, blob, offset, NULL);
  152. if (err && !ret) {
  153. ret = err;
  154. debug("%s: ret=%d\n", fdt_get_name(blob, offset, NULL),
  155. ret);
  156. }
  157. }
  158. if (ret)
  159. dm_warn("Some drivers failed to bind\n");
  160. return ret;
  161. }
  162. int dm_scan_fdt(const void *blob, bool pre_reloc_only)
  163. {
  164. return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only);
  165. }
  166. #endif
  167. __weak int dm_scan_other(bool pre_reloc_only)
  168. {
  169. return 0;
  170. }
  171. int dm_init_and_scan(bool pre_reloc_only)
  172. {
  173. int ret;
  174. ret = dm_init();
  175. if (ret) {
  176. debug("dm_init() failed: %d\n", ret);
  177. return ret;
  178. }
  179. ret = dm_scan_platdata(pre_reloc_only);
  180. if (ret) {
  181. debug("dm_scan_platdata() failed: %d\n", ret);
  182. return ret;
  183. }
  184. if (CONFIG_IS_ENABLED(OF_CONTROL)) {
  185. ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
  186. if (ret) {
  187. debug("dm_scan_fdt() failed: %d\n", ret);
  188. return ret;
  189. }
  190. }
  191. ret = dm_scan_other(pre_reloc_only);
  192. if (ret)
  193. return ret;
  194. return 0;
  195. }
  196. /* This is the root driver - all drivers are children of this */
  197. U_BOOT_DRIVER(root_driver) = {
  198. .name = "root_driver",
  199. .id = UCLASS_ROOT,
  200. };
  201. /* This is the root uclass */
  202. UCLASS_DRIVER(root) = {
  203. .name = "root",
  204. .id = UCLASS_ROOT,
  205. };