cpu-uclass.c 2.5 KB

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