processor_thermal.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * processor_thermal.c - Passive cooling submodule of the ACPI processor driver
  4. *
  5. * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  6. * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  7. * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de>
  8. * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
  9. * - Added processor hotplug support
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/init.h>
  14. #include <linux/cpufreq.h>
  15. #include <linux/acpi.h>
  16. #include <acpi/processor.h>
  17. #include <linux/uaccess.h>
  18. #define PREFIX "ACPI: "
  19. #define ACPI_PROCESSOR_CLASS "processor"
  20. #ifdef CONFIG_CPU_FREQ
  21. /* If a passive cooling situation is detected, primarily CPUfreq is used, as it
  22. * offers (in most cases) voltage scaling in addition to frequency scaling, and
  23. * thus a cubic (instead of linear) reduction of energy. Also, we allow for
  24. * _any_ cpufreq driver and not only the acpi-cpufreq driver.
  25. */
  26. #define CPUFREQ_THERMAL_MIN_STEP 0
  27. #define CPUFREQ_THERMAL_MAX_STEP 3
  28. static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg);
  29. #define reduction_pctg(cpu) \
  30. per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu))
  31. /*
  32. * Emulate "per package data" using per cpu data (which should really be
  33. * provided elsewhere)
  34. *
  35. * Note we can lose a CPU on cpu hotunplug, in this case we forget the state
  36. * temporarily. Fortunately that's not a big issue here (I hope)
  37. */
  38. static int phys_package_first_cpu(int cpu)
  39. {
  40. int i;
  41. int id = topology_physical_package_id(cpu);
  42. for_each_online_cpu(i)
  43. if (topology_physical_package_id(i) == id)
  44. return i;
  45. return 0;
  46. }
  47. static int cpu_has_cpufreq(unsigned int cpu)
  48. {
  49. struct cpufreq_policy policy;
  50. if (!acpi_processor_cpufreq_init || cpufreq_get_policy(&policy, cpu))
  51. return 0;
  52. return 1;
  53. }
  54. static int cpufreq_get_max_state(unsigned int cpu)
  55. {
  56. if (!cpu_has_cpufreq(cpu))
  57. return 0;
  58. return CPUFREQ_THERMAL_MAX_STEP;
  59. }
  60. static int cpufreq_get_cur_state(unsigned int cpu)
  61. {
  62. if (!cpu_has_cpufreq(cpu))
  63. return 0;
  64. return reduction_pctg(cpu);
  65. }
  66. static int cpufreq_set_cur_state(unsigned int cpu, int state)
  67. {
  68. struct cpufreq_policy *policy;
  69. struct acpi_processor *pr;
  70. unsigned long max_freq;
  71. int i, ret;
  72. if (!cpu_has_cpufreq(cpu))
  73. return 0;
  74. reduction_pctg(cpu) = state;
  75. /*
  76. * Update all the CPUs in the same package because they all
  77. * contribute to the temperature and often share the same
  78. * frequency.
  79. */
  80. for_each_online_cpu(i) {
  81. if (topology_physical_package_id(i) !=
  82. topology_physical_package_id(cpu))
  83. continue;
  84. pr = per_cpu(processors, i);
  85. if (unlikely(!freq_qos_request_active(&pr->thermal_req)))
  86. continue;
  87. policy = cpufreq_cpu_get(i);
  88. if (!policy)
  89. return -EINVAL;
  90. max_freq = (policy->cpuinfo.max_freq * (100 - reduction_pctg(i) * 20)) / 100;
  91. cpufreq_cpu_put(policy);
  92. ret = freq_qos_update_request(&pr->thermal_req, max_freq);
  93. if (ret < 0) {
  94. pr_warn("Failed to update thermal freq constraint: CPU%d (%d)\n",
  95. pr->id, ret);
  96. }
  97. }
  98. return 0;
  99. }
  100. void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy)
  101. {
  102. unsigned int cpu;
  103. for_each_cpu(cpu, policy->related_cpus) {
  104. struct acpi_processor *pr = per_cpu(processors, cpu);
  105. int ret;
  106. if (!pr)
  107. continue;
  108. ret = freq_qos_add_request(&policy->constraints,
  109. &pr->thermal_req,
  110. FREQ_QOS_MAX, INT_MAX);
  111. if (ret < 0)
  112. pr_err("Failed to add freq constraint for CPU%d (%d)\n",
  113. cpu, ret);
  114. }
  115. }
  116. void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy)
  117. {
  118. unsigned int cpu;
  119. for_each_cpu(cpu, policy->related_cpus) {
  120. struct acpi_processor *pr = per_cpu(processors, policy->cpu);
  121. if (pr)
  122. freq_qos_remove_request(&pr->thermal_req);
  123. }
  124. }
  125. #else /* ! CONFIG_CPU_FREQ */
  126. static int cpufreq_get_max_state(unsigned int cpu)
  127. {
  128. return 0;
  129. }
  130. static int cpufreq_get_cur_state(unsigned int cpu)
  131. {
  132. return 0;
  133. }
  134. static int cpufreq_set_cur_state(unsigned int cpu, int state)
  135. {
  136. return 0;
  137. }
  138. #endif
  139. /* thermal cooling device callbacks */
  140. static int acpi_processor_max_state(struct acpi_processor *pr)
  141. {
  142. int max_state = 0;
  143. /*
  144. * There exists four states according to
  145. * cpufreq_thermal_reduction_pctg. 0, 1, 2, 3
  146. */
  147. max_state += cpufreq_get_max_state(pr->id);
  148. if (pr->flags.throttling)
  149. max_state += (pr->throttling.state_count -1);
  150. return max_state;
  151. }
  152. static int
  153. processor_get_max_state(struct thermal_cooling_device *cdev,
  154. unsigned long *state)
  155. {
  156. struct acpi_device *device = cdev->devdata;
  157. struct acpi_processor *pr;
  158. if (!device)
  159. return -EINVAL;
  160. pr = acpi_driver_data(device);
  161. if (!pr)
  162. return -EINVAL;
  163. *state = acpi_processor_max_state(pr);
  164. return 0;
  165. }
  166. static int
  167. processor_get_cur_state(struct thermal_cooling_device *cdev,
  168. unsigned long *cur_state)
  169. {
  170. struct acpi_device *device = cdev->devdata;
  171. struct acpi_processor *pr;
  172. if (!device)
  173. return -EINVAL;
  174. pr = acpi_driver_data(device);
  175. if (!pr)
  176. return -EINVAL;
  177. *cur_state = cpufreq_get_cur_state(pr->id);
  178. if (pr->flags.throttling)
  179. *cur_state += pr->throttling.state;
  180. return 0;
  181. }
  182. static int
  183. processor_set_cur_state(struct thermal_cooling_device *cdev,
  184. unsigned long state)
  185. {
  186. struct acpi_device *device = cdev->devdata;
  187. struct acpi_processor *pr;
  188. int result = 0;
  189. int max_pstate;
  190. if (!device)
  191. return -EINVAL;
  192. pr = acpi_driver_data(device);
  193. if (!pr)
  194. return -EINVAL;
  195. max_pstate = cpufreq_get_max_state(pr->id);
  196. if (state > acpi_processor_max_state(pr))
  197. return -EINVAL;
  198. if (state <= max_pstate) {
  199. if (pr->flags.throttling && pr->throttling.state)
  200. result = acpi_processor_set_throttling(pr, 0, false);
  201. cpufreq_set_cur_state(pr->id, state);
  202. } else {
  203. cpufreq_set_cur_state(pr->id, max_pstate);
  204. result = acpi_processor_set_throttling(pr,
  205. state - max_pstate, false);
  206. }
  207. return result;
  208. }
  209. const struct thermal_cooling_device_ops processor_cooling_ops = {
  210. .get_max_state = processor_get_max_state,
  211. .get_cur_state = processor_get_cur_state,
  212. .set_cur_state = processor_set_cur_state,
  213. };