cpufreq_cooling.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * linux/drivers/thermal/cpufreq_cooling.c
  4. *
  5. * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
  6. *
  7. * Copyright (C) 2012-2018 Linaro Limited.
  8. *
  9. * Authors: Amit Daniel <amit.kachhap@linaro.org>
  10. * Viresh Kumar <viresh.kumar@linaro.org>
  11. *
  12. */
  13. #include <linux/cpu.h>
  14. #include <linux/cpufreq.h>
  15. #include <linux/cpu_cooling.h>
  16. #include <linux/device.h>
  17. #include <linux/energy_model.h>
  18. #include <linux/err.h>
  19. #include <linux/export.h>
  20. #include <linux/pm_opp.h>
  21. #include <linux/pm_qos.h>
  22. #include <linux/slab.h>
  23. #include <linux/thermal.h>
  24. #include <linux/units.h>
  25. #include "thermal_trace.h"
  26. /*
  27. * Cooling state <-> CPUFreq frequency
  28. *
  29. * Cooling states are translated to frequencies throughout this driver and this
  30. * is the relation between them.
  31. *
  32. * Highest cooling state corresponds to lowest possible frequency.
  33. *
  34. * i.e.
  35. * level 0 --> 1st Max Freq
  36. * level 1 --> 2nd Max Freq
  37. * ...
  38. */
  39. /**
  40. * struct time_in_idle - Idle time stats
  41. * @time: previous reading of the absolute time that this cpu was idle
  42. * @timestamp: wall time of the last invocation of get_cpu_idle_time_us()
  43. */
  44. struct time_in_idle {
  45. u64 time;
  46. u64 timestamp;
  47. };
  48. /**
  49. * struct cpufreq_cooling_device - data for cooling device with cpufreq
  50. * @last_load: load measured by the latest call to cpufreq_get_requested_power()
  51. * @cpufreq_state: integer value representing the current state of cpufreq
  52. * cooling devices.
  53. * @max_level: maximum cooling level. One less than total number of valid
  54. * cpufreq frequencies.
  55. * @em: Reference on the Energy Model of the device
  56. * @policy: cpufreq policy.
  57. * @cooling_ops: cpufreq callbacks to thermal cooling device ops
  58. * @idle_time: idle time stats
  59. * @qos_req: PM QoS contraint to apply
  60. *
  61. * This structure is required for keeping information of each registered
  62. * cpufreq_cooling_device.
  63. */
  64. struct cpufreq_cooling_device {
  65. u32 last_load;
  66. unsigned int cpufreq_state;
  67. unsigned int max_level;
  68. struct em_perf_domain *em;
  69. struct cpufreq_policy *policy;
  70. struct thermal_cooling_device_ops cooling_ops;
  71. #ifndef CONFIG_SMP
  72. struct time_in_idle *idle_time;
  73. #endif
  74. struct freq_qos_request qos_req;
  75. };
  76. #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
  77. /**
  78. * get_level: Find the level for a particular frequency
  79. * @cpufreq_cdev: cpufreq_cdev for which the property is required
  80. * @freq: Frequency
  81. *
  82. * Return: level corresponding to the frequency.
  83. */
  84. static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_cdev,
  85. unsigned int freq)
  86. {
  87. struct em_perf_state *table;
  88. int i;
  89. rcu_read_lock();
  90. table = em_perf_state_from_pd(cpufreq_cdev->em);
  91. for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
  92. if (freq > table[i].frequency)
  93. break;
  94. }
  95. rcu_read_unlock();
  96. return cpufreq_cdev->max_level - i - 1;
  97. }
  98. static u32 cpu_freq_to_power(struct cpufreq_cooling_device *cpufreq_cdev,
  99. u32 freq)
  100. {
  101. struct em_perf_state *table;
  102. unsigned long power_mw;
  103. int i;
  104. rcu_read_lock();
  105. table = em_perf_state_from_pd(cpufreq_cdev->em);
  106. for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
  107. if (freq > table[i].frequency)
  108. break;
  109. }
  110. power_mw = table[i + 1].power;
  111. power_mw /= MICROWATT_PER_MILLIWATT;
  112. rcu_read_unlock();
  113. return power_mw;
  114. }
  115. static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev,
  116. u32 power)
  117. {
  118. struct em_perf_state *table;
  119. unsigned long em_power_mw;
  120. u32 freq;
  121. int i;
  122. rcu_read_lock();
  123. table = em_perf_state_from_pd(cpufreq_cdev->em);
  124. for (i = cpufreq_cdev->max_level; i > 0; i--) {
  125. /* Convert EM power to milli-Watts to make safe comparison */
  126. em_power_mw = table[i].power;
  127. em_power_mw /= MICROWATT_PER_MILLIWATT;
  128. if (power >= em_power_mw)
  129. break;
  130. }
  131. freq = table[i].frequency;
  132. rcu_read_unlock();
  133. return freq;
  134. }
  135. /**
  136. * get_load() - get load for a cpu
  137. * @cpufreq_cdev: struct cpufreq_cooling_device for the cpu
  138. * @cpu: cpu number
  139. * @cpu_idx: index of the cpu in time_in_idle array
  140. *
  141. * Return: The average load of cpu @cpu in percentage since this
  142. * function was last called.
  143. */
  144. #ifdef CONFIG_SMP
  145. static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu,
  146. int cpu_idx)
  147. {
  148. unsigned long util = sched_cpu_util(cpu);
  149. return (util * 100) / arch_scale_cpu_capacity(cpu);
  150. }
  151. #else /* !CONFIG_SMP */
  152. static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu,
  153. int cpu_idx)
  154. {
  155. u32 load;
  156. u64 now, now_idle, delta_time, delta_idle;
  157. struct time_in_idle *idle_time = &cpufreq_cdev->idle_time[cpu_idx];
  158. now_idle = get_cpu_idle_time(cpu, &now, 0);
  159. delta_idle = now_idle - idle_time->time;
  160. delta_time = now - idle_time->timestamp;
  161. if (delta_time <= delta_idle)
  162. load = 0;
  163. else
  164. load = div64_u64(100 * (delta_time - delta_idle), delta_time);
  165. idle_time->time = now_idle;
  166. idle_time->timestamp = now;
  167. return load;
  168. }
  169. #endif /* CONFIG_SMP */
  170. /**
  171. * get_dynamic_power() - calculate the dynamic power
  172. * @cpufreq_cdev: &cpufreq_cooling_device for this cdev
  173. * @freq: current frequency
  174. *
  175. * Return: the dynamic power consumed by the cpus described by
  176. * @cpufreq_cdev.
  177. */
  178. static u32 get_dynamic_power(struct cpufreq_cooling_device *cpufreq_cdev,
  179. unsigned long freq)
  180. {
  181. u32 raw_cpu_power;
  182. raw_cpu_power = cpu_freq_to_power(cpufreq_cdev, freq);
  183. return (raw_cpu_power * cpufreq_cdev->last_load) / 100;
  184. }
  185. /**
  186. * cpufreq_get_requested_power() - get the current power
  187. * @cdev: &thermal_cooling_device pointer
  188. * @power: pointer in which to store the resulting power
  189. *
  190. * Calculate the current power consumption of the cpus in milliwatts
  191. * and store it in @power. This function should actually calculate
  192. * the requested power, but it's hard to get the frequency that
  193. * cpufreq would have assigned if there were no thermal limits.
  194. * Instead, we calculate the current power on the assumption that the
  195. * immediate future will look like the immediate past.
  196. *
  197. * We use the current frequency and the average load since this
  198. * function was last called. In reality, there could have been
  199. * multiple opps since this function was last called and that affects
  200. * the load calculation. While it's not perfectly accurate, this
  201. * simplification is good enough and works. REVISIT this, as more
  202. * complex code may be needed if experiments show that it's not
  203. * accurate enough.
  204. *
  205. * Return: 0 on success, this function doesn't fail.
  206. */
  207. static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
  208. u32 *power)
  209. {
  210. unsigned long freq;
  211. int i = 0, cpu;
  212. u32 total_load = 0;
  213. struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
  214. struct cpufreq_policy *policy = cpufreq_cdev->policy;
  215. freq = cpufreq_quick_get(policy->cpu);
  216. for_each_cpu(cpu, policy->related_cpus) {
  217. u32 load;
  218. if (cpu_online(cpu))
  219. load = get_load(cpufreq_cdev, cpu, i);
  220. else
  221. load = 0;
  222. total_load += load;
  223. }
  224. cpufreq_cdev->last_load = total_load;
  225. *power = get_dynamic_power(cpufreq_cdev, freq);
  226. trace_thermal_power_cpu_get_power_simple(policy->cpu, *power);
  227. return 0;
  228. }
  229. /**
  230. * cpufreq_state2power() - convert a cpu cdev state to power consumed
  231. * @cdev: &thermal_cooling_device pointer
  232. * @state: cooling device state to be converted
  233. * @power: pointer in which to store the resulting power
  234. *
  235. * Convert cooling device state @state into power consumption in
  236. * milliwatts assuming 100% load. Store the calculated power in
  237. * @power.
  238. *
  239. * Return: 0 on success, -EINVAL if the cooling device state is bigger
  240. * than maximum allowed.
  241. */
  242. static int cpufreq_state2power(struct thermal_cooling_device *cdev,
  243. unsigned long state, u32 *power)
  244. {
  245. struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
  246. unsigned int freq, num_cpus, idx;
  247. struct em_perf_state *table;
  248. /* Request state should be less than max_level */
  249. if (state > cpufreq_cdev->max_level)
  250. return -EINVAL;
  251. num_cpus = cpumask_weight(cpufreq_cdev->policy->cpus);
  252. idx = cpufreq_cdev->max_level - state;
  253. rcu_read_lock();
  254. table = em_perf_state_from_pd(cpufreq_cdev->em);
  255. freq = table[idx].frequency;
  256. rcu_read_unlock();
  257. *power = cpu_freq_to_power(cpufreq_cdev, freq) * num_cpus;
  258. return 0;
  259. }
  260. /**
  261. * cpufreq_power2state() - convert power to a cooling device state
  262. * @cdev: &thermal_cooling_device pointer
  263. * @power: power in milliwatts to be converted
  264. * @state: pointer in which to store the resulting state
  265. *
  266. * Calculate a cooling device state for the cpus described by @cdev
  267. * that would allow them to consume at most @power mW and store it in
  268. * @state. Note that this calculation depends on external factors
  269. * such as the CPUs load. Calling this function with the same power
  270. * as input can yield different cooling device states depending on those
  271. * external factors.
  272. *
  273. * Return: 0 on success, this function doesn't fail.
  274. */
  275. static int cpufreq_power2state(struct thermal_cooling_device *cdev,
  276. u32 power, unsigned long *state)
  277. {
  278. unsigned int target_freq;
  279. u32 last_load, normalised_power;
  280. struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
  281. struct cpufreq_policy *policy = cpufreq_cdev->policy;
  282. last_load = cpufreq_cdev->last_load ?: 1;
  283. normalised_power = (power * 100) / last_load;
  284. target_freq = cpu_power_to_freq(cpufreq_cdev, normalised_power);
  285. *state = get_level(cpufreq_cdev, target_freq);
  286. trace_thermal_power_cpu_limit(policy->related_cpus, target_freq, *state,
  287. power);
  288. return 0;
  289. }
  290. static inline bool em_is_sane(struct cpufreq_cooling_device *cpufreq_cdev,
  291. struct em_perf_domain *em) {
  292. struct cpufreq_policy *policy;
  293. unsigned int nr_levels;
  294. if (!em || em_is_artificial(em))
  295. return false;
  296. policy = cpufreq_cdev->policy;
  297. if (!cpumask_equal(policy->related_cpus, em_span_cpus(em))) {
  298. pr_err("The span of pd %*pbl is misaligned with cpufreq policy %*pbl\n",
  299. cpumask_pr_args(em_span_cpus(em)),
  300. cpumask_pr_args(policy->related_cpus));
  301. return false;
  302. }
  303. nr_levels = cpufreq_cdev->max_level + 1;
  304. if (em_pd_nr_perf_states(em) != nr_levels) {
  305. pr_err("The number of performance states in pd %*pbl (%u) doesn't match the number of cooling levels (%u)\n",
  306. cpumask_pr_args(em_span_cpus(em)),
  307. em_pd_nr_perf_states(em), nr_levels);
  308. return false;
  309. }
  310. return true;
  311. }
  312. #endif /* CONFIG_THERMAL_GOV_POWER_ALLOCATOR */
  313. #ifdef CONFIG_SMP
  314. static inline int allocate_idle_time(struct cpufreq_cooling_device *cpufreq_cdev)
  315. {
  316. return 0;
  317. }
  318. static inline void free_idle_time(struct cpufreq_cooling_device *cpufreq_cdev)
  319. {
  320. }
  321. #else
  322. static int allocate_idle_time(struct cpufreq_cooling_device *cpufreq_cdev)
  323. {
  324. unsigned int num_cpus = cpumask_weight(cpufreq_cdev->policy->related_cpus);
  325. cpufreq_cdev->idle_time = kzalloc_objs(*cpufreq_cdev->idle_time,
  326. num_cpus);
  327. if (!cpufreq_cdev->idle_time)
  328. return -ENOMEM;
  329. return 0;
  330. }
  331. static void free_idle_time(struct cpufreq_cooling_device *cpufreq_cdev)
  332. {
  333. kfree(cpufreq_cdev->idle_time);
  334. cpufreq_cdev->idle_time = NULL;
  335. }
  336. #endif /* CONFIG_SMP */
  337. static unsigned int get_state_freq(struct cpufreq_cooling_device *cpufreq_cdev,
  338. unsigned long state)
  339. {
  340. struct cpufreq_policy *policy;
  341. unsigned long idx;
  342. #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
  343. /* Use the Energy Model table if available */
  344. if (cpufreq_cdev->em) {
  345. struct em_perf_state *table;
  346. unsigned int freq;
  347. idx = cpufreq_cdev->max_level - state;
  348. rcu_read_lock();
  349. table = em_perf_state_from_pd(cpufreq_cdev->em);
  350. freq = table[idx].frequency;
  351. rcu_read_unlock();
  352. return freq;
  353. }
  354. #endif
  355. /* Otherwise, fallback on the CPUFreq table */
  356. policy = cpufreq_cdev->policy;
  357. if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING)
  358. idx = cpufreq_cdev->max_level - state;
  359. else
  360. idx = state;
  361. return policy->freq_table[idx].frequency;
  362. }
  363. /* cpufreq cooling device callback functions are defined below */
  364. /**
  365. * cpufreq_get_max_state - callback function to get the max cooling state.
  366. * @cdev: thermal cooling device pointer.
  367. * @state: fill this variable with the max cooling state.
  368. *
  369. * Callback for the thermal cooling device to return the cpufreq
  370. * max cooling state.
  371. *
  372. * Return: 0 on success, this function doesn't fail.
  373. */
  374. static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
  375. unsigned long *state)
  376. {
  377. struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
  378. *state = cpufreq_cdev->max_level;
  379. return 0;
  380. }
  381. /**
  382. * cpufreq_get_cur_state - callback function to get the current cooling state.
  383. * @cdev: thermal cooling device pointer.
  384. * @state: fill this variable with the current cooling state.
  385. *
  386. * Callback for the thermal cooling device to return the cpufreq
  387. * current cooling state.
  388. *
  389. * Return: 0 on success, this function doesn't fail.
  390. */
  391. static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
  392. unsigned long *state)
  393. {
  394. struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
  395. *state = cpufreq_cdev->cpufreq_state;
  396. return 0;
  397. }
  398. /**
  399. * cpufreq_set_cur_state - callback function to set the current cooling state.
  400. * @cdev: thermal cooling device pointer.
  401. * @state: set this variable to the current cooling state.
  402. *
  403. * Callback for the thermal cooling device to change the cpufreq
  404. * current cooling state.
  405. *
  406. * Return: 0 on success, an error code otherwise.
  407. */
  408. static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
  409. unsigned long state)
  410. {
  411. struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
  412. unsigned int frequency;
  413. int ret;
  414. /* Request state should be less than max_level */
  415. if (state > cpufreq_cdev->max_level)
  416. return -EINVAL;
  417. /* Check if the old cooling action is same as new cooling action */
  418. if (cpufreq_cdev->cpufreq_state == state)
  419. return 0;
  420. frequency = get_state_freq(cpufreq_cdev, state);
  421. ret = freq_qos_update_request(&cpufreq_cdev->qos_req, frequency);
  422. if (ret >= 0) {
  423. cpufreq_cdev->cpufreq_state = state;
  424. ret = 0;
  425. }
  426. return ret;
  427. }
  428. /**
  429. * __cpufreq_cooling_register - helper function to create cpufreq cooling device
  430. * @np: a valid struct device_node to the cooling device tree node
  431. * @policy: cpufreq policy
  432. * Normally this should be same as cpufreq policy->related_cpus.
  433. * @em: Energy Model of the cpufreq policy
  434. *
  435. * This interface function registers the cpufreq cooling device with the name
  436. * "cpufreq-%s". This API can support multiple instances of cpufreq
  437. * cooling devices. It also gives the opportunity to link the cooling device
  438. * with a device tree node, in order to bind it via the thermal DT code.
  439. *
  440. * Return: a valid struct thermal_cooling_device pointer on success,
  441. * on failure, it returns a corresponding ERR_PTR().
  442. */
  443. static struct thermal_cooling_device *
  444. __cpufreq_cooling_register(struct device_node *np,
  445. struct cpufreq_policy *policy,
  446. struct em_perf_domain *em)
  447. {
  448. struct thermal_cooling_device *cdev;
  449. struct cpufreq_cooling_device *cpufreq_cdev;
  450. unsigned int i;
  451. struct device *dev;
  452. int ret;
  453. struct thermal_cooling_device_ops *cooling_ops;
  454. char *name;
  455. if (IS_ERR_OR_NULL(policy)) {
  456. pr_err("%s: cpufreq policy isn't valid: %p\n", __func__, policy);
  457. return ERR_PTR(-EINVAL);
  458. }
  459. dev = get_cpu_device(policy->cpu);
  460. if (unlikely(!dev)) {
  461. pr_warn("No cpu device for cpu %d\n", policy->cpu);
  462. return ERR_PTR(-ENODEV);
  463. }
  464. i = cpufreq_table_count_valid_entries(policy);
  465. if (!i) {
  466. pr_debug("%s: CPUFreq table not found or has no valid entries\n",
  467. __func__);
  468. return ERR_PTR(-ENODEV);
  469. }
  470. cpufreq_cdev = kzalloc_obj(*cpufreq_cdev);
  471. if (!cpufreq_cdev)
  472. return ERR_PTR(-ENOMEM);
  473. cpufreq_cdev->policy = policy;
  474. ret = allocate_idle_time(cpufreq_cdev);
  475. if (ret) {
  476. cdev = ERR_PTR(ret);
  477. goto free_cdev;
  478. }
  479. /* max_level is an index, not a counter */
  480. cpufreq_cdev->max_level = i - 1;
  481. cooling_ops = &cpufreq_cdev->cooling_ops;
  482. cooling_ops->get_max_state = cpufreq_get_max_state;
  483. cooling_ops->get_cur_state = cpufreq_get_cur_state;
  484. cooling_ops->set_cur_state = cpufreq_set_cur_state;
  485. #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
  486. if (em_is_sane(cpufreq_cdev, em)) {
  487. cpufreq_cdev->em = em;
  488. cooling_ops->get_requested_power = cpufreq_get_requested_power;
  489. cooling_ops->state2power = cpufreq_state2power;
  490. cooling_ops->power2state = cpufreq_power2state;
  491. } else
  492. #endif
  493. if (policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED) {
  494. pr_err("%s: unsorted frequency tables are not supported\n",
  495. __func__);
  496. cdev = ERR_PTR(-EINVAL);
  497. goto free_idle_time;
  498. }
  499. ret = freq_qos_add_request(&policy->constraints,
  500. &cpufreq_cdev->qos_req, FREQ_QOS_MAX,
  501. get_state_freq(cpufreq_cdev, 0));
  502. if (ret < 0) {
  503. pr_err("%s: Failed to add freq constraint (%d)\n", __func__,
  504. ret);
  505. cdev = ERR_PTR(ret);
  506. goto free_idle_time;
  507. }
  508. cdev = ERR_PTR(-ENOMEM);
  509. name = kasprintf(GFP_KERNEL, "cpufreq-%s", dev_name(dev));
  510. if (!name)
  511. goto remove_qos_req;
  512. cdev = thermal_of_cooling_device_register(np, name, cpufreq_cdev,
  513. cooling_ops);
  514. kfree(name);
  515. if (IS_ERR(cdev))
  516. goto remove_qos_req;
  517. return cdev;
  518. remove_qos_req:
  519. freq_qos_remove_request(&cpufreq_cdev->qos_req);
  520. free_idle_time:
  521. free_idle_time(cpufreq_cdev);
  522. free_cdev:
  523. kfree(cpufreq_cdev);
  524. return cdev;
  525. }
  526. /**
  527. * cpufreq_cooling_register - function to create cpufreq cooling device.
  528. * @policy: cpufreq policy
  529. *
  530. * This interface function registers the cpufreq cooling device with the name
  531. * "cpufreq-%s". This API can support multiple instances of cpufreq cooling
  532. * devices.
  533. *
  534. * Return: a valid struct thermal_cooling_device pointer on success,
  535. * on failure, it returns a corresponding ERR_PTR().
  536. */
  537. struct thermal_cooling_device *
  538. cpufreq_cooling_register(struct cpufreq_policy *policy)
  539. {
  540. return __cpufreq_cooling_register(NULL, policy, NULL);
  541. }
  542. EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
  543. /**
  544. * of_cpufreq_cooling_register - function to create cpufreq cooling device.
  545. * @policy: cpufreq policy
  546. *
  547. * This interface function registers the cpufreq cooling device with the name
  548. * "cpufreq-%s". This API can support multiple instances of cpufreq cooling
  549. * devices. Using this API, the cpufreq cooling device will be linked to the
  550. * device tree node provided.
  551. *
  552. * Using this function, the cooling device will implement the power
  553. * extensions by using the Energy Model (if present). The cpus must have
  554. * registered their OPPs using the OPP library.
  555. *
  556. * Return: a valid struct thermal_cooling_device pointer on success,
  557. * and NULL on failure.
  558. */
  559. struct thermal_cooling_device *
  560. of_cpufreq_cooling_register(struct cpufreq_policy *policy)
  561. {
  562. struct device_node *np = of_get_cpu_node(policy->cpu, NULL);
  563. struct thermal_cooling_device *cdev = NULL;
  564. if (!np) {
  565. pr_err("cpufreq_cooling: OF node not available for cpu%d\n",
  566. policy->cpu);
  567. return NULL;
  568. }
  569. if (of_property_present(np, "#cooling-cells")) {
  570. struct em_perf_domain *em = em_cpu_get(policy->cpu);
  571. cdev = __cpufreq_cooling_register(np, policy, em);
  572. if (IS_ERR(cdev)) {
  573. pr_err("cpufreq_cooling: cpu%d failed to register as cooling device: %ld\n",
  574. policy->cpu, PTR_ERR(cdev));
  575. cdev = NULL;
  576. }
  577. }
  578. of_node_put(np);
  579. return cdev;
  580. }
  581. EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register);
  582. /**
  583. * cpufreq_cooling_unregister - function to remove cpufreq cooling device.
  584. * @cdev: thermal cooling device pointer.
  585. *
  586. * This interface function unregisters the "cpufreq-%x" cooling device.
  587. */
  588. void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
  589. {
  590. struct cpufreq_cooling_device *cpufreq_cdev;
  591. if (!cdev)
  592. return;
  593. cpufreq_cdev = cdev->devdata;
  594. thermal_cooling_device_unregister(cdev);
  595. freq_qos_remove_request(&cpufreq_cdev->qos_req);
  596. free_idle_time(cpufreq_cdev);
  597. kfree(cpufreq_cdev);
  598. }
  599. EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister);