0001 ===================================
0002 Generic Thermal Sysfs driver How To
0003 ===================================
0004
0005 Written by Sujith Thomas <sujith.thomas@intel.com>, Zhang Rui <rui.zhang@intel.com>
0006
0007 Updated: 2 January 2008
0008
0009 Copyright (c) 2008 Intel Corporation
0010
0011
0012 0. Introduction
0013 ===============
0014
0015 The generic thermal sysfs provides a set of interfaces for thermal zone
0016 devices (sensors) and thermal cooling devices (fan, processor...) to register
0017 with the thermal management solution and to be a part of it.
0018
0019 This how-to focuses on enabling new thermal zone and cooling devices to
0020 participate in thermal management.
0021 This solution is platform independent and any type of thermal zone devices
0022 and cooling devices should be able to make use of the infrastructure.
0023
0024 The main task of the thermal sysfs driver is to expose thermal zone attributes
0025 as well as cooling device attributes to the user space.
0026 An intelligent thermal management application can make decisions based on
0027 inputs from thermal zone attributes (the current temperature and trip point
0028 temperature) and throttle appropriate devices.
0029
0030 - `[0-*]` denotes any positive number starting from 0
0031 - `[1-*]` denotes any positive number starting from 1
0032
0033 1. thermal sysfs driver interface functions
0034 ===========================================
0035
0036 1.1 thermal zone device interface
0037 ---------------------------------
0038
0039 ::
0040
0041 struct thermal_zone_device
0042 *thermal_zone_device_register(char *type,
0043 int trips, int mask, void *devdata,
0044 struct thermal_zone_device_ops *ops,
0045 const struct thermal_zone_params *tzp,
0046 int passive_delay, int polling_delay))
0047
0048 This interface function adds a new thermal zone device (sensor) to
0049 /sys/class/thermal folder as `thermal_zone[0-*]`. It tries to bind all the
0050 thermal cooling devices registered at the same time.
0051
0052 type:
0053 the thermal zone type.
0054 trips:
0055 the total number of trip points this thermal zone supports.
0056 mask:
0057 Bit string: If 'n'th bit is set, then trip point 'n' is writable.
0058 devdata:
0059 device private data
0060 ops:
0061 thermal zone device call-backs.
0062
0063 .bind:
0064 bind the thermal zone device with a thermal cooling device.
0065 .unbind:
0066 unbind the thermal zone device with a thermal cooling device.
0067 .get_temp:
0068 get the current temperature of the thermal zone.
0069 .set_trips:
0070 set the trip points window. Whenever the current temperature
0071 is updated, the trip points immediately below and above the
0072 current temperature are found.
0073 .get_mode:
0074 get the current mode (enabled/disabled) of the thermal zone.
0075
0076 - "enabled" means the kernel thermal management is
0077 enabled.
0078 - "disabled" will prevent kernel thermal driver action
0079 upon trip points so that user applications can take
0080 charge of thermal management.
0081 .set_mode:
0082 set the mode (enabled/disabled) of the thermal zone.
0083 .get_trip_type:
0084 get the type of certain trip point.
0085 .get_trip_temp:
0086 get the temperature above which the certain trip point
0087 will be fired.
0088 .set_emul_temp:
0089 set the emulation temperature which helps in debugging
0090 different threshold temperature points.
0091 tzp:
0092 thermal zone platform parameters.
0093 passive_delay:
0094 number of milliseconds to wait between polls when
0095 performing passive cooling.
0096 polling_delay:
0097 number of milliseconds to wait between polls when checking
0098 whether trip points have been crossed (0 for interrupt driven systems).
0099
0100 ::
0101
0102 void thermal_zone_device_unregister(struct thermal_zone_device *tz)
0103
0104 This interface function removes the thermal zone device.
0105 It deletes the corresponding entry from /sys/class/thermal folder and
0106 unbinds all the thermal cooling devices it uses.
0107
0108 ::
0109
0110 struct thermal_zone_device
0111 *thermal_zone_of_sensor_register(struct device *dev, int sensor_id,
0112 void *data,
0113 const struct thermal_zone_of_device_ops *ops)
0114
0115 This interface adds a new sensor to a DT thermal zone.
0116 This function will search the list of thermal zones described in
0117 device tree and look for the zone that refer to the sensor device
0118 pointed by dev->of_node as temperature providers. For the zone
0119 pointing to the sensor node, the sensor will be added to the DT
0120 thermal zone device.
0121
0122 The parameters for this interface are:
0123
0124 dev:
0125 Device node of sensor containing valid node pointer in
0126 dev->of_node.
0127 sensor_id:
0128 a sensor identifier, in case the sensor IP has more
0129 than one sensors
0130 data:
0131 a private pointer (owned by the caller) that will be
0132 passed back, when a temperature reading is needed.
0133 ops:
0134 `struct thermal_zone_of_device_ops *`.
0135
0136 ============== =======================================
0137 get_temp a pointer to a function that reads the
0138 sensor temperature. This is mandatory
0139 callback provided by sensor driver.
0140 set_trips a pointer to a function that sets a
0141 temperature window. When this window is
0142 left the driver must inform the thermal
0143 core via thermal_zone_device_update.
0144 get_trend a pointer to a function that reads the
0145 sensor temperature trend.
0146 set_emul_temp a pointer to a function that sets
0147 sensor emulated temperature.
0148 ============== =======================================
0149
0150 The thermal zone temperature is provided by the get_temp() function
0151 pointer of thermal_zone_of_device_ops. When called, it will
0152 have the private pointer @data back.
0153
0154 It returns error pointer if fails otherwise valid thermal zone device
0155 handle. Caller should check the return handle with IS_ERR() for finding
0156 whether success or not.
0157
0158 ::
0159
0160 void thermal_zone_of_sensor_unregister(struct device *dev,
0161 struct thermal_zone_device *tzd)
0162
0163 This interface unregisters a sensor from a DT thermal zone which was
0164 successfully added by interface thermal_zone_of_sensor_register().
0165 This function removes the sensor callbacks and private data from the
0166 thermal zone device registered with thermal_zone_of_sensor_register()
0167 interface. It will also silent the zone by remove the .get_temp() and
0168 get_trend() thermal zone device callbacks.
0169
0170 ::
0171
0172 struct thermal_zone_device
0173 *devm_thermal_zone_of_sensor_register(struct device *dev,
0174 int sensor_id,
0175 void *data,
0176 const struct thermal_zone_of_device_ops *ops)
0177
0178 This interface is resource managed version of
0179 thermal_zone_of_sensor_register().
0180
0181 All details of thermal_zone_of_sensor_register() described in
0182 section 1.1.3 is applicable here.
0183
0184 The benefit of using this interface to register sensor is that it
0185 is not require to explicitly call thermal_zone_of_sensor_unregister()
0186 in error path or during driver unbinding as this is done by driver
0187 resource manager.
0188
0189 ::
0190
0191 void devm_thermal_zone_of_sensor_unregister(struct device *dev,
0192 struct thermal_zone_device *tzd)
0193
0194 This interface is resource managed version of
0195 thermal_zone_of_sensor_unregister().
0196 All details of thermal_zone_of_sensor_unregister() described in
0197 section 1.1.4 is applicable here.
0198 Normally this function will not need to be called and the resource
0199 management code will ensure that the resource is freed.
0200
0201 ::
0202
0203 int thermal_zone_get_slope(struct thermal_zone_device *tz)
0204
0205 This interface is used to read the slope attribute value
0206 for the thermal zone device, which might be useful for platform
0207 drivers for temperature calculations.
0208
0209 ::
0210
0211 int thermal_zone_get_offset(struct thermal_zone_device *tz)
0212
0213 This interface is used to read the offset attribute value
0214 for the thermal zone device, which might be useful for platform
0215 drivers for temperature calculations.
0216
0217 1.2 thermal cooling device interface
0218 ------------------------------------
0219
0220
0221 ::
0222
0223 struct thermal_cooling_device
0224 *thermal_cooling_device_register(char *name,
0225 void *devdata, struct thermal_cooling_device_ops *)
0226
0227 This interface function adds a new thermal cooling device (fan/processor/...)
0228 to /sys/class/thermal/ folder as `cooling_device[0-*]`. It tries to bind itself
0229 to all the thermal zone devices registered at the same time.
0230
0231 name:
0232 the cooling device name.
0233 devdata:
0234 device private data.
0235 ops:
0236 thermal cooling devices call-backs.
0237
0238 .get_max_state:
0239 get the Maximum throttle state of the cooling device.
0240 .get_cur_state:
0241 get the Currently requested throttle state of the
0242 cooling device.
0243 .set_cur_state:
0244 set the Current throttle state of the cooling device.
0245
0246 ::
0247
0248 void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
0249
0250 This interface function removes the thermal cooling device.
0251 It deletes the corresponding entry from /sys/class/thermal folder and
0252 unbinds itself from all the thermal zone devices using it.
0253
0254 1.3 interface for binding a thermal zone device with a thermal cooling device
0255 -----------------------------------------------------------------------------
0256
0257 ::
0258
0259 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
0260 int trip, struct thermal_cooling_device *cdev,
0261 unsigned long upper, unsigned long lower, unsigned int weight);
0262
0263 This interface function binds a thermal cooling device to a particular trip
0264 point of a thermal zone device.
0265
0266 This function is usually called in the thermal zone device .bind callback.
0267
0268 tz:
0269 the thermal zone device
0270 cdev:
0271 thermal cooling device
0272 trip:
0273 indicates which trip point in this thermal zone the cooling device
0274 is associated with.
0275 upper:
0276 the Maximum cooling state for this trip point.
0277 THERMAL_NO_LIMIT means no upper limit,
0278 and the cooling device can be in max_state.
0279 lower:
0280 the Minimum cooling state can be used for this trip point.
0281 THERMAL_NO_LIMIT means no lower limit,
0282 and the cooling device can be in cooling state 0.
0283 weight:
0284 the influence of this cooling device in this thermal
0285 zone. See 1.4.1 below for more information.
0286
0287 ::
0288
0289 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
0290 int trip, struct thermal_cooling_device *cdev);
0291
0292 This interface function unbinds a thermal cooling device from a particular
0293 trip point of a thermal zone device. This function is usually called in
0294 the thermal zone device .unbind callback.
0295
0296 tz:
0297 the thermal zone device
0298 cdev:
0299 thermal cooling device
0300 trip:
0301 indicates which trip point in this thermal zone the cooling device
0302 is associated with.
0303
0304 1.4 Thermal Zone Parameters
0305 ---------------------------
0306
0307 ::
0308
0309 struct thermal_bind_params
0310
0311 This structure defines the following parameters that are used to bind
0312 a zone with a cooling device for a particular trip point.
0313
0314 .cdev:
0315 The cooling device pointer
0316 .weight:
0317 The 'influence' of a particular cooling device on this
0318 zone. This is relative to the rest of the cooling
0319 devices. For example, if all cooling devices have a
0320 weight of 1, then they all contribute the same. You can
0321 use percentages if you want, but it's not mandatory. A
0322 weight of 0 means that this cooling device doesn't
0323 contribute to the cooling of this zone unless all cooling
0324 devices have a weight of 0. If all weights are 0, then
0325 they all contribute the same.
0326 .trip_mask:
0327 This is a bit mask that gives the binding relation between
0328 this thermal zone and cdev, for a particular trip point.
0329 If nth bit is set, then the cdev and thermal zone are bound
0330 for trip point n.
0331 .binding_limits:
0332 This is an array of cooling state limits. Must have
0333 exactly 2 * thermal_zone.number_of_trip_points. It is an
0334 array consisting of tuples <lower-state upper-state> of
0335 state limits. Each trip will be associated with one state
0336 limit tuple when binding. A NULL pointer means
0337 <THERMAL_NO_LIMITS THERMAL_NO_LIMITS> on all trips.
0338 These limits are used when binding a cdev to a trip point.
0339 .match:
0340 This call back returns success(0) if the 'tz and cdev' need to
0341 be bound, as per platform data.
0342
0343 ::
0344
0345 struct thermal_zone_params
0346
0347 This structure defines the platform level parameters for a thermal zone.
0348 This data, for each thermal zone should come from the platform layer.
0349 This is an optional feature where some platforms can choose not to
0350 provide this data.
0351
0352 .governor_name:
0353 Name of the thermal governor used for this zone
0354 .no_hwmon:
0355 a boolean to indicate if the thermal to hwmon sysfs interface
0356 is required. when no_hwmon == false, a hwmon sysfs interface
0357 will be created. when no_hwmon == true, nothing will be done.
0358 In case the thermal_zone_params is NULL, the hwmon interface
0359 will be created (for backward compatibility).
0360 .num_tbps:
0361 Number of thermal_bind_params entries for this zone
0362 .tbp:
0363 thermal_bind_params entries
0364
0365 2. sysfs attributes structure
0366 =============================
0367
0368 == ================
0369 RO read only value
0370 WO write only value
0371 RW read/write value
0372 == ================
0373
0374 Thermal sysfs attributes will be represented under /sys/class/thermal.
0375 Hwmon sysfs I/F extension is also available under /sys/class/hwmon
0376 if hwmon is compiled in or built as a module.
0377
0378 Thermal zone device sys I/F, created once it's registered::
0379
0380 /sys/class/thermal/thermal_zone[0-*]:
0381 |---type: Type of the thermal zone
0382 |---temp: Current temperature
0383 |---mode: Working mode of the thermal zone
0384 |---policy: Thermal governor used for this zone
0385 |---available_policies: Available thermal governors for this zone
0386 |---trip_point_[0-*]_temp: Trip point temperature
0387 |---trip_point_[0-*]_type: Trip point type
0388 |---trip_point_[0-*]_hyst: Hysteresis value for this trip point
0389 |---emul_temp: Emulated temperature set node
0390 |---sustainable_power: Sustainable dissipatable power
0391 |---k_po: Proportional term during temperature overshoot
0392 |---k_pu: Proportional term during temperature undershoot
0393 |---k_i: PID's integral term in the power allocator gov
0394 |---k_d: PID's derivative term in the power allocator
0395 |---integral_cutoff: Offset above which errors are accumulated
0396 |---slope: Slope constant applied as linear extrapolation
0397 |---offset: Offset constant applied as linear extrapolation
0398
0399 Thermal cooling device sys I/F, created once it's registered::
0400
0401 /sys/class/thermal/cooling_device[0-*]:
0402 |---type: Type of the cooling device(processor/fan/...)
0403 |---max_state: Maximum cooling state of the cooling device
0404 |---cur_state: Current cooling state of the cooling device
0405 |---stats: Directory containing cooling device's statistics
0406 |---stats/reset: Writing any value resets the statistics
0407 |---stats/time_in_state_ms: Time (msec) spent in various cooling states
0408 |---stats/total_trans: Total number of times cooling state is changed
0409 |---stats/trans_table: Cooling state transition table
0410
0411
0412 Then next two dynamic attributes are created/removed in pairs. They represent
0413 the relationship between a thermal zone and its associated cooling device.
0414 They are created/removed for each successful execution of
0415 thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device.
0416
0417 ::
0418
0419 /sys/class/thermal/thermal_zone[0-*]:
0420 |---cdev[0-*]: [0-*]th cooling device in current thermal zone
0421 |---cdev[0-*]_trip_point: Trip point that cdev[0-*] is associated with
0422 |---cdev[0-*]_weight: Influence of the cooling device in
0423 this thermal zone
0424
0425 Besides the thermal zone device sysfs I/F and cooling device sysfs I/F,
0426 the generic thermal driver also creates a hwmon sysfs I/F for each _type_
0427 of thermal zone device. E.g. the generic thermal driver registers one hwmon
0428 class device and build the associated hwmon sysfs I/F for all the registered
0429 ACPI thermal zones.
0430
0431 Please read Documentation/ABI/testing/sysfs-class-thermal for thermal
0432 zone and cooling device attribute details.
0433
0434 ::
0435
0436 /sys/class/hwmon/hwmon[0-*]:
0437 |---name: The type of the thermal zone devices
0438 |---temp[1-*]_input: The current temperature of thermal zone [1-*]
0439 |---temp[1-*]_critical: The critical trip point of thermal zone [1-*]
0440
0441 Please read Documentation/hwmon/sysfs-interface.rst for additional information.
0442
0443 3. A simple implementation
0444 ==========================
0445
0446 ACPI thermal zone may support multiple trip points like critical, hot,
0447 passive, active. If an ACPI thermal zone supports critical, passive,
0448 active[0] and active[1] at the same time, it may register itself as a
0449 thermal_zone_device (thermal_zone1) with 4 trip points in all.
0450 It has one processor and one fan, which are both registered as
0451 thermal_cooling_device. Both are considered to have the same
0452 effectiveness in cooling the thermal zone.
0453
0454 If the processor is listed in _PSL method, and the fan is listed in _AL0
0455 method, the sys I/F structure will be built like this::
0456
0457 /sys/class/thermal:
0458 |thermal_zone1:
0459 |---type: acpitz
0460 |---temp: 37000
0461 |---mode: enabled
0462 |---policy: step_wise
0463 |---available_policies: step_wise fair_share
0464 |---trip_point_0_temp: 100000
0465 |---trip_point_0_type: critical
0466 |---trip_point_1_temp: 80000
0467 |---trip_point_1_type: passive
0468 |---trip_point_2_temp: 70000
0469 |---trip_point_2_type: active0
0470 |---trip_point_3_temp: 60000
0471 |---trip_point_3_type: active1
0472 |---cdev0: --->/sys/class/thermal/cooling_device0
0473 |---cdev0_trip_point: 1 /* cdev0 can be used for passive */
0474 |---cdev0_weight: 1024
0475 |---cdev1: --->/sys/class/thermal/cooling_device3
0476 |---cdev1_trip_point: 2 /* cdev1 can be used for active[0]*/
0477 |---cdev1_weight: 1024
0478
0479 |cooling_device0:
0480 |---type: Processor
0481 |---max_state: 8
0482 |---cur_state: 0
0483
0484 |cooling_device3:
0485 |---type: Fan
0486 |---max_state: 2
0487 |---cur_state: 0
0488
0489 /sys/class/hwmon:
0490 |hwmon0:
0491 |---name: acpitz
0492 |---temp1_input: 37000
0493 |---temp1_crit: 100000
0494
0495 4. Export Symbol APIs
0496 =====================
0497
0498 4.1. get_tz_trend
0499 -----------------
0500
0501 This function returns the trend of a thermal zone, i.e the rate of change
0502 of temperature of the thermal zone. Ideally, the thermal sensor drivers
0503 are supposed to implement the callback. If they don't, the thermal
0504 framework calculated the trend by comparing the previous and the current
0505 temperature values.
0506
0507 4.2. get_thermal_instance
0508 -------------------------
0509
0510 This function returns the thermal_instance corresponding to a given
0511 {thermal_zone, cooling_device, trip_point} combination. Returns NULL
0512 if such an instance does not exist.
0513
0514 4.3. thermal_cdev_update
0515 ------------------------
0516
0517 This function serves as an arbitrator to set the state of a cooling
0518 device. It sets the cooling device to the deepest cooling state if
0519 possible.
0520
0521 5. thermal_emergency_poweroff
0522 =============================
0523
0524 On an event of critical trip temperature crossing the thermal framework
0525 shuts down the system by calling hw_protection_shutdown(). The
0526 hw_protection_shutdown() first attempts to perform an orderly shutdown
0527 but accepts a delay after which it proceeds doing a forced power-off
0528 or as last resort an emergency_restart.
0529
0530 The delay should be carefully profiled so as to give adequate time for
0531 orderly poweroff.
0532
0533 If the delay is set to 0 emergency poweroff will not be supported. So a
0534 carefully profiled non-zero positive value is a must for emergency
0535 poweroff to be triggered.