aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/thermal/sysfs-api.txt21
-rw-r--r--drivers/thermal/Kconfig17
-rw-r--r--drivers/thermal/devfreq_cooling.c152
-rw-r--r--drivers/thermal/intel_soc_dts_thermal.c9
-rw-r--r--drivers/thermal/thermal_core.c64
-rw-r--r--include/linux/devfreq_cooling.h19
-rw-r--r--include/trace/events/thermal.h11
7 files changed, 244 insertions, 49 deletions
diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index ef473dc7f55e..bb9a0a53e76b 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -582,3 +582,24 @@ platform data is provided, this uses the step_wise throttling policy.
582This function serves as an arbitrator to set the state of a cooling 582This function serves as an arbitrator to set the state of a cooling
583device. It sets the cooling device to the deepest cooling state if 583device. It sets the cooling device to the deepest cooling state if
584possible. 584possible.
585
5866. thermal_emergency_poweroff:
587
588On an event of critical trip temperature crossing. Thermal framework
589allows the system to shutdown gracefully by calling orderly_poweroff().
590In the event of a failure of orderly_poweroff() to shut down the system
591we are in danger of keeping the system alive at undesirably high
592temperatures. To mitigate this high risk scenario we program a work
593queue to fire after a pre-determined number of seconds to start
594an emergency shutdown of the device using the kernel_power_off()
595function. In case kernel_power_off() fails then finally
596emergency_restart() is called in the worst case.
597
598The delay should be carefully profiled so as to give adequate time for
599orderly_poweroff(). In case of failure of an orderly_poweroff() the
600emergency poweroff kicks in after the delay has elapsed and shuts down
601the system.
602
603If set to 0 emergency poweroff will not be supported. So a carefully
604profiled non-zero positive value is a must for emergerncy poweroff to be
605triggered.
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index f786ae433032..4edc011fe4a5 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -15,6 +15,23 @@ menuconfig THERMAL
15 15
16if THERMAL 16if THERMAL
17 17
18config THERMAL_EMERGENCY_POWEROFF_DELAY_MS
19 int "Emergency poweroff delay in milli-seconds"
20 depends on THERMAL
21 default 0
22 help
23 Thermal subsystem will issue a graceful shutdown when
24 critical temperatures are reached using orderly_poweroff(). In
25 case of failure of an orderly_poweroff(), the thermal emergency
26 poweroff kicks in after a delay has elapsed and shuts down the system.
27 This config is number of milliseconds to delay before emergency
28 poweroff kicks in. Similarly to the critical trip point,
29 the delay should be carefully profiled so as to give adequate
30 time for orderly_poweroff() to finish on regular execution.
31 If set to 0 emergency poweroff will not be supported.
32
33 In doubt, leave as 0.
34
18config THERMAL_HWMON 35config THERMAL_HWMON
19 bool 36 bool
20 prompt "Expose thermal sensors as hwmon device" 37 prompt "Expose thermal sensors as hwmon device"
diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c
index 4bf4ad58cffd..ef59256887ff 100644
--- a/drivers/thermal/devfreq_cooling.c
+++ b/drivers/thermal/devfreq_cooling.c
@@ -28,6 +28,8 @@
28 28
29#include <trace/events/thermal.h> 29#include <trace/events/thermal.h>
30 30
31#define SCALE_ERROR_MITIGATION 100
32
31static DEFINE_IDA(devfreq_ida); 33static DEFINE_IDA(devfreq_ida);
32 34
33/** 35/**
@@ -45,6 +47,12 @@ static DEFINE_IDA(devfreq_ida);
45 * @freq_table_size: Size of the @freq_table and @power_table 47 * @freq_table_size: Size of the @freq_table and @power_table
46 * @power_ops: Pointer to devfreq_cooling_power, used to generate the 48 * @power_ops: Pointer to devfreq_cooling_power, used to generate the
47 * @power_table. 49 * @power_table.
50 * @res_util: Resource utilization scaling factor for the power.
51 * It is multiplied by 100 to minimize the error. It is used
52 * for estimation of the power budget instead of using
53 * 'utilization' (which is 'busy_time / 'total_time').
54 * The 'res_util' range is from 100 to (power_table[state] * 100)
55 * for the corresponding 'state'.
48 */ 56 */
49struct devfreq_cooling_device { 57struct devfreq_cooling_device {
50 int id; 58 int id;
@@ -55,6 +63,8 @@ struct devfreq_cooling_device {
55 u32 *freq_table; 63 u32 *freq_table;
56 size_t freq_table_size; 64 size_t freq_table_size;
57 struct devfreq_cooling_power *power_ops; 65 struct devfreq_cooling_power *power_ops;
66 u32 res_util;
67 int capped_state;
58}; 68};
59 69
60/** 70/**
@@ -164,27 +174,12 @@ freq_get_state(struct devfreq_cooling_device *dfc, unsigned long freq)
164 return THERMAL_CSTATE_INVALID; 174 return THERMAL_CSTATE_INVALID;
165} 175}
166 176
167/** 177static unsigned long get_voltage(struct devfreq *df, unsigned long freq)
168 * get_static_power() - calculate the static power
169 * @dfc: Pointer to devfreq cooling device
170 * @freq: Frequency in Hz
171 *
172 * Calculate the static power in milliwatts using the supplied
173 * get_static_power(). The current voltage is calculated using the
174 * OPP library. If no get_static_power() was supplied, assume the
175 * static power is negligible.
176 */
177static unsigned long
178get_static_power(struct devfreq_cooling_device *dfc, unsigned long freq)
179{ 178{
180 struct devfreq *df = dfc->devfreq;
181 struct device *dev = df->dev.parent; 179 struct device *dev = df->dev.parent;
182 unsigned long voltage; 180 unsigned long voltage;
183 struct dev_pm_opp *opp; 181 struct dev_pm_opp *opp;
184 182
185 if (!dfc->power_ops->get_static_power)
186 return 0;
187
188 opp = dev_pm_opp_find_freq_exact(dev, freq, true); 183 opp = dev_pm_opp_find_freq_exact(dev, freq, true);
189 if (PTR_ERR(opp) == -ERANGE) 184 if (PTR_ERR(opp) == -ERANGE)
190 opp = dev_pm_opp_find_freq_exact(dev, freq, false); 185 opp = dev_pm_opp_find_freq_exact(dev, freq, false);
@@ -202,9 +197,35 @@ get_static_power(struct devfreq_cooling_device *dfc, unsigned long freq)
202 dev_err_ratelimited(dev, 197 dev_err_ratelimited(dev,
203 "Failed to get voltage for frequency %lu\n", 198 "Failed to get voltage for frequency %lu\n",
204 freq); 199 freq);
205 return 0;
206 } 200 }
207 201
202 return voltage;
203}
204
205/**
206 * get_static_power() - calculate the static power
207 * @dfc: Pointer to devfreq cooling device
208 * @freq: Frequency in Hz
209 *
210 * Calculate the static power in milliwatts using the supplied
211 * get_static_power(). The current voltage is calculated using the
212 * OPP library. If no get_static_power() was supplied, assume the
213 * static power is negligible.
214 */
215static unsigned long
216get_static_power(struct devfreq_cooling_device *dfc, unsigned long freq)
217{
218 struct devfreq *df = dfc->devfreq;
219 unsigned long voltage;
220
221 if (!dfc->power_ops->get_static_power)
222 return 0;
223
224 voltage = get_voltage(df, freq);
225
226 if (voltage == 0)
227 return 0;
228
208 return dfc->power_ops->get_static_power(df, voltage); 229 return dfc->power_ops->get_static_power(df, voltage);
209} 230}
210 231
@@ -239,6 +260,16 @@ get_dynamic_power(struct devfreq_cooling_device *dfc, unsigned long freq,
239 return power; 260 return power;
240} 261}
241 262
263
264static inline unsigned long get_total_power(struct devfreq_cooling_device *dfc,
265 unsigned long freq,
266 unsigned long voltage)
267{
268 return get_static_power(dfc, freq) + get_dynamic_power(dfc, freq,
269 voltage);
270}
271
272
242static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cdev, 273static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cdev,
243 struct thermal_zone_device *tz, 274 struct thermal_zone_device *tz,
244 u32 *power) 275 u32 *power)
@@ -248,27 +279,55 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd
248 struct devfreq_dev_status *status = &df->last_status; 279 struct devfreq_dev_status *status = &df->last_status;
249 unsigned long state; 280 unsigned long state;
250 unsigned long freq = status->current_frequency; 281 unsigned long freq = status->current_frequency;
251 u32 dyn_power, static_power; 282 unsigned long voltage;
283 u32 dyn_power = 0;
284 u32 static_power = 0;
285 int res;
252 286
253 /* Get dynamic power for state */
254 state = freq_get_state(dfc, freq); 287 state = freq_get_state(dfc, freq);
255 if (state == THERMAL_CSTATE_INVALID) 288 if (state == THERMAL_CSTATE_INVALID) {
256 return -EAGAIN; 289 res = -EAGAIN;
290 goto fail;
291 }
257 292
258 dyn_power = dfc->power_table[state]; 293 if (dfc->power_ops->get_real_power) {
294 voltage = get_voltage(df, freq);
295 if (voltage == 0) {
296 res = -EINVAL;
297 goto fail;
298 }
259 299
260 /* Scale dynamic power for utilization */ 300 res = dfc->power_ops->get_real_power(df, power, freq, voltage);
261 dyn_power = (dyn_power * status->busy_time) / status->total_time; 301 if (!res) {
302 state = dfc->capped_state;
303 dfc->res_util = dfc->power_table[state];
304 dfc->res_util *= SCALE_ERROR_MITIGATION;
262 305
263 /* Get static power */ 306 if (*power > 1)
264 static_power = get_static_power(dfc, freq); 307 dfc->res_util /= *power;
308 } else {
309 goto fail;
310 }
311 } else {
312 dyn_power = dfc->power_table[state];
265 313
266 trace_thermal_power_devfreq_get_power(cdev, status, freq, dyn_power, 314 /* Scale dynamic power for utilization */
267 static_power); 315 dyn_power *= status->busy_time;
316 dyn_power /= status->total_time;
317 /* Get static power */
318 static_power = get_static_power(dfc, freq);
268 319
269 *power = dyn_power + static_power; 320 *power = dyn_power + static_power;
321 }
322
323 trace_thermal_power_devfreq_get_power(cdev, status, freq, dyn_power,
324 static_power, *power);
270 325
271 return 0; 326 return 0;
327fail:
328 /* It is safe to set max in this case */
329 dfc->res_util = SCALE_ERROR_MITIGATION;
330 return res;
272} 331}
273 332
274static int devfreq_cooling_state2power(struct thermal_cooling_device *cdev, 333static int devfreq_cooling_state2power(struct thermal_cooling_device *cdev,
@@ -301,26 +360,34 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev,
301 unsigned long busy_time; 360 unsigned long busy_time;
302 s32 dyn_power; 361 s32 dyn_power;
303 u32 static_power; 362 u32 static_power;
363 s32 est_power;
304 int i; 364 int i;
305 365
306 static_power = get_static_power(dfc, freq); 366 if (dfc->power_ops->get_real_power) {
367 /* Scale for resource utilization */
368 est_power = power * dfc->res_util;
369 est_power /= SCALE_ERROR_MITIGATION;
370 } else {
371 static_power = get_static_power(dfc, freq);
307 372
308 dyn_power = power - static_power; 373 dyn_power = power - static_power;
309 dyn_power = dyn_power > 0 ? dyn_power : 0; 374 dyn_power = dyn_power > 0 ? dyn_power : 0;
310 375
311 /* Scale dynamic power for utilization */ 376 /* Scale dynamic power for utilization */
312 busy_time = status->busy_time ?: 1; 377 busy_time = status->busy_time ?: 1;
313 dyn_power = (dyn_power * status->total_time) / busy_time; 378 est_power = (dyn_power * status->total_time) / busy_time;
379 }
314 380
315 /* 381 /*
316 * Find the first cooling state that is within the power 382 * Find the first cooling state that is within the power
317 * budget for dynamic power. 383 * budget for dynamic power.
318 */ 384 */
319 for (i = 0; i < dfc->freq_table_size - 1; i++) 385 for (i = 0; i < dfc->freq_table_size - 1; i++)
320 if (dyn_power >= dfc->power_table[i]) 386 if (est_power >= dfc->power_table[i])
321 break; 387 break;
322 388
323 *state = i; 389 *state = i;
390 dfc->capped_state = i;
324 trace_thermal_power_devfreq_limit(cdev, freq, *state, power); 391 trace_thermal_power_devfreq_limit(cdev, freq, *state, power);
325 return 0; 392 return 0;
326} 393}
@@ -376,7 +443,7 @@ static int devfreq_cooling_gen_tables(struct devfreq_cooling_device *dfc)
376 } 443 }
377 444
378 for (i = 0, freq = ULONG_MAX; i < num_opps; i++, freq--) { 445 for (i = 0, freq = ULONG_MAX; i < num_opps; i++, freq--) {
379 unsigned long power_dyn, voltage; 446 unsigned long power, voltage;
380 struct dev_pm_opp *opp; 447 struct dev_pm_opp *opp;
381 448
382 opp = dev_pm_opp_find_freq_floor(dev, &freq); 449 opp = dev_pm_opp_find_freq_floor(dev, &freq);
@@ -389,12 +456,15 @@ static int devfreq_cooling_gen_tables(struct devfreq_cooling_device *dfc)
389 dev_pm_opp_put(opp); 456 dev_pm_opp_put(opp);
390 457
391 if (dfc->power_ops) { 458 if (dfc->power_ops) {
392 power_dyn = get_dynamic_power(dfc, freq, voltage); 459 if (dfc->power_ops->get_real_power)
460 power = get_total_power(dfc, freq, voltage);
461 else
462 power = get_dynamic_power(dfc, freq, voltage);
393 463
394 dev_dbg(dev, "Dynamic power table: %lu MHz @ %lu mV: %lu = %lu mW\n", 464 dev_dbg(dev, "Power table: %lu MHz @ %lu mV: %lu = %lu mW\n",
395 freq / 1000000, voltage, power_dyn, power_dyn); 465 freq / 1000000, voltage, power, power);
396 466
397 power_table[i] = power_dyn; 467 power_table[i] = power;
398 } 468 }
399 469
400 freq_table[i] = freq; 470 freq_table[i] = freq;
diff --git a/drivers/thermal/intel_soc_dts_thermal.c b/drivers/thermal/intel_soc_dts_thermal.c
index b2bbaa1c60b0..c27868b2c6af 100644
--- a/drivers/thermal/intel_soc_dts_thermal.c
+++ b/drivers/thermal/intel_soc_dts_thermal.c
@@ -73,8 +73,12 @@ static int __init intel_soc_thermal_init(void)
73 IRQF_TRIGGER_RISING | IRQF_ONESHOT, 73 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
74 "soc_dts", soc_dts); 74 "soc_dts", soc_dts);
75 if (err) { 75 if (err) {
76 pr_err("request_threaded_irq ret %d\n", err); 76 /*
77 goto error_irq; 77 * Do not just error out because the user space thermal
78 * daemon such as DPTF may use polling instead of being
79 * interrupt driven.
80 */
81 pr_warn("request_threaded_irq ret %d\n", err);
78 } 82 }
79 } 83 }
80 84
@@ -88,7 +92,6 @@ static int __init intel_soc_thermal_init(void)
88error_trips: 92error_trips:
89 if (soc_dts_thres_irq) 93 if (soc_dts_thres_irq)
90 free_irq(soc_dts_thres_irq, soc_dts); 94 free_irq(soc_dts_thres_irq, soc_dts);
91error_irq:
92 intel_soc_dts_iosf_exit(soc_dts); 95 intel_soc_dts_iosf_exit(soc_dts);
93 96
94 return err; 97 return err;
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 11f0675cb7e5..b21b9cc2c8d6 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -45,8 +45,10 @@ static LIST_HEAD(thermal_governor_list);
45 45
46static DEFINE_MUTEX(thermal_list_lock); 46static DEFINE_MUTEX(thermal_list_lock);
47static DEFINE_MUTEX(thermal_governor_lock); 47static DEFINE_MUTEX(thermal_governor_lock);
48static DEFINE_MUTEX(poweroff_lock);
48 49
49static atomic_t in_suspend; 50static atomic_t in_suspend;
51static bool power_off_triggered;
50 52
51static struct thermal_governor *def_governor; 53static struct thermal_governor *def_governor;
52 54
@@ -322,6 +324,54 @@ static void handle_non_critical_trips(struct thermal_zone_device *tz,
322 def_governor->throttle(tz, trip); 324 def_governor->throttle(tz, trip);
323} 325}
324 326
327/**
328 * thermal_emergency_poweroff_func - emergency poweroff work after a known delay
329 * @work: work_struct associated with the emergency poweroff function
330 *
331 * This function is called in very critical situations to force
332 * a kernel poweroff after a configurable timeout value.
333 */
334static void thermal_emergency_poweroff_func(struct work_struct *work)
335{
336 /*
337 * We have reached here after the emergency thermal shutdown
338 * Waiting period has expired. This means orderly_poweroff has
339 * not been able to shut off the system for some reason.
340 * Try to shut down the system immediately using kernel_power_off
341 * if populated
342 */
343 WARN(1, "Attempting kernel_power_off: Temperature too high\n");
344 kernel_power_off();
345
346 /*
347 * Worst of the worst case trigger emergency restart
348 */
349 WARN(1, "Attempting emergency_restart: Temperature too high\n");
350 emergency_restart();
351}
352
353static DECLARE_DELAYED_WORK(thermal_emergency_poweroff_work,
354 thermal_emergency_poweroff_func);
355
356/**
357 * thermal_emergency_poweroff - Trigger an emergency system poweroff
358 *
359 * This may be called from any critical situation to trigger a system shutdown
360 * after a known period of time. By default this is not scheduled.
361 */
362void thermal_emergency_poweroff(void)
363{
364 int poweroff_delay_ms = CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS;
365 /*
366 * poweroff_delay_ms must be a carefully profiled positive value.
367 * Its a must for thermal_emergency_poweroff_work to be scheduled
368 */
369 if (poweroff_delay_ms <= 0)
370 return;
371 schedule_delayed_work(&thermal_emergency_poweroff_work,
372 msecs_to_jiffies(poweroff_delay_ms));
373}
374
325static void handle_critical_trips(struct thermal_zone_device *tz, 375static void handle_critical_trips(struct thermal_zone_device *tz,
326 int trip, enum thermal_trip_type trip_type) 376 int trip, enum thermal_trip_type trip_type)
327{ 377{
@@ -342,7 +392,17 @@ static void handle_critical_trips(struct thermal_zone_device *tz,
342 dev_emerg(&tz->device, 392 dev_emerg(&tz->device,
343 "critical temperature reached(%d C),shutting down\n", 393 "critical temperature reached(%d C),shutting down\n",
344 tz->temperature / 1000); 394 tz->temperature / 1000);
345 orderly_poweroff(true); 395 mutex_lock(&poweroff_lock);
396 if (!power_off_triggered) {
397 /*
398 * Queue a backup emergency shutdown in the event of
399 * orderly_poweroff failure
400 */
401 thermal_emergency_poweroff();
402 orderly_poweroff(true);
403 power_off_triggered = true;
404 }
405 mutex_unlock(&poweroff_lock);
346 } 406 }
347} 407}
348 408
@@ -1463,6 +1523,7 @@ static int __init thermal_init(void)
1463{ 1523{
1464 int result; 1524 int result;
1465 1525
1526 mutex_init(&poweroff_lock);
1466 result = thermal_register_governors(); 1527 result = thermal_register_governors();
1467 if (result) 1528 if (result)
1468 goto error; 1529 goto error;
@@ -1497,6 +1558,7 @@ error:
1497 ida_destroy(&thermal_cdev_ida); 1558 ida_destroy(&thermal_cdev_ida);
1498 mutex_destroy(&thermal_list_lock); 1559 mutex_destroy(&thermal_list_lock);
1499 mutex_destroy(&thermal_governor_lock); 1560 mutex_destroy(&thermal_governor_lock);
1561 mutex_destroy(&poweroff_lock);
1500 return result; 1562 return result;
1501} 1563}
1502 1564
diff --git a/include/linux/devfreq_cooling.h b/include/linux/devfreq_cooling.h
index c35d0c0e0ada..4635f95000a4 100644
--- a/include/linux/devfreq_cooling.h
+++ b/include/linux/devfreq_cooling.h
@@ -34,6 +34,23 @@
34 * If get_dynamic_power() is NULL, then the 34 * If get_dynamic_power() is NULL, then the
35 * dynamic power is calculated as 35 * dynamic power is calculated as
36 * @dyn_power_coeff * frequency * voltage^2 36 * @dyn_power_coeff * frequency * voltage^2
37 * @get_real_power: When this is set, the framework uses it to ask the
38 * device driver for the actual power.
39 * Some devices have more sophisticated methods
40 * (like power counters) to approximate the actual power
41 * that they use.
42 * This function provides more accurate data to the
43 * thermal governor. When the driver does not provide
44 * such function, framework just uses pre-calculated
45 * table and scale the power by 'utilization'
46 * (based on 'busy_time' and 'total_time' taken from
47 * devfreq 'last_status').
48 * The value returned by this function must be lower
49 * or equal than the maximum power value
50 * for the current state
51 * (which can be found in power_table[state]).
52 * When this interface is used, the power_table holds
53 * max total (static + dynamic) power value for each OPP.
37 */ 54 */
38struct devfreq_cooling_power { 55struct devfreq_cooling_power {
39 unsigned long (*get_static_power)(struct devfreq *devfreq, 56 unsigned long (*get_static_power)(struct devfreq *devfreq,
@@ -41,6 +58,8 @@ struct devfreq_cooling_power {
41 unsigned long (*get_dynamic_power)(struct devfreq *devfreq, 58 unsigned long (*get_dynamic_power)(struct devfreq *devfreq,
42 unsigned long freq, 59 unsigned long freq,
43 unsigned long voltage); 60 unsigned long voltage);
61 int (*get_real_power)(struct devfreq *df, u32 *power,
62 unsigned long freq, unsigned long voltage);
44 unsigned long dyn_power_coeff; 63 unsigned long dyn_power_coeff;
45}; 64};
46 65
diff --git a/include/trace/events/thermal.h b/include/trace/events/thermal.h
index 2b4a8ff72d0d..6cde5b3514c2 100644
--- a/include/trace/events/thermal.h
+++ b/include/trace/events/thermal.h
@@ -151,9 +151,9 @@ TRACE_EVENT(thermal_power_cpu_limit,
151TRACE_EVENT(thermal_power_devfreq_get_power, 151TRACE_EVENT(thermal_power_devfreq_get_power,
152 TP_PROTO(struct thermal_cooling_device *cdev, 152 TP_PROTO(struct thermal_cooling_device *cdev,
153 struct devfreq_dev_status *status, unsigned long freq, 153 struct devfreq_dev_status *status, unsigned long freq,
154 u32 dynamic_power, u32 static_power), 154 u32 dynamic_power, u32 static_power, u32 power),
155 155
156 TP_ARGS(cdev, status, freq, dynamic_power, static_power), 156 TP_ARGS(cdev, status, freq, dynamic_power, static_power, power),
157 157
158 TP_STRUCT__entry( 158 TP_STRUCT__entry(
159 __string(type, cdev->type ) 159 __string(type, cdev->type )
@@ -161,6 +161,7 @@ TRACE_EVENT(thermal_power_devfreq_get_power,
161 __field(u32, load ) 161 __field(u32, load )
162 __field(u32, dynamic_power ) 162 __field(u32, dynamic_power )
163 __field(u32, static_power ) 163 __field(u32, static_power )
164 __field(u32, power)
164 ), 165 ),
165 166
166 TP_fast_assign( 167 TP_fast_assign(
@@ -169,11 +170,13 @@ TRACE_EVENT(thermal_power_devfreq_get_power,
169 __entry->load = (100 * status->busy_time) / status->total_time; 170 __entry->load = (100 * status->busy_time) / status->total_time;
170 __entry->dynamic_power = dynamic_power; 171 __entry->dynamic_power = dynamic_power;
171 __entry->static_power = static_power; 172 __entry->static_power = static_power;
173 __entry->power = power;
172 ), 174 ),
173 175
174 TP_printk("type=%s freq=%lu load=%u dynamic_power=%u static_power=%u", 176 TP_printk("type=%s freq=%lu load=%u dynamic_power=%u static_power=%u power=%u",
175 __get_str(type), __entry->freq, 177 __get_str(type), __entry->freq,
176 __entry->load, __entry->dynamic_power, __entry->static_power) 178 __entry->load, __entry->dynamic_power, __entry->static_power,
179 __entry->power)
177); 180);
178 181
179TRACE_EVENT(thermal_power_devfreq_limit, 182TRACE_EVENT(thermal_power_devfreq_limit,