cpu.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/cpu.h>
  3. #include <linux/kernel.h>
  4. #include <linux/of.h>
  5. /**
  6. * of_get_cpu_hwid - Get the hardware ID from a CPU device node
  7. *
  8. * @cpun: CPU number(logical index) for which device node is required
  9. * @thread: The local thread number to get the hardware ID for.
  10. *
  11. * Return: The hardware ID for the CPU node or ~0ULL if not found.
  12. */
  13. u64 of_get_cpu_hwid(struct device_node *cpun, unsigned int thread)
  14. {
  15. const __be32 *cell;
  16. int ac, len;
  17. ac = of_n_addr_cells(cpun);
  18. cell = of_get_property(cpun, "reg", &len);
  19. if (!cell || !ac || ((sizeof(*cell) * ac * (thread + 1)) > len))
  20. return ~0ULL;
  21. cell += ac * thread;
  22. return of_read_number(cell, ac);
  23. }
  24. /*
  25. * arch_match_cpu_phys_id - Match the given logical CPU and physical id
  26. *
  27. * @cpu: logical cpu index of a core/thread
  28. * @phys_id: physical identifier of a core/thread
  29. *
  30. * CPU logical to physical index mapping is architecture specific.
  31. * However this __weak function provides a default match of physical
  32. * id to logical cpu index. phys_id provided here is usually values read
  33. * from the device tree which must match the hardware internal registers.
  34. *
  35. * Returns true if the physical identifier and the logical cpu index
  36. * correspond to the same core/thread, false otherwise.
  37. */
  38. bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
  39. {
  40. return (u32)phys_id == cpu;
  41. }
  42. /*
  43. * Checks if the given "prop_name" property holds the physical id of the
  44. * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
  45. * NULL, local thread number within the core is returned in it.
  46. */
  47. static bool __of_find_n_match_cpu_property(struct device_node *cpun,
  48. const char *prop_name, int cpu, unsigned int *thread)
  49. {
  50. const __be32 *cell;
  51. int ac, prop_len, tid;
  52. u64 hwid;
  53. ac = of_n_addr_cells(cpun);
  54. cell = of_get_property(cpun, prop_name, &prop_len);
  55. if (!cell && !ac && arch_match_cpu_phys_id(cpu, 0))
  56. return true;
  57. if (!cell || !ac)
  58. return false;
  59. prop_len /= sizeof(*cell) * ac;
  60. for (tid = 0; tid < prop_len; tid++) {
  61. hwid = of_read_number(cell, ac);
  62. if (arch_match_cpu_phys_id(cpu, hwid)) {
  63. if (thread)
  64. *thread = tid;
  65. return true;
  66. }
  67. cell += ac;
  68. }
  69. return false;
  70. }
  71. /*
  72. * arch_find_n_match_cpu_physical_id - See if the given device node is
  73. * for the cpu corresponding to logical cpu 'cpu'. Return true if so,
  74. * else false. If 'thread' is non-NULL, the local thread number within the
  75. * core is returned in it.
  76. */
  77. bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
  78. int cpu, unsigned int *thread)
  79. {
  80. /* Check for non-standard "ibm,ppc-interrupt-server#s" property
  81. * for thread ids on PowerPC. If it doesn't exist fallback to
  82. * standard "reg" property.
  83. */
  84. if (IS_ENABLED(CONFIG_PPC) &&
  85. __of_find_n_match_cpu_property(cpun,
  86. "ibm,ppc-interrupt-server#s",
  87. cpu, thread))
  88. return true;
  89. return __of_find_n_match_cpu_property(cpun, "reg", cpu, thread);
  90. }
  91. /**
  92. * of_get_cpu_node - Get device node associated with the given logical CPU
  93. *
  94. * @cpu: CPU number(logical index) for which device node is required
  95. * @thread: if not NULL, local thread number within the physical core is
  96. * returned
  97. *
  98. * The main purpose of this function is to retrieve the device node for the
  99. * given logical CPU index. It should be used to initialize the of_node in
  100. * cpu device. Once of_node in cpu device is populated, all the further
  101. * references can use that instead.
  102. *
  103. * CPU logical to physical index mapping is architecture specific and is built
  104. * before booting secondary cores. This function uses arch_match_cpu_phys_id
  105. * which can be overridden by architecture specific implementation.
  106. *
  107. * Return: A node pointer for the logical cpu with refcount incremented, use
  108. * of_node_put() on it when done. Returns NULL if not found.
  109. */
  110. struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
  111. {
  112. struct device_node *cpun;
  113. for_each_of_cpu_node(cpun) {
  114. if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
  115. return cpun;
  116. }
  117. return NULL;
  118. }
  119. EXPORT_SYMBOL(of_get_cpu_node);
  120. /**
  121. * of_cpu_device_node_get: Get the CPU device_node for a given logical CPU number
  122. *
  123. * @cpu: The logical CPU number
  124. *
  125. * Return: Pointer to the device_node for CPU with its reference count
  126. * incremented of the given logical CPU number or NULL if the CPU device_node
  127. * is not found.
  128. */
  129. struct device_node *of_cpu_device_node_get(int cpu)
  130. {
  131. struct device *cpu_dev;
  132. cpu_dev = get_cpu_device(cpu);
  133. if (!cpu_dev)
  134. return of_get_cpu_node(cpu, NULL);
  135. return of_node_get(cpu_dev->of_node);
  136. }
  137. EXPORT_SYMBOL(of_cpu_device_node_get);
  138. /**
  139. * of_cpu_node_to_id: Get the logical CPU number for a given device_node
  140. *
  141. * @cpu_node: Pointer to the device_node for CPU.
  142. *
  143. * Return: The logical CPU number of the given CPU device_node or -ENODEV if the
  144. * CPU is not found.
  145. */
  146. int of_cpu_node_to_id(struct device_node *cpu_node)
  147. {
  148. int cpu;
  149. bool found = false;
  150. struct device_node *np;
  151. for_each_possible_cpu(cpu) {
  152. np = of_cpu_device_node_get(cpu);
  153. found = (cpu_node == np);
  154. of_node_put(np);
  155. if (found)
  156. return cpu;
  157. }
  158. return -ENODEV;
  159. }
  160. EXPORT_SYMBOL(of_cpu_node_to_id);
  161. /**
  162. * of_get_cpu_state_node - Get CPU's idle state node at the given index
  163. *
  164. * @cpu_node: The device node for the CPU
  165. * @index: The index in the list of the idle states
  166. *
  167. * Two generic methods can be used to describe a CPU's idle states, either via
  168. * a flattened description through the "cpu-idle-states" binding or via the
  169. * hierarchical layout, using the "power-domains" and the "domain-idle-states"
  170. * bindings. This function check for both and returns the idle state node for
  171. * the requested index.
  172. *
  173. * Return: An idle state node if found at @index. The refcount is incremented
  174. * for it, so call of_node_put() on it when done. Returns NULL if not found.
  175. */
  176. struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
  177. int index)
  178. {
  179. struct of_phandle_args args;
  180. int err;
  181. err = of_parse_phandle_with_args(cpu_node, "power-domains",
  182. "#power-domain-cells", 0, &args);
  183. if (!err) {
  184. struct device_node *state_node =
  185. of_parse_phandle(args.np, "domain-idle-states", index);
  186. of_node_put(args.np);
  187. if (state_node)
  188. return state_node;
  189. }
  190. return of_parse_phandle(cpu_node, "cpu-idle-states", index);
  191. }
  192. EXPORT_SYMBOL(of_get_cpu_state_node);