aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-01-17 20:52:42 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-01-17 20:52:42 -0500
commitf06970f4b03dffeb9831a8ad605db3c85a55aca1 (patch)
treea4477a4878350d63e3399e7f0d57d64e26065f09
parent343a8d17fa8d6dd97f408e8fedbcef12073f3774 (diff)
parentac89c400ebb146604e718b3fa168c15592e73a8c (diff)
Merge branch 'pm-cpufreq-thermal' into pm-cpufreq
* pm-cpufreq-thermal: cpu_cooling: Remove static-power related documentation cpu_cooling: Drop static-power related stuff cpu_cooling: Keep only one of_cpufreq*cooling_register() helper cpu_cooling: Remove unused cpufreq_power_cooling_register() cpu_cooling: Make of_cpufreq_power_cooling_register() parse DT
-rw-r--r--Documentation/thermal/cpu-cooling-api.txt115
-rw-r--r--drivers/cpufreq/arm_big_little.c23
-rw-r--r--drivers/cpufreq/cpufreq-dt.c27
-rw-r--r--drivers/cpufreq/mediatek-cpufreq.c22
-rw-r--r--drivers/cpufreq/qoriq-cpufreq.c14
-rw-r--r--drivers/thermal/cpu_cooling.c201
-rw-r--r--include/linux/cpu_cooling.h75
-rw-r--r--include/trace/events/thermal.h10
8 files changed, 66 insertions, 421 deletions
diff --git a/Documentation/thermal/cpu-cooling-api.txt b/Documentation/thermal/cpu-cooling-api.txt
index 71653584cd03..7df567eaea1a 100644
--- a/Documentation/thermal/cpu-cooling-api.txt
+++ b/Documentation/thermal/cpu-cooling-api.txt
@@ -26,39 +26,16 @@ the user. The registration APIs returns the cooling device pointer.
26 clip_cpus: cpumask of cpus where the frequency constraints will happen. 26 clip_cpus: cpumask of cpus where the frequency constraints will happen.
27 27
281.1.2 struct thermal_cooling_device *of_cpufreq_cooling_register( 281.1.2 struct thermal_cooling_device *of_cpufreq_cooling_register(
29 struct device_node *np, const struct cpumask *clip_cpus) 29 struct cpufreq_policy *policy)
30 30
31 This interface function registers the cpufreq cooling device with 31 This interface function registers the cpufreq cooling device with
32 the name "thermal-cpufreq-%x" linking it with a device tree node, in 32 the name "thermal-cpufreq-%x" linking it with a device tree node, in
33 order to bind it via the thermal DT code. This api can support multiple 33 order to bind it via the thermal DT code. This api can support multiple
34 instances of cpufreq cooling devices. 34 instances of cpufreq cooling devices.
35 35
36 np: pointer to the cooling device device tree node 36 policy: CPUFreq policy.
37 clip_cpus: cpumask of cpus where the frequency constraints will happen.
38 37
391.1.3 struct thermal_cooling_device *cpufreq_power_cooling_register( 381.1.3 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
40 const struct cpumask *clip_cpus, u32 capacitance,
41 get_static_t plat_static_func)
42
43Similar to cpufreq_cooling_register, this function registers a cpufreq
44cooling device. Using this function, the cooling device will
45implement the power extensions by using a simple cpu power model. The
46cpus must have registered their OPPs using the OPP library.
47
48The additional parameters are needed for the power model (See 2. Power
49models). "capacitance" is the dynamic power coefficient (See 2.1
50Dynamic power). "plat_static_func" is a function to calculate the
51static power consumed by these cpus (See 2.2 Static power).
52
531.1.4 struct thermal_cooling_device *of_cpufreq_power_cooling_register(
54 struct device_node *np, const struct cpumask *clip_cpus, u32 capacitance,
55 get_static_t plat_static_func)
56
57Similar to cpufreq_power_cooling_register, this function register a
58cpufreq cooling device with power extensions using the device tree
59information supplied by the np parameter.
60
611.1.5 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
62 39
63 This interface function unregisters the "thermal-cpufreq-%x" cooling device. 40 This interface function unregisters the "thermal-cpufreq-%x" cooling device.
64 41
@@ -67,20 +44,14 @@ information supplied by the np parameter.
672. Power models 442. Power models
68 45
69The power API registration functions provide a simple power model for 46The power API registration functions provide a simple power model for
70CPUs. The current power is calculated as dynamic + (optionally) 47CPUs. The current power is calculated as dynamic power (static power isn't
71static power. This power model requires that the operating-points of 48supported currently). This power model requires that the operating-points of
72the CPUs are registered using the kernel's opp library and the 49the CPUs are registered using the kernel's opp library and the
73`cpufreq_frequency_table` is assigned to the `struct device` of the 50`cpufreq_frequency_table` is assigned to the `struct device` of the
74cpu. If you are using CONFIG_CPUFREQ_DT then the 51cpu. If you are using CONFIG_CPUFREQ_DT then the
75`cpufreq_frequency_table` should already be assigned to the cpu 52`cpufreq_frequency_table` should already be assigned to the cpu
76device. 53device.
77 54
78The `plat_static_func` parameter of `cpufreq_power_cooling_register()`
79and `of_cpufreq_power_cooling_register()` is optional. If you don't
80provide it, only dynamic power will be considered.
81
822.1 Dynamic power
83
84The dynamic power consumption of a processor depends on many factors. 55The dynamic power consumption of a processor depends on many factors.
85For a given processor implementation the primary factors are: 56For a given processor implementation the primary factors are:
86 57
@@ -119,79 +90,3 @@ mW/MHz/uVolt^2. Typical values for mobile CPUs might lie in range
119from 100 to 500. For reference, the approximate values for the SoC in 90from 100 to 500. For reference, the approximate values for the SoC in
120ARM's Juno Development Platform are 530 for the Cortex-A57 cluster and 91ARM's Juno Development Platform are 530 for the Cortex-A57 cluster and
121140 for the Cortex-A53 cluster. 92140 for the Cortex-A53 cluster.
122
123
1242.2 Static power
125
126Static leakage power consumption depends on a number of factors. For a
127given circuit implementation the primary factors are:
128
129- Time the circuit spends in each 'power state'
130- Temperature
131- Operating voltage
132- Process grade
133
134The time the circuit spends in each 'power state' for a given
135evaluation period at first order means OFF or ON. However,
136'retention' states can also be supported that reduce power during
137inactive periods without loss of context.
138
139Note: The visibility of state entries to the OS can vary, according to
140platform specifics, and this can then impact the accuracy of a model
141based on OS state information alone. It might be possible in some
142cases to extract more accurate information from system resources.
143
144The temperature, operating voltage and process 'grade' (slow to fast)
145of the circuit are all significant factors in static leakage power
146consumption. All of these have complex relationships to static power.
147
148Circuit implementation specific factors include the chosen silicon
149process as well as the type, number and size of transistors in both
150the logic gates and any RAM elements included.
151
152The static power consumption modelling must take into account the
153power managed regions that are implemented. Taking the example of an
154ARM processor cluster, the modelling would take into account whether
155each CPU can be powered OFF separately or if only a single power
156region is implemented for the complete cluster.
157
158In one view, there are others, a static power consumption model can
159then start from a set of reference values for each power managed
160region (e.g. CPU, Cluster/L2) in each state (e.g. ON, OFF) at an
161arbitrary process grade, voltage and temperature point. These values
162are then scaled for all of the following: the time in each state, the
163process grade, the current temperature and the operating voltage.
164However, since both implementation specific and complex relationships
165dominate the estimate, the appropriate interface to the model from the
166cpu cooling device is to provide a function callback that calculates
167the static power in this platform. When registering the cpu cooling
168device pass a function pointer that follows the `get_static_t`
169prototype:
170
171 int plat_get_static(cpumask_t *cpumask, int interval,
172 unsigned long voltage, u32 &power);
173
174`cpumask` is the cpumask of the cpus involved in the calculation.
175`voltage` is the voltage at which they are operating. The function
176should calculate the average static power for the last `interval`
177milliseconds. It returns 0 on success, -E* on error. If it
178succeeds, it should store the static power in `power`. Reading the
179temperature of the cpus described by `cpumask` is left for
180plat_get_static() to do as the platform knows best which thermal
181sensor is closest to the cpu.
182
183If `plat_static_func` is NULL, static power is considered to be
184negligible for this platform and only dynamic power is considered.
185
186The platform specific callback can then use any combination of tables
187and/or equations to permute the estimated value. Process grade
188information is not passed to the model since access to such data, from
189on-chip measurement capability or manufacture time data, is platform
190specific.
191
192Note: the significance of static power for CPUs in comparison to
193dynamic power is highly dependent on implementation. Given the
194potential complexity in implementation, the importance and accuracy of
195its inclusion when using cpu cooling devices should be assessed on a
196case by case basis.
197
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index 65ec5f01aa8d..c56b57dcfda5 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -526,34 +526,13 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy)
526 526
527static void bL_cpufreq_ready(struct cpufreq_policy *policy) 527static void bL_cpufreq_ready(struct cpufreq_policy *policy)
528{ 528{
529 struct device *cpu_dev = get_cpu_device(policy->cpu);
530 int cur_cluster = cpu_to_cluster(policy->cpu); 529 int cur_cluster = cpu_to_cluster(policy->cpu);
531 struct device_node *np;
532 530
533 /* Do not register a cpu_cooling device if we are in IKS mode */ 531 /* Do not register a cpu_cooling device if we are in IKS mode */
534 if (cur_cluster >= MAX_CLUSTERS) 532 if (cur_cluster >= MAX_CLUSTERS)
535 return; 533 return;
536 534
537 np = of_node_get(cpu_dev->of_node); 535 cdev[cur_cluster] = of_cpufreq_cooling_register(policy);
538 if (WARN_ON(!np))
539 return;
540
541 if (of_find_property(np, "#cooling-cells", NULL)) {
542 u32 power_coefficient = 0;
543
544 of_property_read_u32(np, "dynamic-power-coefficient",
545 &power_coefficient);
546
547 cdev[cur_cluster] = of_cpufreq_power_cooling_register(np,
548 policy, power_coefficient, NULL);
549 if (IS_ERR(cdev[cur_cluster])) {
550 dev_err(cpu_dev,
551 "running cpufreq without cooling device: %ld\n",
552 PTR_ERR(cdev[cur_cluster]));
553 cdev[cur_cluster] = NULL;
554 }
555 }
556 of_node_put(np);
557} 536}
558 537
559static struct cpufreq_driver bL_cpufreq_driver = { 538static struct cpufreq_driver bL_cpufreq_driver = {
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index 545946ad0752..de3d104c25d7 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -319,33 +319,8 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
319static void cpufreq_ready(struct cpufreq_policy *policy) 319static void cpufreq_ready(struct cpufreq_policy *policy)
320{ 320{
321 struct private_data *priv = policy->driver_data; 321 struct private_data *priv = policy->driver_data;
322 struct device_node *np = of_node_get(priv->cpu_dev->of_node);
323 322
324 if (WARN_ON(!np)) 323 priv->cdev = of_cpufreq_cooling_register(policy);
325 return;
326
327 /*
328 * For now, just loading the cooling device;
329 * thermal DT code takes care of matching them.
330 */
331 if (of_find_property(np, "#cooling-cells", NULL)) {
332 u32 power_coefficient = 0;
333
334 of_property_read_u32(np, "dynamic-power-coefficient",
335 &power_coefficient);
336
337 priv->cdev = of_cpufreq_power_cooling_register(np,
338 policy, power_coefficient, NULL);
339 if (IS_ERR(priv->cdev)) {
340 dev_err(priv->cpu_dev,
341 "running cpufreq without cooling device: %ld\n",
342 PTR_ERR(priv->cdev));
343
344 priv->cdev = NULL;
345 }
346 }
347
348 of_node_put(np);
349} 324}
350 325
351static struct cpufreq_driver dt_cpufreq_driver = { 326static struct cpufreq_driver dt_cpufreq_driver = {
diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
index b783919f063d..8c04dddd3c28 100644
--- a/drivers/cpufreq/mediatek-cpufreq.c
+++ b/drivers/cpufreq/mediatek-cpufreq.c
@@ -310,28 +310,8 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
310static void mtk_cpufreq_ready(struct cpufreq_policy *policy) 310static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
311{ 311{
312 struct mtk_cpu_dvfs_info *info = policy->driver_data; 312 struct mtk_cpu_dvfs_info *info = policy->driver_data;
313 struct device_node *np = of_node_get(info->cpu_dev->of_node);
314 u32 capacitance = 0;
315 313
316 if (WARN_ON(!np)) 314 info->cdev = of_cpufreq_cooling_register(policy);
317 return;
318
319 if (of_find_property(np, "#cooling-cells", NULL)) {
320 of_property_read_u32(np, DYNAMIC_POWER, &capacitance);
321
322 info->cdev = of_cpufreq_power_cooling_register(np,
323 policy, capacitance, NULL);
324
325 if (IS_ERR(info->cdev)) {
326 dev_err(info->cpu_dev,
327 "running cpufreq without cooling device: %ld\n",
328 PTR_ERR(info->cdev));
329
330 info->cdev = NULL;
331 }
332 }
333
334 of_node_put(np);
335} 315}
336 316
337static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) 317static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c
index 4ada55b8856e..0562761a3dec 100644
--- a/drivers/cpufreq/qoriq-cpufreq.c
+++ b/drivers/cpufreq/qoriq-cpufreq.c
@@ -275,20 +275,8 @@ static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
275static void qoriq_cpufreq_ready(struct cpufreq_policy *policy) 275static void qoriq_cpufreq_ready(struct cpufreq_policy *policy)
276{ 276{
277 struct cpu_data *cpud = policy->driver_data; 277 struct cpu_data *cpud = policy->driver_data;
278 struct device_node *np = of_get_cpu_node(policy->cpu, NULL);
279 278
280 if (of_find_property(np, "#cooling-cells", NULL)) { 279 cpud->cdev = of_cpufreq_cooling_register(policy);
281 cpud->cdev = of_cpufreq_cooling_register(np, policy);
282
283 if (IS_ERR(cpud->cdev) && PTR_ERR(cpud->cdev) != -ENOSYS) {
284 pr_err("cpu%d is not running as cooling device: %ld\n",
285 policy->cpu, PTR_ERR(cpud->cdev));
286
287 cpud->cdev = NULL;
288 }
289 }
290
291 of_node_put(np);
292} 280}
293 281
294static struct cpufreq_driver qoriq_cpufreq_driver = { 282static struct cpufreq_driver qoriq_cpufreq_driver = {
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index dc63aba092e4..dfd23245f778 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -88,7 +88,6 @@ struct time_in_idle {
88 * @policy: cpufreq policy. 88 * @policy: cpufreq policy.
89 * @node: list_head to link all cpufreq_cooling_device together. 89 * @node: list_head to link all cpufreq_cooling_device together.
90 * @idle_time: idle time stats 90 * @idle_time: idle time stats
91 * @plat_get_static_power: callback to calculate the static power
92 * 91 *
93 * This structure is required for keeping information of each registered 92 * This structure is required for keeping information of each registered
94 * cpufreq_cooling_device. 93 * cpufreq_cooling_device.
@@ -104,7 +103,6 @@ struct cpufreq_cooling_device {
104 struct cpufreq_policy *policy; 103 struct cpufreq_policy *policy;
105 struct list_head node; 104 struct list_head node;
106 struct time_in_idle *idle_time; 105 struct time_in_idle *idle_time;
107 get_static_t plat_get_static_power;
108}; 106};
109 107
110static DEFINE_IDA(cpufreq_ida); 108static DEFINE_IDA(cpufreq_ida);
@@ -319,60 +317,6 @@ static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu,
319} 317}
320 318
321/** 319/**
322 * get_static_power() - calculate the static power consumed by the cpus
323 * @cpufreq_cdev: struct &cpufreq_cooling_device for this cpu cdev
324 * @tz: thermal zone device in which we're operating
325 * @freq: frequency in KHz
326 * @power: pointer in which to store the calculated static power
327 *
328 * Calculate the static power consumed by the cpus described by
329 * @cpu_actor running at frequency @freq. This function relies on a
330 * platform specific function that should have been provided when the
331 * actor was registered. If it wasn't, the static power is assumed to
332 * be negligible. The calculated static power is stored in @power.
333 *
334 * Return: 0 on success, -E* on failure.
335 */
336static int get_static_power(struct cpufreq_cooling_device *cpufreq_cdev,
337 struct thermal_zone_device *tz, unsigned long freq,
338 u32 *power)
339{
340 struct dev_pm_opp *opp;
341 unsigned long voltage;
342 struct cpufreq_policy *policy = cpufreq_cdev->policy;
343 struct cpumask *cpumask = policy->related_cpus;
344 unsigned long freq_hz = freq * 1000;
345 struct device *dev;
346
347 if (!cpufreq_cdev->plat_get_static_power) {
348 *power = 0;
349 return 0;
350 }
351
352 dev = get_cpu_device(policy->cpu);
353 WARN_ON(!dev);
354
355 opp = dev_pm_opp_find_freq_exact(dev, freq_hz, true);
356 if (IS_ERR(opp)) {
357 dev_warn_ratelimited(dev, "Failed to find OPP for frequency %lu: %ld\n",
358 freq_hz, PTR_ERR(opp));
359 return -EINVAL;
360 }
361
362 voltage = dev_pm_opp_get_voltage(opp);
363 dev_pm_opp_put(opp);
364
365 if (voltage == 0) {
366 dev_err_ratelimited(dev, "Failed to get voltage for frequency %lu\n",
367 freq_hz);
368 return -EINVAL;
369 }
370
371 return cpufreq_cdev->plat_get_static_power(cpumask, tz->passive_delay,
372 voltage, power);
373}
374
375/**
376 * get_dynamic_power() - calculate the dynamic power 320 * get_dynamic_power() - calculate the dynamic power
377 * @cpufreq_cdev: &cpufreq_cooling_device for this cdev 321 * @cpufreq_cdev: &cpufreq_cooling_device for this cdev
378 * @freq: current frequency 322 * @freq: current frequency
@@ -491,8 +435,8 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
491 u32 *power) 435 u32 *power)
492{ 436{
493 unsigned long freq; 437 unsigned long freq;
494 int i = 0, cpu, ret; 438 int i = 0, cpu;
495 u32 static_power, dynamic_power, total_load = 0; 439 u32 total_load = 0;
496 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; 440 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
497 struct cpufreq_policy *policy = cpufreq_cdev->policy; 441 struct cpufreq_policy *policy = cpufreq_cdev->policy;
498 u32 *load_cpu = NULL; 442 u32 *load_cpu = NULL;
@@ -522,22 +466,15 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
522 466
523 cpufreq_cdev->last_load = total_load; 467 cpufreq_cdev->last_load = total_load;
524 468
525 dynamic_power = get_dynamic_power(cpufreq_cdev, freq); 469 *power = get_dynamic_power(cpufreq_cdev, freq);
526 ret = get_static_power(cpufreq_cdev, tz, freq, &static_power);
527 if (ret) {
528 kfree(load_cpu);
529 return ret;
530 }
531 470
532 if (load_cpu) { 471 if (load_cpu) {
533 trace_thermal_power_cpu_get_power(policy->related_cpus, freq, 472 trace_thermal_power_cpu_get_power(policy->related_cpus, freq,
534 load_cpu, i, dynamic_power, 473 load_cpu, i, *power);
535 static_power);
536 474
537 kfree(load_cpu); 475 kfree(load_cpu);
538 } 476 }
539 477
540 *power = static_power + dynamic_power;
541 return 0; 478 return 0;
542} 479}
543 480
@@ -561,8 +498,6 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev,
561 unsigned long state, u32 *power) 498 unsigned long state, u32 *power)
562{ 499{
563 unsigned int freq, num_cpus; 500 unsigned int freq, num_cpus;
564 u32 static_power, dynamic_power;
565 int ret;
566 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; 501 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
567 502
568 /* Request state should be less than max_level */ 503 /* Request state should be less than max_level */
@@ -572,13 +507,9 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev,
572 num_cpus = cpumask_weight(cpufreq_cdev->policy->cpus); 507 num_cpus = cpumask_weight(cpufreq_cdev->policy->cpus);
573 508
574 freq = cpufreq_cdev->freq_table[state].frequency; 509 freq = cpufreq_cdev->freq_table[state].frequency;
575 dynamic_power = cpu_freq_to_power(cpufreq_cdev, freq) * num_cpus; 510 *power = cpu_freq_to_power(cpufreq_cdev, freq) * num_cpus;
576 ret = get_static_power(cpufreq_cdev, tz, freq, &static_power);
577 if (ret)
578 return ret;
579 511
580 *power = static_power + dynamic_power; 512 return 0;
581 return ret;
582} 513}
583 514
584/** 515/**
@@ -606,21 +537,14 @@ static int cpufreq_power2state(struct thermal_cooling_device *cdev,
606 unsigned long *state) 537 unsigned long *state)
607{ 538{
608 unsigned int cur_freq, target_freq; 539 unsigned int cur_freq, target_freq;
609 int ret; 540 u32 last_load, normalised_power;
610 s32 dyn_power;
611 u32 last_load, normalised_power, static_power;
612 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; 541 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
613 struct cpufreq_policy *policy = cpufreq_cdev->policy; 542 struct cpufreq_policy *policy = cpufreq_cdev->policy;
614 543
615 cur_freq = cpufreq_quick_get(policy->cpu); 544 cur_freq = cpufreq_quick_get(policy->cpu);
616 ret = get_static_power(cpufreq_cdev, tz, cur_freq, &static_power); 545 power = power > 0 ? power : 0;
617 if (ret)
618 return ret;
619
620 dyn_power = power - static_power;
621 dyn_power = dyn_power > 0 ? dyn_power : 0;
622 last_load = cpufreq_cdev->last_load ?: 1; 546 last_load = cpufreq_cdev->last_load ?: 1;
623 normalised_power = (dyn_power * 100) / last_load; 547 normalised_power = (power * 100) / last_load;
624 target_freq = cpu_power_to_freq(cpufreq_cdev, normalised_power); 548 target_freq = cpu_power_to_freq(cpufreq_cdev, normalised_power);
625 549
626 *state = get_level(cpufreq_cdev, target_freq); 550 *state = get_level(cpufreq_cdev, target_freq);
@@ -671,8 +595,6 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table,
671 * @policy: cpufreq policy 595 * @policy: cpufreq policy
672 * Normally this should be same as cpufreq policy->related_cpus. 596 * Normally this should be same as cpufreq policy->related_cpus.
673 * @capacitance: dynamic power coefficient for these cpus 597 * @capacitance: dynamic power coefficient for these cpus
674 * @plat_static_func: function to calculate the static power consumed by these
675 * cpus (optional)
676 * 598 *
677 * This interface function registers the cpufreq cooling device with the name 599 * This interface function registers the cpufreq cooling device with the name
678 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq 600 * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
@@ -684,8 +606,7 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table,
684 */ 606 */
685static struct thermal_cooling_device * 607static struct thermal_cooling_device *
686__cpufreq_cooling_register(struct device_node *np, 608__cpufreq_cooling_register(struct device_node *np,
687 struct cpufreq_policy *policy, u32 capacitance, 609 struct cpufreq_policy *policy, u32 capacitance)
688 get_static_t plat_static_func)
689{ 610{
690 struct thermal_cooling_device *cdev; 611 struct thermal_cooling_device *cdev;
691 struct cpufreq_cooling_device *cpufreq_cdev; 612 struct cpufreq_cooling_device *cpufreq_cdev;
@@ -755,8 +676,6 @@ __cpufreq_cooling_register(struct device_node *np,
755 } 676 }
756 677
757 if (capacitance) { 678 if (capacitance) {
758 cpufreq_cdev->plat_get_static_power = plat_static_func;
759
760 ret = update_freq_table(cpufreq_cdev, capacitance); 679 ret = update_freq_table(cpufreq_cdev, capacitance);
761 if (ret) { 680 if (ret) {
762 cdev = ERR_PTR(ret); 681 cdev = ERR_PTR(ret);
@@ -813,13 +732,12 @@ free_cdev:
813struct thermal_cooling_device * 732struct thermal_cooling_device *
814cpufreq_cooling_register(struct cpufreq_policy *policy) 733cpufreq_cooling_register(struct cpufreq_policy *policy)
815{ 734{
816 return __cpufreq_cooling_register(NULL, policy, 0, NULL); 735 return __cpufreq_cooling_register(NULL, policy, 0);
817} 736}
818EXPORT_SYMBOL_GPL(cpufreq_cooling_register); 737EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
819 738
820/** 739/**
821 * of_cpufreq_cooling_register - function to create cpufreq cooling device. 740 * of_cpufreq_cooling_register - function to create cpufreq cooling device.
822 * @np: a valid struct device_node to the cooling device device tree node
823 * @policy: cpufreq policy 741 * @policy: cpufreq policy
824 * 742 *
825 * This interface function registers the cpufreq cooling device with the name 743 * This interface function registers the cpufreq cooling device with the name
@@ -827,86 +745,45 @@ EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
827 * cooling devices. Using this API, the cpufreq cooling device will be 745 * cooling devices. Using this API, the cpufreq cooling device will be
828 * linked to the device tree node provided. 746 * linked to the device tree node provided.
829 * 747 *
830 * Return: a valid struct thermal_cooling_device pointer on success,
831 * on failure, it returns a corresponding ERR_PTR().
832 */
833struct thermal_cooling_device *
834of_cpufreq_cooling_register(struct device_node *np,
835 struct cpufreq_policy *policy)
836{
837 if (!np)
838 return ERR_PTR(-EINVAL);
839
840 return __cpufreq_cooling_register(np, policy, 0, NULL);
841}
842EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register);
843
844/**
845 * cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions
846 * @policy: cpufreq policy
847 * @capacitance: dynamic power coefficient for these cpus
848 * @plat_static_func: function to calculate the static power consumed by these
849 * cpus (optional)
850 *
851 * This interface function registers the cpufreq cooling device with
852 * the name "thermal-cpufreq-%x". This api can support multiple
853 * instances of cpufreq cooling devices. Using this function, the
854 * cooling device will implement the power extensions by using a
855 * simple cpu power model. The cpus must have registered their OPPs
856 * using the OPP library.
857 *
858 * An optional @plat_static_func may be provided to calculate the
859 * static power consumed by these cpus. If the platform's static
860 * power consumption is unknown or negligible, make it NULL.
861 *
862 * Return: a valid struct thermal_cooling_device pointer on success,
863 * on failure, it returns a corresponding ERR_PTR().
864 */
865struct thermal_cooling_device *
866cpufreq_power_cooling_register(struct cpufreq_policy *policy, u32 capacitance,
867 get_static_t plat_static_func)
868{
869 return __cpufreq_cooling_register(NULL, policy, capacitance,
870 plat_static_func);
871}
872EXPORT_SYMBOL(cpufreq_power_cooling_register);
873
874/**
875 * of_cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions
876 * @np: a valid struct device_node to the cooling device device tree node
877 * @policy: cpufreq policy
878 * @capacitance: dynamic power coefficient for these cpus
879 * @plat_static_func: function to calculate the static power consumed by these
880 * cpus (optional)
881 *
882 * This interface function registers the cpufreq cooling device with
883 * the name "thermal-cpufreq-%x". This api can support multiple
884 * instances of cpufreq cooling devices. Using this API, the cpufreq
885 * cooling device will be linked to the device tree node provided.
886 * Using this function, the cooling device will implement the power 748 * Using this function, the cooling device will implement the power
887 * extensions by using a simple cpu power model. The cpus must have 749 * extensions by using a simple cpu power model. The cpus must have
888 * registered their OPPs using the OPP library. 750 * registered their OPPs using the OPP library.
889 * 751 *
890 * An optional @plat_static_func may be provided to calculate the 752 * It also takes into account, if property present in policy CPU node, the
891 * static power consumed by these cpus. If the platform's static 753 * static power consumed by the cpu.
892 * power consumption is unknown or negligible, make it NULL.
893 * 754 *
894 * Return: a valid struct thermal_cooling_device pointer on success, 755 * Return: a valid struct thermal_cooling_device pointer on success,
895 * on failure, it returns a corresponding ERR_PTR(). 756 * and NULL on failure.
896 */ 757 */
897struct thermal_cooling_device * 758struct thermal_cooling_device *
898of_cpufreq_power_cooling_register(struct device_node *np, 759of_cpufreq_cooling_register(struct cpufreq_policy *policy)
899 struct cpufreq_policy *policy,
900 u32 capacitance,
901 get_static_t plat_static_func)
902{ 760{
903 if (!np) 761 struct device_node *np = of_get_cpu_node(policy->cpu, NULL);
904 return ERR_PTR(-EINVAL); 762 struct thermal_cooling_device *cdev = NULL;
763 u32 capacitance = 0;
764
765 if (!np) {
766 pr_err("cpu_cooling: OF node not available for cpu%d\n",
767 policy->cpu);
768 return NULL;
769 }
770
771 if (of_find_property(np, "#cooling-cells", NULL)) {
772 of_property_read_u32(np, "dynamic-power-coefficient",
773 &capacitance);
905 774
906 return __cpufreq_cooling_register(np, policy, capacitance, 775 cdev = __cpufreq_cooling_register(np, policy, capacitance);
907 plat_static_func); 776 if (IS_ERR(cdev)) {
777 pr_err("cpu_cooling: cpu%d is not running as cooling device: %ld\n",
778 policy->cpu, PTR_ERR(cdev));
779 cdev = NULL;
780 }
781 }
782
783 of_node_put(np);
784 return cdev;
908} 785}
909EXPORT_SYMBOL(of_cpufreq_power_cooling_register); 786EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register);
910 787
911/** 788/**
912 * cpufreq_cooling_unregister - function to remove cpufreq cooling device. 789 * cpufreq_cooling_unregister - function to remove cpufreq cooling device.
diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h
index d4292ebc5c8b..de0dafb9399d 100644
--- a/include/linux/cpu_cooling.h
+++ b/include/linux/cpu_cooling.h
@@ -30,9 +30,6 @@
30 30
31struct cpufreq_policy; 31struct cpufreq_policy;
32 32
33typedef int (*get_static_t)(cpumask_t *cpumask, int interval,
34 unsigned long voltage, u32 *power);
35
36#ifdef CONFIG_CPU_THERMAL 33#ifdef CONFIG_CPU_THERMAL
37/** 34/**
38 * cpufreq_cooling_register - function to create cpufreq cooling device. 35 * cpufreq_cooling_register - function to create cpufreq cooling device.
@@ -41,43 +38,6 @@ typedef int (*get_static_t)(cpumask_t *cpumask, int interval,
41struct thermal_cooling_device * 38struct thermal_cooling_device *
42cpufreq_cooling_register(struct cpufreq_policy *policy); 39cpufreq_cooling_register(struct cpufreq_policy *policy);
43 40
44struct thermal_cooling_device *
45cpufreq_power_cooling_register(struct cpufreq_policy *policy,
46 u32 capacitance, get_static_t plat_static_func);
47
48/**
49 * of_cpufreq_cooling_register - create cpufreq cooling device based on DT.
50 * @np: a valid struct device_node to the cooling device device tree node.
51 * @policy: cpufreq policy.
52 */
53#ifdef CONFIG_THERMAL_OF
54struct thermal_cooling_device *
55of_cpufreq_cooling_register(struct device_node *np,
56 struct cpufreq_policy *policy);
57
58struct thermal_cooling_device *
59of_cpufreq_power_cooling_register(struct device_node *np,
60 struct cpufreq_policy *policy,
61 u32 capacitance,
62 get_static_t plat_static_func);
63#else
64static inline struct thermal_cooling_device *
65of_cpufreq_cooling_register(struct device_node *np,
66 struct cpufreq_policy *policy)
67{
68 return ERR_PTR(-ENOSYS);
69}
70
71static inline struct thermal_cooling_device *
72of_cpufreq_power_cooling_register(struct device_node *np,
73 struct cpufreq_policy *policy,
74 u32 capacitance,
75 get_static_t plat_static_func)
76{
77 return NULL;
78}
79#endif
80
81/** 41/**
82 * cpufreq_cooling_unregister - function to remove cpufreq cooling device. 42 * cpufreq_cooling_unregister - function to remove cpufreq cooling device.
83 * @cdev: thermal cooling device pointer. 43 * @cdev: thermal cooling device pointer.
@@ -90,34 +50,27 @@ cpufreq_cooling_register(struct cpufreq_policy *policy)
90{ 50{
91 return ERR_PTR(-ENOSYS); 51 return ERR_PTR(-ENOSYS);
92} 52}
93static inline struct thermal_cooling_device *
94cpufreq_power_cooling_register(struct cpufreq_policy *policy,
95 u32 capacitance, get_static_t plat_static_func)
96{
97 return NULL;
98}
99 53
100static inline struct thermal_cooling_device * 54static inline
101of_cpufreq_cooling_register(struct device_node *np, 55void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
102 struct cpufreq_policy *policy)
103{ 56{
104 return ERR_PTR(-ENOSYS); 57 return;
105} 58}
59#endif /* CONFIG_CPU_THERMAL */
106 60
61#if defined(CONFIG_THERMAL_OF) && defined(CONFIG_CPU_THERMAL)
62/**
63 * of_cpufreq_cooling_register - create cpufreq cooling device based on DT.
64 * @policy: cpufreq policy.
65 */
66struct thermal_cooling_device *
67of_cpufreq_cooling_register(struct cpufreq_policy *policy);
68#else
107static inline struct thermal_cooling_device * 69static inline struct thermal_cooling_device *
108of_cpufreq_power_cooling_register(struct device_node *np, 70of_cpufreq_cooling_register(struct cpufreq_policy *policy)
109 struct cpufreq_policy *policy,
110 u32 capacitance,
111 get_static_t plat_static_func)
112{ 71{
113 return NULL; 72 return NULL;
114} 73}
115 74#endif /* defined(CONFIG_THERMAL_OF) && defined(CONFIG_CPU_THERMAL) */
116static inline
117void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
118{
119 return;
120}
121#endif /* CONFIG_CPU_THERMAL */
122 75
123#endif /* __CPU_COOLING_H__ */ 76#endif /* __CPU_COOLING_H__ */
diff --git a/include/trace/events/thermal.h b/include/trace/events/thermal.h
index 78946640fe03..135e5421f003 100644
--- a/include/trace/events/thermal.h
+++ b/include/trace/events/thermal.h
@@ -94,9 +94,9 @@ TRACE_EVENT(thermal_zone_trip,
94#ifdef CONFIG_CPU_THERMAL 94#ifdef CONFIG_CPU_THERMAL
95TRACE_EVENT(thermal_power_cpu_get_power, 95TRACE_EVENT(thermal_power_cpu_get_power,
96 TP_PROTO(const struct cpumask *cpus, unsigned long freq, u32 *load, 96 TP_PROTO(const struct cpumask *cpus, unsigned long freq, u32 *load,
97 size_t load_len, u32 dynamic_power, u32 static_power), 97 size_t load_len, u32 dynamic_power),
98 98
99 TP_ARGS(cpus, freq, load, load_len, dynamic_power, static_power), 99 TP_ARGS(cpus, freq, load, load_len, dynamic_power),
100 100
101 TP_STRUCT__entry( 101 TP_STRUCT__entry(
102 __bitmask(cpumask, num_possible_cpus()) 102 __bitmask(cpumask, num_possible_cpus())
@@ -104,7 +104,6 @@ TRACE_EVENT(thermal_power_cpu_get_power,
104 __dynamic_array(u32, load, load_len) 104 __dynamic_array(u32, load, load_len)
105 __field(size_t, load_len ) 105 __field(size_t, load_len )
106 __field(u32, dynamic_power ) 106 __field(u32, dynamic_power )
107 __field(u32, static_power )
108 ), 107 ),
109 108
110 TP_fast_assign( 109 TP_fast_assign(
@@ -115,13 +114,12 @@ TRACE_EVENT(thermal_power_cpu_get_power,
115 load_len * sizeof(*load)); 114 load_len * sizeof(*load));
116 __entry->load_len = load_len; 115 __entry->load_len = load_len;
117 __entry->dynamic_power = dynamic_power; 116 __entry->dynamic_power = dynamic_power;
118 __entry->static_power = static_power;
119 ), 117 ),
120 118
121 TP_printk("cpus=%s freq=%lu load={%s} dynamic_power=%d static_power=%d", 119 TP_printk("cpus=%s freq=%lu load={%s} dynamic_power=%d",
122 __get_bitmask(cpumask), __entry->freq, 120 __get_bitmask(cpumask), __entry->freq,
123 __print_array(__get_dynamic_array(load), __entry->load_len, 4), 121 __print_array(__get_dynamic_array(load), __entry->load_len, 4),
124 __entry->dynamic_power, __entry->static_power) 122 __entry->dynamic_power)
125); 123);
126 124
127TRACE_EVENT(thermal_power_cpu_limit, 125TRACE_EVENT(thermal_power_cpu_limit,