cpu-uclass.c 2.5 KB

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