Lines Matching +full:cooling +full:- +full:device
1 // SPDX-License-Identifier: GPL-2.0
7 * Copyright (C) 2012-2018 Linaro Limited.
16 #include <linux/device.h>
29 * Cooling state <-> CPUFreq frequency
31 * Cooling states are translated to frequencies throughout this driver and this
34 * Highest cooling state corresponds to lowest possible frequency.
37 * level 0 --> 1st Max Freq
38 * level 1 --> 2nd Max Freq
43 * struct time_in_idle - Idle time stats
53 * struct cpufreq_cooling_device - data for cooling device with cpufreq
56 * cooling devices.
57 * @max_level: maximum cooling level. One less than total number of valid
59 * @em: Reference on the Energy Model of the device
61 * registered cooling device.
63 * @cooling_ops: cpufreq callbacks to thermal cooling device ops
96 for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) { in get_level()
97 if (freq > cpufreq_cdev->em->table[i].frequency) in get_level()
101 return cpufreq_cdev->max_level - i - 1; in get_level()
110 for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) { in cpu_freq_to_power()
111 if (freq > cpufreq_cdev->em->table[i].frequency) in cpu_freq_to_power()
115 power_mw = cpufreq_cdev->em->table[i + 1].power; in cpu_freq_to_power()
127 for (i = cpufreq_cdev->max_level; i > 0; i--) { in cpu_power_to_freq()
128 /* Convert EM power to milli-Watts to make safe comparison */ in cpu_power_to_freq()
129 em_power_mw = cpufreq_cdev->em->table[i].power; in cpu_power_to_freq()
135 return cpufreq_cdev->em->table[i].frequency; in cpu_power_to_freq()
139 * get_load() - get load for a cpu
161 struct time_in_idle *idle_time = &cpufreq_cdev->idle_time[cpu_idx]; in get_load()
164 delta_idle = now_idle - idle_time->time; in get_load()
165 delta_time = now - idle_time->timestamp; in get_load()
170 load = div64_u64(100 * (delta_time - delta_idle), delta_time); in get_load()
172 idle_time->time = now_idle; in get_load()
173 idle_time->timestamp = now; in get_load()
180 * get_dynamic_power() - calculate the dynamic power
193 return (raw_cpu_power * cpufreq_cdev->last_load) / 100; in get_dynamic_power()
197 * cpufreq_get_requested_power() - get the current power
224 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; in cpufreq_get_requested_power()
225 struct cpufreq_policy *policy = cpufreq_cdev->policy; in cpufreq_get_requested_power()
227 freq = cpufreq_quick_get(policy->cpu); in cpufreq_get_requested_power()
229 for_each_cpu(cpu, policy->related_cpus) { in cpufreq_get_requested_power()
240 cpufreq_cdev->last_load = total_load; in cpufreq_get_requested_power()
244 trace_thermal_power_cpu_get_power_simple(policy->cpu, *power); in cpufreq_get_requested_power()
250 * cpufreq_state2power() - convert a cpu cdev state to power consumed
252 * @state: cooling device state to be converted
255 * Convert cooling device state @state into power consumption in
259 * Return: 0 on success, -EINVAL if the cooling device state is bigger
266 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; in cpufreq_state2power()
269 if (state > cpufreq_cdev->max_level) in cpufreq_state2power()
270 return -EINVAL; in cpufreq_state2power()
272 num_cpus = cpumask_weight(cpufreq_cdev->policy->cpus); in cpufreq_state2power()
274 idx = cpufreq_cdev->max_level - state; in cpufreq_state2power()
275 freq = cpufreq_cdev->em->table[idx].frequency; in cpufreq_state2power()
282 * cpufreq_power2state() - convert power to a cooling device state
287 * Calculate a cooling device state for the cpus described by @cdev
291 * as input can yield different cooling device states depending on those
301 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; in cpufreq_power2state()
302 struct cpufreq_policy *policy = cpufreq_cdev->policy; in cpufreq_power2state()
304 last_load = cpufreq_cdev->last_load ?: 1; in cpufreq_power2state()
309 trace_thermal_power_cpu_limit(policy->related_cpus, target_freq, *state, in cpufreq_power2state()
322 policy = cpufreq_cdev->policy; in em_is_sane()
323 if (!cpumask_equal(policy->related_cpus, em_span_cpus(em))) { in em_is_sane()
326 cpumask_pr_args(policy->related_cpus)); in em_is_sane()
330 nr_levels = cpufreq_cdev->max_level + 1; in em_is_sane()
332 …pr_err("The number of performance states in pd %*pbl (%u) doesn't match the number of cooling leve… in em_is_sane()
354 unsigned int num_cpus = cpumask_weight(cpufreq_cdev->policy->related_cpus); in allocate_idle_time()
356 cpufreq_cdev->idle_time = kcalloc(num_cpus, in allocate_idle_time()
357 sizeof(*cpufreq_cdev->idle_time), in allocate_idle_time()
359 if (!cpufreq_cdev->idle_time) in allocate_idle_time()
360 return -ENOMEM; in allocate_idle_time()
367 kfree(cpufreq_cdev->idle_time); in free_idle_time()
368 cpufreq_cdev->idle_time = NULL; in free_idle_time()
380 if (cpufreq_cdev->em) { in get_state_freq()
381 idx = cpufreq_cdev->max_level - state; in get_state_freq()
382 return cpufreq_cdev->em->table[idx].frequency; in get_state_freq()
387 policy = cpufreq_cdev->policy; in get_state_freq()
388 if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING) in get_state_freq()
389 idx = cpufreq_cdev->max_level - state; in get_state_freq()
393 return policy->freq_table[idx].frequency; in get_state_freq()
396 /* cpufreq cooling device callback functions are defined below */
399 * cpufreq_get_max_state - callback function to get the max cooling state.
400 * @cdev: thermal cooling device pointer.
401 * @state: fill this variable with the max cooling state.
403 * Callback for the thermal cooling device to return the cpufreq
404 * max cooling state.
411 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; in cpufreq_get_max_state()
413 *state = cpufreq_cdev->max_level; in cpufreq_get_max_state()
418 * cpufreq_get_cur_state - callback function to get the current cooling state.
419 * @cdev: thermal cooling device pointer.
420 * @state: fill this variable with the current cooling state.
422 * Callback for the thermal cooling device to return the cpufreq
423 * current cooling state.
430 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; in cpufreq_get_cur_state()
432 *state = cpufreq_cdev->cpufreq_state; in cpufreq_get_cur_state()
438 * cpufreq_set_cur_state - callback function to set the current cooling state.
439 * @cdev: thermal cooling device pointer.
440 * @state: set this variable to the current cooling state.
442 * Callback for the thermal cooling device to change the cpufreq
443 * current cooling state.
450 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; in cpufreq_set_cur_state()
456 if (state > cpufreq_cdev->max_level) in cpufreq_set_cur_state()
457 return -EINVAL; in cpufreq_set_cur_state()
459 /* Check if the old cooling action is same as new cooling action */ in cpufreq_set_cur_state()
460 if (cpufreq_cdev->cpufreq_state == state) in cpufreq_set_cur_state()
465 ret = freq_qos_update_request(&cpufreq_cdev->qos_req, frequency); in cpufreq_set_cur_state()
467 cpufreq_cdev->cpufreq_state = state; in cpufreq_set_cur_state()
468 cpus = cpufreq_cdev->policy->related_cpus; in cpufreq_set_cur_state()
477 * __cpufreq_cooling_register - helper function to create cpufreq cooling device
478 * @np: a valid struct device_node to the cooling device tree node
480 * Normally this should be same as cpufreq policy->related_cpus.
483 * This interface function registers the cpufreq cooling device with the name
484 * "cpufreq-%s". This API can support multiple instances of cpufreq
485 * cooling devices. It also gives the opportunity to link the cooling device
486 * with a device tree node, in order to bind it via the thermal DT code.
499 struct device *dev; in __cpufreq_cooling_register()
506 return ERR_PTR(-EINVAL); in __cpufreq_cooling_register()
509 dev = get_cpu_device(policy->cpu); in __cpufreq_cooling_register()
511 pr_warn("No cpu device for cpu %d\n", policy->cpu); in __cpufreq_cooling_register()
512 return ERR_PTR(-ENODEV); in __cpufreq_cooling_register()
519 return ERR_PTR(-ENODEV); in __cpufreq_cooling_register()
524 return ERR_PTR(-ENOMEM); in __cpufreq_cooling_register()
526 cpufreq_cdev->policy = policy; in __cpufreq_cooling_register()
535 cpufreq_cdev->max_level = i - 1; in __cpufreq_cooling_register()
537 cooling_ops = &cpufreq_cdev->cooling_ops; in __cpufreq_cooling_register()
538 cooling_ops->get_max_state = cpufreq_get_max_state; in __cpufreq_cooling_register()
539 cooling_ops->get_cur_state = cpufreq_get_cur_state; in __cpufreq_cooling_register()
540 cooling_ops->set_cur_state = cpufreq_set_cur_state; in __cpufreq_cooling_register()
544 cpufreq_cdev->em = em; in __cpufreq_cooling_register()
545 cooling_ops->get_requested_power = cpufreq_get_requested_power; in __cpufreq_cooling_register()
546 cooling_ops->state2power = cpufreq_state2power; in __cpufreq_cooling_register()
547 cooling_ops->power2state = cpufreq_power2state; in __cpufreq_cooling_register()
550 if (policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED) { in __cpufreq_cooling_register()
553 cdev = ERR_PTR(-EINVAL); in __cpufreq_cooling_register()
557 ret = freq_qos_add_request(&policy->constraints, in __cpufreq_cooling_register()
558 &cpufreq_cdev->qos_req, FREQ_QOS_MAX, in __cpufreq_cooling_register()
567 cdev = ERR_PTR(-ENOMEM); in __cpufreq_cooling_register()
568 name = kasprintf(GFP_KERNEL, "cpufreq-%s", dev_name(dev)); in __cpufreq_cooling_register()
582 freq_qos_remove_request(&cpufreq_cdev->qos_req); in __cpufreq_cooling_register()
591 * cpufreq_cooling_register - function to create cpufreq cooling device.
594 * This interface function registers the cpufreq cooling device with the name
595 * "cpufreq-%s". This API can support multiple instances of cpufreq cooling
609 * of_cpufreq_cooling_register - function to create cpufreq cooling device.
612 * This interface function registers the cpufreq cooling device with the name
613 * "cpufreq-%s". This API can support multiple instances of cpufreq cooling
614 * devices. Using this API, the cpufreq cooling device will be linked to the
615 * device tree node provided.
617 * Using this function, the cooling device will implement the power
627 struct device_node *np = of_get_cpu_node(policy->cpu, NULL); in of_cpufreq_cooling_register()
632 policy->cpu); in of_cpufreq_cooling_register()
636 if (of_find_property(np, "#cooling-cells", NULL)) { in of_cpufreq_cooling_register()
637 struct em_perf_domain *em = em_cpu_get(policy->cpu); in of_cpufreq_cooling_register()
641 pr_err("cpufreq_cooling: cpu%d failed to register as cooling device: %ld\n", in of_cpufreq_cooling_register()
642 policy->cpu, PTR_ERR(cdev)); in of_cpufreq_cooling_register()
653 * cpufreq_cooling_unregister - function to remove cpufreq cooling device.
654 * @cdev: thermal cooling device pointer.
656 * This interface function unregisters the "cpufreq-%x" cooling device.
665 cpufreq_cdev = cdev->devdata; in cpufreq_cooling_unregister()
668 freq_qos_remove_request(&cpufreq_cdev->qos_req); in cpufreq_cooling_unregister()