History

Merge tag 'thermal-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux

Pull thermal updates from Daniel Lezcano: - Add support to enable/disable the thermal zones resulting on core code and drivers cleanup (Andrzej Pietrasiewicz) - Add generic netlink support for userspace notifications: events, temperature and discovery commands (Daniel Lezcano) - Fix redundant initialization for a ret variable (Colin Ian King) - Remove the clock cooling code as it is used nowhere (Amit Kucheria) - Add the rcar_gen3_thermal's r8a774e1 support (Marian-Cristian Rotariu) - Replace all references to thermal.txt in the documentation to the corresponding yaml files (Amit Kucheria) - Add maintainer entry for the IPA (Lukasz Luba) - Add support for MSM8939 for the tsens (Shawn Guo) - Update power allocator and devfreq cooling to SPDX licensing (Lukasz Luba) - Add Cannon Lake Low Power PCH support (Sumeet Pawnikar) - Add tsensor support for V2 mediatek thermal system (Henry Yen) - Fix thermal zone lookup by ID for the core code (Thierry Reding) * tag 'thermal-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux: (40 commits) thermal: intel: intel_pch_thermal: Add Cannon Lake Low Power PCH support thermal: mediatek: Add tsensor support for V2 thermal system thermal: mediatek: Prepare to add support for other platforms thermal: Update power allocator and devfreq cooling to SPDX licensing MAINTAINERS: update entry to thermal governors file name prefixing thermal: core: Add thermal zone enable/disable notification thermal: qcom: tsens-v0_1: Add support for MSM8939 dt-bindings: tsens: qcom: Document MSM8939 compatible thermal: core: Fix thermal zone lookup by ID thermal: int340x: processor_thermal: fix: update Jasper Lake PCI id thermal: imx8mm: Support module autoloading thermal: ti-soc-thermal: Fix reversed condition in ti_thermal_expose_sensor() MAINTAINERS: Add maintenance information for IPA thermal: rcar_gen3_thermal: Do not shadow thcode variable dt-bindings: thermal: Get rid of thermal.txt and replace references thermal: core: Move initialization after core initcall thermal: netlink: Improve the initcall ordering net: genetlink: Move initialization to core_initcall thermal: rcar_gen3_thermal: Add r8a774e1 support thermal/drivers/clock_cooling: Remove clock_cooling code ...

Linus Torvalds committed 6 years ago

Commit 96e3f3c2 parents ed35832 c569e8075 files · +1632 −1609Browse files

Unified · Split

75 files
  1. Documentation/devicetree/bindings/arm/arm,scmi.txt +1 −1
  2. Documentation/devicetree/bindings/arm/arm,scpi.txt +1 −1
  3. Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt +1 −1
  4. Documentation/devicetree/bindings/arm/marvell/ap80x-system-controller.txt +1 −1
  5. Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt +1 −1
  6. Documentation/devicetree/bindings/cpufreq/cpufreq-dt.txt +2 −1
  7. Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek.txt +2 −2
  8. Documentation/devicetree/bindings/cpufreq/nvidia,tegra20-cpufreq.txt +1 −1
  9. Documentation/devicetree/bindings/hwmon/gpio-fan.txt +2 −1
  10. Documentation/devicetree/bindings/hwmon/lm90.txt +2 −2
  11. Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml +1 −1
  12. Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt +1 −1
  13. Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.yaml +1 −1
  14. Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt +1 −1
  15. Documentation/devicetree/bindings/thermal/hisilicon-thermal.txt +1 −1
  16. Documentation/devicetree/bindings/thermal/max77620_thermal.txt +3 −3
  17. Documentation/devicetree/bindings/thermal/mediatek-thermal.txt +1 −1
  18. Documentation/devicetree/bindings/thermal/nvidia,tegra124-soctherm.txt +6 −4
  19. Documentation/devicetree/bindings/thermal/nvidia,tegra186-bpmp-thermal.txt +1 −1
  20. Documentation/devicetree/bindings/thermal/qcom-spmi-temp-alarm.txt +1 −1
  21. Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +1 −0
  22. Documentation/devicetree/bindings/thermal/rockchip-thermal.txt +1 −1
  23. Documentation/devicetree/bindings/thermal/tango-thermal.txt +1 −1
  24. Documentation/devicetree/bindings/thermal/thermal-generic-adc.txt +1 −1
  25. Documentation/devicetree/bindings/thermal/thermal.txt +0 −586
  26. MAINTAINERS +8 −0
  27. drivers/acpi/thermal.c +21 −55
  28. drivers/net/ethernet/chelsio/cxgb4/cxgb4_thermal.c +8 −0
  29. drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +17 −74
  30. drivers/net/wireless/intel/iwlwifi/mvm/tt.c +8 −1
  31. drivers/platform/x86/acerhdf.c +13 −20
  32. drivers/platform/x86/intel_mid_thermal.c +6 −0
  33. drivers/power/supply/power_supply_core.c +7 −2
  34. drivers/thermal/Kconfig +10 −10
  35. drivers/thermal/Makefile +3 −3
  36. drivers/thermal/armada_thermal.c +6 −0
  37. drivers/thermal/clock_cooling.c +0 −445
  38. drivers/thermal/da9062-thermal.c +5 −11
  39. drivers/thermal/devfreq_cooling.c +1 −9
  40. drivers/thermal/dove_thermal.c +6 −0
  41. drivers/thermal/gov_power_allocator.c +1 −8
  42. drivers/thermal/hisi_thermal.c +4 −2
  43. drivers/thermal/imx8mm_thermal.c +1 −0
  44. drivers/thermal/imx_thermal.c +19 −41
  45. drivers/thermal/intel/int340x_thermal/int3400_thermal.c +7 −31
  46. drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +5 −0
  47. drivers/thermal/intel/int340x_thermal/processor_thermal_device.c +1 −1
  48. drivers/thermal/intel/intel_pch_thermal.c +8 −0
  49. drivers/thermal/intel/intel_quark_dts_thermal.c +6 −28
  50. drivers/thermal/intel/intel_soc_dts_iosf.c +3 −0
  51. drivers/thermal/intel/x86_pkg_temp_thermal.c +6 −0
  52. drivers/thermal/kirkwood_thermal.c +7 −0
  53. drivers/thermal/mtk_thermal.c +181 −53
  54. drivers/thermal/qcom/tsens-v0_1.c +143 −1
  55. drivers/thermal/qcom/tsens.c +3 −0
  56. drivers/thermal/qcom/tsens.h +1 −1
  57. drivers/thermal/rcar_gen3_thermal.c +7 −3
  58. drivers/thermal/rcar_thermal.c +8 −1
  59. drivers/thermal/rockchip_thermal.c +4 −2
  60. drivers/thermal/spear_thermal.c +7 −0
  61. drivers/thermal/sprd_thermal.c +4 −2
  62. drivers/thermal/st/st_thermal.c +5 −0
  63. drivers/thermal/thermal_core.c +165 −9
  64. drivers/thermal/thermal_core.h +15 −0
  65. drivers/thermal/thermal_helpers.c +11 −2
  66. drivers/thermal/thermal_netlink.c +647 −0
  67. drivers/thermal/thermal_netlink.h +104 −0
  68. drivers/thermal/thermal_of.c +1 −40
  69. drivers/thermal/thermal_sysfs.c +18 −34
  70. drivers/thermal/ti-soc-thermal/ti-thermal-common.c +1 −1
  71. include/linux/clock_cooling.h +0 −57
  72. include/linux/devfreq_cooling.h +1 −8
  73. include/linux/thermal.h +11 −20
  74. include/uapi/linux/thermal.h +72 −17
  75. net/netlink/genetlink.c +1 −1
