mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'thermal-v5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux
Pull thermal updates from Daniel Lezcano: - Add the hwmon support on the i.MX SC (Anson Huang) - Thermal framework cleanups (self-encapsulation, pointless stubs, private structures) (Daniel Lezcano) - Use the PM QoS frequency changes for the devfreq cooling device (Matthias Kaehlcke) - Remove duplicate error messages from platform_get_irq() error handling (Markus Elfring) - Add support for the bandgap sensors (Keerthy) - Statically initialize .get_mode/.set_mode ops (Andrzej Pietrasiewicz) - Add Renesas R-Car maintainer entry (Niklas Söderlund) - Fix error checking after calling ti_bandgap_get_sensor_data() for the TI SoC thermal (Sudip Mukherjee) - Add latency constraint for the idle injection, the DT binding and the change the registering function (Daniel Lezcano) - Convert the thermal framework binding to the Yaml schema (Amit Kucheria) - Replace zero-length array with flexible-array on i.MX 8MM (Gustavo A. R. Silva) - Thermal framework cleanups (alphabetic order for heads, replace module.h by export.h, make file naming consistent) (Amit Kucheria) - Merge tsens-common into the tsens driver (Amit Kucheria) - Fix platform dependency for the Qoriq driver (Geert Uytterhoeven) - Clean up the rcar_thermal_update_temp() function in the rcar thermal driver (Niklas Söderlund) - Fix the TMSAR register for the TMUv2 on the Qoriq platform (Yuantian Tang) - Export GDDV, OEM vendor variables, and don't require IDSP for the int340x thermal driver - trivial conflicts fixed (Matthew Garrett) * tag 'thermal-v5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux: (48 commits) thermal/int340x_thermal: Don't require IDSP to exist thermal/int340x_thermal: Export OEM vendor variables thermal/int340x_thermal: Export GDDV thermal: qoriq: Update the settings for TMUv2 thermal: rcar_thermal: Clean up rcar_thermal_update_temp() thermal: qoriq: Add platform dependencies drivers: thermal: tsens: Merge tsens-common.c into tsens.c thermal/of: Rename of-thermal.c thermal/governors: Prefix all source files with gov_ thermal/drivers/user_space: Sort headers alphabetically thermal/drivers/of-thermal: Sort headers alphabetically thermal/drivers/cpufreq_cooling: Replace module.h with export.h thermal/drivers/cpufreq_cooling: Sort headers alphabetically thermal/drivers/clock_cooling: Include export.h thermal/drivers/clock_cooling: Sort headers alphabetically thermal/drivers/thermal_hwmon: Include export.h thermal/drivers/thermal_hwmon: Sort headers alphabetically thermal/drivers/thermal_helpers: Include export.h thermal/drivers/thermal_helpers: Sort headers alphabetically thermal/core: Replace module.h with export.h ...
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0)
|
||||
# Copyright 2020 Linaro Ltd.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/thermal/thermal-cooling-devices.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Thermal cooling device binding
|
||||
|
||||
maintainers:
|
||||
- Amit Kucheria <amitk@kernel.org>
|
||||
|
||||
description: |
|
||||
Thermal management is achieved in devicetree by describing the sensor hardware
|
||||
and the software abstraction of cooling devices and thermal zones required to
|
||||
take appropriate action to mitigate thermal overload.
|
||||
|
||||
The following node types are used to completely describe a thermal management
|
||||
system in devicetree:
|
||||
- thermal-sensor: device that measures temperature, has SoC-specific bindings
|
||||
- cooling-device: device used to dissipate heat either passively or actively
|
||||
- thermal-zones: a container of the following node types used to describe all
|
||||
thermal data for the platform
|
||||
|
||||
This binding describes the cooling devices.
|
||||
|
||||
There are essentially two ways to provide control on power dissipation:
|
||||
- Passive cooling: by means of regulating device performance. A typical
|
||||
passive cooling mechanism is a CPU that has dynamic voltage and frequency
|
||||
scaling (DVFS), and uses lower frequencies as cooling states.
|
||||
- Active cooling: by means of activating devices in order to remove the
|
||||
dissipated heat, e.g. regulating fan speeds.
|
||||
|
||||
Any cooling device has a range of cooling states (i.e. different levels of
|
||||
heat dissipation). They also have a way to determine the state of cooling in
|
||||
which the device is. For example, a fan's cooling states correspond to the
|
||||
different fan speeds possible. Cooling states are referred to by single
|
||||
unsigned integers, where larger numbers mean greater heat dissipation. The
|
||||
precise set of cooling states associated with a device should be defined in
|
||||
a particular device's binding.
|
||||
|
||||
select: true
|
||||
|
||||
properties:
|
||||
"#cooling-cells":
|
||||
description:
|
||||
Must be 2, in order to specify minimum and maximum cooling state used in
|
||||
the cooling-maps reference. The first cell is the minimum cooling state
|
||||
and the second cell is the maximum cooling state requested.
|
||||
const: 2
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/thermal/thermal.h>
|
||||
|
||||
// Example 1: Cpufreq cooling device on CPU0
|
||||
cpus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
CPU0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "qcom,kryo385";
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "psci";
|
||||
cpu-idle-states = <&LITTLE_CPU_SLEEP_0
|
||||
&LITTLE_CPU_SLEEP_1
|
||||
&CLUSTER_SLEEP_0>;
|
||||
capacity-dmips-mhz = <607>;
|
||||
dynamic-power-coefficient = <100>;
|
||||
qcom,freq-domain = <&cpufreq_hw 0>;
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_0>;
|
||||
L2_0: l2-cache {
|
||||
compatible = "cache";
|
||||
next-level-cache = <&L3_0>;
|
||||
L3_0: l3-cache {
|
||||
compatible = "cache";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* ... */
|
||||
|
||||
};
|
||||
|
||||
/* ... */
|
||||
|
||||
thermal-zones {
|
||||
cpu0-thermal {
|
||||
polling-delay-passive = <250>;
|
||||
polling-delay = <1000>;
|
||||
|
||||
thermal-sensors = <&tsens0 1>;
|
||||
|
||||
trips {
|
||||
cpu0_alert0: trip-point0 {
|
||||
temperature = <90000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
};
|
||||
};
|
||||
|
||||
cooling-maps {
|
||||
map0 {
|
||||
trip = <&cpu0_alert0>;
|
||||
/* Corresponds to 1000MHz in OPP table */
|
||||
cooling-device = <&CPU0 5 5>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* ... */
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,145 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright 2020 Linaro Ltd.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/thermal/thermal-idle.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Thermal idle cooling device binding
|
||||
|
||||
maintainers:
|
||||
- Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
|
||||
description: |
|
||||
The thermal idle cooling device allows the system to passively
|
||||
mitigate the temperature on the device by injecting idle cycles,
|
||||
forcing it to cool down.
|
||||
|
||||
This binding describes the thermal idle node.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
const: thermal-idle
|
||||
description: |
|
||||
A thermal-idle node describes the idle cooling device properties to
|
||||
cool down efficiently the attached thermal zone.
|
||||
|
||||
'#cooling-cells':
|
||||
const: 2
|
||||
description: |
|
||||
Must be 2, in order to specify minimum and maximum cooling state used in
|
||||
the cooling-maps reference. The first cell is the minimum cooling state
|
||||
and the second cell is the maximum cooling state requested.
|
||||
|
||||
duration-us:
|
||||
description: |
|
||||
The idle duration in microsecond the device should cool down.
|
||||
|
||||
exit-latency-us:
|
||||
description: |
|
||||
The exit latency constraint in microsecond for the injected
|
||||
idle state for the device. It is the latency constraint to
|
||||
apply when selecting an idle state from among all the present
|
||||
ones.
|
||||
|
||||
required:
|
||||
- '#cooling-cells'
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/thermal/thermal.h>
|
||||
|
||||
// Example: Combining idle cooling device on big CPUs with cpufreq cooling device
|
||||
cpus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/* ... */
|
||||
|
||||
cpu_b0: cpu@100 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a72";
|
||||
reg = <0x0 0x100>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
dynamic-power-coefficient = <436>;
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
|
||||
thermal-idle {
|
||||
#cooling-cells = <2>;
|
||||
duration-us = <10000>;
|
||||
exit-latency-us = <500>;
|
||||
};
|
||||
};
|
||||
|
||||
cpu_b1: cpu@101 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a72";
|
||||
reg = <0x0 0x101>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
dynamic-power-coefficient = <436>;
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
|
||||
thermal-idle {
|
||||
#cooling-cells = <2>;
|
||||
duration-us = <10000>;
|
||||
exit-latency-us = <500>;
|
||||
};
|
||||
};
|
||||
|
||||
/* ... */
|
||||
|
||||
};
|
||||
|
||||
/* ... */
|
||||
|
||||
thermal_zones {
|
||||
cpu_thermal: cpu {
|
||||
polling-delay-passive = <100>;
|
||||
polling-delay = <1000>;
|
||||
|
||||
/* ... */
|
||||
|
||||
trips {
|
||||
cpu_alert0: cpu_alert0 {
|
||||
temperature = <65000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
};
|
||||
|
||||
cpu_alert1: cpu_alert1 {
|
||||
temperature = <70000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
};
|
||||
|
||||
cpu_alert2: cpu_alert2 {
|
||||
temperature = <75000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
};
|
||||
|
||||
cpu_crit: cpu_crit {
|
||||
temperature = <95000>;
|
||||
hysteresis = <2000>;
|
||||
type = "critical";
|
||||
};
|
||||
};
|
||||
|
||||
cooling-maps {
|
||||
map0 {
|
||||
trip = <&cpu_alert1>;
|
||||
cooling-device = <&{/cpus/cpu@100/thermal-idle} 0 15 >,
|
||||
<&{/cpus/cpu@101/thermal-idle} 0 15>;
|
||||
};
|
||||
|
||||
map1 {
|
||||
trip = <&cpu_alert2>;
|
||||
cooling-device =
|
||||
<&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
<&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0)
|
||||
# Copyright 2020 Linaro Ltd.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/thermal/thermal-sensor.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Thermal sensor binding
|
||||
|
||||
maintainers:
|
||||
- Amit Kucheria <amitk@kernel.org>
|
||||
|
||||
description: |
|
||||
Thermal management is achieved in devicetree by describing the sensor hardware
|
||||
and the software abstraction of thermal zones required to take appropriate
|
||||
action to mitigate thermal overloads.
|
||||
|
||||
The following node types are used to completely describe a thermal management
|
||||
system in devicetree:
|
||||
- thermal-sensor: device that measures temperature, has SoC-specific bindings
|
||||
- cooling-device: device used to dissipate heat either passively or actively
|
||||
- thermal-zones: a container of the following node types used to describe all
|
||||
thermal data for the platform
|
||||
|
||||
This binding describes the thermal-sensor.
|
||||
|
||||
Thermal sensor devices provide temperature sensing capabilities on thermal
|
||||
zones. Typical devices are I2C ADC converters and bandgaps. Thermal sensor
|
||||
devices may control one or more internal sensors.
|
||||
|
||||
properties:
|
||||
"#thermal-sensor-cells":
|
||||
description:
|
||||
Used to uniquely identify a thermal sensor instance within an IC. Will be
|
||||
0 on sensor nodes with only a single sensor and at least 1 on nodes
|
||||
containing several internal sensors.
|
||||
enum: [0, 1]
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
// Example 1: SDM845 TSENS
|
||||
soc: soc@0 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
/* ... */
|
||||
|
||||
tsens0: thermal-sensor@c263000 {
|
||||
compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
|
||||
reg = <0 0x0c263000 0 0x1ff>, /* TM */
|
||||
<0 0x0c222000 0 0x1ff>; /* SROT */
|
||||
#qcom,sensors = <13>;
|
||||
interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "uplow", "critical";
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
|
||||
tsens1: thermal-sensor@c265000 {
|
||||
compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
|
||||
reg = <0 0x0c265000 0 0x1ff>, /* TM */
|
||||
<0 0x0c223000 0 0x1ff>; /* SROT */
|
||||
#qcom,sensors = <8>;
|
||||
interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "uplow", "critical";
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,341 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0)
|
||||
# Copyright 2020 Linaro Ltd.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/thermal/thermal-zones.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/base.yaml#
|
||||
|
||||
title: Thermal zone binding
|
||||
|
||||
maintainers:
|
||||
- Amit Kucheria <amitk@kernel.org>
|
||||
|
||||
description: |
|
||||
Thermal management is achieved in devicetree by describing the sensor hardware
|
||||
and the software abstraction of cooling devices and thermal zones required to
|
||||
take appropriate action to mitigate thermal overloads.
|
||||
|
||||
The following node types are used to completely describe a thermal management
|
||||
system in devicetree:
|
||||
- thermal-sensor: device that measures temperature, has SoC-specific bindings
|
||||
- cooling-device: device used to dissipate heat either passively or actively
|
||||
- thermal-zones: a container of the following node types used to describe all
|
||||
thermal data for the platform
|
||||
|
||||
This binding describes the thermal-zones.
|
||||
|
||||
The polling-delay properties of a thermal-zone are bound to the maximum dT/dt
|
||||
(temperature derivative over time) in two situations for a thermal zone:
|
||||
1. when passive cooling is activated (polling-delay-passive)
|
||||
2. when the zone just needs to be monitored (polling-delay) or when
|
||||
active cooling is activated.
|
||||
|
||||
The maximum dT/dt is highly bound to hardware power consumption and
|
||||
dissipation capability. The delays should be chosen to account for said
|
||||
max dT/dt, such that a device does not cross several trip boundaries
|
||||
unexpectedly between polls. Choosing the right polling delays shall avoid
|
||||
having the device in temperature ranges that may damage the silicon structures
|
||||
and reduce silicon lifetime.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
const: thermal-zones
|
||||
description:
|
||||
A /thermal-zones node is required in order to use the thermal framework to
|
||||
manage input from the various thermal zones in the system in order to
|
||||
mitigate thermal overload conditions. It does not represent a real device
|
||||
in the system, but acts as a container to link a thermal sensor device,
|
||||
platform-data regarding temperature thresholds and the mitigation actions
|
||||
to take when the temperature crosses those thresholds.
|
||||
|
||||
patternProperties:
|
||||
"^[a-zA-Z][a-zA-Z0-9\\-]{1,12}-thermal$":
|
||||
type: object
|
||||
description:
|
||||
Each thermal zone node contains information about how frequently it
|
||||
must be checked, the sensor responsible for reporting temperature for
|
||||
this zone, one sub-node containing the various trip points for this
|
||||
zone and one sub-node containing all the zone cooling-maps.
|
||||
|
||||
properties:
|
||||
polling-delay:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
The maximum number of milliseconds to wait between polls when
|
||||
checking this thermal zone. Setting this to 0 disables the polling
|
||||
timers setup by the thermal framework and assumes that the thermal
|
||||
sensors in this zone support interrupts.
|
||||
|
||||
polling-delay-passive:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
The maximum number of milliseconds to wait between polls when
|
||||
checking this thermal zone while doing passive cooling. Setting
|
||||
this to 0 disables the polling timers setup by the thermal
|
||||
framework and assumes that the thermal sensors in this zone
|
||||
support interrupts.
|
||||
|
||||
thermal-sensors:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
maxItems: 1
|
||||
description:
|
||||
The thermal sensor phandle and sensor specifier used to monitor this
|
||||
thermal zone.
|
||||
|
||||
coefficients:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
An array of integers containing the coefficients of a linear equation
|
||||
that binds all the sensors listed in this thermal zone.
|
||||
|
||||
The linear equation used is as follows,
|
||||
z = c0 * x0 + c1 * x1 + ... + c(n-1) * x(n-1) + cn
|
||||
where c0, c1, .., cn are the coefficients.
|
||||
|
||||
Coefficients default to 1 in case this property is not specified. The
|
||||
coefficients are ordered and are matched with sensors by means of the
|
||||
sensor ID. Additional coefficients are interpreted as constant offset.
|
||||
|
||||
sustainable-power:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
An estimate of the sustainable power (in mW) that this thermal zone
|
||||
can dissipate at the desired control temperature. For reference, the
|
||||
sustainable power of a 4-inch phone is typically 2000mW, while on a
|
||||
10-inch tablet is around 4500mW.
|
||||
|
||||
trips:
|
||||
type: object
|
||||
description:
|
||||
This node describes a set of points in the temperature domain at
|
||||
which the thermal framework needs to take action. The actions to
|
||||
be taken are defined in another node called cooling-maps.
|
||||
|
||||
patternProperties:
|
||||
"^[a-zA-Z][a-zA-Z0-9\\-_]{0,63}$":
|
||||
type: object
|
||||
|
||||
properties:
|
||||
temperature:
|
||||
$ref: /schemas/types.yaml#/definitions/int32
|
||||
minimum: -273000
|
||||
maximum: 200000
|
||||
description:
|
||||
An integer expressing the trip temperature in millicelsius.
|
||||
|
||||
hysteresis:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
An unsigned integer expressing the hysteresis delta with
|
||||
respect to the trip temperature property above, also in
|
||||
millicelsius. Any cooling action initiated by the framework is
|
||||
maintained until the temperature falls below
|
||||
(trip temperature - hysteresis). This potentially prevents a
|
||||
situation where the trip gets constantly triggered soon after
|
||||
cooling action is removed.
|
||||
|
||||
type:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum:
|
||||
- active # enable active cooling e.g. fans
|
||||
- passive # enable passive cooling e.g. throttling cpu
|
||||
- hot # send notification to driver
|
||||
- critical # send notification to driver, trigger shutdown
|
||||
description: |
|
||||
There are four valid trip types: active, passive, hot,
|
||||
critical.
|
||||
|
||||
The critical trip type is used to set the maximum
|
||||
temperature threshold above which the HW becomes
|
||||
unstable and underlying firmware might even trigger a
|
||||
reboot. Hitting the critical threshold triggers a system
|
||||
shutdown.
|
||||
|
||||
The hot trip type can be used to send a notification to
|
||||
the thermal driver (if a .notify callback is registered).
|
||||
The action to be taken is left to the driver.
|
||||
|
||||
The passive trip type can be used to slow down HW e.g. run
|
||||
the CPU, GPU, bus at a lower frequency.
|
||||
|
||||
The active trip type can be used to control other HW to
|
||||
help in cooling e.g. fans can be sped up or slowed down
|
||||
|
||||
required:
|
||||
- temperature
|
||||
- hysteresis
|
||||
- type
|
||||
additionalProperties: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
cooling-maps:
|
||||
type: object
|
||||
description:
|
||||
This node describes the action to be taken when a thermal zone
|
||||
crosses one of the temperature thresholds described in the trips
|
||||
node. The action takes the form of a mapping relation between a
|
||||
trip and the target cooling device state.
|
||||
|
||||
patternProperties:
|
||||
"^map[-a-zA-Z0-9]*$":
|
||||
type: object
|
||||
|
||||
properties:
|
||||
trip:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
A phandle of a trip point node within this thermal zone.
|
||||
|
||||
cooling-device:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description:
|
||||
A list of cooling device phandles along with the minimum
|
||||
and maximum cooling state specifiers for each cooling
|
||||
device. Using the THERMAL_NO_LIMIT (-1UL) constant in the
|
||||
cooling-device phandle limit specifier lets the framework
|
||||
use the minimum and maximum cooling state for that cooling
|
||||
device automatically.
|
||||
|
||||
contribution:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
description:
|
||||
The percentage contribution of the cooling devices at the
|
||||
specific trip temperature referenced in this map
|
||||
to this thermal zone
|
||||
|
||||
required:
|
||||
- trip
|
||||
- cooling-device
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- polling-delay
|
||||
- polling-delay-passive
|
||||
- thermal-sensors
|
||||
- trips
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/thermal/thermal.h>
|
||||
|
||||
// Example 1: SDM845 TSENS
|
||||
soc: soc@0 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
/* ... */
|
||||
|
||||
tsens0: thermal-sensor@c263000 {
|
||||
compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
|
||||
reg = <0 0x0c263000 0 0x1ff>, /* TM */
|
||||
<0 0x0c222000 0 0x1ff>; /* SROT */
|
||||
#qcom,sensors = <13>;
|
||||
interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "uplow", "critical";
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
|
||||
tsens1: thermal-sensor@c265000 {
|
||||
compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
|
||||
reg = <0 0x0c265000 0 0x1ff>, /* TM */
|
||||
<0 0x0c223000 0 0x1ff>; /* SROT */
|
||||
#qcom,sensors = <8>;
|
||||
interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "uplow", "critical";
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
/* ... */
|
||||
|
||||
thermal-zones {
|
||||
cpu0-thermal {
|
||||
polling-delay-passive = <250>;
|
||||
polling-delay = <1000>;
|
||||
|
||||
thermal-sensors = <&tsens0 1>;
|
||||
|
||||
trips {
|
||||
cpu0_alert0: trip-point0 {
|
||||
temperature = <90000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
};
|
||||
|
||||
cpu0_alert1: trip-point1 {
|
||||
temperature = <95000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
};
|
||||
|
||||
cpu0_crit: cpu_crit {
|
||||
temperature = <110000>;
|
||||
hysteresis = <1000>;
|
||||
type = "critical";
|
||||
};
|
||||
};
|
||||
|
||||
cooling-maps {
|
||||
map0 {
|
||||
trip = <&cpu0_alert0>;
|
||||
/* Corresponds to 1400MHz in OPP table */
|
||||
cooling-device = <&CPU0 3 3>, <&CPU1 3 3>,
|
||||
<&CPU2 3 3>, <&CPU3 3 3>;
|
||||
};
|
||||
|
||||
map1 {
|
||||
trip = <&cpu0_alert1>;
|
||||
/* Corresponds to 1000MHz in OPP table */
|
||||
cooling-device = <&CPU0 5 5>, <&CPU1 5 5>,
|
||||
<&CPU2 5 5>, <&CPU3 5 5>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* ... */
|
||||
|
||||
cluster0-thermal {
|
||||
polling-delay-passive = <250>;
|
||||
polling-delay = <1000>;
|
||||
|
||||
thermal-sensors = <&tsens0 5>;
|
||||
|
||||
trips {
|
||||
cluster0_alert0: trip-point0 {
|
||||
temperature = <90000>;
|
||||
hysteresis = <2000>;
|
||||
type = "hot";
|
||||
};
|
||||
cluster0_crit: cluster0_crit {
|
||||
temperature = <110000>;
|
||||
hysteresis = <2000>;
|
||||
type = "critical";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* ... */
|
||||
|
||||
gpu-top-thermal {
|
||||
polling-delay-passive = <250>;
|
||||
polling-delay = <1000>;
|
||||
|
||||
thermal-sensors = <&tsens0 11>;
|
||||
|
||||
trips {
|
||||
gpu1_alert0: trip-point0 {
|
||||
temperature = <90000>;
|
||||
hysteresis = <2000>;
|
||||
type = "hot";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,56 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/thermal/ti,am654-thermal.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments AM654 VTM (DTS) binding
|
||||
|
||||
maintainers:
|
||||
- Keerthy <j-keerthy@ti.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,am654-vtm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
"#thermal-sensor-cells":
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- power-domains
|
||||
- "#thermal-sensor-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/soc/ti,sci_pm_domain.h>
|
||||
vtm: thermal@42050000 {
|
||||
compatible = "ti,am654-vtm";
|
||||
reg = <0x0 0x42050000 0x0 0x25c>;
|
||||
power-domains = <&k3_pds 80 TI_SCI_PD_EXCLUSIVE>;
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
|
||||
mpu0_thermal: mpu0_thermal {
|
||||
polling-delay-passive = <250>; /* milliseconds */
|
||||
polling-delay = <500>; /* milliseconds */
|
||||
thermal-sensors = <&vtm0 0>;
|
||||
|
||||
trips {
|
||||
mpu0_crit: mpu0_crit {
|
||||
temperature = <125000>; /* milliCelsius */
|
||||
hysteresis = <2000>; /* milliCelsius */
|
||||
type = "critical";
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -14556,6 +14556,15 @@ F: Documentation/devicetree/bindings/i2c/renesas,iic.txt
|
||||
F: drivers/i2c/busses/i2c-rcar.c
|
||||
F: drivers/i2c/busses/i2c-sh_mobile.c
|
||||
|
||||
RENESAS R-CAR THERMAL DRIVERS
|
||||
M: Niklas Söderlund <niklas.soderlund@ragnatech.se>
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
|
||||
F: Documentation/devicetree/bindings/thermal/rcar-thermal.txt
|
||||
F: drivers/thermal/rcar_gen3_thermal.c
|
||||
F: drivers/thermal/rcar_thermal.c
|
||||
|
||||
RENESAS RIIC DRIVER
|
||||
M: Chris Brandt <chris.brandt@renesas.com>
|
||||
S: Supported
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#define pr_fmt(fmt) "CPUidle arm: " fmt
|
||||
|
||||
#include <linux/cpu_cooling.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
@@ -124,6 +125,8 @@ static int __init arm_idle_init_cpu(int cpu)
|
||||
if (ret)
|
||||
goto out_kfree_drv;
|
||||
|
||||
cpuidle_cooling_register(drv);
|
||||
|
||||
return 0;
|
||||
|
||||
out_kfree_drv:
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define pr_fmt(fmt) "CPUidle PSCI: " fmt
|
||||
|
||||
#include <linux/cpuhotplug.h>
|
||||
#include <linux/cpu_cooling.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
@@ -319,6 +320,8 @@ static int __init psci_idle_init_cpu(int cpu)
|
||||
if (ret)
|
||||
goto out_kfree_drv;
|
||||
|
||||
cpuidle_cooling_register(drv);
|
||||
|
||||
return 0;
|
||||
|
||||
out_kfree_drv:
|
||||
|
||||
@@ -61,12 +61,14 @@ struct idle_inject_thread {
|
||||
* @timer: idle injection period timer
|
||||
* @idle_duration_us: duration of CPU idle time to inject
|
||||
* @run_duration_us: duration of CPU run time to allow
|
||||
* @latency_us: max allowed latency
|
||||
* @cpumask: mask of CPUs affected by idle injection
|
||||
*/
|
||||
struct idle_inject_device {
|
||||
struct hrtimer timer;
|
||||
unsigned int idle_duration_us;
|
||||
unsigned int run_duration_us;
|
||||
unsigned int latency_us;
|
||||
unsigned long cpumask[];
|
||||
};
|
||||
|
||||
@@ -138,7 +140,8 @@ static void idle_inject_fn(unsigned int cpu)
|
||||
*/
|
||||
iit->should_run = 0;
|
||||
|
||||
play_idle(READ_ONCE(ii_dev->idle_duration_us));
|
||||
play_idle_precise(READ_ONCE(ii_dev->idle_duration_us) * NSEC_PER_USEC,
|
||||
READ_ONCE(ii_dev->latency_us) * NSEC_PER_USEC);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,6 +172,16 @@ void idle_inject_get_duration(struct idle_inject_device *ii_dev,
|
||||
*idle_duration_us = READ_ONCE(ii_dev->idle_duration_us);
|
||||
}
|
||||
|
||||
/**
|
||||
* idle_inject_set_latency - set the maximum latency allowed
|
||||
* @latency_us: set the latency requirement for the idle state
|
||||
*/
|
||||
void idle_inject_set_latency(struct idle_inject_device *ii_dev,
|
||||
unsigned int latency_us)
|
||||
{
|
||||
WRITE_ONCE(ii_dev->latency_us, latency_us);
|
||||
}
|
||||
|
||||
/**
|
||||
* idle_inject_start - start idle injections
|
||||
* @ii_dev: idle injection control device structure
|
||||
@@ -297,6 +310,7 @@ struct idle_inject_device *idle_inject_register(struct cpumask *cpumask)
|
||||
cpumask_copy(to_cpumask(ii_dev->cpumask), cpumask);
|
||||
hrtimer_init(&ii_dev->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
ii_dev->timer.function = idle_inject_timer_fn;
|
||||
ii_dev->latency_us = UINT_MAX;
|
||||
|
||||
for_each_cpu(cpu, to_cpumask(ii_dev->cpumask)) {
|
||||
|
||||
|
||||
+12
-2
@@ -273,6 +273,16 @@ config IMX8MM_THERMAL
|
||||
cpufreq is used as the cooling device to throttle CPUs when the passive
|
||||
trip is crossed.
|
||||
|
||||
config K3_THERMAL
|
||||
tristate "Texas Instruments K3 thermal support"
|
||||
depends on ARCH_K3 || COMPILE_TEST
|
||||
help
|
||||
If you say yes here you get thermal support for the Texas Instruments
|
||||
K3 SoC family. The current chip supported is:
|
||||
- AM654
|
||||
|
||||
This includes temperature reading functionality.
|
||||
|
||||
config MAX77620_THERMAL
|
||||
tristate "Temperature sensor driver for Maxim MAX77620 PMIC"
|
||||
depends on MFD_MAX77620
|
||||
@@ -285,8 +295,8 @@ config MAX77620_THERMAL
|
||||
|
||||
config QORIQ_THERMAL
|
||||
tristate "QorIQ Thermal Monitoring Unit"
|
||||
depends on THERMAL_OF
|
||||
depends on HAS_IOMEM
|
||||
depends on THERMAL_OF && HAS_IOMEM
|
||||
depends on PPC_E500MC || SOC_LS1021A || ARCH_LAYERSCAPE || (ARCH_MXC && ARM64) || COMPILE_TEST
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
Support for Thermal Monitoring Unit (TMU) found on QorIQ platforms.
|
||||
|
||||
@@ -9,14 +9,14 @@ thermal_sys-y += thermal_core.o thermal_sysfs.o \
|
||||
|
||||
# interface to/from other layers providing sensors
|
||||
thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o
|
||||
thermal_sys-$(CONFIG_THERMAL_OF) += of-thermal.o
|
||||
thermal_sys-$(CONFIG_THERMAL_OF) += thermal_of.o
|
||||
|
||||
# governors
|
||||
thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += fair_share.o
|
||||
thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += gov_fair_share.o
|
||||
thermal_sys-$(CONFIG_THERMAL_GOV_BANG_BANG) += gov_bang_bang.o
|
||||
thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE) += step_wise.o
|
||||
thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o
|
||||
thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += power_allocator.o
|
||||
thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE) += gov_step_wise.o
|
||||
thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += gov_user_space.o
|
||||
thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += gov_power_allocator.o
|
||||
|
||||
# cpufreq cooling
|
||||
thermal_sys-$(CONFIG_CPU_FREQ_THERMAL) += cpufreq_cooling.o
|
||||
@@ -28,6 +28,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o
|
||||
# devfreq cooling
|
||||
thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
|
||||
|
||||
obj-$(CONFIG_K3_THERMAL) += k3_bandgap.o
|
||||
# platform thermal drivers
|
||||
obj-y += broadcom/
|
||||
obj-$(CONFIG_THERMAL_MMIO) += thermal_mmio.o
|
||||
|
||||
@@ -12,15 +12,16 @@
|
||||
* Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clock_cooling.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/clock_cooling.h>
|
||||
|
||||
/**
|
||||
* struct clock_cooling_device - data for cooling device with clock
|
||||
|
||||
@@ -10,17 +10,17 @@
|
||||
* Viresh Kumar <viresh.kumar@linaro.org>
|
||||
*
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/cpu_cooling.h>
|
||||
#include <linux/energy_model.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpu_cooling.h>
|
||||
#include <linux/energy_model.h>
|
||||
#include <linux/thermal.h>
|
||||
|
||||
#include <trace/events/thermal.h>
|
||||
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
* Author: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
*
|
||||
*/
|
||||
#define pr_fmt(fmt) "cpuidle cooling: " fmt
|
||||
|
||||
#include <linux/cpu_cooling.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/idle_inject.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/thermal.h>
|
||||
|
||||
@@ -154,22 +157,25 @@ static struct thermal_cooling_device_ops cpuidle_cooling_ops = {
|
||||
};
|
||||
|
||||
/**
|
||||
* cpuidle_of_cooling_register - Idle cooling device initialization function
|
||||
* __cpuidle_cooling_register: register the cooling device
|
||||
* @drv: a cpuidle driver structure pointer
|
||||
* @np: a node pointer to a device tree cooling device node
|
||||
* @np: a device node structure pointer used for the thermal binding
|
||||
*
|
||||
* This function is in charge of creating a cooling device per cpuidle
|
||||
* driver and register it to thermal framework.
|
||||
* This function is in charge of allocating the cpuidle cooling device
|
||||
* structure, the idle injection, initialize them and register the
|
||||
* cooling device to the thermal framework.
|
||||
*
|
||||
* Return: zero on success, or negative value corresponding to the
|
||||
* error detected in the underlying subsystems.
|
||||
* Return: zero on success, a negative value returned by one of the
|
||||
* underlying subsystem in case of error
|
||||
*/
|
||||
int cpuidle_of_cooling_register(struct device_node *np,
|
||||
struct cpuidle_driver *drv)
|
||||
static int __cpuidle_cooling_register(struct device_node *np,
|
||||
struct cpuidle_driver *drv)
|
||||
{
|
||||
struct idle_inject_device *ii_dev;
|
||||
struct cpuidle_cooling_device *idle_cdev;
|
||||
struct thermal_cooling_device *cdev;
|
||||
unsigned int idle_duration_us = TICK_USEC;
|
||||
unsigned int latency_us = UINT_MAX;
|
||||
char dev_name[THERMAL_NAME_LENGTH];
|
||||
int id, ret;
|
||||
|
||||
@@ -191,7 +197,11 @@ int cpuidle_of_cooling_register(struct device_node *np,
|
||||
goto out_id;
|
||||
}
|
||||
|
||||
idle_inject_set_duration(ii_dev, TICK_USEC, TICK_USEC);
|
||||
of_property_read_u32(np, "duration-us", &idle_duration_us);
|
||||
of_property_read_u32(np, "exit-latency-us", &latency_us);
|
||||
|
||||
idle_inject_set_duration(ii_dev, TICK_USEC, idle_duration_us);
|
||||
idle_inject_set_latency(ii_dev, latency_us);
|
||||
|
||||
idle_cdev->ii_dev = ii_dev;
|
||||
|
||||
@@ -204,6 +214,9 @@ int cpuidle_of_cooling_register(struct device_node *np,
|
||||
goto out_unregister;
|
||||
}
|
||||
|
||||
pr_debug("%s: Idle injection set with idle duration=%u, latency=%u\n",
|
||||
dev_name, idle_duration_us, latency_us);
|
||||
|
||||
return 0;
|
||||
|
||||
out_unregister:
|
||||
@@ -221,12 +234,38 @@ out:
|
||||
* @drv: a cpuidle driver structure pointer
|
||||
*
|
||||
* This function is in charge of creating a cooling device per cpuidle
|
||||
* driver and register it to thermal framework.
|
||||
* driver and register it to the thermal framework.
|
||||
*
|
||||
* Return: zero on success, or negative value corresponding to the
|
||||
* error detected in the underlying subsystems.
|
||||
*/
|
||||
int cpuidle_cooling_register(struct cpuidle_driver *drv)
|
||||
void cpuidle_cooling_register(struct cpuidle_driver *drv)
|
||||
{
|
||||
return cpuidle_of_cooling_register(NULL, drv);
|
||||
struct device_node *cooling_node;
|
||||
struct device_node *cpu_node;
|
||||
int cpu, ret;
|
||||
|
||||
for_each_cpu(cpu, drv->cpumask) {
|
||||
|
||||
cpu_node = of_cpu_device_node_get(cpu);
|
||||
|
||||
cooling_node = of_get_child_by_name(cpu_node, "thermal-idle");
|
||||
|
||||
of_node_put(cpu_node);
|
||||
|
||||
if (!cooling_node) {
|
||||
pr_debug("'thermal-idle' node not found for cpu%d\n", cpu);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = __cpuidle_cooling_register(cooling_node, drv);
|
||||
|
||||
of_node_put(cooling_node);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Failed to register the cpuidle cooling device" \
|
||||
"for cpu%d: %d\n", cpu, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,11 +24,13 @@
|
||||
#include <linux/idr.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/thermal.h>
|
||||
|
||||
#include <trace/events/thermal.h>
|
||||
|
||||
#define SCALE_ERROR_MITIGATION 100
|
||||
#define HZ_PER_KHZ 1000
|
||||
#define SCALE_ERROR_MITIGATION 100
|
||||
|
||||
static DEFINE_IDA(devfreq_ida);
|
||||
|
||||
@@ -54,6 +56,8 @@ static DEFINE_IDA(devfreq_ida);
|
||||
* The 'res_util' range is from 100 to (power_table[state] * 100)
|
||||
* for the corresponding 'state'.
|
||||
* @capped_state: index to cooling state with in dynamic power budget
|
||||
* @req_max_freq: PM QoS request for limiting the maximum frequency
|
||||
* of the devfreq device.
|
||||
*/
|
||||
struct devfreq_cooling_device {
|
||||
int id;
|
||||
@@ -66,49 +70,9 @@ struct devfreq_cooling_device {
|
||||
struct devfreq_cooling_power *power_ops;
|
||||
u32 res_util;
|
||||
int capped_state;
|
||||
struct dev_pm_qos_request req_max_freq;
|
||||
};
|
||||
|
||||
/**
|
||||
* partition_enable_opps() - disable all opps above a given state
|
||||
* @dfc: Pointer to devfreq we are operating on
|
||||
* @cdev_state: cooling device state we're setting
|
||||
*
|
||||
* Go through the OPPs of the device, enabling all OPPs until
|
||||
* @cdev_state and disabling those frequencies above it.
|
||||
*/
|
||||
static int partition_enable_opps(struct devfreq_cooling_device *dfc,
|
||||
unsigned long cdev_state)
|
||||
{
|
||||
int i;
|
||||
struct device *dev = dfc->devfreq->dev.parent;
|
||||
|
||||
for (i = 0; i < dfc->freq_table_size; i++) {
|
||||
struct dev_pm_opp *opp;
|
||||
int ret = 0;
|
||||
unsigned int freq = dfc->freq_table[i];
|
||||
bool want_enable = i >= cdev_state ? true : false;
|
||||
|
||||
opp = dev_pm_opp_find_freq_exact(dev, freq, !want_enable);
|
||||
|
||||
if (PTR_ERR(opp) == -ERANGE)
|
||||
continue;
|
||||
else if (IS_ERR(opp))
|
||||
return PTR_ERR(opp);
|
||||
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
if (want_enable)
|
||||
ret = dev_pm_opp_enable(dev, freq);
|
||||
else
|
||||
ret = dev_pm_opp_disable(dev, freq);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int devfreq_cooling_get_max_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long *state)
|
||||
{
|
||||
@@ -135,7 +99,7 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
|
||||
struct devfreq_cooling_device *dfc = cdev->devdata;
|
||||
struct devfreq *df = dfc->devfreq;
|
||||
struct device *dev = df->dev.parent;
|
||||
int ret;
|
||||
unsigned long freq;
|
||||
|
||||
if (state == dfc->cooling_state)
|
||||
return 0;
|
||||
@@ -145,9 +109,10 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
|
||||
if (state >= dfc->freq_table_size)
|
||||
return -EINVAL;
|
||||
|
||||
ret = partition_enable_opps(dfc, state);
|
||||
if (ret)
|
||||
return ret;
|
||||
freq = dfc->freq_table[state];
|
||||
|
||||
dev_pm_qos_update_request(&dfc->req_max_freq,
|
||||
DIV_ROUND_UP(freq, HZ_PER_KHZ));
|
||||
|
||||
dfc->cooling_state = state;
|
||||
|
||||
@@ -530,9 +495,15 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
|
||||
if (err)
|
||||
goto free_dfc;
|
||||
|
||||
err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL);
|
||||
err = dev_pm_qos_add_request(df->dev.parent, &dfc->req_max_freq,
|
||||
DEV_PM_QOS_MAX_FREQUENCY,
|
||||
PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
|
||||
if (err < 0)
|
||||
goto free_tables;
|
||||
|
||||
err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL);
|
||||
if (err < 0)
|
||||
goto remove_qos_req;
|
||||
dfc->id = err;
|
||||
|
||||
snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d", dfc->id);
|
||||
@@ -553,6 +524,10 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
|
||||
|
||||
release_ida:
|
||||
ida_simple_remove(&devfreq_ida, dfc->id);
|
||||
|
||||
remove_qos_req:
|
||||
dev_pm_qos_remove_request(&dfc->req_max_freq);
|
||||
|
||||
free_tables:
|
||||
kfree(dfc->power_table);
|
||||
kfree(dfc->freq_table);
|
||||
@@ -601,6 +576,7 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
|
||||
|
||||
thermal_cooling_device_unregister(dfc->cdev);
|
||||
ida_simple_remove(&devfreq_ida, dfc->id);
|
||||
dev_pm_qos_remove_request(&dfc->req_max_freq);
|
||||
kfree(dfc->power_table);
|
||||
kfree(dfc->freq_table);
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/thermal.h>
|
||||
|
||||
#include "thermal_core.h"
|
||||
|
||||
@@ -54,7 +54,7 @@ struct imx8mm_tmu {
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
const struct thermal_soc_data *socdata;
|
||||
struct tmu_sensor sensors[0];
|
||||
struct tmu_sensor sensors[];
|
||||
};
|
||||
|
||||
static int imx8mm_tmu_get_temp(void *data, int *temp)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user