cpu-uclass.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2015 Google, Inc
  4. * Written by Simon Glass <sjg@chromium.org>
  5. */
  6. #define LOG_CATEGORY UCLASS_CPU
  7. #include <common.h>
  8. #include <cpu.h>
  9. #include <dm.h>
  10. #include <errno.h>
  11. #include <log.h>
  12. #include <dm/lists.h>
  13. #include <dm/root.h>
  14. #include <linux/err.h>
  15. #include <relocate.h>
  16. DECLARE_GLOBAL_DATA_PTR;
  17. int cpu_probe_all(void)
  18. {
  19. int ret = uclass_probe_all(UCLASS_CPU);
  20. if (ret) {
  21. debug("%s: Error while probing CPUs (err = %d %s)\n",
  22. __func__, ret, errno_str(ret));
  23. }
  24. return ret;
  25. }
  26. int cpu_is_current(struct udevice *cpu)
  27. {
  28. struct cpu_ops *ops = cpu_get_ops(cpu);
  29. if (ops->is_current) {
  30. if (ops->is_current(cpu))
  31. return 1;
  32. }
  33. return -ENOSYS;
  34. }
  35. struct udevice *cpu_get_current_dev(void)
  36. {
  37. struct udevice *cpu;
  38. int ret;
  39. uclass_foreach_dev_probe(UCLASS_CPU, cpu) {
  40. if (cpu_is_current(cpu) > 0)
  41. return cpu;
  42. }
  43. /* If can't find current cpu device, use the first dev instead */
  44. ret = uclass_first_device_err(UCLASS_CPU, &cpu);
  45. if (ret) {
  46. debug("%s: Could not get CPU device (err = %d)\n",
  47. __func__, ret);
  48. return NULL;
  49. }
  50. return cpu;
  51. }
  52. int cpu_get_desc(const struct udevice *dev, char *buf, int size)
  53. {
  54. struct cpu_ops *ops = cpu_get_ops(dev);
  55. if (!ops->get_desc)
  56. return -ENOSYS;
  57. return ops->get_desc(dev, buf, size);
  58. }
  59. int cpu_get_info(const struct udevice *dev, struct cpu_info *info)
  60. {
  61. struct cpu_ops *ops = cpu_get_ops(dev);
  62. if (!ops->get_info)
  63. return -ENOSYS;
  64. /* Init cpu_info to 0 */
  65. memset(info, 0, sizeof(struct cpu_info));
  66. return ops->get_info(dev, info);
  67. }
  68. int cpu_get_count(const struct udevice *dev)
  69. {
  70. struct cpu_ops *ops = cpu_get_ops(dev);
  71. if (!ops->get_count)
  72. return -ENOSYS;
  73. return ops->get_count(dev);
  74. }
  75. int cpu_get_vendor(const struct udevice *dev, char *buf, int size)
  76. {
  77. struct cpu_ops *ops = cpu_get_ops(dev);
  78. if (!ops->get_vendor)
  79. return -ENOSYS;
  80. return ops->get_vendor(dev, buf, size);
  81. }
  82. U_BOOT_DRIVER(cpu_bus) = {
  83. .name = "cpu_bus",
  84. .id = UCLASS_SIMPLE_BUS,
  85. .per_child_plat_auto = sizeof(struct cpu_plat),
  86. };
  87. static int uclass_cpu_init(struct uclass *uc)
  88. {
  89. struct udevice *dev;
  90. ofnode node;
  91. int ret;
  92. node = ofnode_path("/cpus");
  93. if (!ofnode_valid(node))
  94. return 0;
  95. ret = device_bind_driver_to_node(dm_root(), "cpu_bus", "cpus", node,
  96. &dev);
  97. return ret;
  98. }
  99. static int uclass_cpu_post_bind(struct udevice *dev)
  100. {
  101. if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC) &&
  102. (gd->flags & GD_FLG_RELOC)) {
  103. struct cpu_ops *ops = cpu_get_ops(dev);
  104. static int reloc_done;
  105. if (!reloc_done) {
  106. if (ops->get_desc)
  107. MANUAL_RELOC(ops->get_desc);
  108. if (ops->get_info)
  109. MANUAL_RELOC(ops->get_info);
  110. if (ops->get_count)
  111. MANUAL_RELOC(ops->get_count);
  112. if (ops->get_vendor)
  113. MANUAL_RELOC(ops->get_vendor);
  114. if (ops->is_current)
  115. MANUAL_RELOC(ops->is_current);
  116. reloc_done++;
  117. }
  118. }
  119. return 0;
  120. }
  121. UCLASS_DRIVER(cpu) = {
  122. .id = UCLASS_CPU,
  123. .name = "cpu",
  124. .flags = DM_UC_FLAG_SEQ_ALIAS,
  125. .init = uclass_cpu_init,
  126. .post_bind = uclass_cpu_post_bind,
  127. };