Documentation/devicetree/bindings/arm/arm,scmi.txt+1−1
@@ -102,7 +102,7 @@ Required sub-node properties: · 101 unmodified lines
102102 [0] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/index.html
103103 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
104104 [2] Documentation/devicetree/bindings/power/power-domain.yaml
105−[3] Documentation/devicetree/bindings/thermal/thermal.txt
105+[3] Documentation/devicetree/bindings/thermal/thermal*.yaml
106106 [4] Documentation/devicetree/bindings/sram/sram.yaml
107107 [5] Documentation/devicetree/bindings/reset/reset.txt
108108
Documentation/devicetree/bindings/arm/arm,scpi.txt+1−1
@@ -108,7 +108,7 @@ Required properties: · 107 unmodified lines
108108
109109 [0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html
110110 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
111−[2] Documentation/devicetree/bindings/thermal/thermal.txt
111+[2] Documentation/devicetree/bindings/thermal/thermal*.yaml
112112 [3] Documentation/devicetree/bindings/sram/sram.yaml
113113 [4] Documentation/devicetree/bindings/power/power-domain.yaml
114114
Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt+1−1
@@ -176,7 +176,7 @@ Required properties: · 175 unmodified lines
176176 "fsl,imx8qxp-sc-thermal"
177177 followed by "fsl,imx-sc-thermal";
178178
179−- #thermal-sensor-cells: See Documentation/devicetree/bindings/thermal/thermal.txt
179+- #thermal-sensor-cells: See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml
180180 for a description.
181181
182182 Example (imx8qxp):
Documentation/devicetree/bindings/arm/marvell/ap80x-system-controller.txt+1−1
@@ -111,7 +111,7 @@ Thermal: · 110 unmodified lines
111111 --------
112112
113113 For common binding part and usage, refer to
114−Documentation/devicetree/bindings/thermal/thermal.txt
114+Documentation/devicetree/bindings/thermal/thermal*.yaml
115115
116116 The thermal IP can probe the temperature all around the processor. It
117117 may feature several channels, each of them wired to one sensor.
Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt+1−1
@@ -203,7 +203,7 @@ It is possible to setup an overheat interrupt by giving at least one · 202 unmodified lines
203203 critical point to any subnode of the thermal-zone node.
204204
205205 For common binding part and usage, refer to
206−Documentation/devicetree/bindings/thermal/thermal.txt
206+Documentation/devicetree/bindings/thermal/thermal*.yaml
207207
208208 Required properties:
209209 - compatible: must be one of:
Documentation/devicetree/bindings/cpufreq/cpufreq-dt.txt+2−1
@@ -18,7 +18,8 @@ Optional properties: · 17 unmodified lines
1818 in unit of nanoseconds.
1919 - voltage-tolerance: Specify the CPU voltage tolerance in percentage.
2020 - #cooling-cells:
21− Please refer to Documentation/devicetree/bindings/thermal/thermal.txt.
21+ Please refer to
22+ Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml.
2223
2324 Examples:
2425
Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek.txt+2−2
@@ -21,8 +21,8 @@ Optional properties: · 20 unmodified lines
2121 flow is handled by hardware, hence no software "voltage tracking" is
2222 needed.
2323 - #cooling-cells:
24− Please refer to Documentation/devicetree/bindings/thermal/thermal.txt
25− for detail.
24+ For details, please refer to
25+ Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
2626
2727 Example 1 (MT7623 SoC):
2828
Documentation/devicetree/bindings/cpufreq/nvidia,tegra20-cpufreq.txt+1−1
@@ -5,7 +5,7 @@ Required properties: · 4 unmodified lines
55 - clocks: Must contain an entry for the CPU clock.
66 See ../clocks/clock-bindings.txt for details.
77 - operating-points-v2: See ../bindings/opp/opp.txt for details.
8−- #cooling-cells: Should be 2. See ../thermal/thermal.txt for details.
8+- #cooling-cells: Should be 2. See ../thermal/thermal-cooling-devices.yaml for details.
99
1010 For each opp entry in 'operating-points-v2' table:
1111 - opp-supported-hw: Two bitfields indicating:
Documentation/devicetree/bindings/hwmon/gpio-fan.txt+2−1
@@ -12,7 +12,8 @@ Optional properties: · 11 unmodified lines
1212 - alarm-gpios: This pin going active indicates something is wrong with
1313 the fan, and a udev event will be fired.
1414 - #cooling-cells: If used as a cooling device, must be <2>
15− Also see: Documentation/devicetree/bindings/thermal/thermal.txt
15+ Also see:
16+ Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
1617 min and max states are derived from the speed-map of the fan.
1718
1819 Note: At least one the "gpios" or "alarm-gpios" properties must be set.
Documentation/devicetree/bindings/hwmon/lm90.txt+2−2
@@ -34,8 +34,8 @@ Optional properties: · 33 unmodified lines
3434 LM90 "-ALERT" pin output.
3535 See interrupt-controller/interrupts.txt for the format.
3636
37−- #thermal-sensor-cells: should be set to 1. See thermal/thermal.txt for
38− details. See <include/dt-bindings/thermal/lm90.h> for the
37+- #thermal-sensor-cells: should be set to 1. See thermal/thermal-sensor.yaml
38+ for details. See <include/dt-bindings/thermal/lm90.h> for the
3939 definition of the local, remote and 2nd remote sensor index
4040 constants.
4141
Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml+1−1
@@ -50,7 +50,7 @@ properties: · 49 unmodified lines
5050 nvmem-cell-names:
5151 const: calibration
5252
53− # See ./thermal.txt for details
53+ # See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for details
5454 "#thermal-sensor-cells":
5555 enum:
5656 - 0
Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt+1−1
@@ -6,7 +6,7 @@ transaction. · 5 unmodified lines
66 Required properties:
77 - compatible: "amazon,al-thermal".
88 - reg: The physical base address and length of the sensor's registers.
9−- #thermal-sensor-cells: Must be 1. See ./thermal.txt for a description.
9+- #thermal-sensor-cells: Must be 1. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description.
1010
1111 Example:
1212 thermal: thermal {
Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.yaml+1−1
@@ -23,7 +23,7 @@ properties: · 22 unmodified lines
2323 compatible:
2424 const: brcm,bcm2711-thermal
2525
26− # See ./thermal.txt for details
26+ # See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for details
2727 "#thermal-sensor-cells":
2828 const: 0
2929
Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt+1−1
@@ -7,7 +7,7 @@ compatible: should be one of: "brcm,bcm2835-thermal", · 6 unmodified lines
77 "brcm,bcm2836-thermal" or "brcm,bcm2837-thermal"
88 reg: Address range of the thermal registers.
99 clocks: Phandle of the clock used by the thermal sensor.
10−#thermal-sensor-cells: should be 0 (see thermal.txt)
10+#thermal-sensor-cells: should be 0 (see Documentation/devicetree/bindings/thermal/thermal-sensor.yaml)
1111
1212 Example:
1313
Documentation/devicetree/bindings/thermal/hisilicon-thermal.txt+1−1
@@ -9,7 +9,7 @@ · 8 unmodified lines
99 by /SOCTHERM/tsensor.
1010 - clock-names: Input clock name, should be 'thermal_clk'.
1111 - clocks: phandles for clock specified in "clock-names" property.
12−- #thermal-sensor-cells: Should be 1. See ./thermal.txt for a description.
12+- #thermal-sensor-cells: Should be 1. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description.
1313
1414 Example :
1515
Documentation/devicetree/bindings/thermal/max77620_thermal.txt+3−3
@@ -8,12 +8,12 @@ below threshold level. · 7 unmodified lines
88
99 Required properties:
1010 -------------------
11−#thermal-sensor-cells: Please refer <devicetree/bindings/thermal/thermal.txt>
12− for more details.
11+#thermal-sensor-cells: For more details, please refer to
12+ <devicetree/bindings/thermal/thermal-sensor.yaml>
1313 The value must be 0.
1414
1515 For more details, please refer generic thermal DT binding document
16−<devicetree/bindings/thermal/thermal.txt>.
16+<devicetree/bindings/thermal/thermal*.yaml>.
1717
1818 Please refer <devicetree/bindings/mfd/max77620.txt> for mfd DT binding
1919 document for the MAX77620.
Documentation/devicetree/bindings/thermal/mediatek-thermal.txt+1−1
@@ -23,7 +23,7 @@ Required properties: · 22 unmodified lines
2323 - resets: Reference to the reset controller controlling the thermal controller.
2424 - mediatek,auxadc: A phandle to the AUXADC which the thermal controller uses
2525 - mediatek,apmixedsys: A phandle to the APMIXEDSYS controller.
26−- #thermal-sensor-cells : Should be 0. See ./thermal.txt for a description.
26+- #thermal-sensor-cells : Should be 0. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description.
2727
2828 Optional properties:
2929 - nvmem-cells: A phandle to the calibration data provided by a nvmem device. If
Documentation/devicetree/bindings/thermal/nvidia,tegra124-soctherm.txt+6−4
@@ -28,9 +28,10 @@ Required properties : · 27 unmodified lines
2828 See ../reset/reset.txt for details.
2929 - reset-names : Must include the following entries:
3030 - soctherm
31−- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description
32− of this property. See <dt-bindings/thermal/tegra124-soctherm.h> for a
33− list of valid values when referring to thermal sensors.
31+- #thermal-sensor-cells : Should be 1. For a description of this property, see
32+ Documentation/devicetree/bindings/thermal/thermal-sensor.yaml.
33+ See <dt-bindings/thermal/tegra124-soctherm.h> for a list of valid values
34+ when referring to thermal sensors.
3435 - throttle-cfgs: A sub-node which is a container of configuration for each
3536 hardware throttle events. These events can be set as cooling devices.
3637 * throttle events: Sub-nodes must be named as "light" or "heavy".
@@ -62,7 +63,8 @@ Required properties : · 25 unmodified lines
6263 TEGRA_SOCTHERM_THROT_LEVEL_MED (75%),
6364 TEGRA_SOCTHERM_THROT_LEVEL_HIGH (85%).
6465 - #cooling-cells: Should be 1. This cooling device only support on/off state.
65− See ./thermal.txt for a description of this property.
66+ For a description of this property see:
67+ Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
6668
6769 Optional properties: The following properties are T210 specific and
6870 valid only for OCx throttle events.
Documentation/devicetree/bindings/thermal/nvidia,tegra186-bpmp-thermal.txt+1−1
@@ -8,7 +8,7 @@ exposed by BPMP. · 7 unmodified lines
88 The BPMP thermal node must be located directly inside the main BPMP node. See
99 ../firmware/nvidia,tegra186-bpmp.txt for details of the BPMP binding.
1010
11−This node represents a thermal sensor. See thermal.txt for details of the
11+This node represents a thermal sensor. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for details of the
1212 core thermal binding.
1313
1414 Required properties:
Documentation/devicetree/bindings/thermal/qcom-spmi-temp-alarm.txt+1−1
@@ -8,7 +8,7 @@ Required properties: · 7 unmodified lines
88 - compatible: Should contain "qcom,spmi-temp-alarm".
99 - reg: Specifies the SPMI address.
1010 - interrupts: PMIC temperature alarm interrupt.
11−- #thermal-sensor-cells: Should be 0. See thermal.txt for a description.
11+- #thermal-sensor-cells: Should be 0. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description.
1212
1313 Optional properties:
1414 - io-channels: Should contain IIO channel specifier for the ADC channel,
Documentation/devicetree/bindings/thermal/qcom-tsens.yaml+1−0
@@ -23,6 +23,7 @@ properties: · 22 unmodified lines
2323 items:
2424 - enum:
2525 - qcom,msm8916-tsens
26+ - qcom,msm8939-tsens
2627 - qcom,msm8974-tsens
2728 - const: qcom,tsens-v0_1
2829
Documentation/devicetree/bindings/thermal/rockchip-thermal.txt+1−1
@@ -24,7 +24,7 @@ Required properties: · 23 unmodified lines
2424 - pinctrl-1 : The "default" pinctrl state, it will be set after reset the
2525 TSADC controller.
2626 - pinctrl-2 : The "sleep" pinctrl state, it will be in for suspend.
27−- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
27+- #thermal-sensor-cells : Should be 1. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description.
2828
2929 Optional properties:
3030 - rockchip,hw-tshut-temp : The hardware-controlled shutdown temperature value.
Documentation/devicetree/bindings/thermal/tango-thermal.txt+1−1
@@ -4,7 +4,7 @@ The SMP8758 SoC includes 3 instances of this temperature sensor · 3 unmodified lines
44 (in the CPU, video decoder, and PCIe controller).
55
66 Required properties:
7−- #thermal-sensor-cells: Should be 0 (see thermal.txt)
7+- #thermal-sensor-cells: Should be 0 (see Documentation/devicetree/bindings/thermal/thermal-sensor.yaml)
88 - compatible: "sigma,smp8758-thermal"
99 - reg: Address range of the thermal registers
1010
Documentation/devicetree/bindings/thermal/thermal-generic-adc.txt+1−1
@@ -8,7 +8,7 @@ temperature using voltage-temperature lookup table. · 7 unmodified lines
88 Required properties:
99 ===================
1010 - compatible: Must be "generic-adc-thermal".
11−- #thermal-sensor-cells: Should be 1. See ./thermal.txt for a description
11+- #thermal-sensor-cells: Should be 1. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description
1212 of this property.
1313 Optional properties:
1414 ===================
Documentation/devicetree/bindings/thermal/thermal.txt+0−586
@@ -1,586 +0,0 @@
1−* Thermal Framework Device Tree descriptor
2−
3−This file describes a generic binding to provide a way of
4−defining hardware thermal structure using device tree.
5−A thermal structure includes thermal zones and their components,
6−such as trip points, polling intervals, sensors and cooling devices
7−binding descriptors.
8−
9−The target of device tree thermal descriptors is to describe only
10−the hardware thermal aspects. The thermal device tree bindings are
11−not about how the system must control or which algorithm or policy
12−must be taken in place.
13−
14−There are five types of nodes involved to describe thermal bindings:
15−- thermal sensors: devices which may be used to take temperature
16− measurements.
17−- cooling devices: devices which may be used to dissipate heat.
18−- trip points: describe key temperatures at which cooling is recommended. The
19− set of points should be chosen based on hardware limits.
20−- cooling maps: used to describe links between trip points and cooling devices;
21−- thermal zones: used to describe thermal data within the hardware;
22−
23−The following is a description of each of these node types.
24−
25−* Thermal sensor devices
26−
27−Thermal sensor devices are nodes providing temperature sensing capabilities on
28−thermal zones. Typical devices are I2C ADC converters and bandgaps. These are
29−nodes providing temperature data to thermal zones. Thermal sensor devices may
30−control one or more internal sensors.
31−
32−Required property:
33−- #thermal-sensor-cells: Used to provide sensor device specific information
34− Type: unsigned while referring to it. Typically 0 on thermal sensor
35− Size: one cell nodes with only one sensor, and at least 1 on nodes
36− with several internal sensors, in order
37− to identify uniquely the sensor instances within
38− the IC. See thermal zone binding for more details
39− on how consumers refer to sensor devices.
40−
41−* Cooling device nodes
42−
43−Cooling devices are nodes providing control on power dissipation. There
44−are essentially two ways to provide control on power dissipation. First
45−is by means of regulating device performance, which is known as passive
46−cooling. A typical passive cooling is a CPU that has dynamic voltage and
47−frequency scaling (DVFS), and uses lower frequencies as cooling states.
48−Second is by means of activating devices in order to remove
49−the dissipated heat, which is known as active cooling, e.g. regulating
50−fan speeds. In both cases, cooling devices shall have a way to determine
51−the state of cooling in which the device is.
52−
53−Any cooling device has a range of cooling states (i.e. different levels
54−of heat dissipation). For example a fan's cooling states correspond to
55−the different fan speeds possible. Cooling states are referred to by
56−single unsigned integers, where larger numbers mean greater heat
57−dissipation. The precise set of cooling states associated with a device
58−should be defined in a particular device's binding.
59−For more examples of cooling devices, refer to the example sections below.
60−
61−Required properties:
62−- #cooling-cells: Used to provide cooling device specific information
63− Type: unsigned while referring to it. Must be at least 2, in order
64− Size: one cell to specify minimum and maximum cooling state used
65− in the reference. The first cell is the minimum
66− cooling state requested and the second cell is
67− the maximum cooling state requested in the reference.
68− See Cooling device maps section below for more details
69− on how consumers refer to cooling devices.
70−
71−* Trip points
72−
73−The trip node is a node to describe a point in the temperature domain
74−in which the system takes an action. This node describes just the point,
75−not the action.
76−
77−Required properties:
78−- temperature: An integer indicating the trip temperature level,
79− Type: signed in millicelsius.
80− Size: one cell
81−
82−- hysteresis: A low hysteresis value on temperature property (above).
83− Type: unsigned This is a relative value, in millicelsius.
84− Size: one cell
85−
86−- type: a string containing the trip type. Expected values are:
87− "active": A trip point to enable active cooling
88− "passive": A trip point to enable passive cooling
89− "hot": A trip point to notify emergency
90− "critical": Hardware not reliable.
91− Type: string
92−
93−* Cooling device maps
94−
95−The cooling device maps node is a node to describe how cooling devices
96−get assigned to trip points of the zone. The cooling devices are expected
97−to be loaded in the target system.
98−
99−Required properties:
100−- cooling-device: A list of phandles of cooling devices with their specifiers,
101− Type: phandle + referring to which cooling devices are used in this
102− cooling specifier binding. In the cooling specifier, the first cell
103− is the minimum cooling state and the second cell
104− is the maximum cooling state used in this map.
105−- trip: A phandle of a trip point node within the same thermal
106− Type: phandle of zone.
107− trip point node
108−
109−Optional property:
110−- contribution: The cooling contribution to the thermal zone of the
111− Type: unsigned referred cooling device at the referred trip point.
112− Size: one cell The contribution is a ratio of the sum
113− of all cooling contributions within a thermal zone.
114−
115−Note: Using the THERMAL_NO_LIMIT (-1UL) constant in the cooling-device phandle
116−limit specifier means:
117−(i) - minimum state allowed for minimum cooling state used in the reference.
118−(ii) - maximum state allowed for maximum cooling state used in the reference.
119−Refer to include/dt-bindings/thermal/thermal.h for definition of this constant.
120−
121−* Thermal zone nodes
122−
123−The thermal zone node is the node containing all the required info
124−for describing a thermal zone, including its cooling device bindings. The
125−thermal zone node must contain, apart from its own properties, one sub-node
126−containing trip nodes and one sub-node containing all the zone cooling maps.
127−
128−Required properties:
129−- polling-delay: The maximum number of milliseconds to wait between polls
130− Type: unsigned when checking this thermal zone.
131− Size: one cell
132−
133−- polling-delay-passive: The maximum number of milliseconds to wait
134− Type: unsigned between polls when performing passive cooling.
135− Size: one cell
136−
137−- thermal-sensors: A list of thermal sensor phandles and sensor specifier
138− Type: list of used while monitoring the thermal zone.
139− phandles + sensor
140− specifier
141−
142−- trips: A sub-node which is a container of only trip point nodes
143− Type: sub-node required to describe the thermal zone.
144−
145−Optional property:
146−- cooling-maps: A sub-node which is a container of only cooling device
147− Type: sub-node map nodes, used to describe the relation between trips
148− and cooling devices.
149−
150−- coefficients: An array of integers (one signed cell) containing
151− Type: array coefficients to compose a linear relation between
152− Elem size: one cell the sensors listed in the thermal-sensors property.
153− Elem type: signed Coefficients defaults to 1, in case this property
154− is not specified. A simple linear polynomial is used:
155− Z = c0 * x0 + c1 * x1 + ... + c(n-1) * x(n-1) + cn.
156−
157− The coefficients are ordered and they match with sensors
158− by means of sensor ID. Additional coefficients are
159− interpreted as constant offset.
160−
161−- sustainable-power: An estimate of the sustainable power (in mW) that the
162− Type: unsigned thermal zone can dissipate at the desired
163− Size: one cell control temperature. For reference, the
164− sustainable power of a 4'' phone is typically
165− 2000mW, while on a 10'' tablet is around
166− 4500mW.
167−
168−Note: The delay properties are bound to the maximum dT/dt (temperature
169−derivative over time) in two situations for a thermal zone:
170−(i) - when passive cooling is activated (polling-delay-passive); and
171−(ii) - when the zone just needs to be monitored (polling-delay) or
172−when active cooling is activated.
173−
174−The maximum dT/dt is highly bound to hardware power consumption and dissipation
175−capability. The delays should be chosen to account for said max dT/dt,
176−such that a device does not cross several trip boundaries unexpectedly
177−between polls. Choosing the right polling delays shall avoid having the
178−device in temperature ranges that may damage the silicon structures and
179−reduce silicon lifetime.
180−
181−* The thermal-zones node
182−
183−The "thermal-zones" node is a container for all thermal zone nodes. It shall
184−contain only sub-nodes describing thermal zones as in the section
185−"Thermal zone nodes". The "thermal-zones" node appears under "/".
186−
187−* Examples
188−
189−Below are several examples on how to use thermal data descriptors
190−using device tree bindings:
191−
192−(a) - CPU thermal zone
193−
194−The CPU thermal zone example below describes how to setup one thermal zone
195−using one single sensor as temperature source and many cooling devices and
196−power dissipation control sources.
197−
198−#include <dt-bindings/thermal/thermal.h>
199−
200−cpus {
201− /*
202− * Here is an example of describing a cooling device for a DVFS
203− * capable CPU. The CPU node describes its four OPPs.
204− * The cooling states possible are 0..3, and they are
205− * used as OPP indexes. The minimum cooling state is 0, which means
206− * all four OPPs can be available to the system. The maximum
207− * cooling state is 3, which means only the lowest OPPs (198MHz@0.85V)
208− * can be available in the system.
209− */
210− cpu0: cpu@0 {
211− ...
212− operating-points = <
213− /* kHz uV */
214− 970000 1200000
215− 792000 1100000
216− 396000 950000
217− 198000 850000
218− >;
219− #cooling-cells = <2>; /* min followed by max */
220− };
221− ...
222−};
223−
224−&i2c1 {
225− ...
226− /*
227− * A simple fan controller which supports 10 speeds of operation
228− * (represented as 0-9).
229− */
230− fan0: fan@48 {
231− ...
232− #cooling-cells = <2>; /* min followed by max */
233− };
234−};
235−
236−ocp {
237− ...
238− /*
239− * A simple IC with a single bandgap temperature sensor.
240− */
241− bandgap0: bandgap@0000ed00 {
242− ...
243− #thermal-sensor-cells = <0>;
244− };
245−};
246−
247−thermal-zones {
248− cpu_thermal: cpu-thermal {
249− polling-delay-passive = <250>; /* milliseconds */
250− polling-delay = <1000>; /* milliseconds */
251−
252− thermal-sensors = <&bandgap0>;
253−
254− trips {
255− cpu_alert0: cpu-alert0 {
256− temperature = <90000>; /* millicelsius */
257− hysteresis = <2000>; /* millicelsius */
258− type = "active";
259− };
260− cpu_alert1: cpu-alert1 {
261− temperature = <100000>; /* millicelsius */
262− hysteresis = <2000>; /* millicelsius */
263− type = "passive";
264− };
265− cpu_crit: cpu-crit {
266− temperature = <125000>; /* millicelsius */
267− hysteresis = <2000>; /* millicelsius */
268− type = "critical";
269− };
270− };
271−
272− cooling-maps {
273− map0 {
274− trip = <&cpu_alert0>;
275− cooling-device = <&fan0 THERMAL_NO_LIMIT 4>;
276− };
277− map1 {
278− trip = <&cpu_alert1>;
279− cooling-device = <&fan0 5 THERMAL_NO_LIMIT>, <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
280− };
281− };
282− };
283−};
284−
285−In the example above, the ADC sensor (bandgap0) at address 0x0000ED00 is
286−used to monitor the zone 'cpu-thermal' using its sole sensor. A fan
287−device (fan0) is controlled via I2C bus 1, at address 0x48, and has ten
288−different cooling states 0-9. It is used to remove the heat out of
289−the thermal zone 'cpu-thermal' using its cooling states
290−from its minimum to 4, when it reaches trip point 'cpu_alert0'
291−at 90C, as an example of active cooling. The same cooling device is used at
292−'cpu_alert1', but from 5 to its maximum state. The cpu@0 device is also
293−linked to the same thermal zone, 'cpu-thermal', as a passive cooling device,
294−using all its cooling states at trip point 'cpu_alert1',
295−which is a trip point at 100C. On the thermal zone 'cpu-thermal', at the
296−temperature of 125C, represented by the trip point 'cpu_crit', the silicon
297−is not reliable anymore.
298−
299−(b) - IC with several internal sensors
300−
301−The example below describes how to deploy several thermal zones based off a
302−single sensor IC, assuming it has several internal sensors. This is a common
303−case on SoC designs with several internal IPs that may need different thermal
304−requirements, and thus may have their own sensor to monitor or detect internal
305−hotspots in their silicon.
306−
307−#include <dt-bindings/thermal/thermal.h>
308−
309−ocp {
310− ...
311− /*
312− * A simple IC with several bandgap temperature sensors.
313− */
314− bandgap0: bandgap@0000ed00 {
315− ...
316− #thermal-sensor-cells = <1>;
317− };
318−};
319−
320−thermal-zones {
321− cpu_thermal: cpu-thermal {
322− polling-delay-passive = <250>; /* milliseconds */
323− polling-delay = <1000>; /* milliseconds */
324−
325− /* sensor ID */
326− thermal-sensors = <&bandgap0 0>;
327−
328− trips {
329− /* each zone within the SoC may have its own trips */
330− cpu_alert: cpu-alert {
331− temperature = <100000>; /* millicelsius */
332− hysteresis = <2000>; /* millicelsius */
333− type = "passive";
334− };
335− cpu_crit: cpu-crit {
336− temperature = <125000>; /* millicelsius */
337− hysteresis = <2000>; /* millicelsius */
338− type = "critical";
339− };
340− };
341−
342− cooling-maps {
343− /* each zone within the SoC may have its own cooling */
344− ...
345− };
346− };
347−
348− gpu_thermal: gpu-thermal {
349− polling-delay-passive = <120>; /* milliseconds */
350− polling-delay = <1000>; /* milliseconds */
351−
352− /* sensor ID */
353− thermal-sensors = <&bandgap0 1>;
354−
355− trips {
356− /* each zone within the SoC may have its own trips */
357− gpu_alert: gpu-alert {
358− temperature = <90000>; /* millicelsius */
359− hysteresis = <2000>; /* millicelsius */
360− type = "passive";
361− };
362− gpu_crit: gpu-crit {
363− temperature = <105000>; /* millicelsius */
364− hysteresis = <2000>; /* millicelsius */
365− type = "critical";
366− };
367− };
368−
369− cooling-maps {
370− /* each zone within the SoC may have its own cooling */
371− ...
372− };
373− };
374−
375− dsp_thermal: dsp-thermal {
376− polling-delay-passive = <50>; /* milliseconds */
377− polling-delay = <1000>; /* milliseconds */
378−
379− /* sensor ID */
380− thermal-sensors = <&bandgap0 2>;
381−
382− trips {
383− /* each zone within the SoC may have its own trips */
384− dsp_alert: dsp-alert {
385− temperature = <90000>; /* millicelsius */
386− hysteresis = <2000>; /* millicelsius */
387− type = "passive";
388− };
389− dsp_crit: gpu-crit {
390− temperature = <135000>; /* millicelsius */
391− hysteresis = <2000>; /* millicelsius */
392− type = "critical";
393− };
394− };
395−
396− cooling-maps {
397− /* each zone within the SoC may have its own cooling */
398− ...
399− };
400− };
401−};
402−
403−In the example above, there is one bandgap IC which has the capability to
404−monitor three sensors. The hardware has been designed so that sensors are
405−placed on different places in the DIE to monitor different temperature
406−hotspots: one for CPU thermal zone, one for GPU thermal zone and the
407−other to monitor a DSP thermal zone.
408−
409−Thus, there is a need to assign each sensor provided by the bandgap IC
410−to different thermal zones. This is achieved by means of using the
411−#thermal-sensor-cells property and using the first cell of the sensor
412−specifier as sensor ID. In the example, then, <bandgap 0> is used to
413−monitor CPU thermal zone, <bandgap 1> is used to monitor GPU thermal
414−zone and <bandgap 2> is used to monitor DSP thermal zone. Each zone
415−may be uncorrelated, having its own dT/dt requirements, trips
416−and cooling maps.
417−
418−
419−(c) - Several sensors within one single thermal zone
420−
421−The example below illustrates how to use more than one sensor within
422−one thermal zone.
423−
424−#include <dt-bindings/thermal/thermal.h>
425−
426−&i2c1 {
427− ...
428− /*
429− * A simple IC with a single temperature sensor.
430− */
431− adc: sensor@49 {
432− ...
433− #thermal-sensor-cells = <0>;
434− };
435−};
436−
437−ocp {
438− ...
439− /*
440− * A simple IC with a single bandgap temperature sensor.
441− */
442− bandgap0: bandgap@0000ed00 {
443− ...
444− #thermal-sensor-cells = <0>;
445− };
446−};
447−
448−thermal-zones {
449− cpu_thermal: cpu-thermal {
450− polling-delay-passive = <250>; /* milliseconds */
451− polling-delay = <1000>; /* milliseconds */
452−
453− thermal-sensors = <&bandgap0>, /* cpu */
454− <&adc>; /* pcb north */
455−
456− /* hotspot = 100 * bandgap - 120 * adc + 484 */
457− coefficients = <100 -120 484>;
458−
459− trips {
460− ...
461− };
462−
463− cooling-maps {
464− ...
465− };
466− };
467−};
468−
469−In some cases, there is a need to use more than one sensor to extrapolate
470−a thermal hotspot in the silicon. The above example illustrates this situation.
471−For instance, it may be the case that a sensor external to CPU IP may be placed
472−close to CPU hotspot and together with internal CPU sensor, it is used
473−to determine the hotspot. Assuming this is the case for the above example,
474−the hypothetical extrapolation rule would be:
475− hotspot = 100 * bandgap - 120 * adc + 484
476−
477−In other context, the same idea can be used to add fixed offset. For instance,
478−consider the hotspot extrapolation rule below:
479− hotspot = 1 * adc + 6000
480−
481−In the above equation, the hotspot is always 6C higher than what is read
482−from the ADC sensor. The binding would be then:
483− thermal-sensors = <&adc>;
484−
485− /* hotspot = 1 * adc + 6000 */
486− coefficients = <1 6000>;
487−
488−(d) - Board thermal
489−
490−The board thermal example below illustrates how to setup one thermal zone
491−with many sensors and many cooling devices.
492−
493−#include <dt-bindings/thermal/thermal.h>
494−
495−&i2c1 {
496− ...
497− /*
498− * An IC with several temperature sensor.
499− */
500− adc_dummy: sensor@50 {
501− ...
502− #thermal-sensor-cells = <1>; /* sensor internal ID */
503− };
504−};
505−
506−thermal-zones {
507− batt-thermal {
508− polling-delay-passive = <500>; /* milliseconds */
509− polling-delay = <2500>; /* milliseconds */
510−
511− /* sensor ID */
512− thermal-sensors = <&adc_dummy 4>;
513−
514− trips {
515− ...
516− };
517−
518− cooling-maps {
519− ...
520− };
521− };
522−
523− board_thermal: board-thermal {
524− polling-delay-passive = <1000>; /* milliseconds */
525− polling-delay = <2500>; /* milliseconds */
526−
527− /* sensor ID */
528− thermal-sensors = <&adc_dummy 0>, /* pcb top edge */
529− <&adc_dummy 1>, /* lcd */
530− <&adc_dummy 2>; /* back cover */
531− /*
532− * An array of coefficients describing the sensor
533− * linear relation. E.g.:
534− * z = c1*x1 + c2*x2 + c3*x3
535− */
536− coefficients = <1200 -345 890>;
537−
538− sustainable-power = <2500>;
539−
540− trips {
541− /* Trips are based on resulting linear equation */
542− cpu_trip: cpu-trip {
543− temperature = <60000>; /* millicelsius */
544− hysteresis = <2000>; /* millicelsius */
545− type = "passive";
546− };
547− gpu_trip: gpu-trip {
548− temperature = <55000>; /* millicelsius */
549− hysteresis = <2000>; /* millicelsius */
550− type = "passive";
551− }
552− lcd_trip: lcp-trip {
553− temperature = <53000>; /* millicelsius */
554− hysteresis = <2000>; /* millicelsius */
555− type = "passive";
556− };
557− crit_trip: crit-trip {
558− temperature = <68000>; /* millicelsius */
559− hysteresis = <2000>; /* millicelsius */
560− type = "critical";
561− };
562− };
563−
564− cooling-maps {
565− map0 {
566− trip = <&cpu_trip>;
567− cooling-device = <&cpu0 0 2>;
568− contribution = <55>;
569− };
570− map1 {
571− trip = <&gpu_trip>;
572− cooling-device = <&gpu0 0 2>;
573− contribution = <20>;
574− };
575− map2 {
576− trip = <&lcd_trip>;
577− cooling-device = <&lcd0 5 10>;
578− contribution = <15>;
579− };
580− };
581− };
582−};
583−
584−The above example is a mix of previous examples, a sensor IP with several internal
585−sensors used to monitor different zones, one of them is composed by several sensors and
586−with different cooling devices.
MAINTAINERS+8−0
@@ -17086,6 +17086,14 @@ F: drivers/thermal/cpufreq_cooling.c · 17085 unmodified lines
1708617086 F: drivers/thermal/cpuidle_cooling.c
1708717087 F: include/linux/cpu_cooling.h
1708817088
17089+THERMAL/POWER_ALLOCATOR
17090+M: Lukasz Luba <lukasz.luba@arm.com>
17091+L: linux-pm@vger.kernel.org
17092+S: Maintained
17093+F: Documentation/driver-api/thermal/power_allocator.rst
17094+F: drivers/thermal/gov_power_allocator.c
17095+F: include/trace/events/thermal_power_allocator.h
17096+
1708917097 THINKPAD ACPI EXTRAS DRIVER
1709017098 M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br>
1709117099 L: ibm-acpi-devel@lists.sourceforge.net
drivers/acpi/thermal.c+21−55
@@ -172,7 +172,6 @@ struct acpi_thermal { · 171 unmodified lines
172172 struct acpi_thermal_trips trips;
173173 struct acpi_handle_list devices;
174174 struct thermal_zone_device *thermal_zone;
175− int tz_enabled;
176175 int kelvin_offset; /* in millidegrees */
177176 struct work_struct thermal_check_work;
178177 };
@@ -500,9 +499,6 @@ static void acpi_thermal_check(void *data) · 321 unmodified lines
500499 {
501500 struct acpi_thermal *tz = data;
502501
503− if (!tz->tz_enabled)
504− return;
505−
506502 thermal_zone_device_update(tz->thermal_zone,
507503 THERMAL_EVENT_UNSPECIFIED);
508504 }
@@ -526,50 +522,6 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) · 17 unmodified lines
526522 return 0;
527523 }
528524
529−static int thermal_get_mode(struct thermal_zone_device *thermal,
530− enum thermal_device_mode *mode)
531−{
532− struct acpi_thermal *tz = thermal->devdata;
533−
534− if (!tz)
535− return -EINVAL;
536−
537− *mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
538− THERMAL_DEVICE_DISABLED;
539−
540− return 0;
541−}
542−
543−static int thermal_set_mode(struct thermal_zone_device *thermal,
544− enum thermal_device_mode mode)
545−{
546− struct acpi_thermal *tz = thermal->devdata;
547− int enable;
548−
549− if (!tz)
550− return -EINVAL;
551−
552− /*
553− * enable/disable thermal management from ACPI thermal driver
554− */
555− if (mode == THERMAL_DEVICE_ENABLED)
556− enable = 1;
557− else if (mode == THERMAL_DEVICE_DISABLED) {
558− enable = 0;
559− pr_warn("thermal zone will be disabled\n");
560− } else
561− return -EINVAL;
562−
563− if (enable != tz->tz_enabled) {
564− tz->tz_enabled = enable;
565− ACPI_DEBUG_PRINT((ACPI_DB_INFO,
566− "%s kernel ACPI thermal control\n",
567− tz->tz_enabled ? "Enable" : "Disable"));
568− acpi_thermal_check(tz);
569− }
570− return 0;
571−}
572−
573525 static int thermal_get_trip_type(struct thermal_zone_device *thermal,
574526 int trip, enum thermal_trip_type *type)
575527 {
@@ -856,8 +808,6 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = { · 280 unmodified lines
856808 .bind = acpi_thermal_bind_cooling_device,
857809 .unbind = acpi_thermal_unbind_cooling_device,
858810 .get_temp = thermal_get_temp,
859− .get_mode = thermal_get_mode,
860− .set_mode = thermal_set_mode,
861811 .get_trip_type = thermal_get_trip_type,
862812 .get_trip_temp = thermal_get_trip_temp,
863813 .get_crit_temp = thermal_get_crit_temp,
@@ -901,23 +851,39 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) · 37 unmodified lines
901851 result = sysfs_create_link(&tz->device->dev.kobj,
902852 &tz->thermal_zone->device.kobj, "thermal_zone");
903853 if (result)
904− return result;
854+ goto unregister_tzd;
905855
906856 result = sysfs_create_link(&tz->thermal_zone->device.kobj,
907857 &tz->device->dev.kobj, "device");
908858 if (result)
909− return result;
859+ goto remove_tz_link;
910860
911861 status = acpi_bus_attach_private_data(tz->device->handle,
912862 tz->thermal_zone);
913− if (ACPI_FAILURE(status))
914− return -ENODEV;
863+ if (ACPI_FAILURE(status)) {
864+ result = -ENODEV;
865+ goto remove_dev_link;
866+ }
915867
916− tz->tz_enabled = 1;
868+ result = thermal_zone_device_enable(tz->thermal_zone);
869+ if (result)
870+ goto acpi_bus_detach;
917871
918872 dev_info(&tz->device->dev, "registered as thermal_zone%d\n",
919873 tz->thermal_zone->id);
874+
920875 return 0;
876+
877+acpi_bus_detach:
878+ acpi_bus_detach_private_data(tz->device->handle);
879+remove_dev_link:
880+ sysfs_remove_link(&tz->thermal_zone->device.kobj, "device");
881+remove_tz_link:
882+ sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone");
883+unregister_tzd:
884+ thermal_zone_device_unregister(tz->thermal_zone);
885+
886+ return result;
921887 }
922888
923889 static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
drivers/net/ethernet/chelsio/cxgb4/cxgb4_thermal.c+8−0
@@ -92,6 +92,14 @@ int cxgb4_thermal_init(struct adapter *adap) · 91 unmodified lines
9292 ch_thermal->tzdev = NULL;
9393 return ret;
9494 }
95+
96+ ret = thermal_zone_device_enable(ch_thermal->tzdev);
97+ if (ret) {
98+ dev_err(adap->pdev_dev, "Failed to enable thermal zone\n");
99+ thermal_zone_device_unregister(adap->ch_thermal.tzdev);
100+ return ret;
101+ }
102+
95103 return 0;
96104 }
97105
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c+17−74
@@ -98,7 +98,6 @@ struct mlxsw_thermal_module { · 97 unmodified lines
9898 struct mlxsw_thermal *parent;
9999 struct thermal_zone_device *tzdev;
100100 struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
101− enum thermal_device_mode mode;
102101 int module; /* Module or gearbox number */
103102 };
104103
@@ -110,7 +109,6 @@ struct mlxsw_thermal { · 5 unmodified lines
110109 struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
111110 u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
112111 struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
113− enum thermal_device_mode mode;
114112 struct mlxsw_thermal_module *tz_module_arr;
115113 u8 tz_module_num;
116114 struct mlxsw_thermal_module *tz_gearbox_arr;
@@ -277,36 +275,6 @@ static int mlxsw_thermal_unbind(struct thermal_zone_device *tzdev, · 160 unmodified lines
277275 return 0;
278276 }
279277
280−static int mlxsw_thermal_get_mode(struct thermal_zone_device *tzdev,
281− enum thermal_device_mode *mode)
282−{
283− struct mlxsw_thermal *thermal = tzdev->devdata;
284−
285− *mode = thermal->mode;
286−
287− return 0;
288−}
289−
290−static int mlxsw_thermal_set_mode(struct thermal_zone_device *tzdev,
291− enum thermal_device_mode mode)
292−{
293− struct mlxsw_thermal *thermal = tzdev->devdata;
294−
295− mutex_lock(&tzdev->lock);
296−
297− if (mode == THERMAL_DEVICE_ENABLED)
298− tzdev->polling_delay = thermal->polling_delay;
299− else
300− tzdev->polling_delay = 0;
301−
302− mutex_unlock(&tzdev->lock);
303−
304− thermal->mode = mode;
305− thermal_zone_device_update(tzdev, THERMAL_EVENT_UNSPECIFIED);
306−
307− return 0;
308−}
309−
310278 static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
311279 int *p_temp)
312280 {
@@ -406,8 +374,6 @@ static int mlxsw_thermal_trend_get(struct thermal_zone_device *tzdev, · 93 unmodified lines
406374 static struct thermal_zone_device_ops mlxsw_thermal_ops = {
407375 .bind = mlxsw_thermal_bind,
408376 .unbind = mlxsw_thermal_unbind,
409− .get_mode = mlxsw_thermal_get_mode,
410− .set_mode = mlxsw_thermal_set_mode,
411377 .get_temp = mlxsw_thermal_get_temp,
412378 .get_trip_type = mlxsw_thermal_get_trip_type,
413379 .get_trip_temp = mlxsw_thermal_get_trip_temp,
@@ -465,37 +431,6 @@ static int mlxsw_thermal_module_unbind(struct thermal_zone_device *tzdev, · 51 unmodified lines
465431 return err;
466432 }
467433
468−static int mlxsw_thermal_module_mode_get(struct thermal_zone_device *tzdev,
469− enum thermal_device_mode *mode)
470−{
471− struct mlxsw_thermal_module *tz = tzdev->devdata;
472−
473− *mode = tz->mode;
474−
475− return 0;
476−}
477−
478−static int mlxsw_thermal_module_mode_set(struct thermal_zone_device *tzdev,
479− enum thermal_device_mode mode)
480−{
481− struct mlxsw_thermal_module *tz = tzdev->devdata;
482− struct mlxsw_thermal *thermal = tz->parent;
483−
484− mutex_lock(&tzdev->lock);
485−
486− if (mode == THERMAL_DEVICE_ENABLED)
487− tzdev->polling_delay = thermal->polling_delay;
488− else
489− tzdev->polling_delay = 0;
490−
491− mutex_unlock(&tzdev->lock);
492−
493− tz->mode = mode;
494− thermal_zone_device_update(tzdev, THERMAL_EVENT_UNSPECIFIED);
495−
496− return 0;
497−}
498−
499434 static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
500435 int *p_temp)
501436 {
@@ -611,8 +546,6 @@ static int mlxsw_thermal_module_trend_get(struct thermal_zone_device *tzdev, · 109 unmodified lines
611546 static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
612547 .bind = mlxsw_thermal_module_bind,
613548 .unbind = mlxsw_thermal_module_unbind,
614− .get_mode = mlxsw_thermal_module_mode_get,
615− .set_mode = mlxsw_thermal_module_mode_set,
616549 .get_temp = mlxsw_thermal_module_temp_get,
617550 .get_trip_type = mlxsw_thermal_module_trip_type_get,
618551 .get_trip_temp = mlxsw_thermal_module_trip_temp_get,
@@ -650,8 +583,6 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev, · 31 unmodified lines
650583 static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
651584 .bind = mlxsw_thermal_module_bind,
652585 .unbind = mlxsw_thermal_module_unbind,
653− .get_mode = mlxsw_thermal_module_mode_get,
654− .set_mode = mlxsw_thermal_module_mode_set,
655586 .get_temp = mlxsw_thermal_gearbox_temp_get,
656587 .get_trip_type = mlxsw_thermal_module_trip_type_get,
657588 .get_trip_temp = mlxsw_thermal_module_trip_temp_get,
@@ -780,8 +711,11 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz) · 122 unmodified lines
780711 return err;
781712 }
782713
783− module_tz->mode = THERMAL_DEVICE_ENABLED;
784− return 0;
714+ err = thermal_zone_device_enable(module_tz->tzdev);
715+ if (err)
716+ thermal_zone_device_unregister(module_tz->tzdev);
717+
718+ return err;
785719 }
786720
787721 static void mlxsw_thermal_module_tz_fini(struct thermal_zone_device *tzdev)
@@ -884,6 +818,7 @@ static int · 96 unmodified lines
884818 mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
885819 {
886820 char tz_name[MLXSW_THERMAL_ZONE_MAX_NAME];
821+ int ret;
887822
888823 snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d",
889824 gearbox_tz->module + 1);
@@ -896,8 +831,11 @@ mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz) · 6 unmodified lines
896831 if (IS_ERR(gearbox_tz->tzdev))
897832 return PTR_ERR(gearbox_tz->tzdev);
898833
899− gearbox_tz->mode = THERMAL_DEVICE_ENABLED;
900− return 0;
834+ ret = thermal_zone_device_enable(gearbox_tz->tzdev);
835+ if (ret)
836+ thermal_zone_device_unregister(gearbox_tz->tzdev);
837+
838+ return ret;
901839 }
902840
903841 static void
@@ -1065,10 +1003,15 @@ int mlxsw_thermal_init(struct mlxsw_core *core, · 161 unmodified lines
10651003 if (err)
10661004 goto err_unreg_modules_tzdev;
10671005
1068− thermal->mode = THERMAL_DEVICE_ENABLED;
1006+ err = thermal_zone_device_enable(thermal->tzdev);
1007+ if (err)
1008+ goto err_unreg_gearboxes;
1009+
10691010 *p_thermal = thermal;
10701011 return 0;
10711012
1013+err_unreg_gearboxes:
1014+ mlxsw_thermal_gearboxes_fini(thermal);
10721015 err_unreg_modules_tzdev:
10731016 mlxsw_thermal_modules_fini(thermal);
10741017 err_unreg_tzdev:
drivers/net/wireless/intel/iwlwifi/mvm/tt.c+8−1
@@ -733,7 +733,7 @@ static struct thermal_zone_device_ops tzone_ops = { · 732 unmodified lines
733733
734734 static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
735735 {
736− int i;
736+ int i, ret;
737737 char name[16];
738738 static atomic_t counter = ATOMIC_INIT(0);
739739
@@ -759,6 +759,13 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm) · 19 unmodified lines
759759 return;
760760 }
761761
762+ ret = thermal_zone_device_enable(mvm->tz_device.tzone);
763+ if (ret) {
764+ IWL_DEBUG_TEMP(mvm, "Failed to enable thermal zone\n");
765+ thermal_zone_device_unregister(mvm->tz_device.tzone);
766+ return;
767+ }
768+
762769 /* 0 is a valid temperature,
763770 * so initialize the array with S16_MIN which invalid temperature
764771 */
drivers/platform/x86/acerhdf.c+13−20
@@ -397,39 +397,24 @@ static inline void acerhdf_revert_to_bios_mode(void) · 396 unmodified lines
397397 {
398398 acerhdf_change_fanstate(ACERHDF_FAN_AUTO);
399399 kernelmode = 0;
400− if (thz_dev)
401− thz_dev->polling_delay = 0;
400+
402401 pr_notice("kernel mode fan control OFF\n");
403402 }
404403 static inline void acerhdf_enable_kernelmode(void)
405404 {
406405 kernelmode = 1;
407406
408− thz_dev->polling_delay = interval*1000;
409− thermal_zone_device_update(thz_dev, THERMAL_EVENT_UNSPECIFIED);
410407 pr_notice("kernel mode fan control ON\n");
411408 }
412409
413−static int acerhdf_get_mode(struct thermal_zone_device *thermal,
414− enum thermal_device_mode *mode)
415−{
416− if (verbose)
417− pr_notice("kernel mode fan control %d\n", kernelmode);
418−
419− *mode = (kernelmode) ? THERMAL_DEVICE_ENABLED
420− : THERMAL_DEVICE_DISABLED;
421−
422− return 0;
423−}
424−
425410 /*
426411 * set operation mode;
427412 * enabled: the thermal layer of the kernel takes care about
428413 * the temperature and the fan.
429414 * disabled: the BIOS takes control of the fan.
430415 */
431−static int acerhdf_set_mode(struct thermal_zone_device *thermal,
432− enum thermal_device_mode mode)
416+static int acerhdf_change_mode(struct thermal_zone_device *thermal,
417+ enum thermal_device_mode mode)
433418 {
434419 if (mode == THERMAL_DEVICE_DISABLED && kernelmode)
435420 acerhdf_revert_to_bios_mode();
@@ -488,8 +473,7 @@ static struct thermal_zone_device_ops acerhdf_dev_ops = { · 52 unmodified lines
488473 .bind = acerhdf_bind,
489474 .unbind = acerhdf_unbind,
490475 .get_temp = acerhdf_get_ec_temp,
491− .get_mode = acerhdf_get_mode,
492− .set_mode = acerhdf_set_mode,
476+ .change_mode = acerhdf_change_mode,
493477 .get_trip_type = acerhdf_get_trip_type,
494478 .get_trip_hyst = acerhdf_get_trip_hyst,
495479 .get_trip_temp = acerhdf_get_trip_temp,
@@ -733,6 +717,8 @@ static void acerhdf_unregister_platform(void) · 237 unmodified lines
733717
734718 static int __init acerhdf_register_thermal(void)
735719 {
720+ int ret;
721+
736722 cl_dev = thermal_cooling_device_register("acerhdf-fan", NULL,
737723 &acerhdf_cooling_ops);
738724
@@ -746,6 +732,13 @@ static int __init acerhdf_register_thermal(void) · 7 unmodified lines
746732 if (IS_ERR(thz_dev))
747733 return -EINVAL;
748734
735+ if (kernelmode)
736+ ret = thermal_zone_device_enable(thz_dev);
737+ else
738+ ret = thermal_zone_device_disable(thz_dev);
739+ if (ret)
740+ return ret;
741+
749742 if (strcmp(thz_dev->governor->name,
750743 acerhdf_zone_params.governor_name)) {
751744 pr_err("Didn't get thermal governor %s, perhaps not compiled into thermal subsystem.\n",
drivers/platform/x86/intel_mid_thermal.c+6−0
@@ -493,6 +493,12 @@ static int mid_thermal_probe(struct platform_device *pdev) · 492 unmodified lines
493493 ret = PTR_ERR(pinfo->tzd[i]);
494494 goto err;
495495 }
496+ ret = thermal_zone_device_enable(pinfo->tzd[i]);
497+ if (ret) {
498+ kfree(td_info);
499+ thermal_zone_device_unregister(pinfo->tzd[i]);
500+ goto err;
501+ }
496502 }
497503
498504 pinfo->pdev = pdev;
drivers/power/supply/power_supply_core.c+7−2
@@ -939,7 +939,7 @@ static struct thermal_zone_device_ops psy_tzd_ops = { · 938 unmodified lines
939939
940940 static int psy_register_thermal(struct power_supply *psy)
941941 {
942− int i;
942+ int i, ret;
943943
944944 if (psy->desc->no_thermal)
945945 return 0;
@@ -949,7 +949,12 @@ static int psy_register_thermal(struct power_supply *psy) · 3 unmodified lines
949949 if (psy->desc->properties[i] == POWER_SUPPLY_PROP_TEMP) {
950950 psy->tzd = thermal_zone_device_register(psy->desc->name,
951951 0, 0, psy, &psy_tzd_ops, NULL, 0, 0);
952− return PTR_ERR_OR_ZERO(psy->tzd);
952+ if (IS_ERR(psy->tzd))
953+ return PTR_ERR(psy->tzd);
954+ ret = thermal_zone_device_enable(psy->tzd);
955+ if (ret)
956+ thermal_zone_device_unregister(psy->tzd);
957+ return ret;
953958 }
954959 }
955960 return 0;
drivers/thermal/Kconfig+10−10
@@ -17,6 +17,16 @@ menuconfig THERMAL · 16 unmodified lines
1717
1818 if THERMAL
1919
20+config THERMAL_NETLINK
21+ bool "Thermal netlink management"
22+ depends on NET
23+ default y
24+ help
25+ The thermal framework has a netlink interface to do thermal
26+ zones discovery, temperature readings and events such as
27+ trip point crossed, cooling device update or governor
28+ change. It is recommended to enable the feature.
29+
2030 config THERMAL_STATISTICS
2131 bool "Thermal state transition statistics"
2232 help
@@ -180,16 +190,6 @@ config CPU_IDLE_THERMAL · 157 unmodified lines
180190 idle cycle.
181191 endif
182192
183−config CLOCK_THERMAL
184− bool "Generic clock cooling support"
185− depends on COMMON_CLK
186− depends on PM_OPP
187− help
188− This entry implements the generic clock cooling mechanism through
189− frequency clipping. Typically used to cool off co-processors. The
190− device that is configured to use this cooling mechanism will be
191− controlled to reduce clock frequency whenever temperature is high.
192−
193193 config DEVFREQ_THERMAL
194194 bool "Generic device cooling support"
195195 depends on PM_DEVFREQ
drivers/thermal/Makefile+3−3
@@ -7,6 +7,9 @@ obj-$(CONFIG_THERMAL) += thermal_sys.o · 6 unmodified lines
77 thermal_sys-y += thermal_core.o thermal_sysfs.o \
88 thermal_helpers.o
99
10+# netlink interface to manage the thermal framework
11+thermal_sys-$(CONFIG_THERMAL_NETLINK) += thermal_netlink.o
12+
1013 # interface to/from other layers providing sensors
1114 thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o
1215 thermal_sys-$(CONFIG_THERMAL_OF) += thermal_of.o
@@ -22,9 +25,6 @@ thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += gov_power_allocator.o · 9 unmodified lines
2225 thermal_sys-$(CONFIG_CPU_FREQ_THERMAL) += cpufreq_cooling.o
2326 thermal_sys-$(CONFIG_CPU_IDLE_THERMAL) += cpuidle_cooling.o
2427
25−# clock cooling
26−thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o
27−
2828 # devfreq cooling
2929 thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
3030
drivers/thermal/armada_thermal.c+6−0
@@ -874,6 +874,12 @@ static int armada_thermal_probe(struct platform_device *pdev) · 873 unmodified lines
874874 return PTR_ERR(tz);
875875 }
876876
877+ ret = thermal_zone_device_enable(tz);
878+ if (ret) {
879+ thermal_zone_device_unregister(tz);
880+ return ret;
881+ }
882+
877883 drvdata->type = LEGACY;
878884 drvdata->data.tz = tz;
879885 platform_set_drvdata(pdev, drvdata);
drivers/thermal/clock_cooling.c+0−445
@@ -1,445 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-only
2−/*
3− * drivers/thermal/clock_cooling.c
4− *
5− * Copyright (C) 2014 Eduardo Valentin <edubezval@gmail.com>
6− *
7− * Copyright (C) 2013 Texas Instruments Inc.
8− * Contact: Eduardo Valentin <eduardo.valentin@ti.com>
9− *
10− * Highly based on cpufreq_cooling.c.
11− * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
12− * Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
13− */
14−#include <linux/clk.h>
15−#include <linux/clock_cooling.h>
16−#include <linux/cpufreq.h>
17−#include <linux/device.h>
18−#include <linux/err.h>
19−#include <linux/export.h>
20−#include <linux/idr.h>
21−#include <linux/mutex.h>
22−#include <linux/pm_opp.h>
23−#include <linux/slab.h>
24−#include <linux/thermal.h>
25−
26−/**
27− * struct clock_cooling_device - data for cooling device with clock
28− * @id: unique integer value corresponding to each clock_cooling_device
29− * registered.
30− * @dev: struct device pointer to the device being used to cool off using
31− * clock frequencies.
32− * @cdev: thermal_cooling_device pointer to keep track of the
33− * registered cooling device.
34− * @clk_rate_change_nb: reference to notifier block used to receive clock
35− * rate changes.
36− * @freq_table: frequency table used to keep track of available frequencies.
37− * @clock_state: integer value representing the current state of clock
38− * cooling devices.
39− * @clock_val: integer value representing the absolute value of the clipped
40− * frequency.
41− * @clk: struct clk reference used to enforce clock limits.
42− * @lock: mutex lock to protect this struct.
43− *
44− * This structure is required for keeping information of each
45− * clock_cooling_device registered. In order to prevent corruption of this a
46− * mutex @lock is used.
47− */
48−struct clock_cooling_device {
49− int id;
50− struct device *dev;
51− struct thermal_cooling_device *cdev;
52− struct notifier_block clk_rate_change_nb;
53− struct cpufreq_frequency_table *freq_table;
54− unsigned long clock_state;
55− unsigned long clock_val;
56− struct clk *clk;
57− struct mutex lock; /* lock to protect the content of this struct */
58−};
59−#define to_clock_cooling_device(x) \
60− container_of(x, struct clock_cooling_device, clk_rate_change_nb)
61−static DEFINE_IDA(clock_ida);
62−
63−/* Below code defines functions to be used for clock as cooling device */
64−
65−enum clock_cooling_property {
66− GET_LEVEL,
67− GET_FREQ,
68− GET_MAXL,
69−};
70−
71−/**
72− * clock_cooling_get_property - fetch a property of interest for a give cpu.
73− * @ccdev: clock cooling device reference
74− * @input: query parameter
75− * @output: query return
76− * @property: type of query (frequency, level, max level)
77− *
78− * This is the common function to
79− * 1. get maximum clock cooling states
80− * 2. translate frequency to cooling state
81− * 3. translate cooling state to frequency
82− * Note that the code may be not in good shape
83− * but it is written in this way in order to:
84− * a) reduce duplicate code as most of the code can be shared.
85− * b) make sure the logic is consistent when translating between
86− * cooling states and frequencies.
87− *
88− * Return: 0 on success, -EINVAL when invalid parameters are passed.
89− */
90−static int clock_cooling_get_property(struct clock_cooling_device *ccdev,
91− unsigned long input,
92− unsigned long *output,
93− enum clock_cooling_property property)
94−{
95− int i;
96− unsigned long max_level = 0, level = 0;
97− unsigned int freq = CPUFREQ_ENTRY_INVALID;
98− int descend = -1;
99− struct cpufreq_frequency_table *pos, *table = ccdev->freq_table;
100−
101− if (!output)
102− return -EINVAL;
103−
104− if (!table)
105− return -EINVAL;
106−
107− cpufreq_for_each_valid_entry(pos, table) {
108− /* ignore duplicate entry */
109− if (freq == pos->frequency)
110− continue;
111−
112− /* get the frequency order */
113− if (freq != CPUFREQ_ENTRY_INVALID && descend == -1)
114− descend = freq > pos->frequency;
115−
116− freq = pos->frequency;
117− max_level++;
118− }
119−
120− /* No valid cpu frequency entry */
121− if (max_level == 0)
122− return -EINVAL;
123−
124− /* max_level is an index, not a counter */
125− max_level--;
126−
127− /* get max level */
128− if (property == GET_MAXL) {
129− *output = max_level;
130− return 0;
131− }
132−
133− if (property == GET_FREQ)
134− level = descend ? input : (max_level - input);
135−
136− i = 0;
137− cpufreq_for_each_valid_entry(pos, table) {
138− /* ignore duplicate entry */
139− if (freq == pos->frequency)
140− continue;
141−
142− /* now we have a valid frequency entry */
143− freq = pos->frequency;
144−
145− if (property == GET_LEVEL && (unsigned int)input == freq) {
146− /* get level by frequency */
147− *output = descend ? i : (max_level - i);
148− return 0;
149− }
150− if (property == GET_FREQ && level == i) {
151− /* get frequency by level */
152− *output = freq;
153− return 0;
154− }
155− i++;
156− }
157−
158− return -EINVAL;
159−}
160−
161−/**
162− * clock_cooling_get_level - return the cooling level of given clock cooling.
163− * @cdev: reference of a thermal cooling device of used as clock cooling device
164− * @freq: the frequency of interest
165− *
166− * This function will match the cooling level corresponding to the
167− * requested @freq and return it.
168− *
169− * Return: The matched cooling level on success or THERMAL_CSTATE_INVALID
170− * otherwise.
171− */
172−unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev,
173− unsigned long freq)
174−{
175− struct clock_cooling_device *ccdev = cdev->devdata;
176− unsigned long val;
177−
178− if (clock_cooling_get_property(ccdev, (unsigned long)freq, &val,
179− GET_LEVEL))
180− return THERMAL_CSTATE_INVALID;
181−
182− return val;
183−}
184−EXPORT_SYMBOL_GPL(clock_cooling_get_level);
185−
186−/**
187− * clock_cooling_get_frequency - get the absolute value of frequency from level.
188− * @ccdev: clock cooling device reference
189− * @level: cooling level
190− *
191− * This function matches cooling level with frequency. Based on a cooling level
192− * of frequency, equals cooling state of cpu cooling device, it will return
193− * the corresponding frequency.
194− * e.g level=0 --> 1st MAX FREQ, level=1 ---> 2nd MAX FREQ, .... etc
195− *
196− * Return: 0 on error, the corresponding frequency otherwise.
197− */
198−static unsigned long
199−clock_cooling_get_frequency(struct clock_cooling_device *ccdev,
200− unsigned long level)
201−{
202− int ret = 0;
203− unsigned long freq;
204−
205− ret = clock_cooling_get_property(ccdev, level, &freq, GET_FREQ);
206− if (ret)
207− return 0;
208−
209− return freq;
210−}
211−
212−/**
213− * clock_cooling_apply - function to apply frequency clipping.
214− * @ccdev: clock_cooling_device pointer containing frequency clipping data.
215− * @cooling_state: value of the cooling state.
216− *
217− * Function used to make sure the clock layer is aware of current thermal
218− * limits. The limits are applied by updating the clock rate in case it is
219− * higher than the corresponding frequency based on the requested cooling_state.
220− *
221− * Return: 0 on success, an error code otherwise (-EINVAL in case wrong
222− * cooling state).
223− */
224−static int clock_cooling_apply(struct clock_cooling_device *ccdev,
225− unsigned long cooling_state)
226−{
227− unsigned long clip_freq, cur_freq;
228− int ret = 0;
229−
230− /* Here we write the clipping */
231− /* Check if the old cooling action is same as new cooling action */
232− if (ccdev->clock_state == cooling_state)
233− return 0;
234−
235− clip_freq = clock_cooling_get_frequency(ccdev, cooling_state);
236− if (!clip_freq)
237− return -EINVAL;
238−
239− cur_freq = clk_get_rate(ccdev->clk);
240−
241− mutex_lock(&ccdev->lock);
242− ccdev->clock_state = cooling_state;
243− ccdev->clock_val = clip_freq;
244− /* enforce clock level */
245− if (cur_freq > clip_freq)
246− ret = clk_set_rate(ccdev->clk, clip_freq);
247− mutex_unlock(&ccdev->lock);
248−
249− return ret;
250−}
251−
252−/**
253− * clock_cooling_clock_notifier - notifier callback on clock rate changes.
254− * @nb: struct notifier_block * with callback info.
255− * @event: value showing clock event for which this function invoked.
256− * @data: callback-specific data
257− *
258− * Callback to hijack the notification on clock transition.
259− * Every time there is a clock change, we intercept all pre change events
260− * and block the transition in case the new rate infringes thermal limits.
261− *
262− * Return: NOTIFY_DONE (success) or NOTIFY_BAD (new_rate > thermal limit).
263− */
264−static int clock_cooling_clock_notifier(struct notifier_block *nb,
265− unsigned long event, void *data)
266−{
267− struct clk_notifier_data *ndata = data;
268− struct clock_cooling_device *ccdev = to_clock_cooling_device(nb);
269−
270− switch (event) {
271− case PRE_RATE_CHANGE:
272− /*
273− * checks on current state
274− * TODO: current method is not best we can find as it
275− * allows possibly voltage transitions, in case DVFS
276− * layer is also hijacking clock pre notifications.
277− */
278− if (ndata->new_rate > ccdev->clock_val)
279− return NOTIFY_BAD;
280− /* fall through */
281− case POST_RATE_CHANGE:
282− case ABORT_RATE_CHANGE:
283− default:
284− return NOTIFY_DONE;
285− }
286−}
287−
288−/* clock cooling device thermal callback functions are defined below */
289−
290−/**
291− * clock_cooling_get_max_state - callback function to get the max cooling state.
292− * @cdev: thermal cooling device pointer.
293− * @state: fill this variable with the max cooling state.
294− *
295− * Callback for the thermal cooling device to return the clock
296− * max cooling state.
297− *
298− * Return: 0 on success, an error code otherwise.
299− */
300−static int clock_cooling_get_max_state(struct thermal_cooling_device *cdev,
301− unsigned long *state)
302−{
303− struct clock_cooling_device *ccdev = cdev->devdata;
304− unsigned long count = 0;
305− int ret;
306−
307− ret = clock_cooling_get_property(ccdev, 0, &count, GET_MAXL);
308− if (!ret)
309− *state = count;
310−
311− return ret;
312−}
313−
314−/**
315− * clock_cooling_get_cur_state - function to get the current cooling state.
316− * @cdev: thermal cooling device pointer.
317− * @state: fill this variable with the current cooling state.
318− *
319− * Callback for the thermal cooling device to return the clock
320− * current cooling state.
321− *
322− * Return: 0 (success)
323− */
324−static int clock_cooling_get_cur_state(struct thermal_cooling_device *cdev,
325− unsigned long *state)
326−{
327− struct clock_cooling_device *ccdev = cdev->devdata;
328−
329− *state = ccdev->clock_state;
330−
331− return 0;
332−}
333−
334−/**
335− * clock_cooling_set_cur_state - function to set the current cooling state.
336− * @cdev: thermal cooling device pointer.
337− * @state: set this variable to the current cooling state.
338− *
339− * Callback for the thermal cooling device to change the clock cooling
340− * current cooling state.
341− *
342− * Return: 0 on success, an error code otherwise.
343− */
344−static int clock_cooling_set_cur_state(struct thermal_cooling_device *cdev,
345− unsigned long state)
346−{
347− struct clock_cooling_device *clock_device = cdev->devdata;
348−
349− return clock_cooling_apply(clock_device, state);
350−}
351−
352−/* Bind clock callbacks to thermal cooling device ops */
353−static struct thermal_cooling_device_ops const clock_cooling_ops = {
354− .get_max_state = clock_cooling_get_max_state,
355− .get_cur_state = clock_cooling_get_cur_state,
356− .set_cur_state = clock_cooling_set_cur_state,
357−};
358−
359−/**
360− * clock_cooling_register - function to create clock cooling device.
361− * @dev: struct device pointer to the device used as clock cooling device.
362− * @clock_name: string containing the clock used as cooling mechanism.
363− *
364− * This interface function registers the clock cooling device with the name
365− * "thermal-clock-%x". The cooling device is based on clock frequencies.
366− * The struct device is assumed to be capable of DVFS transitions.
367− * The OPP layer is used to fetch and fill the available frequencies for
368− * the referred device. The ordered frequency table is used to control
369− * the clock cooling device cooling states and to limit clock transitions
370− * based on the cooling state requested by the thermal framework.
371− *
372− * Return: a valid struct thermal_cooling_device pointer on success,
373− * on failure, it returns a corresponding ERR_PTR().
374− */
375−struct thermal_cooling_device *
376−clock_cooling_register(struct device *dev, const char *clock_name)
377−{
378− struct thermal_cooling_device *cdev;
379− struct clock_cooling_device *ccdev = NULL;
380− char dev_name[THERMAL_NAME_LENGTH];
381− int ret = 0;
382−
383− ccdev = devm_kzalloc(dev, sizeof(*ccdev), GFP_KERNEL);
384− if (!ccdev)
385− return ERR_PTR(-ENOMEM);
386−
387− mutex_init(&ccdev->lock);
388− ccdev->dev = dev;
389− ccdev->clk = devm_clk_get(dev, clock_name);
390− if (IS_ERR(ccdev->clk))
391− return ERR_CAST(ccdev->clk);
392−
393− ret = ida_simple_get(&clock_ida, 0, 0, GFP_KERNEL);
394− if (ret < 0)
395− return ERR_PTR(ret);
396− ccdev->id = ret;
397−
398− snprintf(dev_name, sizeof(dev_name), "thermal-clock-%d", ccdev->id);
399−
400− cdev = thermal_cooling_device_register(dev_name, ccdev,
401− &clock_cooling_ops);
402− if (IS_ERR(cdev)) {
403− ida_simple_remove(&clock_ida, ccdev->id);
404− return ERR_PTR(-EINVAL);
405− }
406− ccdev->cdev = cdev;
407− ccdev->clk_rate_change_nb.notifier_call = clock_cooling_clock_notifier;
408−
409− /* Assuming someone has already filled the opp table for this device */
410− ret = dev_pm_opp_init_cpufreq_table(dev, &ccdev->freq_table);
411− if (ret) {
412− ida_simple_remove(&clock_ida, ccdev->id);
413− return ERR_PTR(ret);
414− }
415− ccdev->clock_state = 0;
416− ccdev->clock_val = clock_cooling_get_frequency(ccdev, 0);
417−
418− clk_notifier_register(ccdev->clk, &ccdev->clk_rate_change_nb);
419−
420− return cdev;
421−}
422−EXPORT_SYMBOL_GPL(clock_cooling_register);
423−
424−/**
425− * clock_cooling_unregister - function to remove clock cooling device.
426− * @cdev: thermal cooling device pointer.
427− *
428− * This interface function unregisters the "thermal-clock-%x" cooling device.
429− */
430−void clock_cooling_unregister(struct thermal_cooling_device *cdev)
431−{
432− struct clock_cooling_device *ccdev;
433−
434− if (!cdev)
435− return;
436−
437− ccdev = cdev->devdata;
438−
439− clk_notifier_unregister(ccdev->clk, &ccdev->clk_rate_change_nb);
440− dev_pm_opp_free_cpufreq_table(ccdev->dev, &ccdev->freq_table);
441−
442− thermal_cooling_device_unregister(ccdev->cdev);
443− ida_simple_remove(&clock_ida, ccdev->id);
444−}
445−EXPORT_SYMBOL_GPL(clock_cooling_unregister);
drivers/thermal/da9062-thermal.c+5−11
@@ -49,7 +49,6 @@ struct da9062_thermal { · 48 unmodified lines
4949 struct da9062 *hw;
5050 struct delayed_work work;
5151 struct thermal_zone_device *zone;
52− enum thermal_device_mode mode;
5352 struct mutex lock; /* protection for da9062_thermal temperature */
5453 int temperature;
5554 int irq;
@@ -121,14 +120,6 @@ static irqreturn_t da9062_thermal_irq_handler(int irq, void *data) · 65 unmodified lines
121120 return IRQ_HANDLED;
122121 }
123122
124−static int da9062_thermal_get_mode(struct thermal_zone_device *z,
125− enum thermal_device_mode *mode)
126−{
127− struct da9062_thermal *thermal = z->devdata;
128− *mode = thermal->mode;
129− return 0;
130−}
131−
132123 static int da9062_thermal_get_trip_type(struct thermal_zone_device *z,
133124 int trip,
134125 enum thermal_trip_type *type)
@@ -181,7 +172,6 @@ static int da9062_thermal_get_temp(struct thermal_zone_device *z, · 46 unmodified lines
181172
182173 static struct thermal_zone_device_ops da9062_thermal_ops = {
183174 .get_temp = da9062_thermal_get_temp,
184− .get_mode = da9062_thermal_get_mode,
185175 .get_trip_type = da9062_thermal_get_trip_type,
186176 .get_trip_temp = da9062_thermal_get_trip_temp,
187177 };
@@ -233,7 +223,6 @@ static int da9062_thermal_probe(struct platform_device *pdev) · 45 unmodified lines
233223
234224 thermal->config = match->data;
235225 thermal->hw = chip;
236− thermal->mode = THERMAL_DEVICE_ENABLED;
237226 thermal->dev = &pdev->dev;
238227
239228 INIT_DELAYED_WORK(&thermal->work, da9062_thermal_poll_on);
@@ -248,6 +237,11 @@ static int da9062_thermal_probe(struct platform_device *pdev) · 8 unmodified lines
248237 ret = PTR_ERR(thermal->zone);
249238 goto err;
250239 }
240+ ret = thermal_zone_device_enable(thermal->zone);
241+ if (ret) {
242+ dev_err(&pdev->dev, "Cannot enable thermal zone device\n");
243+ goto err_zone;
244+ }
251245
252246 dev_dbg(&pdev->dev,
253247 "TJUNC temperature polling period set at %d ms\n",
drivers/thermal/devfreq_cooling.c+1−9
@@ -1,18 +1,10 @@
1+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * devfreq_cooling: Thermal cooling device implementation for devices using
34 * devfreq
45 *
56 * Copyright (C) 2014-2015 ARM Limited
67 *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License version 2 as
9− * published by the Free Software Foundation.
10− *
11− * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12− * kind, whether express or implied; without even the implied warranty
13− * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
168 * TODO:
179 * - If OPPs are added or removed after devfreq cooling has
1810 * registered, the devfreq cooling won't react to it.
drivers/thermal/dove_thermal.c+6−0
@@ -153,6 +153,12 @@ static int dove_thermal_probe(struct platform_device *pdev) · 152 unmodified lines
153153 return PTR_ERR(thermal);
154154 }
155155
156+ ret = thermal_zone_device_enable(thermal);
157+ if (ret) {
158+ thermal_zone_device_unregister(thermal);
159+ return ret;
160+ }
161+
156162 platform_set_drvdata(pdev, thermal);
157163
158164 return 0;
drivers/thermal/gov_power_allocator.c+1−8
@@ -1,16 +1,9 @@
1+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * A power allocator to manage temperature
34 *
45 * Copyright (C) 2014 ARM Ltd.
56 *
6− * This program is free software; you can redistribute it and/or modify
7− * it under the terms of the GNU General Public License version 2 as
8− * published by the Free Software Foundation.
9− *
10− * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11− * kind, whether express or implied; without even the implied warranty
12− * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13− * GNU General Public License for more details.
147 */
158
169 #define pr_fmt(fmt) "Power allocator: " fmt
drivers/thermal/hisi_thermal.c+4−2
@@ -549,8 +549,10 @@ static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor, · 548 unmodified lines
549549 {
550550 struct thermal_zone_device *tzd = sensor->tzd;
551551
552− tzd->ops->set_mode(tzd,
553− on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
552+ if (on)
553+ thermal_zone_device_enable(tzd);
554+ else
555+ thermal_zone_device_disable(tzd);
554556 }
555557
556558 static int hisi_thermal_probe(struct platform_device *pdev)
drivers/thermal/imx8mm_thermal.c+1−0
@@ -220,6 +220,7 @@ static const struct of_device_id imx8mm_tmu_table[] = { · 219 unmodified lines
220220 { .compatible = "fsl,imx8mp-tmu", .data = &imx8mp_tmu_data, },
221221 { },
222222 };
223+MODULE_DEVICE_TABLE(of, imx8mm_tmu_table);
223224
224225 static struct platform_driver imx8mm_tmu = {
225226 .driver = {
drivers/thermal/imx_thermal.c+19−41
@@ -197,7 +197,6 @@ struct imx_thermal_data { · 196 unmodified lines
197197 struct cpufreq_policy *policy;
198198 struct thermal_zone_device *tz;
199199 struct thermal_cooling_device *cdev;
200− enum thermal_device_mode mode;
201200 struct regmap *tempmon;
202201 u32 c1, c2; /* See formula in imx_init_calib() */
203202 int temp_passive;
@@ -253,10 +252,11 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp) · 49 unmodified lines
253252 const struct thermal_soc_data *soc_data = data->socdata;
254253 struct regmap *map = data->tempmon;
255254 unsigned int n_meas;
256− bool wait;
255+ bool wait, run_measurement;
257256 u32 val;
258257
259− if (data->mode == THERMAL_DEVICE_ENABLED) {
258+ run_measurement = !data->irq_enabled;
259+ if (!run_measurement) {
260260 /* Check if a measurement is currently in progress */
261261 regmap_read(map, soc_data->temp_data, &val);
262262 wait = !(val & soc_data->temp_valid_mask);
@@ -283,7 +283,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp) · 20 unmodified lines
283283
284284 regmap_read(map, soc_data->temp_data, &val);
285285
286− if (data->mode != THERMAL_DEVICE_ENABLED) {
286+ if (run_measurement) {
287287 regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
288288 soc_data->measure_temp_mask);
289289 regmap_write(map, soc_data->sensor_ctrl + REG_SET,
@@ -331,27 +331,14 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp) · 41 unmodified lines
331331 return 0;
332332 }
333333
334−static int imx_get_mode(struct thermal_zone_device *tz,
335− enum thermal_device_mode *mode)
336−{
337− struct imx_thermal_data *data = tz->devdata;
338−
339− *mode = data->mode;
340−
341− return 0;
342−}
343−
344−static int imx_set_mode(struct thermal_zone_device *tz,
345− enum thermal_device_mode mode)
334+static int imx_change_mode(struct thermal_zone_device *tz,
335+ enum thermal_device_mode mode)
346336 {
347337 struct imx_thermal_data *data = tz->devdata;
348338 struct regmap *map = data->tempmon;
349339 const struct thermal_soc_data *soc_data = data->socdata;
350340
351341 if (mode == THERMAL_DEVICE_ENABLED) {
352− tz->polling_delay = IMX_POLLING_DELAY;
353− tz->passive_delay = IMX_PASSIVE_DELAY;
354−
355342 regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
356343 soc_data->power_down_mask);
357344 regmap_write(map, soc_data->sensor_ctrl + REG_SET,
@@ -367,18 +354,12 @@ static int imx_set_mode(struct thermal_zone_device *tz, · 9 unmodified lines
367354 regmap_write(map, soc_data->sensor_ctrl + REG_SET,
368355 soc_data->power_down_mask);
369356
370− tz->polling_delay = 0;
371− tz->passive_delay = 0;
372−
373357 if (data->irq_enabled) {
374358 disable_irq(data->irq);
375359 data->irq_enabled = false;
376360 }
377361 }
378362
379− data->mode = mode;
380− thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
381−
382363 return 0;
383364 }
384365
@@ -467,8 +448,7 @@ static struct thermal_zone_device_ops imx_tz_ops = { · 82 unmodified lines
467448 .bind = imx_bind,
468449 .unbind = imx_unbind,
469450 .get_temp = imx_get_temp,
470− .get_mode = imx_get_mode,
471− .set_mode = imx_set_mode,
451+ .change_mode = imx_change_mode,
472452 .get_trip_type = imx_get_trip_type,
473453 .get_trip_temp = imx_get_trip_temp,
474454 .get_crit_temp = imx_get_crit_temp,
@@ -832,7 +812,9 @@ static int imx_thermal_probe(struct platform_device *pdev) · 357 unmodified lines
832812 data->socdata->measure_temp_mask);
833813
834814 data->irq_enabled = true;
835− data->mode = THERMAL_DEVICE_ENABLED;
815+ ret = thermal_zone_device_enable(data->tz);
816+ if (ret)
817+ goto thermal_zone_unregister;
836818
837819 ret = devm_request_threaded_irq(&pdev->dev, data->irq,
838820 imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
@@ -874,19 +856,18 @@ static int imx_thermal_remove(struct platform_device *pdev) · 35 unmodified lines
874856 static int __maybe_unused imx_thermal_suspend(struct device *dev)
875857 {
876858 struct imx_thermal_data *data = dev_get_drvdata(dev);
877− struct regmap *map = data->tempmon;
859+ int ret;
878860
879861 /*
880862 * Need to disable thermal sensor, otherwise, when thermal core
881863 * try to get temperature before thermal sensor resume, a wrong
882864 * temperature will be read as the thermal sensor is powered
883− * down.
865+ * down. This is done in change_mode() operation called from
866+ * thermal_zone_device_disable()
884867 */
885− regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
886− data->socdata->measure_temp_mask);
887− regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
888− data->socdata->power_down_mask);
889− data->mode = THERMAL_DEVICE_DISABLED;
868+ ret = thermal_zone_device_disable(data->tz);
869+ if (ret)
870+ return ret;
890871 clk_disable_unprepare(data->thermal_clk);
891872
892873 return 0;
@@ -895,18 +876,15 @@ static int __maybe_unused imx_thermal_suspend(struct device *dev) · 2 unmodified lines
895876 static int __maybe_unused imx_thermal_resume(struct device *dev)
896877 {
897878 struct imx_thermal_data *data = dev_get_drvdata(dev);
898− struct regmap *map = data->tempmon;
899879 int ret;
900880
901881 ret = clk_prepare_enable(data->thermal_clk);
902882 if (ret)
903883 return ret;
904884 /* Enabled thermal sensor after resume */
905− regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
906− data->socdata->power_down_mask);
907− regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
908− data->socdata->measure_temp_mask);
909− data->mode = THERMAL_DEVICE_ENABLED;
885+ ret = thermal_zone_device_enable(data->tz);
886+ if (ret)
887+ return ret;
910888
911889 return 0;
912890 }
drivers/thermal/intel/int340x_thermal/int3400_thermal.c+7−31
@@ -48,7 +48,6 @@ struct int3400_thermal_priv { · 47 unmodified lines
4848 struct acpi_device *adev;
4949 struct platform_device *pdev;
5050 struct thermal_zone_device *thermal;
51− int mode;
5251 int art_count;
5352 struct art *arts;
5453 int trt_count;
@@ -383,42 +382,20 @@ static int int3400_thermal_get_temp(struct thermal_zone_device *thermal, · 328 unmodified lines
383382 return 0;
384383 }
385384
386−static int int3400_thermal_get_mode(struct thermal_zone_device *thermal,
387− enum thermal_device_mode *mode)
385+static int int3400_thermal_change_mode(struct thermal_zone_device *thermal,
386+ enum thermal_device_mode mode)
388387 {
389388 struct int3400_thermal_priv *priv = thermal->devdata;
390−
391− if (!priv)
392− return -EINVAL;
393−
394− *mode = priv->mode;
395−
396− return 0;
397−}
398−
399−static int int3400_thermal_set_mode(struct thermal_zone_device *thermal,
400− enum thermal_device_mode mode)
401−{
402− struct int3400_thermal_priv *priv = thermal->devdata;
403− bool enable;
404389 int result = 0;
405390
406391 if (!priv)
407392 return -EINVAL;
408393
409− if (mode == THERMAL_DEVICE_ENABLED)
410− enable = true;
411− else if (mode == THERMAL_DEVICE_DISABLED)
412− enable = false;
413− else
414− return -EINVAL;
415−
416− if (enable != priv->mode) {
417− priv->mode = enable;
394+ if (mode != thermal->mode)
418395 result = int3400_thermal_run_osc(priv->adev->handle,
419− priv->current_uuid_index,
420− enable);
421− }
396+ priv->current_uuid_index,
397+ mode == THERMAL_DEVICE_ENABLED);
398+
422399
423400 evaluate_odvp(priv);
424401
@@ -427,8 +404,7 @@ static int int3400_thermal_set_mode(struct thermal_zone_device *thermal, · 2 unmodified lines
427404
428405 static struct thermal_zone_device_ops int3400_thermal_ops = {
429406 .get_temp = int3400_thermal_get_temp,
430− .get_mode = int3400_thermal_get_mode,
431− .set_mode = int3400_thermal_set_mode,
407+ .change_mode = int3400_thermal_change_mode,
432408 };
433409
434410 static struct thermal_zone_params int3400_thermal_params = {
drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c+5−0
@@ -259,9 +259,14 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, · 258 unmodified lines
259259 ret = PTR_ERR(int34x_thermal_zone->zone);
260260 goto err_thermal_zone;
261261 }
262+ ret = thermal_zone_device_enable(int34x_thermal_zone->zone);
263+ if (ret)
264+ goto err_enable;
262265
263266 return int34x_thermal_zone;
264267
268+err_enable:
269+ thermal_zone_device_unregister(int34x_thermal_zone->zone);
265270 err_thermal_zone:
266271 acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table);
267272 kfree(int34x_thermal_zone->aux_trips);
drivers/thermal/intel/int340x_thermal/processor_thermal_device.c+1−1
@@ -43,7 +43,7 @@ · 42 unmodified lines
4343 #define PCI_DEVICE_ID_PROC_ICL_THERMAL 0x8a03
4444
4545 /* JasperLake thermal reporting device */
46−#define PCI_DEVICE_ID_PROC_JSL_THERMAL 0x4503
46+#define PCI_DEVICE_ID_PROC_JSL_THERMAL 0x4E03
4747
4848 /* TigerLake thermal reporting device */
4949 #define PCI_DEVICE_ID_PROC_TGL_THERMAL 0x9A03
drivers/thermal/intel/intel_pch_thermal.c+8−0
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 #define PCH_THERMAL_DID_SKL_H 0xA131 /* Skylake PCH 100 series */
2525 #define PCH_THERMAL_DID_CNL 0x9Df9 /* CNL PCH */
2626 #define PCH_THERMAL_DID_CNL_H 0xA379 /* CNL-H PCH */
27+#define PCH_THERMAL_DID_CNL_LP 0x02F9 /* CNL-LP PCH */
2728 #define PCH_THERMAL_DID_CML_H 0X06F9 /* CML-H PCH */
2829
2930 /* Wildcat Point-LP PCH Thermal registers */
@@ -352,9 +353,14 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev, · 322 unmodified lines
352353 err = PTR_ERR(ptd->tzd);
353354 goto error_cleanup;
354355 }
356+ err = thermal_zone_device_enable(ptd->tzd);
357+ if (err)
358+ goto err_unregister;
355359
356360 return 0;
357361
362+err_unregister:
363+ thermal_zone_device_unregister(ptd->tzd);
358364 error_cleanup:
359365 iounmap(ptd->hw_base);
360366 error_release:
@@ -405,6 +411,8 @@ static const struct pci_device_id intel_pch_thermal_id[] = { · 44 unmodified lines
405411 .driver_data = board_cnl, },
406412 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_CNL_H),
407413 .driver_data = board_cnl, },
414+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_CNL_LP),
415+ .driver_data = board_cnl, },
408416 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_CML_H),
409417 .driver_data = board_cml, },
410418 { 0, },
drivers/thermal/intel/intel_quark_dts_thermal.c+6−28
@@ -103,7 +103,6 @@ struct soc_sensor_entry { · 102 unmodified lines
103103 bool locked;
104104 u32 store_ptps;
105105 u32 store_dts_enable;
106− enum thermal_device_mode mode;
107106 struct thermal_zone_device *tzone;
108107 };
109108
@@ -127,10 +126,8 @@ static int soc_dts_enable(struct thermal_zone_device *tzd) · 17 unmodified lines
127126 if (ret)
128127 return ret;
129128
130− if (out & QRK_DTS_ENABLE_BIT) {
131− aux_entry->mode = THERMAL_DEVICE_ENABLED;
129+ if (out & QRK_DTS_ENABLE_BIT)
132130 return 0;
133− }
134131
135132 if (!aux_entry->locked) {
136133 out |= QRK_DTS_ENABLE_BIT;
@@ -138,10 +135,7 @@ static int soc_dts_enable(struct thermal_zone_device *tzd) · 1 unmodified line
138135 QRK_DTS_REG_OFFSET_ENABLE, out);
139136 if (ret)
140137 return ret;
141−
142− aux_entry->mode = THERMAL_DEVICE_ENABLED;
143138 } else {
144− aux_entry->mode = THERMAL_DEVICE_DISABLED;
145139 pr_info("DTS is locked. Cannot enable DTS\n");
146140 ret = -EPERM;
147141 }
@@ -160,10 +154,8 @@ static int soc_dts_disable(struct thermal_zone_device *tzd) · 12 unmodified lines
160154 if (ret)
161155 return ret;
162156
163− if (!(out & QRK_DTS_ENABLE_BIT)) {
164− aux_entry->mode = THERMAL_DEVICE_DISABLED;
157+ if (!(out & QRK_DTS_ENABLE_BIT))
165158 return 0;
166− }
167159
168160 if (!aux_entry->locked) {
169161 out &= ~QRK_DTS_ENABLE_BIT;
@@ -172,10 +164,7 @@ static int soc_dts_disable(struct thermal_zone_device *tzd) · 2 unmodified lines
172164
173165 if (ret)
174166 return ret;
175−
176− aux_entry->mode = THERMAL_DEVICE_DISABLED;
177167 } else {
178− aux_entry->mode = THERMAL_DEVICE_ENABLED;
179168 pr_info("DTS is locked. Cannot disable DTS\n");
180169 ret = -EPERM;
181170 }
@@ -309,16 +298,8 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, · 127 unmodified lines
309298 return 0;
310299 }
311300
312−static int sys_get_mode(struct thermal_zone_device *tzd,
313− enum thermal_device_mode *mode)
314−{
315− struct soc_sensor_entry *aux_entry = tzd->devdata;
316− *mode = aux_entry->mode;
317− return 0;
318−}
319−
320−static int sys_set_mode(struct thermal_zone_device *tzd,
321− enum thermal_device_mode mode)
301+static int sys_change_mode(struct thermal_zone_device *tzd,
302+ enum thermal_device_mode mode)
322303 {
323304 int ret;
324305
@@ -338,8 +319,7 @@ static struct thermal_zone_device_ops tzone_ops = { · 13 unmodified lines
338319 .get_trip_type = sys_get_trip_type,
339320 .set_trip_temp = sys_set_trip_temp,
340321 .get_crit_temp = sys_get_crit_temp,
341− .get_mode = sys_get_mode,
342− .set_mode = sys_set_mode,
322+ .change_mode = sys_change_mode,
343323 };
344324
345325 static void free_soc_dts(struct soc_sensor_entry *aux_entry)
@@ -414,9 +394,7 @@ static struct soc_sensor_entry *alloc_soc_dts(void) · 68 unmodified lines
414394 goto err_ret;
415395 }
416396
417− mutex_lock(&dts_update_mutex);
418− err = soc_dts_enable(aux_entry->tzone);
419− mutex_unlock(&dts_update_mutex);
397+ err = thermal_zone_device_enable(aux_entry->tzone);
420398 if (err)
421399 goto err_aux_status;
422400
drivers/thermal/intel/intel_soc_dts_iosf.c+3−0
@@ -329,6 +329,9 @@ static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts, · 328 unmodified lines
329329 ret = PTR_ERR(dts->tzone);
330330 goto err_ret;
331331 }
332+ ret = thermal_zone_device_enable(dts->tzone);
333+ if (ret)
334+ goto err_enable;
332335
333336 ret = soc_dts_enable(id);
334337 if (ret)
drivers/thermal/intel/x86_pkg_temp_thermal.c+6−0
@@ -363,6 +363,12 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) · 362 unmodified lines
363363 kfree(zonedev);
364364 return err;
365365 }
366+ err = thermal_zone_device_enable(zonedev->tzone);
367+ if (err) {
368+ thermal_zone_device_unregister(zonedev->tzone);
369+ kfree(zonedev);
370+ return err;
371+ }
366372 /* Store MSR value for package thermal interrupt, to restore at exit */
367373 rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm_low,
368374 zonedev->msr_pkg_therm_high);
drivers/thermal/kirkwood_thermal.c+7−0
@@ -65,6 +65,7 @@ static int kirkwood_thermal_probe(struct platform_device *pdev) · 64 unmodified lines
6565 struct thermal_zone_device *thermal = NULL;
6666 struct kirkwood_thermal_priv *priv;
6767 struct resource *res;
68+ int ret;
6869
6970 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
7071 if (!priv)
@@ -82,6 +83,12 @@ static int kirkwood_thermal_probe(struct platform_device *pdev) · 11 unmodified lines
8283 "Failed to register thermal zone device\n");
8384 return PTR_ERR(thermal);
8485 }
86+ ret = thermal_zone_device_enable(thermal);
87+ if (ret) {
88+ thermal_zone_device_unregister(thermal);
89+ dev_err(&pdev->dev, "Failed to enable thermal zone device\n");
90+ return ret;
91+ }
8592
8693 platform_set_drvdata(pdev, thermal);
8794
drivers/thermal/mtk_thermal.c+181−53
@@ -38,6 +38,7 @@ · 37 unmodified lines
3838 #define TEMP_MONIDET0 0x014
3939 #define TEMP_MONIDET1 0x018
4040 #define TEMP_MSRCTL0 0x038
41+#define TEMP_MSRCTL1 0x03c
4142 #define TEMP_AHBPOLL 0x040
4243 #define TEMP_AHBTO 0x044
4344 #define TEMP_ADCPNP0 0x048
@@ -120,18 +121,32 @@ · 76 unmodified lines
120121 * MT2701 has 3 sensors and needs 3 VTS calibration data.
121122 * MT2712 has 4 sensors and needs 4 VTS calibration data.
122123 */
123−#define CALIB_BUF0_VALID BIT(0)
124−#define CALIB_BUF1_ADC_GE(x) (((x) >> 22) & 0x3ff)
125−#define CALIB_BUF0_VTS_TS1(x) (((x) >> 17) & 0x1ff)
126−#define CALIB_BUF0_VTS_TS2(x) (((x) >> 8) & 0x1ff)
127−#define CALIB_BUF1_VTS_TS3(x) (((x) >> 0) & 0x1ff)
128−#define CALIB_BUF2_VTS_TS4(x) (((x) >> 23) & 0x1ff)
129−#define CALIB_BUF2_VTS_TS5(x) (((x) >> 5) & 0x1ff)
130−#define CALIB_BUF2_VTS_TSABB(x) (((x) >> 14) & 0x1ff)
131−#define CALIB_BUF0_DEGC_CALI(x) (((x) >> 1) & 0x3f)
132−#define CALIB_BUF0_O_SLOPE(x) (((x) >> 26) & 0x3f)
133−#define CALIB_BUF0_O_SLOPE_SIGN(x) (((x) >> 7) & 0x1)
134−#define CALIB_BUF1_ID(x) (((x) >> 9) & 0x1)
124+#define CALIB_BUF0_VALID_V1 BIT(0)
125+#define CALIB_BUF1_ADC_GE_V1(x) (((x) >> 22) & 0x3ff)
126+#define CALIB_BUF0_VTS_TS1_V1(x) (((x) >> 17) & 0x1ff)
127+#define CALIB_BUF0_VTS_TS2_V1(x) (((x) >> 8) & 0x1ff)
128+#define CALIB_BUF1_VTS_TS3_V1(x) (((x) >> 0) & 0x1ff)
129+#define CALIB_BUF2_VTS_TS4_V1(x) (((x) >> 23) & 0x1ff)
130+#define CALIB_BUF2_VTS_TS5_V1(x) (((x) >> 5) & 0x1ff)
131+#define CALIB_BUF2_VTS_TSABB_V1(x) (((x) >> 14) & 0x1ff)
132+#define CALIB_BUF0_DEGC_CALI_V1(x) (((x) >> 1) & 0x3f)
133+#define CALIB_BUF0_O_SLOPE_V1(x) (((x) >> 26) & 0x3f)
134+#define CALIB_BUF0_O_SLOPE_SIGN_V1(x) (((x) >> 7) & 0x1)
135+#define CALIB_BUF1_ID_V1(x) (((x) >> 9) & 0x1)
136+
137+/*
138+ * Layout of the fuses providing the calibration data
139+ * These macros could be used for MT7622.
140+ */
141+#define CALIB_BUF0_ADC_OE_V2(x) (((x) >> 22) & 0x3ff)
142+#define CALIB_BUF0_ADC_GE_V2(x) (((x) >> 12) & 0x3ff)
143+#define CALIB_BUF0_DEGC_CALI_V2(x) (((x) >> 6) & 0x3f)
144+#define CALIB_BUF0_O_SLOPE_V2(x) (((x) >> 0) & 0x3f)
145+#define CALIB_BUF1_VTS_TS1_V2(x) (((x) >> 23) & 0x1ff)
146+#define CALIB_BUF1_VTS_TS2_V2(x) (((x) >> 14) & 0x1ff)
147+#define CALIB_BUF1_VTS_TSABB_V2(x) (((x) >> 5) & 0x1ff)
148+#define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1)
149+#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1)
135150
136151 enum {
137152 VTS1,
@@ -143,6 +158,11 @@ enum { · 5 unmodified lines
143158 MAX_NUM_VTS,
144159 };
145160
161+enum mtk_thermal_version {
162+ MTK_THERMAL_V1 = 1,
163+ MTK_THERMAL_V2,
164+};
165+
146166 /* MT2701 thermal sensors */
147167 #define MT2701_TS1 0
148168 #define MT2701_TS2 1
@@ -248,6 +268,7 @@ struct mtk_thermal_data { · 99 unmodified lines
248268 const int *controller_offset;
249269 bool need_switch_bank;
250270 struct thermal_bank_cfg bank_data[MAX_NUM_ZONES];
271+ enum mtk_thermal_version version;
251272 };
252273
253274 struct mtk_thermal {
@@ -261,8 +282,10 @@ struct mtk_thermal { · 7 unmodified lines
261282
262283 /* Calibration values */
263284 s32 adc_ge;
285+ s32 adc_oe;
264286 s32 degc_cali;
265287 s32 o_slope;
288+ s32 o_slope_sign;
266289 s32 vts[MAX_NUM_VTS];
267290
268291 const struct mtk_thermal_data *conf;
@@ -401,6 +424,7 @@ static const struct mtk_thermal_data mt8173_thermal_data = { · 132 unmodified lines
401424 .msr = mt8173_msr,
402425 .adcpnp = mt8173_adcpnp,
403426 .sensor_mux_values = mt8173_mux_values,
427+ .version = MTK_THERMAL_V1,
404428 };
405429
406430 /*
@@ -431,6 +455,7 @@ static const struct mtk_thermal_data mt2701_thermal_data = { · 24 unmodified lines
431455 .msr = mt2701_msr,
432456 .adcpnp = mt2701_adcpnp,
433457 .sensor_mux_values = mt2701_mux_values,
458+ .version = MTK_THERMAL_V1,
434459 };
435460
436461 /*
@@ -461,6 +486,7 @@ static const struct mtk_thermal_data mt2712_thermal_data = { · 24 unmodified lines
461486 .msr = mt2712_msr,
462487 .adcpnp = mt2712_adcpnp,
463488 .sensor_mux_values = mt2712_mux_values,
489+ .version = MTK_THERMAL_V1,
464490 };
465491
466492 /*
@@ -485,6 +511,7 @@ static const struct mtk_thermal_data mt7622_thermal_data = { · 18 unmodified lines
485511 .msr = mt7622_msr,
486512 .adcpnp = mt7622_adcpnp,
487513 .sensor_mux_values = mt7622_mux_values,
514+ .version = MTK_THERMAL_V2,
488515 };
489516
490517 /*
@@ -517,6 +544,7 @@ static const struct mtk_thermal_data mt8183_thermal_data = { · 26 unmodified lines
517544 .msr = mt8183_msr,
518545 .adcpnp = mt8183_adcpnp,
519546 .sensor_mux_values = mt8183_mux_values,
547+ .version = MTK_THERMAL_V1,
520548 };
521549
522550 /**
@@ -528,7 +556,7 @@ static const struct mtk_thermal_data mt8183_thermal_data = { · 5 unmodified lines
528556 * This converts the raw ADC value to mcelsius using the SoC specific
529557 * calibration constants
530558 */
531−static int raw_to_mcelsius(struct mtk_thermal *mt, int sensno, s32 raw)
559+static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw)
532560 {
533561 s32 tmp;
534562
@@ -543,6 +571,36 @@ static int raw_to_mcelsius(struct mtk_thermal *mt, int sensno, s32 raw) · 8 unmodified lines
543571 return mt->degc_cali * 500 - tmp;
544572 }
545573
574+static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
575+{
576+ s32 format_1 = 0;
577+ s32 format_2 = 0;
578+ s32 g_oe = 1;
579+ s32 g_gain = 1;
580+ s32 g_x_roomt = 0;
581+ s32 tmp = 0;
582+
583+ if (raw == 0)
584+ return 0;
585+
586+ raw &= 0xfff;
587+ g_gain = 10000 + (((mt->adc_ge - 512) * 10000) >> 12);
588+ g_oe = mt->adc_oe - 512;
589+ format_1 = mt->vts[VTS2] + 3105 - g_oe;
590+ format_2 = (mt->degc_cali * 10) >> 1;
591+ g_x_roomt = (((format_1 * 10000) >> 12) * 10000) / g_gain;
592+
593+ tmp = (((((raw - g_oe) * 10000) >> 12) * 10000) / g_gain) - g_x_roomt;
594+ tmp = tmp * 10 * 100 / 11;
595+
596+ if (mt->o_slope_sign == 0)
597+ tmp = tmp / (165 - mt->o_slope);
598+ else
599+ tmp = tmp / (165 + mt->o_slope);
600+
601+ return (format_2 - tmp) * 100;
602+}
603+
546604 /**
547605 * mtk_thermal_get_bank - get bank
548606 * @bank: The bank
@@ -596,9 +654,13 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) · 47 unmodified lines
596654 for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
597655 raw = readl(mt->thermal_base + conf->msr[i]);
598656
599− temp = raw_to_mcelsius(mt,
600− conf->bank_data[bank->id].sensors[i],
601− raw);
657+ if (mt->conf->version == MTK_THERMAL_V1) {
658+ temp = raw_to_mcelsius_v1(
659+ mt, conf->bank_data[bank->id].sensors[i], raw);
660+ } else {
661+ temp = raw_to_mcelsius_v2(
662+ mt, conf->bank_data[bank->id].sensors[i], raw);
663+ }
602664
603665 /*
604666 * The first read of a sensor often contains very high bogus
@@ -700,9 +762,11 @@ static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num, · 95 unmodified lines
700762 writel(auxadc_phys_base + AUXADC_CON1_CLR_V,
701763 controller_base + TEMP_ADCMUXADDR);
702764
703− /* AHB address for pnp sensor mux selection */
704− writel(apmixed_phys_base + APMIXED_SYS_TS_CON1,
705− controller_base + TEMP_PNPMUXADDR);
765+ if (mt->conf->version == MTK_THERMAL_V1) {
766+ /* AHB address for pnp sensor mux selection */
767+ writel(apmixed_phys_base + APMIXED_SYS_TS_CON1,
768+ controller_base + TEMP_PNPMUXADDR);
769+ }
706770
707771 /* AHB value for auxadc enable */
708772 writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCEN);
@@ -759,6 +823,68 @@ static u64 of_get_phys_base(struct device_node *np) · 50 unmodified lines
759823 return of_translate_address(np, regaddr_p);
760824 }
761825
826+static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf)
827+{
828+ int i;
829+
830+ if (!(buf[0] & CALIB_BUF0_VALID_V1))
831+ return -EINVAL;
832+
833+ mt->adc_ge = CALIB_BUF1_ADC_GE_V1(buf[1]);
834+
835+ for (i = 0; i < mt->conf->num_sensors; i++) {
836+ switch (mt->conf->vts_index[i]) {
837+ case VTS1:
838+ mt->vts[VTS1] = CALIB_BUF0_VTS_TS1_V1(buf[0]);
839+ break;
840+ case VTS2:
841+ mt->vts[VTS2] = CALIB_BUF0_VTS_TS2_V1(buf[0]);
842+ break;
843+ case VTS3:
844+ mt->vts[VTS3] = CALIB_BUF1_VTS_TS3_V1(buf[1]);
845+ break;
846+ case VTS4:
847+ mt->vts[VTS4] = CALIB_BUF2_VTS_TS4_V1(buf[2]);
848+ break;
849+ case VTS5:
850+ mt->vts[VTS5] = CALIB_BUF2_VTS_TS5_V1(buf[2]);
851+ break;
852+ case VTSABB:
853+ mt->vts[VTSABB] =
854+ CALIB_BUF2_VTS_TSABB_V1(buf[2]);
855+ break;
856+ default:
857+ break;
858+ }
859+ }
860+
861+ mt->degc_cali = CALIB_BUF0_DEGC_CALI_V1(buf[0]);
862+ if (CALIB_BUF1_ID_V1(buf[1]) &
863+ CALIB_BUF0_O_SLOPE_SIGN_V1(buf[0]))
864+ mt->o_slope = -CALIB_BUF0_O_SLOPE_V1(buf[0]);
865+ else
866+ mt->o_slope = CALIB_BUF0_O_SLOPE_V1(buf[0]);
867+
868+ return 0;
869+}
870+
871+static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf)
872+{
873+ if (!CALIB_BUF1_VALID_V2(buf[1]))
874+ return -EINVAL;
875+
876+ mt->adc_oe = CALIB_BUF0_ADC_OE_V2(buf[0]);
877+ mt->adc_ge = CALIB_BUF0_ADC_GE_V2(buf[0]);
878+ mt->degc_cali = CALIB_BUF0_DEGC_CALI_V2(buf[0]);
879+ mt->o_slope = CALIB_BUF0_O_SLOPE_V2(buf[0]);
880+ mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V2(buf[1]);
881+ mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V2(buf[1]);
882+ mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V2(buf[1]);
883+ mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V2(buf[1]);
884+
885+ return 0;
886+}
887+
762888 static int mtk_thermal_get_calibration_data(struct device *dev,
763889 struct mtk_thermal *mt)
764890 {
@@ -794,42 +920,14 @@ static int mtk_thermal_get_calibration_data(struct device *dev, · 29 unmodified lines
794920 goto out;
795921 }
796922
797− if (buf[0] & CALIB_BUF0_VALID) {
798− mt->adc_ge = CALIB_BUF1_ADC_GE(buf[1]);
799−
800− for (i = 0; i < mt->conf->num_sensors; i++) {
801− switch (mt->conf->vts_index[i]) {
802− case VTS1:
803− mt->vts[VTS1] = CALIB_BUF0_VTS_TS1(buf[0]);
804− break;
805− case VTS2:
806− mt->vts[VTS2] = CALIB_BUF0_VTS_TS2(buf[0]);
807− break;
808− case VTS3:
809− mt->vts[VTS3] = CALIB_BUF1_VTS_TS3(buf[1]);
810− break;
811− case VTS4:
812− mt->vts[VTS4] = CALIB_BUF2_VTS_TS4(buf[2]);
813− break;
814− case VTS5:
815− mt->vts[VTS5] = CALIB_BUF2_VTS_TS5(buf[2]);
816− break;
817− case VTSABB:
818− mt->vts[VTSABB] = CALIB_BUF2_VTS_TSABB(buf[2]);
819− break;
820− default:
821− break;
822− }
823− }
923+ if (mt->conf->version == MTK_THERMAL_V1)
924+ ret = mtk_thermal_extract_efuse_v1(mt, buf);
925+ else
926+ ret = mtk_thermal_extract_efuse_v2(mt, buf);
824927
825− mt->degc_cali = CALIB_BUF0_DEGC_CALI(buf[0]);
826− if (CALIB_BUF1_ID(buf[1]) &
827− CALIB_BUF0_O_SLOPE_SIGN(buf[0]))
828− mt->o_slope = -CALIB_BUF0_O_SLOPE(buf[0]);
829− else
830− mt->o_slope = CALIB_BUF0_O_SLOPE(buf[0]);
831− } else {
928+ if (ret) {
832929 dev_info(dev, "Device not calibrated, using default calibration values\n");
930+ ret = 0;
833931 }
834932
835933 out:
@@ -863,6 +961,28 @@ static const struct of_device_id mtk_thermal_of_match[] = { · 27 unmodified lines
863961 };
864962 MODULE_DEVICE_TABLE(of, mtk_thermal_of_match);
865963
964+static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base)
965+{
966+ int tmp;
967+
968+ tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1);
969+ tmp &= ~(0x37);
970+ tmp |= 0x1;
971+ writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1);
972+ udelay(200);
973+}
974+
975+static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt,
976+ void __iomem *auxadc_base)
977+{
978+ int tmp;
979+
980+ writel(0x800, auxadc_base + AUXADC_CON1_SET_V);
981+ writel(0x1, mt->thermal_base + TEMP_MONCTL0);
982+ tmp = readl(mt->thermal_base + TEMP_MSRCTL1);
983+ writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1);
984+}
985+
866986 static int mtk_thermal_probe(struct platform_device *pdev)
867987 {
868988 int ret, i, ctrl_id;
@@ -871,6 +991,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) · 2 unmodified lines
871991 struct resource *res;
872992 u64 auxadc_phys_base, apmixed_phys_base;
873993 struct thermal_zone_device *tzdev;
994+ void __iomem *apmixed_base, *auxadc_base;
874995
875996 mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
876997 if (!mt)
@@ -905,6 +1026,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) · 28 unmodified lines
9051026 return -ENODEV;
9061027 }
9071028
1029+ auxadc_base = of_iomap(auxadc, 0);
9081030 auxadc_phys_base = of_get_phys_base(auxadc);
9091031
9101032 of_node_put(auxadc);
@@ -920,6 +1042,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) · 9 unmodified lines
9201042 return -ENODEV;
9211043 }
9221044
1045+ apmixed_base = of_iomap(apmixedsys, 0);
9231046 apmixed_phys_base = of_get_phys_base(apmixedsys);
9241047
9251048 of_node_put(apmixedsys);
@@ -945,6 +1068,11 @@ static int mtk_thermal_probe(struct platform_device *pdev) · 19 unmodified lines
9451068 goto err_disable_clk_auxadc;
9461069 }
9471070
1071+ if (mt->conf->version == MTK_THERMAL_V2) {
1072+ mtk_thermal_turn_on_buffer(apmixed_base);
1073+ mtk_thermal_release_periodic_ts(mt, auxadc_base);
1074+ }
1075+
9481076 for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
9491077 for (i = 0; i < mt->conf->num_banks; i++)
9501078 mtk_thermal_init_bank(mt, i, apmixed_phys_base,
drivers/thermal/qcom/tsens-v0_1.c+143−1
@@ -48,6 +48,63 @@ · 47 unmodified lines
4848 #define MSM8916_CAL_SEL_MASK 0xe0000000
4949 #define MSM8916_CAL_SEL_SHIFT 29
5050
51+/* eeprom layout data for 8939 */
52+#define MSM8939_BASE0_MASK 0x000000ff
53+#define MSM8939_BASE1_MASK 0xff000000
54+#define MSM8939_BASE0_SHIFT 0
55+#define MSM8939_BASE1_SHIFT 24
56+
57+#define MSM8939_S0_P1_MASK 0x000001f8
58+#define MSM8939_S1_P1_MASK 0x001f8000
59+#define MSM8939_S2_P1_MASK_0_4 0xf8000000
60+#define MSM8939_S2_P1_MASK_5 0x00000001
61+#define MSM8939_S3_P1_MASK 0x00001f80
62+#define MSM8939_S4_P1_MASK 0x01f80000
63+#define MSM8939_S5_P1_MASK 0x00003f00
64+#define MSM8939_S6_P1_MASK 0x03f00000
65+#define MSM8939_S7_P1_MASK 0x0000003f
66+#define MSM8939_S8_P1_MASK 0x0003f000
67+#define MSM8939_S9_P1_MASK 0x07e00000
68+
69+#define MSM8939_S0_P2_MASK 0x00007e00
70+#define MSM8939_S1_P2_MASK 0x07e00000
71+#define MSM8939_S2_P2_MASK 0x0000007e
72+#define MSM8939_S3_P2_MASK 0x0007e000
73+#define MSM8939_S4_P2_MASK 0x7e000000
74+#define MSM8939_S5_P2_MASK 0x000fc000
75+#define MSM8939_S6_P2_MASK 0xfc000000
76+#define MSM8939_S7_P2_MASK 0x00000fc0
77+#define MSM8939_S8_P2_MASK 0x00fc0000
78+#define MSM8939_S9_P2_MASK_0_4 0xf8000000
79+#define MSM8939_S9_P2_MASK_5 0x00002000
80+
81+#define MSM8939_S0_P1_SHIFT 3
82+#define MSM8939_S1_P1_SHIFT 15
83+#define MSM8939_S2_P1_SHIFT_0_4 27
84+#define MSM8939_S2_P1_SHIFT_5 0
85+#define MSM8939_S3_P1_SHIFT 7
86+#define MSM8939_S4_P1_SHIFT 19
87+#define MSM8939_S5_P1_SHIFT 8
88+#define MSM8939_S6_P1_SHIFT 20
89+#define MSM8939_S7_P1_SHIFT 0
90+#define MSM8939_S8_P1_SHIFT 12
91+#define MSM8939_S9_P1_SHIFT 21
92+
93+#define MSM8939_S0_P2_SHIFT 9
94+#define MSM8939_S1_P2_SHIFT 21
95+#define MSM8939_S2_P2_SHIFT 1
96+#define MSM8939_S3_P2_SHIFT 13
97+#define MSM8939_S4_P2_SHIFT 25
98+#define MSM8939_S5_P2_SHIFT 14
99+#define MSM8939_S6_P2_SHIFT 26
100+#define MSM8939_S7_P2_SHIFT 6
101+#define MSM8939_S8_P2_SHIFT 18
102+#define MSM8939_S9_P2_SHIFT_0_4 27
103+#define MSM8939_S9_P2_SHIFT_5 13
104+
105+#define MSM8939_CAL_SEL_MASK 0x7
106+#define MSM8939_CAL_SEL_SHIFT 0
107+
51108 /* eeprom layout data for 8974 */
52109 #define BASE1_MASK 0xff
53110 #define S0_P1_MASK 0x3f00
@@ -189,6 +246,76 @@ static int calibrate_8916(struct tsens_priv *priv) · 135 unmodified lines
189246 return 0;
190247 }
191248
249+static int calibrate_8939(struct tsens_priv *priv)
250+{
251+ int base0 = 0, base1 = 0, i;
252+ u32 p1[10], p2[10];
253+ int mode = 0;
254+ u32 *qfprom_cdata;
255+ u32 cdata[6];
256+
257+ qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
258+ if (IS_ERR(qfprom_cdata))
259+ return PTR_ERR(qfprom_cdata);
260+
261+ /* Mapping between qfprom nvmem and calibration data */
262+ cdata[0] = qfprom_cdata[12];
263+ cdata[1] = qfprom_cdata[13];
264+ cdata[2] = qfprom_cdata[0];
265+ cdata[3] = qfprom_cdata[1];
266+ cdata[4] = qfprom_cdata[22];
267+ cdata[5] = qfprom_cdata[21];
268+
269+ mode = (cdata[0] & MSM8939_CAL_SEL_MASK) >> MSM8939_CAL_SEL_SHIFT;
270+ dev_dbg(priv->dev, "calibration mode is %d\n", mode);
271+
272+ switch (mode) {
273+ case TWO_PT_CALIB:
274+ base1 = (cdata[3] & MSM8939_BASE1_MASK) >> MSM8939_BASE1_SHIFT;
275+ p2[0] = (cdata[0] & MSM8939_S0_P2_MASK) >> MSM8939_S0_P2_SHIFT;
276+ p2[1] = (cdata[0] & MSM8939_S1_P2_MASK) >> MSM8939_S1_P2_SHIFT;
277+ p2[2] = (cdata[1] & MSM8939_S2_P2_MASK) >> MSM8939_S2_P2_SHIFT;
278+ p2[3] = (cdata[1] & MSM8939_S3_P2_MASK) >> MSM8939_S3_P2_SHIFT;
279+ p2[4] = (cdata[1] & MSM8939_S4_P2_MASK) >> MSM8939_S4_P2_SHIFT;
280+ p2[5] = (cdata[2] & MSM8939_S5_P2_MASK) >> MSM8939_S5_P2_SHIFT;
281+ p2[6] = (cdata[2] & MSM8939_S6_P2_MASK) >> MSM8939_S6_P2_SHIFT;
282+ p2[7] = (cdata[3] & MSM8939_S7_P2_MASK) >> MSM8939_S7_P2_SHIFT;
283+ p2[8] = (cdata[3] & MSM8939_S8_P2_MASK) >> MSM8939_S8_P2_SHIFT;
284+ p2[9] = (cdata[4] & MSM8939_S9_P2_MASK_0_4) >> MSM8939_S9_P2_SHIFT_0_4;
285+ p2[9] |= ((cdata[5] & MSM8939_S9_P2_MASK_5) >> MSM8939_S9_P2_SHIFT_5) << 5;
286+ for (i = 0; i < priv->num_sensors; i++)
287+ p2[i] = (base1 + p2[i]) << 2;
288+ fallthrough;
289+ case ONE_PT_CALIB2:
290+ base0 = (cdata[2] & MSM8939_BASE0_MASK) >> MSM8939_BASE0_SHIFT;
291+ p1[0] = (cdata[0] & MSM8939_S0_P1_MASK) >> MSM8939_S0_P1_SHIFT;
292+ p1[1] = (cdata[0] & MSM8939_S1_P1_MASK) >> MSM8939_S1_P1_SHIFT;
293+ p1[2] = (cdata[0] & MSM8939_S2_P1_MASK_0_4) >> MSM8939_S2_P1_SHIFT_0_4;
294+ p1[2] |= ((cdata[1] & MSM8939_S2_P1_MASK_5) >> MSM8939_S2_P1_SHIFT_5) << 5;
295+ p1[3] = (cdata[1] & MSM8939_S3_P1_MASK) >> MSM8939_S3_P1_SHIFT;
296+ p1[4] = (cdata[1] & MSM8939_S4_P1_MASK) >> MSM8939_S4_P1_SHIFT;
297+ p1[5] = (cdata[2] & MSM8939_S5_P1_MASK) >> MSM8939_S5_P1_SHIFT;
298+ p1[6] = (cdata[2] & MSM8939_S6_P1_MASK) >> MSM8939_S6_P1_SHIFT;
299+ p1[7] = (cdata[3] & MSM8939_S7_P1_MASK) >> MSM8939_S7_P1_SHIFT;
300+ p1[8] = (cdata[3] & MSM8939_S8_P1_MASK) >> MSM8939_S8_P1_SHIFT;
301+ p1[9] = (cdata[4] & MSM8939_S9_P1_MASK) >> MSM8939_S9_P1_SHIFT;
302+ for (i = 0; i < priv->num_sensors; i++)
303+ p1[i] = ((base0) + p1[i]) << 2;
304+ break;
305+ default:
306+ for (i = 0; i < priv->num_sensors; i++) {
307+ p1[i] = 500;
308+ p2[i] = 780;
309+ }
310+ break;
311+ }
312+
313+ compute_intercept_slope(priv, p1, p2, mode);
314+ kfree(qfprom_cdata);
315+
316+ return 0;
317+}
318+
192319 static int calibrate_8974(struct tsens_priv *priv)
193320 {
194321 int base1 = 0, base2 = 0, i;
@@ -325,7 +452,7 @@ static int calibrate_8974(struct tsens_priv *priv) · 130 unmodified lines
325452 return 0;
326453 }
327454
328−/* v0.1: 8916, 8974 */
455+/* v0.1: 8916, 8939, 8974 */
329456
330457 static struct tsens_features tsens_v0_1_feat = {
331458 .ver_major = VER_0_1,
@@ -386,6 +513,21 @@ struct tsens_plat_data data_8916 = { · 54 unmodified lines
386513 .fields = tsens_v0_1_regfields,
387514 };
388515
516+static const struct tsens_ops ops_8939 = {
517+ .init = init_common,
518+ .calibrate = calibrate_8939,
519+ .get_temp = get_temp_common,
520+};
521+
522+struct tsens_plat_data data_8939 = {
523+ .num_sensors = 10,
524+ .ops = &ops_8939,
525+ .hw_ids = (unsigned int []){ 0, 1, 2, 4, 5, 6, 7, 8, 9, 10 },
526+
527+ .feat = &tsens_v0_1_feat,
528+ .fields = tsens_v0_1_regfields,
529+};
530+
389531 static const struct tsens_ops ops_8974 = {
390532 .init = init_common,
391533 .calibrate = calibrate_8974,
drivers/thermal/qcom/tsens.c+3−0
@@ -897,6 +897,9 @@ static const struct of_device_id tsens_table[] = { · 896 unmodified lines
897897 {
898898 .compatible = "qcom,msm8916-tsens",
899899 .data = &data_8916,
900+ }, {
901+ .compatible = "qcom,msm8939-tsens",
902+ .data = &data_8939,
900903 }, {
901904 .compatible = "qcom,msm8974-tsens",
902905 .data = &data_8974,
drivers/thermal/qcom/tsens.h+1−1
@@ -585,7 +585,7 @@ int get_temp_common(const struct tsens_sensor *s, int *temp); · 584 unmodified lines
585585 extern struct tsens_plat_data data_8960;
586586
587587 /* TSENS v0.1 targets */
588−extern struct tsens_plat_data data_8916, data_8974;
588+extern struct tsens_plat_data data_8916, data_8939, data_8974;
589589
590590 /* TSENS v1 targets */
591591 extern struct tsens_plat_data data_tsens_v1, data_8976;
drivers/thermal/rcar_gen3_thermal.c+7−3
@@ -63,7 +63,7 @@ · 62 unmodified lines
6363 #define TSC_MAX_NUM 3
6464
6565 /* default THCODE values if FUSEs are missing */
66−static const int thcode[TSC_MAX_NUM][3] = {
66+static const int thcodes[TSC_MAX_NUM][3] = {
6767 { 3397, 2800, 2221 },
6868 { 3393, 2795, 2216 },
6969 { 3389, 2805, 2237 },
@@ -172,7 +172,7 @@ static int rcar_gen3_thermal_get_temp(void *devdata, int *temp) · 102 unmodified lines
172172 /* Read register and convert to mili Celsius */
173173 reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK;
174174
175− if (reg <= thcode[tsc->id][1])
175+ if (reg <= thcodes[tsc->id][1])
176176 val = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b1,
177177 tsc->coef.a1);
178178 else
@@ -314,6 +314,10 @@ static const struct of_device_id rcar_gen3_thermal_dt_ids[] = { · 135 unmodified lines
314314 .compatible = "renesas,r8a774b1-thermal",
315315 .data = &rcar_gen3_ths_tj_1,
316316 },
317+ {
318+ .compatible = "renesas,r8a774e1-thermal",
319+ .data = &rcar_gen3_ths_tj_1,
320+ },
317321 {
318322 .compatible = "renesas,r8a7795-thermal",
319323 .data = &rcar_gen3_ths_tj_1,
@@ -430,7 +434,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev) · 110 unmodified lines
430434 priv->tscs[i] = tsc;
431435
432436 priv->thermal_init(tsc);
433− rcar_gen3_thermal_calc_coefs(tsc, ptat, thcode[i],
437+ rcar_gen3_thermal_calc_coefs(tsc, ptat, thcodes[i],
434438 *rcar_gen3_ths_tj_1);
435439
436440 zone = devm_thermal_zone_of_sensor_register(dev, i, tsc,
drivers/thermal/rcar_thermal.c+8−1
@@ -550,12 +550,19 @@ static int rcar_thermal_probe(struct platform_device *pdev) · 549 unmodified lines
550550 priv->zone = devm_thermal_zone_of_sensor_register(
551551 dev, i, priv,
552552 &rcar_thermal_zone_of_ops);
553− else
553+ else {
554554 priv->zone = thermal_zone_device_register(
555555 "rcar_thermal",
556556 1, 0, priv,
557557 &rcar_thermal_zone_ops, NULL, 0,
558558 idle);
559+
560+ ret = thermal_zone_device_enable(priv->zone);
561+ if (ret) {
562+ thermal_zone_device_unregister(priv->zone);
563+ priv->zone = ERR_PTR(ret);
564+ }
565+ }
559566 if (IS_ERR(priv->zone)) {
560567 dev_err(dev, "can't register thermal zone\n");
561568 ret = PTR_ERR(priv->zone);
drivers/thermal/rockchip_thermal.c+4−2
@@ -1068,8 +1068,10 @@ rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor *sensor, bool on) · 1067 unmodified lines
10681068 {
10691069 struct thermal_zone_device *tzd = sensor->tzd;
10701070
1071− tzd->ops->set_mode(tzd,
1072− on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
1071+ if (on)
1072+ thermal_zone_device_enable(tzd);
1073+ else
1074+ thermal_zone_device_disable(tzd);
10731075 }
10741076
10751077 static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev)
drivers/thermal/spear_thermal.c+7−0
@@ -131,6 +131,11 @@ static int spear_thermal_probe(struct platform_device *pdev) · 130 unmodified lines
131131 ret = PTR_ERR(spear_thermal);
132132 goto disable_clk;
133133 }
134+ ret = thermal_zone_device_enable(spear_thermal);
135+ if (ret) {
136+ dev_err(&pdev->dev, "Cannot enable thermal zone\n");
137+ goto unregister_tzd;
138+ }
134139
135140 platform_set_drvdata(pdev, spear_thermal);
136141
@@ -139,6 +144,8 @@ static int spear_thermal_probe(struct platform_device *pdev) · 2 unmodified lines
139144
140145 return 0;
141146
147+unregister_tzd:
148+ thermal_zone_device_unregister(spear_thermal);
142149 disable_clk:
143150 clk_disable(stdev->clk);
144151
drivers/thermal/sprd_thermal.c+4−2
@@ -322,8 +322,10 @@ static void sprd_thm_toggle_sensor(struct sprd_thermal_sensor *sen, bool on) · 321 unmodified lines
322322 {
323323 struct thermal_zone_device *tzd = sen->tzd;
324324
325− tzd->ops->set_mode(tzd,
326− on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED);
325+ if (on)
326+ thermal_zone_device_enable(tzd);
327+ else
328+ thermal_zone_device_disable(tzd);
327329 }
328330
329331 static int sprd_thm_probe(struct platform_device *pdev)
drivers/thermal/st/st_thermal.c+5−0
@@ -246,11 +246,16 @@ int st_thermal_register(struct platform_device *pdev, · 245 unmodified lines
246246 ret = PTR_ERR(sensor->thermal_dev);
247247 goto sensor_off;
248248 }
249+ ret = thermal_zone_device_enable(sensor->thermal_dev);
250+ if (ret)
251+ goto tzd_unregister;
249252
250253 platform_set_drvdata(pdev, sensor);
251254
252255 return 0;
253256
257+tzd_unregister:
258+ thermal_zone_device_unregister(sensor->thermal_dev);
254259 sensor_off:
255260 st_thermal_sensor_off(sensor);
256261
drivers/thermal/thermal_core.c+165−9
@@ -215,6 +215,8 @@ exit: · 214 unmodified lines
215215 mutex_unlock(&tz->lock);
216216 mutex_unlock(&thermal_governor_lock);
217217
218+ thermal_notify_tz_gov_change(tz->id, policy);
219+
218220 return ret;
219221 }
220222
@@ -301,13 +303,22 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz, · 80 unmodified lines
301303 cancel_delayed_work(&tz->poll_queue);
302304 }
303305
306+static inline bool should_stop_polling(struct thermal_zone_device *tz)
307+{
308+ return !thermal_zone_device_is_enabled(tz);
309+}
310+
304311 static void monitor_thermal_zone(struct thermal_zone_device *tz)
305312 {
313+ bool stop;
314+
315+ stop = should_stop_polling(tz);
316+
306317 mutex_lock(&tz->lock);
307318
308− if (tz->passive)
319+ if (!stop && tz->passive)
309320 thermal_zone_device_set_polling(tz, tz->passive_delay);
310− else if (tz->polling_delay)
321+ else if (!stop && tz->polling_delay)
311322 thermal_zone_device_set_polling(tz, tz->polling_delay);
312323 else
313324 thermal_zone_device_set_polling(tz, 0);
@@ -406,12 +417,25 @@ static void handle_critical_trips(struct thermal_zone_device *tz, · 92 unmodified lines
406417 static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
407418 {
408419 enum thermal_trip_type type;
420+ int trip_temp, hyst = 0;
409421
410422 /* Ignore disabled trip points */
411423 if (test_bit(trip, &tz->trips_disabled))
412424 return;
413425
426+ tz->ops->get_trip_temp(tz, trip, &trip_temp);
414427 tz->ops->get_trip_type(tz, trip, &type);
428+ if (tz->ops->get_trip_hyst)
429+ tz->ops->get_trip_hyst(tz, trip, &hyst);
430+
431+ if (tz->last_temperature != THERMAL_TEMP_INVALID) {
432+ if (tz->last_temperature < trip_temp &&
433+ tz->temperature >= trip_temp)
434+ thermal_notify_tz_trip_up(tz->id, trip);
435+ if (tz->last_temperature >= trip_temp &&
436+ tz->temperature < (trip_temp - hyst))
437+ thermal_notify_tz_trip_down(tz->id, trip);
438+ }
415439
416440 if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
417441 handle_critical_trips(tz, trip, type);
@@ -443,6 +467,8 @@ static void update_temperature(struct thermal_zone_device *tz) · 25 unmodified lines
443467 mutex_unlock(&tz->lock);
444468
445469 trace_thermal_temperature(tz);
470+
471+ thermal_genl_sampling_temp(tz->id, temp);
446472 }
447473
448474 static void thermal_zone_device_init(struct thermal_zone_device *tz)
@@ -459,11 +485,71 @@ static void thermal_zone_device_reset(struct thermal_zone_device *tz) · 10 unmodified lines
459485 thermal_zone_device_init(tz);
460486 }
461487
488+static int thermal_zone_device_set_mode(struct thermal_zone_device *tz,
489+ enum thermal_device_mode mode)
490+{
491+ int ret = 0;
492+
493+ mutex_lock(&tz->lock);
494+
495+ /* do nothing if mode isn't changing */
496+ if (mode == tz->mode) {
497+ mutex_unlock(&tz->lock);
498+
499+ return ret;
500+ }
501+
502+ if (tz->ops->change_mode)
503+ ret = tz->ops->change_mode(tz, mode);
504+
505+ if (!ret)
506+ tz->mode = mode;
507+
508+ mutex_unlock(&tz->lock);
509+
510+ thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
511+
512+ if (mode == THERMAL_DEVICE_ENABLED)
513+ thermal_notify_tz_enable(tz->id);
514+ else
515+ thermal_notify_tz_disable(tz->id);
516+
517+ return ret;
518+}
519+
520+int thermal_zone_device_enable(struct thermal_zone_device *tz)
521+{
522+ return thermal_zone_device_set_mode(tz, THERMAL_DEVICE_ENABLED);
523+}
524+EXPORT_SYMBOL_GPL(thermal_zone_device_enable);
525+
526+int thermal_zone_device_disable(struct thermal_zone_device *tz)
527+{
528+ return thermal_zone_device_set_mode(tz, THERMAL_DEVICE_DISABLED);
529+}
530+EXPORT_SYMBOL_GPL(thermal_zone_device_disable);
531+
532+int thermal_zone_device_is_enabled(struct thermal_zone_device *tz)
533+{
534+ enum thermal_device_mode mode;
535+
536+ mutex_lock(&tz->lock);
537+
538+ mode = tz->mode;
539+
540+ mutex_unlock(&tz->lock);
541+
542+ return mode == THERMAL_DEVICE_ENABLED;
543+}
544+
462545 void thermal_zone_device_update(struct thermal_zone_device *tz,
463546 enum thermal_notify_event event)
464547 {
465548 int count;
466549
550+ if (should_stop_polling(tz))
551+ return;
552+
467553 if (atomic_read(&in_suspend))
468554 return;
469555
@@ -617,6 +703,73 @@ void thermal_zone_device_rebind_exception(struct thermal_zone_device *tz, · 147 unmodified lines
617703 mutex_unlock(&thermal_list_lock);
618704 }
619705
706+int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),
707+ void *data)
708+{
709+ struct thermal_governor *gov;
710+ int ret = 0;
711+
712+ mutex_lock(&thermal_governor_lock);
713+ list_for_each_entry(gov, &thermal_governor_list, governor_list) {
714+ ret = cb(gov, data);
715+ if (ret)
716+ break;
717+ }
718+ mutex_unlock(&thermal_governor_lock);
719+
720+ return ret;
721+}
722+
723+int for_each_thermal_cooling_device(int (*cb)(struct thermal_cooling_device *,
724+ void *), void *data)
725+{
726+ struct thermal_cooling_device *cdev;
727+ int ret = 0;
728+
729+ mutex_lock(&thermal_list_lock);
730+ list_for_each_entry(cdev, &thermal_cdev_list, node) {
731+ ret = cb(cdev, data);
732+ if (ret)
733+ break;
734+ }
735+ mutex_unlock(&thermal_list_lock);
736+
737+ return ret;
738+}
739+
740+int for_each_thermal_zone(int (*cb)(struct thermal_zone_device *, void *),
741+ void *data)
742+{
743+ struct thermal_zone_device *tz;
744+ int ret = 0;
745+
746+ mutex_lock(&thermal_list_lock);
747+ list_for_each_entry(tz, &thermal_tz_list, node) {
748+ ret = cb(tz, data);
749+ if (ret)
750+ break;
751+ }
752+ mutex_unlock(&thermal_list_lock);
753+
754+ return ret;
755+}
756+
757+struct thermal_zone_device *thermal_zone_get_by_id(int id)
758+{
759+ struct thermal_zone_device *tz, *match = NULL;
760+
761+ mutex_lock(&thermal_list_lock);
762+ list_for_each_entry(tz, &thermal_tz_list, node) {
763+ if (tz->id == id) {
764+ match = tz;
765+ break;
766+ }
767+ }
768+ mutex_unlock(&thermal_list_lock);
769+
770+ return match;
771+}
772+
620773 void thermal_zone_device_unbind_exception(struct thermal_zone_device *tz,
621774 const char *cdev_type, size_t size)
622775 {
@@ -1340,6 +1493,8 @@ thermal_zone_device_register(const char *type, int trips, int mask, · 717 unmodified lines
13401493 if (atomic_cmpxchg(&tz->need_update, 1, 0))
13411494 thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
13421495
1496+ thermal_notify_tz_create(tz->id, tz->type);
1497+
13431498 return tz;
13441499
13451500 unregister:
@@ -1411,6 +1566,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) · 65 unmodified lines
14111566 ida_destroy(&tz->ida);
14121567 mutex_destroy(&tz->lock);
14131568 device_unregister(&tz->device);
1569+
1570+ thermal_notify_tz_delete(tz->id);
14141571 }
14151572 EXPORT_SYMBOL_GPL(thermal_zone_device_unregister);
14161573
@@ -1456,7 +1613,6 @@ static int thermal_pm_notify(struct notifier_block *nb, · 39 unmodified lines
14561613 unsigned long mode, void *_unused)
14571614 {
14581615 struct thermal_zone_device *tz;
1459− enum thermal_device_mode tz_mode;
14601616
14611617 switch (mode) {
14621618 case PM_HIBERNATION_PREPARE:
@@ -1469,11 +1625,7 @@ static int thermal_pm_notify(struct notifier_block *nb, · 6 unmodified lines
14691625 case PM_POST_SUSPEND:
14701626 atomic_set(&in_suspend, 0);
14711627 list_for_each_entry(tz, &thermal_tz_list, node) {
1472− tz_mode = THERMAL_DEVICE_ENABLED;
1473− if (tz->ops->get_mode)
1474− tz->ops->get_mode(tz, &tz_mode);
1475−
1476− if (tz_mode == THERMAL_DEVICE_DISABLED)
1628+ if (!thermal_zone_device_is_enabled(tz))
14771629 continue;
14781630
14791631 thermal_zone_device_init(tz);
@@ -1495,6 +1647,10 @@ static int __init thermal_init(void) · 15 unmodified lines
14951647 {
14961648 int result;
14971649
1650+ result = thermal_netlink_init();
1651+ if (result)
1652+ goto error;
1653+
14981654 mutex_init(&poweroff_lock);
14991655 result = thermal_register_governors();
15001656 if (result)
@@ -1527,4 +1683,4 @@ error: · 26 unmodified lines
15271683 mutex_destroy(&poweroff_lock);
15281684 return result;
15291685 }
1530−core_initcall(thermal_init);
1686+postcore_initcall(thermal_init);
drivers/thermal/thermal_core.h+15−0
@@ -12,6 +12,8 @@ · 11 unmodified lines
1212 #include <linux/device.h>
1313 #include <linux/thermal.h>
1414
15+#include "thermal_netlink.h"
16+
1517 /* Default Thermal Governor */
1618 #if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
1719 #define DEFAULT_THERMAL_GOVERNOR "step_wise"
@@ -41,6 +43,17 @@ extern struct thermal_governor *__governor_thermal_table_end[]; · 23 unmodified lines
4143 __governor < __governor_thermal_table_end; \
4244 __governor++)
4345
46+int for_each_thermal_zone(int (*cb)(struct thermal_zone_device *, void *),
47+ void *);
48+
49+int for_each_thermal_cooling_device(int (*cb)(struct thermal_cooling_device *,
50+ void *), void *);
51+
52+int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),
53+ void *thermal_governor);
54+
55+struct thermal_zone_device *thermal_zone_get_by_id(int id);
56+
4457 struct thermal_attr {
4558 struct device_attribute attr;
4659 char name[THERMAL_NAME_LENGTH];
@@ -166,4 +179,6 @@ of_thermal_get_trip_points(struct thermal_zone_device *tz) · 119 unmodified lines
166179 }
167180 #endif
168181
182+int thermal_zone_device_is_enabled(struct thermal_zone_device *tz);
183+
169184 #endif /* __THERMAL_CORE_H__ */
drivers/thermal/thermal_helpers.c+11−2
@@ -175,6 +175,16 @@ exit: · 174 unmodified lines
175175 mutex_unlock(&tz->lock);
176176 }
177177
178+static void thermal_cdev_set_cur_state(struct thermal_cooling_device *cdev,
179+ int target)
180+{
181+ if (cdev->ops->set_cur_state(cdev, target))
182+ return;
183+
184+ thermal_notify_cdev_state_update(cdev->id, target);
185+ thermal_cooling_device_stats_update(cdev, target);
186+}
187+
178188 void thermal_cdev_update(struct thermal_cooling_device *cdev)
179189 {
180190 struct thermal_instance *instance;
@@ -197,8 +207,7 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev) · 16 unmodified lines
197207 target = instance->target;
198208 }
199209
200− if (!cdev->ops->set_cur_state(cdev, target))
201− thermal_cooling_device_stats_update(cdev, target);
210+ thermal_cdev_set_cur_state(cdev, target);
202211
203212 cdev->updated = true;
204213 mutex_unlock(&cdev->lock);
drivers/thermal/thermal_netlink.c+647−0
@@ -0,0 +1,647 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright 2020 Linaro Limited
4+ *
5+ * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
6+ *
7+ * Generic netlink for thermal management framework
8+ */
9+#include <linux/module.h>
10+#include <linux/kernel.h>
11+#include <net/genetlink.h>
12+#include <uapi/linux/thermal.h>
13+
14+#include "thermal_core.h"
15+
16+static const struct genl_multicast_group thermal_genl_mcgrps[] = {
17+ { .name = THERMAL_GENL_SAMPLING_GROUP_NAME, },
18+ { .name = THERMAL_GENL_EVENT_GROUP_NAME, },
19+};
20+
21+static const struct nla_policy thermal_genl_policy[THERMAL_GENL_ATTR_MAX + 1] = {
22+ /* Thermal zone */
23+ [THERMAL_GENL_ATTR_TZ] = { .type = NLA_NESTED },
24+ [THERMAL_GENL_ATTR_TZ_ID] = { .type = NLA_U32 },
25+ [THERMAL_GENL_ATTR_TZ_TEMP] = { .type = NLA_U32 },
26+ [THERMAL_GENL_ATTR_TZ_TRIP] = { .type = NLA_NESTED },
27+ [THERMAL_GENL_ATTR_TZ_TRIP_ID] = { .type = NLA_U32 },
28+ [THERMAL_GENL_ATTR_TZ_TRIP_TEMP] = { .type = NLA_U32 },
29+ [THERMAL_GENL_ATTR_TZ_TRIP_TYPE] = { .type = NLA_U32 },
30+ [THERMAL_GENL_ATTR_TZ_TRIP_HYST] = { .type = NLA_U32 },
31+ [THERMAL_GENL_ATTR_TZ_MODE] = { .type = NLA_U32 },
32+ [THERMAL_GENL_ATTR_TZ_CDEV_WEIGHT] = { .type = NLA_U32 },
33+ [THERMAL_GENL_ATTR_TZ_NAME] = { .type = NLA_STRING,
34+ .len = THERMAL_NAME_LENGTH },
35+ /* Governor(s) */
36+ [THERMAL_GENL_ATTR_TZ_GOV] = { .type = NLA_NESTED },
37+ [THERMAL_GENL_ATTR_TZ_GOV_NAME] = { .type = NLA_STRING,
38+ .len = THERMAL_NAME_LENGTH },
39+ /* Cooling devices */
40+ [THERMAL_GENL_ATTR_CDEV] = { .type = NLA_NESTED },
41+ [THERMAL_GENL_ATTR_CDEV_ID] = { .type = NLA_U32 },
42+ [THERMAL_GENL_ATTR_CDEV_CUR_STATE] = { .type = NLA_U32 },
43+ [THERMAL_GENL_ATTR_CDEV_MAX_STATE] = { .type = NLA_U32 },
44+ [THERMAL_GENL_ATTR_CDEV_NAME] = { .type = NLA_STRING,
45+ .len = THERMAL_NAME_LENGTH },
46+};
47+
48+struct param {
49+ struct nlattr **attrs;
50+ struct sk_buff *msg;
51+ const char *name;
52+ int tz_id;
53+ int cdev_id;
54+ int trip_id;
55+ int trip_temp;
56+ int trip_type;
57+ int trip_hyst;
58+ int temp;
59+ int cdev_state;
60+ int cdev_max_state;
61+};
62+
63+typedef int (*cb_t)(struct param *);
64+
65+static struct genl_family thermal_gnl_family;
66+
67+/************************** Sampling encoding *******************************/
68+
69+int thermal_genl_sampling_temp(int id, int temp)
70+{
71+ struct sk_buff *skb;
72+ void *hdr;
73+
74+ skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
75+ if (!skb)
76+ return -ENOMEM;
77+
78+ hdr = genlmsg_put(skb, 0, 0, &thermal_gnl_family, 0,
79+ THERMAL_GENL_SAMPLING_TEMP);
80+ if (!hdr)
81+ return -EMSGSIZE;
82+
83+ if (nla_put_u32(skb, THERMAL_GENL_ATTR_TZ_ID, id))
84+ goto out_cancel;
85+
86+ if (nla_put_u32(skb, THERMAL_GENL_ATTR_TZ_TEMP, temp))
87+ goto out_cancel;
88+
89+ genlmsg_end(skb, hdr);
90+
91+ genlmsg_multicast(&thermal_gnl_family, skb, 0, 0, GFP_KERNEL);
92+
93+ return 0;
94+out_cancel:
95+ genlmsg_cancel(skb, hdr);
96+ nlmsg_free(skb);
97+
98+ return -EMSGSIZE;
99+}
100+
101+/**************************** Event encoding *********************************/
102+
103+static int thermal_genl_event_tz_create(struct param *p)
104+{
105+ if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_ID, p->tz_id) ||
106+ nla_put_string(p->msg, THERMAL_GENL_ATTR_TZ_NAME, p->name))
107+ return -EMSGSIZE;
108+
109+ return 0;
110+}
111+
112+static int thermal_genl_event_tz(struct param *p)
113+{
114+ if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_ID, p->tz_id))
115+ return -EMSGSIZE;
116+
117+ return 0;
118+}
119+
120+static int thermal_genl_event_tz_trip_up(struct param *p)
121+{
122+ if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_ID, p->tz_id) ||
123+ nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, p->trip_id))
124+ return -EMSGSIZE;
125+
126+ return 0;
127+}
128+
129+static int thermal_genl_event_tz_trip_add(struct param *p)
130+{
131+ if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_ID, p->tz_id) ||
132+ nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, p->trip_id) ||
133+ nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_TRIP_TYPE, p->trip_type) ||
134+ nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_TRIP_TEMP, p->trip_temp) ||
135+ nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_TRIP_HYST, p->trip_hyst))
136+ return -EMSGSIZE;
137+
138+ return 0;
139+}
140+
141+static int thermal_genl_event_tz_trip_delete(struct param *p)
142+{
143+ if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_ID, p->tz_id) ||
144+ nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, p->trip_id))
145+ return -EMSGSIZE;
146+
147+ return 0;
148+}
149+
150+static int thermal_genl_event_cdev_add(struct param *p)
151+{
152+ if (nla_put_string(p->msg, THERMAL_GENL_ATTR_CDEV_NAME,
153+ p->name) ||
154+ nla_put_u32(p->msg, THERMAL_GENL_ATTR_CDEV_ID,
155+ p->cdev_id) ||
156+ nla_put_u32(p->msg, THERMAL_GENL_ATTR_CDEV_MAX_STATE,
157+ p->cdev_max_state))
158+ return -EMSGSIZE;
159+
160+ return 0;
161+}
162+
163+static int thermal_genl_event_cdev_delete(struct param *p)
164+{
165+ if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_CDEV_ID, p->cdev_id))
166+ return -EMSGSIZE;
167+
168+ return 0;
169+}
170+
171+static int thermal_genl_event_cdev_state_update(struct param *p)
172+{
173+ if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_CDEV_ID,
174+ p->cdev_id) ||
175+ nla_put_u32(p->msg, THERMAL_GENL_ATTR_CDEV_CUR_STATE,
176+ p->cdev_state))
177+ return -EMSGSIZE;
178+
179+ return 0;
180+}
181+
182+static int thermal_genl_event_gov_change(struct param *p)
183+{
184+ if (nla_put_u32(p->msg, THERMAL_GENL_ATTR_TZ_ID, p->tz_id) ||
185+ nla_put_string(p->msg, THERMAL_GENL_ATTR_GOV_NAME, p->name))
186+ return -EMSGSIZE;
187+
188+ return 0;
189+}
190+
191+int thermal_genl_event_tz_delete(struct param *p)
192+ __attribute__((alias("thermal_genl_event_tz")));
193+
194+int thermal_genl_event_tz_enable(struct param *p)
195+ __attribute__((alias("thermal_genl_event_tz")));
196+
197+int thermal_genl_event_tz_disable(struct param *p)
198+ __attribute__((alias("thermal_genl_event_tz")));
199+
200+int thermal_genl_event_tz_trip_down(struct param *p)
201+ __attribute__((alias("thermal_genl_event_tz_trip_up")));
202+
203+int thermal_genl_event_tz_trip_change(struct param *p)
204+ __attribute__((alias("thermal_genl_event_tz_trip_add")));
205+
206+static cb_t event_cb[] = {
207+ [THERMAL_GENL_EVENT_TZ_CREATE] = thermal_genl_event_tz_create,
208+ [THERMAL_GENL_EVENT_TZ_DELETE] = thermal_genl_event_tz_delete,
209+ [THERMAL_GENL_EVENT_TZ_ENABLE] = thermal_genl_event_tz_enable,
210+ [THERMAL_GENL_EVENT_TZ_DISABLE] = thermal_genl_event_tz_disable,
211+ [THERMAL_GENL_EVENT_TZ_TRIP_UP] = thermal_genl_event_tz_trip_up,
212+ [THERMAL_GENL_EVENT_TZ_TRIP_DOWN] = thermal_genl_event_tz_trip_down,
213+ [THERMAL_GENL_EVENT_TZ_TRIP_CHANGE] = thermal_genl_event_tz_trip_change,
214+ [THERMAL_GENL_EVENT_TZ_TRIP_ADD] = thermal_genl_event_tz_trip_add,
215+ [THERMAL_GENL_EVENT_TZ_TRIP_DELETE] = thermal_genl_event_tz_trip_delete,
216+ [THERMAL_GENL_EVENT_CDEV_ADD] = thermal_genl_event_cdev_add,
217+ [THERMAL_GENL_EVENT_CDEV_DELETE] = thermal_genl_event_cdev_delete,
218+ [THERMAL_GENL_EVENT_CDEV_STATE_UPDATE] = thermal_genl_event_cdev_state_update,
219+ [THERMAL_GENL_EVENT_TZ_GOV_CHANGE] = thermal_genl_event_gov_change,
220+};
221+
222+/*
223+ * Generic netlink event encoding
224+ */
225+static int thermal_genl_send_event(enum thermal_genl_event event,
226+ struct param *p)
227+{
228+ struct sk_buff *msg;
229+ int ret = -EMSGSIZE;
230+ void *hdr;
231+
232+ msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
233+ if (!msg)
234+ return -ENOMEM;
235+ p->msg = msg;
236+
237+ hdr = genlmsg_put(msg, 0, 0, &thermal_gnl_family, 0, event);
238+ if (!hdr)
239+ goto out_free_msg;
240+
241+ ret = event_cb[event](p);
242+ if (ret)
243+ goto out_cancel_msg;
244+
245+ genlmsg_end(msg, hdr);
246+
247+ genlmsg_multicast(&thermal_gnl_family, msg, 0, 1, GFP_KERNEL);
248+
249+ return 0;
250+
251+out_cancel_msg:
252+ genlmsg_cancel(msg, hdr);
253+out_free_msg:
254+ nlmsg_free(msg);
255+
256+ return ret;
257+}
258+
259+int thermal_notify_tz_create(int tz_id, const char *name)
260+{
261+ struct param p = { .tz_id = tz_id, .name = name };
262+
263+ return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_CREATE, &p);
264+}
265+
266+int thermal_notify_tz_delete(int tz_id)
267+{
268+ struct param p = { .tz_id = tz_id };
269+
270+ return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_DELETE, &p);
271+}
272+
273+int thermal_notify_tz_enable(int tz_id)
274+{
275+ struct param p = { .tz_id = tz_id };
276+
277+ return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_ENABLE, &p);
278+}
279+
280+int thermal_notify_tz_disable(int tz_id)
281+{
282+ struct param p = { .tz_id = tz_id };
283+
284+ return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_DISABLE, &p);
285+}
286+
287+int thermal_notify_tz_trip_down(int tz_id, int trip_id)
288+{
289+ struct param p = { .tz_id = tz_id, .trip_id = trip_id };
290+
291+ return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_TRIP_DOWN, &p);
292+}
293+
294+int thermal_notify_tz_trip_up(int tz_id, int trip_id)
295+{
296+ struct param p = { .tz_id = tz_id, .trip_id = trip_id };
297+
298+ return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_TRIP_UP, &p);
299+}
300+
301+int thermal_notify_tz_trip_add(int tz_id, int trip_id, int trip_type,
302+ int trip_temp, int trip_hyst)
303+{
304+ struct param p = { .tz_id = tz_id, .trip_id = trip_id,
305+ .trip_type = trip_type, .trip_temp = trip_temp,
306+ .trip_hyst = trip_hyst };
307+
308+ return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_TRIP_ADD, &p);
309+}
310+
311+int thermal_notify_tz_trip_delete(int tz_id, int trip_id)
312+{
313+ struct param p = { .tz_id = tz_id, .trip_id = trip_id };
314+
315+ return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_TRIP_DELETE, &p);
316+}
317+
318+int thermal_notify_tz_trip_change(int tz_id, int trip_id, int trip_type,
319+ int trip_temp, int trip_hyst)
320+{
321+ struct param p = { .tz_id = tz_id, .trip_id = trip_id,
322+ .trip_type = trip_type, .trip_temp = trip_temp,
323+ .trip_hyst = trip_hyst };
324+
325+ return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_TRIP_CHANGE, &p);
326+}
327+
328+int thermal_notify_cdev_state_update(int cdev_id, int cdev_state)
329+{
330+ struct param p = { .cdev_id = cdev_id, .cdev_state = cdev_state };
331+
332+ return thermal_genl_send_event(THERMAL_GENL_EVENT_CDEV_STATE_UPDATE, &p);
333+}
334+
335+int thermal_notify_cdev_add(int cdev_id, const char *name, int cdev_max_state)
336+{
337+ struct param p = { .cdev_id = cdev_id, .name = name,
338+ .cdev_max_state = cdev_max_state };
339+
340+ return thermal_genl_send_event(THERMAL_GENL_EVENT_CDEV_ADD, &p);
341+}
342+
343+int thermal_notify_cdev_delete(int cdev_id)
344+{
345+ struct param p = { .cdev_id = cdev_id };
346+
347+ return thermal_genl_send_event(THERMAL_GENL_EVENT_CDEV_DELETE, &p);
348+}
349+
350+int thermal_notify_tz_gov_change(int tz_id, const char *name)
351+{
352+ struct param p = { .tz_id = tz_id, .name = name };
353+
354+ return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_GOV_CHANGE, &p);
355+}
356+
357+/*************************** Command encoding ********************************/
358+
359+static int __thermal_genl_cmd_tz_get_id(struct thermal_zone_device *tz,
360+ void *data)
361+{
362+ struct sk_buff *msg = data;
363+
364+ if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_ID, tz->id) ||
365+ nla_put_string(msg, THERMAL_GENL_ATTR_TZ_NAME, tz->type))
366+ return -EMSGSIZE;
367+
368+ return 0;
369+}
370+
371+static int thermal_genl_cmd_tz_get_id(struct param *p)
372+{
373+ struct sk_buff *msg = p->msg;
374+ struct nlattr *start_tz;
375+ int ret;
376+
377+ start_tz = nla_nest_start(msg, THERMAL_GENL_ATTR_TZ);
378+ if (!start_tz)
379+ return -EMSGSIZE;
380+
381+ ret = for_each_thermal_zone(__thermal_genl_cmd_tz_get_id, msg);
382+ if (ret)
383+ goto out_cancel_nest;
384+
385+ nla_nest_end(msg, start_tz);
386+
387+ return 0;
388+
389+out_cancel_nest:
390+ nla_nest_cancel(msg, start_tz);
391+
392+ return ret;
393+}
394+
395+static int thermal_genl_cmd_tz_get_trip(struct param *p)
396+{
397+ struct sk_buff *msg = p->msg;
398+ struct thermal_zone_device *tz;
399+ struct nlattr *start_trip;
400+ int i, id;
401+
402+ if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID])
403+ return -EINVAL;
404+
405+ id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]);
406+
407+ tz = thermal_zone_get_by_id(id);
408+ if (!tz)
409+ return -EINVAL;
410+
411+ start_trip = nla_nest_start(msg, THERMAL_GENL_ATTR_TZ_TRIP);
412+ if (!start_trip)
413+ return -EMSGSIZE;
414+
415+ mutex_lock(&tz->lock);
416+
417+ for (i = 0; i < tz->trips; i++) {
418+
419+ enum thermal_trip_type type;
420+ int temp, hyst;
421+
422+ tz->ops->get_trip_type(tz, i, &type);
423+ tz->ops->get_trip_temp(tz, i, &temp);
424+ tz->ops->get_trip_hyst(tz, i, &hyst);
425+
426+ if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, i) ||
427+ nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TYPE, type) ||
428+ nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TEMP, temp) ||
429+ nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_HYST, hyst))
430+ goto out_cancel_nest;
431+ }
432+
433+ mutex_unlock(&tz->lock);
434+
435+ nla_nest_end(msg, start_trip);
436+
437+ return 0;
438+
439+out_cancel_nest:
440+ mutex_unlock(&tz->lock);
441+
442+ return -EMSGSIZE;
443+}
444+
445+static int thermal_genl_cmd_tz_get_temp(struct param *p)
446+{
447+ struct sk_buff *msg = p->msg;
448+ struct thermal_zone_device *tz;
449+ int temp, ret, id;
450+
451+ if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID])
452+ return -EINVAL;
453+
454+ id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]);
455+
456+ tz = thermal_zone_get_by_id(id);
457+ if (!tz)
458+ return -EINVAL;
459+
460+ ret = thermal_zone_get_temp(tz, &temp);
461+ if (ret)
462+ return ret;
463+
464+ if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_ID, id) ||
465+ nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TEMP, temp))
466+ return -EMSGSIZE;
467+
468+ return 0;
469+}
470+
471+static int thermal_genl_cmd_tz_get_gov(struct param *p)
472+{
473+ struct sk_buff *msg = p->msg;
474+ struct thermal_zone_device *tz;
475+ int id, ret = 0;
476+
477+ if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID])
478+ return -EINVAL;
479+
480+ id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]);
481+
482+ tz = thermal_zone_get_by_id(id);
483+ if (!tz)
484+ return -EINVAL;
485+
486+ mutex_lock(&tz->lock);
487+
488+ if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_ID, id) ||
489+ nla_put_string(msg, THERMAL_GENL_ATTR_TZ_GOV_NAME,
490+ tz->governor->name))
491+ ret = -EMSGSIZE;
492+
493+ mutex_unlock(&tz->lock);
494+
495+ return ret;
496+}
497+
498+static int __thermal_genl_cmd_cdev_get(struct thermal_cooling_device *cdev,
499+ void *data)
500+{
501+ struct sk_buff *msg = data;
502+
503+ if (nla_put_u32(msg, THERMAL_GENL_ATTR_CDEV_ID, cdev->id))
504+ return -EMSGSIZE;
505+
506+ if (nla_put_string(msg, THERMAL_GENL_ATTR_CDEV_NAME, cdev->type))
507+ return -EMSGSIZE;
508+
509+ return 0;
510+}
511+
512+static int thermal_genl_cmd_cdev_get(struct param *p)
513+{
514+ struct sk_buff *msg = p->msg;
515+ struct nlattr *start_cdev;
516+ int ret;
517+
518+ start_cdev = nla_nest_start(msg, THERMAL_GENL_ATTR_CDEV);
519+ if (!start_cdev)
520+ return -EMSGSIZE;
521+
522+ ret = for_each_thermal_cooling_device(__thermal_genl_cmd_cdev_get, msg);
523+ if (ret)
524+ goto out_cancel_nest;
525+
526+ nla_nest_end(msg, start_cdev);
527+
528+ return 0;
529+out_cancel_nest:
530+ nla_nest_cancel(msg, start_cdev);
531+
532+ return ret;
533+}
534+
535+static cb_t cmd_cb[] = {
536+ [THERMAL_GENL_CMD_TZ_GET_ID] = thermal_genl_cmd_tz_get_id,
537+ [THERMAL_GENL_CMD_TZ_GET_TRIP] = thermal_genl_cmd_tz_get_trip,
538+ [THERMAL_GENL_CMD_TZ_GET_TEMP] = thermal_genl_cmd_tz_get_temp,
539+ [THERMAL_GENL_CMD_TZ_GET_GOV] = thermal_genl_cmd_tz_get_gov,
540+ [THERMAL_GENL_CMD_CDEV_GET] = thermal_genl_cmd_cdev_get,
541+};
542+
543+static int thermal_genl_cmd_dumpit(struct sk_buff *skb,
544+ struct netlink_callback *cb)
545+{
546+ struct param p = { .msg = skb };
547+ const struct genl_dumpit_info *info = genl_dumpit_info(cb);
548+ int cmd = info->ops->cmd;
549+ int ret;
550+ void *hdr;
551+
552+ hdr = genlmsg_put(skb, 0, 0, &thermal_gnl_family, 0, cmd);
553+ if (!hdr)
554+ return -EMSGSIZE;
555+
556+ ret = cmd_cb[cmd](&p);
557+ if (ret)
558+ goto out_cancel_msg;
559+
560+ genlmsg_end(skb, hdr);
561+
562+ return 0;
563+
564+out_cancel_msg:
565+ genlmsg_cancel(skb, hdr);
566+
567+ return ret;
568+}
569+
570+static int thermal_genl_cmd_doit(struct sk_buff *skb,
571+ struct genl_info *info)
572+{
573+ struct param p = { .attrs = info->attrs };
574+ struct sk_buff *msg;
575+ void *hdr;
576+ int cmd = info->genlhdr->cmd;
577+ int ret = -EMSGSIZE;
578+
579+ msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
580+ if (!msg)
581+ return -ENOMEM;
582+ p.msg = msg;
583+
584+ hdr = genlmsg_put_reply(msg, info, &thermal_gnl_family, 0, cmd);
585+ if (!hdr)
586+ goto out_free_msg;
587+
588+ ret = cmd_cb[cmd](&p);
589+ if (ret)
590+ goto out_cancel_msg;
591+
592+ genlmsg_end(msg, hdr);
593+
594+ return genlmsg_reply(msg, info);
595+
596+out_cancel_msg:
597+ genlmsg_cancel(msg, hdr);
598+out_free_msg:
599+ nlmsg_free(msg);
600+
601+ return ret;
602+}
603+
604+static const struct genl_ops thermal_genl_ops[] = {
605+ {
606+ .cmd = THERMAL_GENL_CMD_TZ_GET_ID,
607+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
608+ .dumpit = thermal_genl_cmd_dumpit,
609+ },
610+ {
611+ .cmd = THERMAL_GENL_CMD_TZ_GET_TRIP,
612+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
613+ .doit = thermal_genl_cmd_doit,
614+ },
615+ {
616+ .cmd = THERMAL_GENL_CMD_TZ_GET_TEMP,
617+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
618+ .doit = thermal_genl_cmd_doit,
619+ },
620+ {
621+ .cmd = THERMAL_GENL_CMD_TZ_GET_GOV,
622+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
623+ .doit = thermal_genl_cmd_doit,
624+ },
625+ {
626+ .cmd = THERMAL_GENL_CMD_CDEV_GET,
627+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
628+ .dumpit = thermal_genl_cmd_dumpit,
629+ },
630+};
631+
632+static struct genl_family thermal_gnl_family __ro_after_init = {
633+ .hdrsize = 0,
634+ .name = THERMAL_GENL_FAMILY_NAME,
635+ .version = THERMAL_GENL_VERSION,
636+ .maxattr = THERMAL_GENL_ATTR_MAX,
637+ .policy = thermal_genl_policy,
638+ .ops = thermal_genl_ops,
639+ .n_ops = ARRAY_SIZE(thermal_genl_ops),
640+ .mcgrps = thermal_genl_mcgrps,
641+ .n_mcgrps = ARRAY_SIZE(thermal_genl_mcgrps),
642+};
643+
644+int __init thermal_netlink_init(void)
645+{
646+ return genl_register_family(&thermal_gnl_family);
647+}
drivers/thermal/thermal_netlink.h+104−0
@@ -0,0 +1,104 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * Copyright (C) Linaro Ltd 2020
4+ * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
5+ */
6+
7+/* Netlink notification function */
8+#ifdef CONFIG_THERMAL_NETLINK
9+int __init thermal_netlink_init(void);
10+int thermal_notify_tz_create(int tz_id, const char *name);
11+int thermal_notify_tz_delete(int tz_id);
12+int thermal_notify_tz_enable(int tz_id);
13+int thermal_notify_tz_disable(int tz_id);
14+int thermal_notify_tz_trip_down(int tz_id, int id);
15+int thermal_notify_tz_trip_up(int tz_id, int id);
16+int thermal_notify_tz_trip_delete(int tz_id, int id);
17+int thermal_notify_tz_trip_add(int tz_id, int id, int type,
18+ int temp, int hyst);
19+int thermal_notify_tz_trip_change(int tz_id, int id, int type,
20+ int temp, int hyst);
21+int thermal_notify_cdev_state_update(int cdev_id, int state);
22+int thermal_notify_cdev_add(int cdev_id, const char *name, int max_state);
23+int thermal_notify_cdev_delete(int cdev_id);
24+int thermal_notify_tz_gov_change(int tz_id, const char *name);
25+int thermal_genl_sampling_temp(int id, int temp);
26+#else
27+static inline int thermal_netlink_init(void)
28+{
29+ return 0;
30+}
31+
32+static inline int thermal_notify_tz_create(int tz_id, const char *name)
33+{
34+ return 0;
35+}
36+
37+static inline int thermal_notify_tz_delete(int tz_id)
38+{
39+ return 0;
40+}
41+
42+static inline int thermal_notify_tz_enable(int tz_id)
43+{
44+ return 0;
45+}
46+
47+static inline int thermal_notify_tz_disable(int tz_id)
48+{
49+ return 0;
50+}
51+
52+static inline int thermal_notify_tz_trip_down(int tz_id, int id)
53+{
54+ return 0;
55+}
56+
57+static inline int thermal_notify_tz_trip_up(int tz_id, int id)
58+{
59+ return 0;
60+}
61+
62+static inline int thermal_notify_tz_trip_delete(int tz_id, int id)
63+{
64+ return 0;
65+}
66+
67+static inline int thermal_notify_tz_trip_add(int tz_id, int id, int type,
68+ int temp, int hyst)
69+{
70+ return 0;
71+}
72+
73+static inline int thermal_notify_tz_trip_change(int tz_id, int id, int type,
74+ int temp, int hyst)
75+{
76+ return 0;
77+}
78+
79+static inline int thermal_notify_cdev_state_update(int cdev_id, int state)
80+{
81+ return 0;
82+}
83+
84+static inline int thermal_notify_cdev_add(int cdev_id, const char *name,
85+ int max_state)
86+{
87+ return 0;
88+}
89+
90+static inline int thermal_notify_cdev_delete(int cdev_id)
91+{
92+ return 0;
93+}
94+
95+static inline int thermal_notify_tz_gov_change(int tz_id, const char *name)
96+{
97+ return 0;
98+}
99+
100+static inline int thermal_genl_sampling_temp(int id, int temp)
101+{
102+ return 0;
103+}
104+#endif /* CONFIG_THERMAL_NETLINK */
drivers/thermal/thermal_of.c+1−40
@@ -51,7 +51,6 @@ struct __thermal_bind_params { · 50 unmodified lines
5151
5252 /**
5353 * struct __thermal_zone - internal representation of a thermal zone
54− * @mode: current thermal zone device mode (enabled/disabled)
5554 * @passive_delay: polling interval while passive cooling is activated
5655 * @polling_delay: zone polling interval
5756 * @slope: slope of the temperature adjustment curve
@@ -65,7 +64,6 @@ struct __thermal_bind_params { · 7 unmodified lines
6564 */
6665
6766 struct __thermal_zone {
68− enum thermal_device_mode mode;
6967 int passive_delay;
7068 int polling_delay;
7169 int slope;
@@ -269,39 +267,6 @@ static int of_thermal_unbind(struct thermal_zone_device *thermal, · 197 unmodified lines
269267 return 0;
270268 }
271269
272−static int of_thermal_get_mode(struct thermal_zone_device *tz,
273− enum thermal_device_mode *mode)
274−{
275− struct __thermal_zone *data = tz->devdata;
276−
277− *mode = data->mode;
278−
279− return 0;
280−}
281−
282−static int of_thermal_set_mode(struct thermal_zone_device *tz,
283− enum thermal_device_mode mode)
284−{
285− struct __thermal_zone *data = tz->devdata;
286−
287− mutex_lock(&tz->lock);
288−
289− if (mode == THERMAL_DEVICE_ENABLED) {
290− tz->polling_delay = data->polling_delay;
291− tz->passive_delay = data->passive_delay;
292− } else {
293− tz->polling_delay = 0;
294− tz->passive_delay = 0;
295− }
296−
297− mutex_unlock(&tz->lock);
298−
299− data->mode = mode;
300− thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
301−
302− return 0;
303−}
304−
305270 static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
306271 enum thermal_trip_type *type)
307272 {
@@ -393,9 +358,6 @@ static int of_thermal_get_crit_temp(struct thermal_zone_device *tz, · 85 unmodified lines
393358 }
394359
395360 static struct thermal_zone_device_ops of_thermal_ops = {
396− .get_mode = of_thermal_get_mode,
397− .set_mode = of_thermal_set_mode,
398−
399361 .get_trip_type = of_thermal_get_trip_type,
400362 .get_trip_temp = of_thermal_get_trip_temp,
401363 .set_trip_temp = of_thermal_set_trip_temp,
@@ -554,7 +516,7 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data, · 152 unmodified lines
554516 tzd = thermal_zone_of_add_sensor(child, sensor_np,
555517 data, ops);
556518 if (!IS_ERR(tzd))
557− tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED);
519+ thermal_zone_device_enable(tzd);
558520
559521 of_node_put(child);
560522 goto exit;
@@ -979,7 +941,6 @@ __init *thermal_of_build_thermal_zone(struct device_node *np) · 418 unmodified lines
979941
980942 finish:
981943 of_node_put(child);
982− tz->mode = THERMAL_DEVICE_DISABLED;
983944
984945 return tz;
985946
drivers/thermal/thermal_sysfs.c+18−34
@@ -49,18 +49,9 @@ static ssize_t · 48 unmodified lines
4949 mode_show(struct device *dev, struct device_attribute *attr, char *buf)
5050 {
5151 struct thermal_zone_device *tz = to_thermal_zone(dev);
52− enum thermal_device_mode mode;
53− int result;
54−
55− if (!tz->ops->get_mode)
56− return -EPERM;
52+ int enabled = thermal_zone_device_is_enabled(tz);
5753
58− result = tz->ops->get_mode(tz, &mode);
59− if (result)
60− return result;
61−
62− return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
63− : "disabled");
54+ return sprintf(buf, "%s\n", enabled ? "enabled" : "disabled");
6455 }
6556
6657 static ssize_t
@@ -70,13 +61,10 @@ mode_store(struct device *dev, struct device_attribute *attr, · 3 unmodified lines
7061 struct thermal_zone_device *tz = to_thermal_zone(dev);
7162 int result;
7263
73− if (!tz->ops->set_mode)
74− return -EPERM;
75−
7664 if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
77− result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
65+ result = thermal_zone_device_enable(tz);
7866 else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
79− result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
67+ result = thermal_zone_device_disable(tz);
8068 else
8169 result = -EINVAL;
8270
@@ -124,7 +112,8 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, · 41 unmodified lines
124112 {
125113 struct thermal_zone_device *tz = to_thermal_zone(dev);
126114 int trip, ret;
127− int temperature;
115+ int temperature, hyst = 0;
116+ enum thermal_trip_type type;
128117
129118 if (!tz->ops->set_trip_temp)
130119 return -EPERM;
@@ -139,6 +128,18 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, · 8 unmodified lines
139128 if (ret)
140129 return ret;
141130
131+ if (tz->ops->get_trip_hyst) {
132+ ret = tz->ops->get_trip_hyst(tz, trip, &hyst);
133+ if (ret)
134+ return ret;
135+ }
136+
137+ ret = tz->ops->get_trip_type(tz, trip, &type);
138+ if (ret)
139+ return ret;
140+
141+ thermal_notify_tz_trip_change(tz->id, trip, type, temperature, hyst);
142+
142143 thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
143144
144145 return count;
@@ -428,30 +429,13 @@ static struct attribute_group thermal_zone_attribute_group = { · 283 unmodified lines
428429 .attrs = thermal_zone_dev_attrs,
429430 };
430431
431−/* We expose mode only if .get_mode is present */
432432 static struct attribute *thermal_zone_mode_attrs[] = {
433433 &dev_attr_mode.attr,
434434 NULL,
435435 };
436436
437−static umode_t thermal_zone_mode_is_visible(struct kobject *kobj,
438− struct attribute *attr,
439− int attrno)
440−{
441− struct device *dev = container_of(kobj, struct device, kobj);
442− struct thermal_zone_device *tz;
443−
444− tz = container_of(dev, struct thermal_zone_device, device);
445−
446− if (tz->ops->get_mode)
447− return attr->mode;
448−
449− return 0;
450−}
451−
452437 static struct attribute_group thermal_zone_mode_attribute_group = {
453438 .attrs = thermal_zone_mode_attrs,
454− .is_visible = thermal_zone_mode_is_visible,
455439 };
456440
457441 /* We expose passive only if passive trips are present */
drivers/thermal/ti-soc-thermal/ti-thermal-common.c+1−1
@@ -169,7 +169,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, · 168 unmodified lines
169169
170170 data = ti_bandgap_get_sensor_data(bgp, id);
171171
172− if (!IS_ERR_OR_NULL(data))
172+ if (IS_ERR_OR_NULL(data))
173173 data = ti_thermal_build_data(bgp, id);
174174
175175 if (!data)
include/linux/clock_cooling.h+0−57
@@ -1,57 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0-only */
2−/*
3− * linux/include/linux/clock_cooling.h
4− *
5− * Copyright (C) 2014 Eduardo Valentin <edubezval@gmail.com>
6− *
7− * Copyright (C) 2013 Texas Instruments Inc.
8− * Contact: Eduardo Valentin <eduardo.valentin@ti.com>
9− *
10− * Highly based on cpufreq_cooling.c.
11− * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
12− * Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
13− */
14−
15−#ifndef __CPU_COOLING_H__
16−#define __CPU_COOLING_H__
17−
18−#include <linux/of.h>
19−#include <linux/thermal.h>
20−#include <linux/cpumask.h>
21−
22−#ifdef CONFIG_CLOCK_THERMAL
23−/**
24− * clock_cooling_register - function to create clock cooling device.
25− * @dev: struct device pointer to the device used as clock cooling device.
26− * @clock_name: string containing the clock used as cooling mechanism.
27− */
28−struct thermal_cooling_device *
29−clock_cooling_register(struct device *dev, const char *clock_name);
30−
31−/**
32− * clock_cooling_unregister - function to remove clock cooling device.
33− * @cdev: thermal cooling device pointer.
34− */
35−void clock_cooling_unregister(struct thermal_cooling_device *cdev);
36−
37−unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev,
38− unsigned long freq);
39−#else /* !CONFIG_CLOCK_THERMAL */
40−static inline struct thermal_cooling_device *
41−clock_cooling_register(struct device *dev, const char *clock_name)
42−{
43− return NULL;
44−}
45−static inline
46−void clock_cooling_unregister(struct thermal_cooling_device *cdev)
47−{
48−}
49−static inline
50−unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev,
51− unsigned long freq)
52−{
53− return THERMAL_CSTATE_INVALID;
54−}
55−#endif /* CONFIG_CLOCK_THERMAL */
56−
57−#endif /* __CPU_COOLING_H__ */
include/linux/devfreq_cooling.h+1−8
@@ -1,17 +1,10 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
12 /*
23 * devfreq_cooling: Thermal cooling device implementation for devices using
34 * devfreq
45 *
56 * Copyright (C) 2014-2015 ARM Limited
67 *
7− * This program is free software; you can redistribute it and/or modify
8− * it under the terms of the GNU General Public License version 2 as
9− * published by the Free Software Foundation.
10− *
11− * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12− * kind, whether express or implied; without even the implied warranty
13− * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
158 */
169
1710 #ifndef __DEVFREQ_COOLING_H__
include/linux/thermal.h+11−20
@@ -37,18 +37,6 @@ struct thermal_cooling_device; · 36 unmodified lines
3737 struct thermal_instance;
3838 struct thermal_attr;
3939
40−enum thermal_device_mode {
41− THERMAL_DEVICE_DISABLED = 0,
42− THERMAL_DEVICE_ENABLED,
43−};
44−
45−enum thermal_trip_type {
46− THERMAL_TRIP_ACTIVE = 0,
47− THERMAL_TRIP_PASSIVE,
48− THERMAL_TRIP_HOT,
49− THERMAL_TRIP_CRITICAL,
50−};
51−
5240 enum thermal_trend {
5341 THERMAL_TREND_STABLE, /* temperature is stable */
5442 THERMAL_TREND_RAISING, /* temperature is raising */
@@ -76,9 +64,7 @@ struct thermal_zone_device_ops { · 21 unmodified lines
7664 struct thermal_cooling_device *);
7765 int (*get_temp) (struct thermal_zone_device *, int *);
7866 int (*set_trips) (struct thermal_zone_device *, int, int);
79− int (*get_mode) (struct thermal_zone_device *,
80− enum thermal_device_mode *);
81− int (*set_mode) (struct thermal_zone_device *,
67+ int (*change_mode) (struct thermal_zone_device *,
8268 enum thermal_device_mode);
8369 int (*get_trip_type) (struct thermal_zone_device *, int,
8470 enum thermal_trip_type *);
@@ -128,6 +114,7 @@ struct thermal_cooling_device { · 43 unmodified lines
128114 * @trip_temp_attrs: attributes for trip points for sysfs: trip temperature
129115 * @trip_type_attrs: attributes for trip points for sysfs: trip type
130116 * @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis
117+ * @mode: current mode of this thermal zone
131118 * @devdata: private pointer for device private data
132119 * @trips: number of trip points the thermal zone supports
133120 * @trips_disabled; bitmap for disabled trips
@@ -170,6 +157,7 @@ struct thermal_zone_device { · 36 unmodified lines
170157 struct thermal_attr *trip_temp_attrs;
171158 struct thermal_attr *trip_type_attrs;
172159 struct thermal_attr *trip_hyst_attrs;
160+ enum thermal_device_mode mode;
173161 void *devdata;
174162 int trips;
175163 unsigned long trips_disabled; /* bitmap for disabled trips */
@@ -303,11 +291,6 @@ struct thermal_zone_params { · 127 unmodified lines
303291 int offset;
304292 };
305293
306−struct thermal_genl_event {
307− u32 orig;
308− enum events event;
309−};
310−
311294 /**
312295 * struct thermal_zone_of_device_ops - scallbacks for handling DT based zones
313296 *
@@ -416,6 +399,8 @@ int thermal_zone_get_offset(struct thermal_zone_device *tz); · 102 unmodified lines
416399
417400 void thermal_cdev_update(struct thermal_cooling_device *);
418401 void thermal_notify_framework(struct thermal_zone_device *, int);
402+int thermal_zone_device_enable(struct thermal_zone_device *tz);
403+int thermal_zone_device_disable(struct thermal_zone_device *tz);
419404 #else
420405 static inline struct thermal_zone_device *thermal_zone_device_register(
421406 const char *type, int trips, int mask, void *devdata,
@@ -463,6 +448,12 @@ static inline void thermal_cdev_update(struct thermal_cooling_device *cdev) · 41 unmodified lines
463448 static inline void thermal_notify_framework(struct thermal_zone_device *tz,
464449 int trip)
465450 { }
451+
452+static inline int thermal_zone_device_enable(struct thermal_zone_device *tz)
453+{ return -ENODEV; }
454+
455+static inline int thermal_zone_device_disable(struct thermal_zone_device *tz)
456+{ return -ENODEV; }
466457 #endif /* CONFIG_THERMAL */
467458
468459 #endif /* __THERMAL_H__ */
include/uapi/linux/thermal.h+72−17
@@ -4,31 +4,86 @@ · 3 unmodified lines
44
55 #define THERMAL_NAME_LENGTH 20
66
7−/* Adding event notification support elements */
8−#define THERMAL_GENL_FAMILY_NAME "thermal_event"
9−#define THERMAL_GENL_VERSION 0x01
10−#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_grp"
11−
12−/* Events supported by Thermal Netlink */
13−enum events {
14− THERMAL_AUX0,
15− THERMAL_AUX1,
16− THERMAL_CRITICAL,
17− THERMAL_DEV_FAULT,
7+enum thermal_device_mode {
8+ THERMAL_DEVICE_DISABLED = 0,
9+ THERMAL_DEVICE_ENABLED,
10+};
11+
12+enum thermal_trip_type {
13+ THERMAL_TRIP_ACTIVE = 0,
14+ THERMAL_TRIP_PASSIVE,
15+ THERMAL_TRIP_HOT,
16+ THERMAL_TRIP_CRITICAL,
1817 };
1918
20−/* attributes of thermal_genl_family */
21−enum {
19+/* Adding event notification support elements */
20+#define THERMAL_GENL_FAMILY_NAME "thermal"
21+#define THERMAL_GENL_VERSION 0x01
22+#define THERMAL_GENL_SAMPLING_GROUP_NAME "sampling"
23+#define THERMAL_GENL_EVENT_GROUP_NAME "event"
24+
25+/* Attributes of thermal_genl_family */
26+enum thermal_genl_attr {
2227 THERMAL_GENL_ATTR_UNSPEC,
23− THERMAL_GENL_ATTR_EVENT,
28+ THERMAL_GENL_ATTR_TZ,
29+ THERMAL_GENL_ATTR_TZ_ID,
30+ THERMAL_GENL_ATTR_TZ_TEMP,
31+ THERMAL_GENL_ATTR_TZ_TRIP,
32+ THERMAL_GENL_ATTR_TZ_TRIP_ID,
33+ THERMAL_GENL_ATTR_TZ_TRIP_TYPE,
34+ THERMAL_GENL_ATTR_TZ_TRIP_TEMP,
35+ THERMAL_GENL_ATTR_TZ_TRIP_HYST,
36+ THERMAL_GENL_ATTR_TZ_MODE,
37+ THERMAL_GENL_ATTR_TZ_NAME,
38+ THERMAL_GENL_ATTR_TZ_CDEV_WEIGHT,
39+ THERMAL_GENL_ATTR_TZ_GOV,
40+ THERMAL_GENL_ATTR_TZ_GOV_NAME,
41+ THERMAL_GENL_ATTR_CDEV,
42+ THERMAL_GENL_ATTR_CDEV_ID,
43+ THERMAL_GENL_ATTR_CDEV_CUR_STATE,
44+ THERMAL_GENL_ATTR_CDEV_MAX_STATE,
45+ THERMAL_GENL_ATTR_CDEV_NAME,
46+ THERMAL_GENL_ATTR_GOV_NAME,
47+
2448 __THERMAL_GENL_ATTR_MAX,
2549 };
2650 #define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1)
2751
28−/* commands supported by the thermal_genl_family */
29−enum {
52+enum thermal_genl_sampling {
53+ THERMAL_GENL_SAMPLING_TEMP,
54+ __THERMAL_GENL_SAMPLING_MAX,
55+};
56+#define THERMAL_GENL_SAMPLING_MAX (__THERMAL_GENL_SAMPLING_MAX - 1)
57+
58+/* Events of thermal_genl_family */
59+enum thermal_genl_event {
60+ THERMAL_GENL_EVENT_UNSPEC,
61+ THERMAL_GENL_EVENT_TZ_CREATE, /* Thermal zone creation */
62+ THERMAL_GENL_EVENT_TZ_DELETE, /* Thermal zone deletion */
63+ THERMAL_GENL_EVENT_TZ_DISABLE, /* Thermal zone disabed */
64+ THERMAL_GENL_EVENT_TZ_ENABLE, /* Thermal zone enabled */
65+ THERMAL_GENL_EVENT_TZ_TRIP_UP, /* Trip point crossed the way up */
66+ THERMAL_GENL_EVENT_TZ_TRIP_DOWN, /* Trip point crossed the way down */
67+ THERMAL_GENL_EVENT_TZ_TRIP_CHANGE, /* Trip point changed */
68+ THERMAL_GENL_EVENT_TZ_TRIP_ADD, /* Trip point added */
69+ THERMAL_GENL_EVENT_TZ_TRIP_DELETE, /* Trip point deleted */
70+ THERMAL_GENL_EVENT_CDEV_ADD, /* Cdev bound to the thermal zone */
71+ THERMAL_GENL_EVENT_CDEV_DELETE, /* Cdev unbound */
72+ THERMAL_GENL_EVENT_CDEV_STATE_UPDATE, /* Cdev state updated */
73+ THERMAL_GENL_EVENT_TZ_GOV_CHANGE, /* Governor policy changed */
74+ __THERMAL_GENL_EVENT_MAX,
75+};
76+#define THERMAL_GENL_EVENT_MAX (__THERMAL_GENL_EVENT_MAX - 1)
77+
78+/* Commands supported by the thermal_genl_family */
79+enum thermal_genl_cmd {
3080 THERMAL_GENL_CMD_UNSPEC,
31− THERMAL_GENL_CMD_EVENT,
81+ THERMAL_GENL_CMD_TZ_GET_ID, /* List of thermal zones id */
82+ THERMAL_GENL_CMD_TZ_GET_TRIP, /* List of thermal trips */
83+ THERMAL_GENL_CMD_TZ_GET_TEMP, /* Get the thermal zone temperature */
84+ THERMAL_GENL_CMD_TZ_GET_GOV, /* Get the thermal zone governor */
85+ THERMAL_GENL_CMD_TZ_GET_MODE, /* Get the thermal zone mode */
86+ THERMAL_GENL_CMD_CDEV_GET, /* List of cdev id */
3287 __THERMAL_GENL_CMD_MAX,
3388 };
3489 #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
net/netlink/genetlink.c+1−1
@@ -1192,7 +1192,7 @@ problem: · 1191 unmodified lines
11921192 panic("GENL: Cannot register controller: %d\n", err);
11931193 }
11941194
1195−subsys_initcall(genl_init);
1195+core_initcall(genl_init);
11961196
11971197 static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
11981198 gfp_t flags)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t