History

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

Pull thermal updates from Daniel Lezcano: - Remove duplicate error message for the amlogic driver (Tang Bin) - Fix spellos in comments for the tegra and sun8i (Bhaskar Chowdhury) - Add the missing fifth node on the rcar_gen3 sensor (Niklas Söderlund) - Remove duplicate include in ti-bandgap (Zhang Yunkai) - Assign error code in the error path in the function thermal_of_populate_bind_params() (Jia-Ju Bai) - Fix spelling mistake in a comment 'disabed' -> 'disabled' (Colin Ian King) - Use the device name instead of auto-numbering for a better identification of the cooling device (Daniel Lezcano) - Improve a bit the division accuracy in the power allocator governor (Jeson Gao) - Enable the missing third sensor on msm8976 (Konrad Dybcio) - Add QCom tsens driver co-maintainer (Thara Gopinath) - Fix memory leak and use after free errors in the core code (Daniel Lezcano) - Add the MDM9607 compatible bindings (Konrad Dybcio) - Fix trivial spello in the copyright name for Hisilicon (Hao Fang) - Fix negative index array access when converting the frequency to power in the energy model (Brian-sy Yang) - Add support for Gen2 new PMIC support for Qcom SPMI (David Collins) - Update maintainer file for CPU cooling device section (Lukasz Luba) - Fix missing put_device on error in the Qcom tsens driver (Guangqing Zhu) - Add compatible DT binding for sm8350 (Robert Foss) - Add support for the MDM9607's tsens driver (Konrad Dybcio) - Remove duplicate error messages in thermal_mmio and the bcm2835 driver (Ruiqi Gong) - Add the Thermal Temperature Cooling driver (Zhang Rui) - Remove duplicate error messages in the Hisilicon sensor driver (Ye Bin) - Use the devm_platform_ioremap_resource_byname() function instead of a couple of corresponding calls (dingsenjie) - Sort the headers alphabetically in the ti-bandgap driver (Zhen Lei) - Add missing property in the DT thermal sensor binding (Rafał Miłecki) - Remove dead code in the ti-bandgap sensor driver (Lin Ruizhe) - Convert the BRCM DT bindings to the yaml schema (Rafał Miłecki) - Replace the thermal_notify_framework() call by a call to the thermal_zone_device_update() function. Remove the function as well as the corresponding documentation (Thara Gopinath) - Add support for the ipq8064-tsens sensor along with a set of cleanups and code preparation (Ansuel Smith) - Add a lockless __thermal_cdev_update() function to improve the locking scheme in the core code and governors (Lukasz Luba) - Fix multiple cooling device notification changes (Lukasz Luba) - Remove unneeded variable initialization (Colin Ian King) * tag 'thermal-v5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux: (55 commits) thermal/drivers/mtk_thermal: Remove redundant initializations of several variables thermal/core/power allocator: Use the lockless __thermal_cdev_update() function thermal/core/fair share: Use the lockless __thermal_cdev_update() function thermal/core/fair share: Lock the thermal zone while looping over instances thermal/core/power_allocator: Update once cooling devices when temp is low thermal/core/power_allocator: Maintain the device statistics from going stale thermal/core: Create a helper __thermal_cdev_update() without a lock dt-bindings: thermal: tsens: Document ipq8064 bindings thermal/drivers/tsens: Add support for ipq8064-tsens thermal/drivers/tsens: Drop unused define for msm8960 thermal/drivers/tsens: Replace custom 8960 apis with generic apis thermal/drivers/tsens: Fix bug in sensor enable for msm8960 thermal/drivers/tsens: Use init_common for msm8960 thermal/drivers/tsens: Add VER_0 tsens version thermal/drivers/tsens: Convert msm8960 to reg_field thermal/drivers/tsens: Don't hardcode sensor slope Documentation: driver-api: thermal: Remove thermal_notify_framework from documentation thermal/core: Remove thermal_notify_framework iwlwifi: mvm: tt: Replace thermal_notify_framework dt-bindings: thermal: brcm,ns-thermal: Convert to the json-schema ...

Linus Torvalds committed 5 years ago

Commit 583f2bc2 parents 5d6a1b8 c310e5438 files · +863 −446Browse files

Unified · Split

38 files
  1. Documentation/devicetree/bindings/thermal/brcm,ns-thermal.txt +0 −37
  2. Documentation/devicetree/bindings/thermal/brcm,ns-thermal.yaml +60 −0
  3. Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +51 −8
  4. Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml +35 −8
  5. Documentation/devicetree/bindings/thermal/thermal-sensor.yaml +3 −0
  6. Documentation/driver-api/thermal/sysfs-api.rst +1 −11
  7. MAINTAINERS +2 −1
  8. drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +1 −1
  9. drivers/net/wireless/intel/iwlwifi/mvm/tt.c +2 −2
  10. drivers/thermal/amlogic_thermal.c +1 −3
  11. drivers/thermal/broadcom/bcm2835_thermal.c +0 −1
  12. drivers/thermal/cpufreq_cooling.c +13 −36
  13. drivers/thermal/cpuidle_cooling.c +19 −18
  14. drivers/thermal/devfreq_cooling.c +8 −17
  15. drivers/thermal/gov_fair_share.c +7 −4
  16. drivers/thermal/gov_power_allocator.c +23 −9
  17. drivers/thermal/hisi_thermal.c +4 −6
  18. drivers/thermal/intel/Kconfig +11 −0
  19. drivers/thermal/intel/Makefile +1 −0
  20. drivers/thermal/intel/intel_tcc_cooling.c +129 −0
  21. drivers/thermal/mtk_thermal.c +6 −6
  22. drivers/thermal/qcom/qcom-spmi-temp-alarm.c +61 −30
  23. drivers/thermal/qcom/tsens-8960.c +116 −119
  24. drivers/thermal/qcom/tsens-v0_1.c +97 −1
  25. drivers/thermal/qcom/tsens-v1.c +2 −2
  26. drivers/thermal/qcom/tsens.c +133 −32
  27. drivers/thermal/qcom/tsens.h +4 −2
  28. drivers/thermal/rcar_gen3_thermal.c +2 −1
  29. drivers/thermal/sun8i_thermal.c +2 −2
  30. drivers/thermal/tegra/soctherm.c +4 −11
  31. drivers/thermal/thermal_core.c +23 −34
  32. drivers/thermal/thermal_core.h +1 −0
  33. drivers/thermal/thermal_helpers.c +17 −10
  34. drivers/thermal/thermal_mmio.c +1 −4
  35. drivers/thermal/thermal_of.c +5 −2
  36. drivers/thermal/ti-soc-thermal/ti-bandgap.c +16 −21
  37. include/linux/thermal.h +1 −6
  38. include/uapi/linux/thermal.h +1 −1
Documentation/devicetree/bindings/thermal/brcm,ns-thermal.txt+0−37
@@ -1,37 +0,0 @@
1* Broadcom Northstar Thermal
2
3This binding describes thermal sensor that is part of Northstar's DMU (Device
4Management Unit).
5
6Required properties:
7- compatible : Must be "brcm,ns-thermal"
8- reg : iomem address range of PVTMON registers
9- #thermal-sensor-cells : Should be <0>
10
11Example:
12
13thermal: thermal@1800c2c0 {
14 compatible = "brcm,ns-thermal";
15 reg = <0x1800c2c0 0x10>;
16 #thermal-sensor-cells = <0>;
17};
18
19thermal-zones {
20 cpu_thermal: cpu-thermal {
21 polling-delay-passive = <0>;
22 polling-delay = <1000>;
23 coefficients = <(-556) 418000>;
24 thermal-sensors = <&thermal>;
25
26 trips {
27 cpu-crit {
28 temperature = <125000>;
29 hysteresis = <0>;
30 type = "critical";
31 };
32 };
33
34 cooling-maps {
35 };
36 };
37};
Documentation/devicetree/bindings/thermal/brcm,ns-thermal.yaml+60−0
@@ -0,0 +1,60 @@
1# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/thermal/brcm,ns-thermal.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Broadcom Northstar Thermal
8
9maintainers:
10 - Rafał Miłecki <rafal@milecki.pl>
11
12description:
13 Thermal sensor that is part of Northstar's DMU (Device Management Unit).
14
15allOf:
16 - $ref: thermal-sensor.yaml#
17
18properties:
19 compatible:
20 const: brcm,ns-thermal
21
22 reg:
23 description: PVTMON registers range
24 maxItems: 1
25
26 "#thermal-sensor-cells":
27 const: 0
28
29unevaluatedProperties: false
30
31required:
32 - reg
33
34examples:
35 - |
36 thermal: thermal@1800c2c0 {
37 compatible = "brcm,ns-thermal";
38 reg = <0x1800c2c0 0x10>;
39 #thermal-sensor-cells = <0>;
40 };
41
42 thermal-zones {
43 cpu-thermal {
44 polling-delay-passive = <0>;
45 polling-delay = <1000>;
46 coefficients = <(-556) 418000>;
47 thermal-sensors = <&thermal>;
48
49 trips {
50 cpu-crit {
51 temperature = <125000>;
52 hysteresis = <0>;
53 type = "critical";
54 };
55 };
56
57 cooling-maps {
58 };
59 };
60 };
Documentation/devicetree/bindings/thermal/qcom-tsens.yaml+51−8
@@ -19,9 +19,15 @@ description: | · 18 unmodified lines
19properties:19properties:
20 compatible:20 compatible:
21 oneOf:21 oneOf:
22 - description: msm9860 TSENS based
23 items:
24 - enum:
25 - qcom,ipq8064-tsens
26
22 - description: v0.1 of TSENS27 - description: v0.1 of TSENS
23 items:28 items:
24 - enum:29 - enum:
30 - qcom,mdm9607-tsens
25 - qcom,msm8916-tsens31 - qcom,msm8916-tsens
26 - qcom,msm8939-tsens32 - qcom,msm8939-tsens
27 - qcom,msm8974-tsens33 - qcom,msm8974-tsens
@@ -43,6 +49,7 @@ properties: · 15 unmodified lines
43 - qcom,sdm845-tsens49 - qcom,sdm845-tsens
44 - qcom,sm8150-tsens50 - qcom,sm8150-tsens
45 - qcom,sm8250-tsens51 - qcom,sm8250-tsens
52 - qcom,sm8350-tsens
46 - const: qcom,tsens-v253 - const: qcom,tsens-v2
47 54
48 reg:55 reg:
@@ -73,7 +80,9 @@ properties: · 24 unmodified lines
73 maxItems: 280 maxItems: 2
74 items:81 items:
75 - const: calib82 - const: calib
76 - const: calib_sel83 - enum:
84 - calib_backup
85 - calib_sel
77 86
78 "#qcom,sensors":87 "#qcom,sensors":
79 description:88 description:
@@ -88,12 +97,21 @@ properties: · 8 unmodified lines
88 Number of cells required to uniquely identify the thermal sensors. Since97 Number of cells required to uniquely identify the thermal sensors. Since
89 we have multiple sensors this is set to 198 we have multiple sensors this is set to 1
90 99
100required:
101 - compatible
102 - interrupts
103 - interrupt-names
104 - "#thermal-sensor-cells"
105 - "#qcom,sensors"
106
91allOf:107allOf:
92 - if:108 - if:
93 properties:109 properties:
94 compatible:110 compatible:
95 contains:111 contains:
96 enum:112 enum:
113 - qcom,ipq8064-tsens
114 - qcom,mdm9607-tsens
97 - qcom,msm8916-tsens115 - qcom,msm8916-tsens
98 - qcom,msm8974-tsens116 - qcom,msm8974-tsens
99 - qcom,msm8976-tsens117 - qcom,msm8976-tsens
@@ -114,17 +132,42 @@ allOf: · 14 unmodified lines
114 interrupt-names:132 interrupt-names:
115 minItems: 2133 minItems: 2
116 134
117required:135 - if:
118 - compatible136 properties:
119 - reg137 compatible:
120 - "#qcom,sensors"138 contains:
121 - interrupts139 enum:
122 - interrupt-names140 - qcom,tsens-v0_1
123 - "#thermal-sensor-cells"141 - qcom,tsens-v1
142 - qcom,tsens-v2
143
144 then:
145 required:
146 - reg
124 147
125additionalProperties: false148additionalProperties: false
126 149
127examples:150examples:
151 - |
152 #include <dt-bindings/interrupt-controller/arm-gic.h>
153 // Example msm9860 based SoC (ipq8064):
154 gcc: clock-controller {
155
156 /* ... */
157
158 tsens: thermal-sensor {
159 compatible = "qcom,ipq8064-tsens";
160
161 nvmem-cells = <&tsens_calib>, <&tsens_calib_backup>;
162 nvmem-cell-names = "calib", "calib_backup";
163 interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
164 interrupt-names = "uplow";
165
166 #qcom,sensors = <11>;
167 #thermal-sensor-cells = <1>;
168 };
169 };
170
128 - |171 - |
129 #include <dt-bindings/interrupt-controller/arm-gic.h>172 #include <dt-bindings/interrupt-controller/arm-gic.h>
130 // Example 1 (legacy: for pre v1 IP):173 // Example 1 (legacy: for pre v1 IP):
Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml+35−8
@@ -28,14 +28,7 @@ properties: · 27 unmodified lines
28 - renesas,r8a77980-thermal # R-Car V3H28 - renesas,r8a77980-thermal # R-Car V3H
29 - renesas,r8a779a0-thermal # R-Car V3U29 - renesas,r8a779a0-thermal # R-Car V3U
30 30
31 reg:31 reg: true
32 minItems: 2
33 maxItems: 4
34 items:
35 - description: TSC1 registers
36 - description: TSC2 registers
37 - description: TSC3 registers
38 - description: TSC4 registers
39 32
40 interrupts:33 interrupts:
41 items:34 items:
@@ -71,8 +64,25 @@ if: · 29 unmodified lines
71 enum:64 enum:
72 - renesas,r8a779a0-thermal65 - renesas,r8a779a0-thermal
73then:66then:
67 properties:
68 reg:
69 minItems: 2
70 maxItems: 3
71 items:
72 - description: TSC1 registers
73 - description: TSC2 registers
74 - description: TSC3 registers
74 required:75 required:
75 - interrupts76 - interrupts
77else:
78 properties:
79 reg:
80 items:
81 - description: TSC0 registers
82 - description: TSC1 registers
83 - description: TSC2 registers
84 - description: TSC3 registers
85 - description: TSC4 registers
76 86
77additionalProperties: false87additionalProperties: false
78 88
@@ -111,3 +121,20 @@ examples: · 32 unmodified lines
111 };121 };
112 };122 };
113 };123 };
124 - |
125 #include <dt-bindings/clock/r8a779a0-cpg-mssr.h>
126 #include <dt-bindings/interrupt-controller/arm-gic.h>
127 #include <dt-bindings/power/r8a779a0-sysc.h>
128
129 tsc_r8a779a0: thermal@e6190000 {
130 compatible = "renesas,r8a779a0-thermal";
131 reg = <0xe6190000 0x200>,
132 <0xe6198000 0x200>,
133 <0xe61a0000 0x200>,
134 <0xe61a8000 0x200>,
135 <0xe61b0000 0x200>;
136 clocks = <&cpg CPG_MOD 919>;
137 power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
138 resets = <&cpg 919>;
139 #thermal-sensor-cells = <1>;
140 };
Documentation/devicetree/bindings/thermal/thermal-sensor.yaml+3−0
@@ -36,6 +36,9 @@ properties: · 35 unmodified lines
36 containing several internal sensors.36 containing several internal sensors.
37 enum: [0, 1]37 enum: [0, 1]
38 38
39required:
40 - "#thermal-sensor-cells"
41
39additionalProperties: true42additionalProperties: true
40 43
41examples:44examples:
Documentation/driver-api/thermal/sysfs-api.rst+1−11
@@ -730,17 +730,7 @@ This function returns the thermal_instance corresponding to a given · 729 unmodified lines
730{thermal_zone, cooling_device, trip_point} combination. Returns NULL730{thermal_zone, cooling_device, trip_point} combination. Returns NULL
731if such an instance does not exist.731if such an instance does not exist.
732 732
7334.3. thermal_notify_framework7334.3. thermal_cdev_update
734-----------------------------
735
736This function handles the trip events from sensor drivers. It starts
737throttling the cooling devices according to the policy configured.
738For CRITICAL and HOT trip points, this notifies the respective drivers,
739and does actual throttling for other trip points i.e ACTIVE and PASSIVE.
740The throttling policy is based on the configured platform data; if no
741platform data is provided, this uses the step_wise throttling policy.
742
7434.4. thermal_cdev_update
744------------------------734------------------------
745 735
746This function serves as an arbitrator to set the state of a cooling736This function serves as an arbitrator to set the state of a cooling
MAINTAINERS+2−1
@@ -15197,6 +15197,7 @@ F: include/linux/if_rmnet.h · 15196 unmodified lines
15197 15197
15198QUALCOMM TSENS THERMAL DRIVER15198QUALCOMM TSENS THERMAL DRIVER
15199M: Amit Kucheria <amitk@kernel.org>15199M: Amit Kucheria <amitk@kernel.org>
15200M: Thara Gopinath <thara.gopinath@linaro.org>
15200L: linux-pm@vger.kernel.org15201L: linux-pm@vger.kernel.org
15201L: linux-arm-msm@vger.kernel.org15202L: linux-arm-msm@vger.kernel.org
15202S: Maintained15203S: Maintained
@@ -18101,7 +18102,7 @@ THERMAL/CPU_COOLING · 2898 unmodified lines
18101M: Amit Daniel Kachhap <amit.kachhap@gmail.com>18102M: Amit Daniel Kachhap <amit.kachhap@gmail.com>
18102M: Daniel Lezcano <daniel.lezcano@linaro.org>18103M: Daniel Lezcano <daniel.lezcano@linaro.org>
18103M: Viresh Kumar <viresh.kumar@linaro.org>18104M: Viresh Kumar <viresh.kumar@linaro.org>
18104M: Javi Merino <javi.merino@kernel.org>18105R: Lukasz Luba <lukasz.luba@arm.com>
18105L: linux-pm@vger.kernel.org18106L: linux-pm@vger.kernel.org
18106S: Supported18107S: Supported
18107F: Documentation/driver-api/thermal/cpu-cooling-api.rst18108F: Documentation/driver-api/thermal/cpu-cooling-api.rst
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c+1−1
@@ -132,7 +132,7 @@ static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal, · 131 unmodified lines
132 /* Allow mlxsw thermal zone binding to an external cooling device */132 /* Allow mlxsw thermal zone binding to an external cooling device */
133 for (i = 0; i < ARRAY_SIZE(mlxsw_thermal_external_allowed_cdev); i++) {133 for (i = 0; i < ARRAY_SIZE(mlxsw_thermal_external_allowed_cdev); i++) {
134 if (strnstr(cdev->type, mlxsw_thermal_external_allowed_cdev[i],134 if (strnstr(cdev->type, mlxsw_thermal_external_allowed_cdev[i],
135 sizeof(cdev->type)))135 strlen(cdev->type)))
136 return 0;136 return 0;
137 }137 }
138 138
drivers/net/wireless/intel/iwlwifi/mvm/tt.c+2−2
@@ -146,8 +146,8 @@ void iwl_mvm_temp_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) · 145 unmodified lines
146 if (mvm->tz_device.tzone) {146 if (mvm->tz_device.tzone) {
147 struct iwl_mvm_thermal_device *tz_dev = &mvm->tz_device;147 struct iwl_mvm_thermal_device *tz_dev = &mvm->tz_device;
148 148
149 thermal_notify_framework(tz_dev->tzone,149 thermal_zone_device_update(tz_dev->tzone,
150 tz_dev->fw_trips_index[ths_crossed]);150 THERMAL_TRIP_VIOLATED);
151 }151 }
152#endif /* CONFIG_THERMAL */152#endif /* CONFIG_THERMAL */
153}153}
drivers/thermal/amlogic_thermal.c+1−3
@@ -254,10 +254,8 @@ static int amlogic_thermal_probe(struct platform_device *pdev) · 253 unmodified lines
254 platform_set_drvdata(pdev, pdata);254 platform_set_drvdata(pdev, pdata);
255 255
256 base = devm_platform_ioremap_resource(pdev, 0);256 base = devm_platform_ioremap_resource(pdev, 0);
257 if (IS_ERR(base)) {257 if (IS_ERR(base))
258 dev_err(dev, "failed to get io address\n");
259 return PTR_ERR(base);258 return PTR_ERR(base);
260 }
261 259
262 pdata->regmap = devm_regmap_init_mmio(dev, base,260 pdata->regmap = devm_regmap_init_mmio(dev, base,
263 pdata->data->regmap_config);261 pdata->data->regmap_config);
drivers/thermal/broadcom/bcm2835_thermal.c+0−1
@@ -184,7 +184,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) · 183 unmodified lines
184 data->regs = devm_ioremap_resource(&pdev->dev, res);184 data->regs = devm_ioremap_resource(&pdev->dev, res);
185 if (IS_ERR(data->regs)) {185 if (IS_ERR(data->regs)) {
186 err = PTR_ERR(data->regs);186 err = PTR_ERR(data->regs);
187 dev_err(&pdev->dev, "Could not get registers: %d\n", err);
188 return err;187 return err;
189 }188 }
190 189
drivers/thermal/cpufreq_cooling.c+13−36
@@ -13,10 +13,10 @@ · 12 unmodified lines
13#include <linux/cpu.h>13#include <linux/cpu.h>
14#include <linux/cpufreq.h>14#include <linux/cpufreq.h>
15#include <linux/cpu_cooling.h>15#include <linux/cpu_cooling.h>
16#include <linux/device.h>
16#include <linux/energy_model.h>17#include <linux/energy_model.h>
17#include <linux/err.h>18#include <linux/err.h>
18#include <linux/export.h>19#include <linux/export.h>
19#include <linux/idr.h>
20#include <linux/pm_opp.h>20#include <linux/pm_opp.h>
21#include <linux/pm_qos.h>21#include <linux/pm_qos.h>
22#include <linux/slab.h>22#include <linux/slab.h>
@@ -50,8 +50,6 @@ struct time_in_idle { · 27 unmodified lines
50 50
51/**51/**
52 * struct cpufreq_cooling_device - data for cooling device with cpufreq52 * struct cpufreq_cooling_device - data for cooling device with cpufreq
53 * @id: unique integer value corresponding to each cpufreq_cooling_device
54 * registered.
55 * @last_load: load measured by the latest call to cpufreq_get_requested_power()53 * @last_load: load measured by the latest call to cpufreq_get_requested_power()
56 * @cpufreq_state: integer value representing the current state of cpufreq54 * @cpufreq_state: integer value representing the current state of cpufreq
57 * cooling devices.55 * cooling devices.
@@ -61,7 +59,6 @@ struct time_in_idle { · 3 unmodified lines
61 * @cdev: thermal_cooling_device pointer to keep track of the59 * @cdev: thermal_cooling_device pointer to keep track of the
62 * registered cooling device.60 * registered cooling device.
63 * @policy: cpufreq policy.61 * @policy: cpufreq policy.
64 * @node: list_head to link all cpufreq_cooling_device together.
65 * @idle_time: idle time stats62 * @idle_time: idle time stats
66 * @qos_req: PM QoS contraint to apply63 * @qos_req: PM QoS contraint to apply
67 *64 *
@@ -69,23 +66,17 @@ struct time_in_idle { · 1 unmodified line
69 * cpufreq_cooling_device.66 * cpufreq_cooling_device.
70 */67 */
71struct cpufreq_cooling_device {68struct cpufreq_cooling_device {
72 int id;
73 u32 last_load;69 u32 last_load;
74 unsigned int cpufreq_state;70 unsigned int cpufreq_state;
75 unsigned int max_level;71 unsigned int max_level;
76 struct em_perf_domain *em;72 struct em_perf_domain *em;
77 struct cpufreq_policy *policy;73 struct cpufreq_policy *policy;
78 struct list_head node;
79#ifndef CONFIG_SMP74#ifndef CONFIG_SMP
80 struct time_in_idle *idle_time;75 struct time_in_idle *idle_time;
81#endif76#endif
82 struct freq_qos_request qos_req;77 struct freq_qos_request qos_req;
83};78};
84 79
85static DEFINE_IDA(cpufreq_ida);
86static DEFINE_MUTEX(cooling_list_lock);
87static LIST_HEAD(cpufreq_cdev_list);
88
89#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR80#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
90/**81/**
91 * get_level: Find the level for a particular frequency82 * get_level: Find the level for a particular frequency
@@ -125,7 +116,7 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev, · 33 unmodified lines
125{116{
126 int i;117 int i;
127 118
128 for (i = cpufreq_cdev->max_level; i >= 0; i--) {119 for (i = cpufreq_cdev->max_level; i > 0; i--) {
129 if (power >= cpufreq_cdev->em->table[i].power)120 if (power >= cpufreq_cdev->em->table[i].power)
130 break;121 break;
131 }122 }
@@ -528,11 +519,11 @@ __cpufreq_cooling_register(struct device_node *np, · 396 unmodified lines
528{519{
529 struct thermal_cooling_device *cdev;520 struct thermal_cooling_device *cdev;
530 struct cpufreq_cooling_device *cpufreq_cdev;521 struct cpufreq_cooling_device *cpufreq_cdev;
531 char dev_name[THERMAL_NAME_LENGTH];
532 unsigned int i;522 unsigned int i;
533 struct device *dev;523 struct device *dev;
534 int ret;524 int ret;
535 struct thermal_cooling_device_ops *cooling_ops;525 struct thermal_cooling_device_ops *cooling_ops;
526 char *name;
536 527
537 dev = get_cpu_device(policy->cpu);528 dev = get_cpu_device(policy->cpu);
538 if (unlikely(!dev)) {529 if (unlikely(!dev)) {
@@ -567,16 +558,6 @@ __cpufreq_cooling_register(struct device_node *np, · 28 unmodified lines
567 /* max_level is an index, not a counter */558 /* max_level is an index, not a counter */
568 cpufreq_cdev->max_level = i - 1;559 cpufreq_cdev->max_level = i - 1;
569 560
570 ret = ida_simple_get(&cpufreq_ida, 0, 0, GFP_KERNEL);
571 if (ret < 0) {
572 cdev = ERR_PTR(ret);
573 goto free_idle_time;
574 }
575 cpufreq_cdev->id = ret;
576
577 snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
578 cpufreq_cdev->id);
579
580 cooling_ops = &cpufreq_cooling_ops;561 cooling_ops = &cpufreq_cooling_ops;
581 562
582#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR563#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
@@ -591,7 +572,7 @@ __cpufreq_cooling_register(struct device_node *np, · 8 unmodified lines
591 pr_err("%s: unsorted frequency tables are not supported\n",572 pr_err("%s: unsorted frequency tables are not supported\n",
592 __func__);573 __func__);
593 cdev = ERR_PTR(-EINVAL);574 cdev = ERR_PTR(-EINVAL);
594 goto remove_ida;575 goto free_idle_time;
595 }576 }
596 577
597 ret = freq_qos_add_request(&policy->constraints,578 ret = freq_qos_add_request(&policy->constraints,
@@ -601,24 +582,25 @@ __cpufreq_cooling_register(struct device_node *np, · 3 unmodified lines
601 pr_err("%s: Failed to add freq constraint (%d)\n", __func__,582 pr_err("%s: Failed to add freq constraint (%d)\n", __func__,
602 ret);583 ret);
603 cdev = ERR_PTR(ret);584 cdev = ERR_PTR(ret);
604 goto remove_ida;585 goto free_idle_time;
605 }586 }
606 587
607 cdev = thermal_of_cooling_device_register(np, dev_name, cpufreq_cdev,588 cdev = ERR_PTR(-ENOMEM);
589 name = kasprintf(GFP_KERNEL, "cpufreq-%s", dev_name(dev));
590 if (!name)
591 goto remove_qos_req;
592
593 cdev = thermal_of_cooling_device_register(np, name, cpufreq_cdev,
608 cooling_ops);594 cooling_ops);
595 kfree(name);
596
609 if (IS_ERR(cdev))597 if (IS_ERR(cdev))
610 goto remove_qos_req;598 goto remove_qos_req;
611 599
612 mutex_lock(&cooling_list_lock);
613 list_add(&cpufreq_cdev->node, &cpufreq_cdev_list);
614 mutex_unlock(&cooling_list_lock);
615
616 return cdev;600 return cdev;
617 601
618remove_qos_req:602remove_qos_req:
619 freq_qos_remove_request(&cpufreq_cdev->qos_req);603 freq_qos_remove_request(&cpufreq_cdev->qos_req);
620remove_ida:
621 ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
622free_idle_time:604free_idle_time:
623 free_idle_time(cpufreq_cdev);605 free_idle_time(cpufreq_cdev);
624free_cdev:606free_cdev:
@@ -706,13 +688,8 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) · 81 unmodified lines
706 688
707 cpufreq_cdev = cdev->devdata;689 cpufreq_cdev = cdev->devdata;
708 690
709 mutex_lock(&cooling_list_lock);
710 list_del(&cpufreq_cdev->node);
711 mutex_unlock(&cooling_list_lock);
712
713 thermal_cooling_device_unregister(cdev);691 thermal_cooling_device_unregister(cdev);
714 freq_qos_remove_request(&cpufreq_cdev->qos_req);692 freq_qos_remove_request(&cpufreq_cdev->qos_req);
715 ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
716 free_idle_time(cpufreq_cdev);693 free_idle_time(cpufreq_cdev);
717 kfree(cpufreq_cdev);694 kfree(cpufreq_cdev);
718}695}
drivers/thermal/cpuidle_cooling.c+19−18
@@ -9,9 +9,9 @@ · 8 unmodified lines
9 9
10#include <linux/cpu_cooling.h>10#include <linux/cpu_cooling.h>
11#include <linux/cpuidle.h>11#include <linux/cpuidle.h>
12#include <linux/device.h>
12#include <linux/err.h>13#include <linux/err.h>
13#include <linux/idle_inject.h>14#include <linux/idle_inject.h>
14#include <linux/idr.h>
15#include <linux/of_device.h>15#include <linux/of_device.h>
16#include <linux/slab.h>16#include <linux/slab.h>
17#include <linux/thermal.h>17#include <linux/thermal.h>
@@ -26,8 +26,6 @@ struct cpuidle_cooling_device { · 8 unmodified lines
26 unsigned long state;26 unsigned long state;
27};27};
28 28
29static DEFINE_IDA(cpuidle_ida);
30
31/**29/**
32 * cpuidle_cooling_runtime - Running time computation30 * cpuidle_cooling_runtime - Running time computation
33 * @idle_duration_us: CPU idle time to inject in microseconds31 * @idle_duration_us: CPU idle time to inject in microseconds
@@ -174,10 +172,11 @@ static int __cpuidle_cooling_register(struct device_node *np, · 140 unmodified lines
174 struct idle_inject_device *ii_dev;172 struct idle_inject_device *ii_dev;
175 struct cpuidle_cooling_device *idle_cdev;173 struct cpuidle_cooling_device *idle_cdev;
176 struct thermal_cooling_device *cdev;174 struct thermal_cooling_device *cdev;
175 struct device *dev;
177 unsigned int idle_duration_us = TICK_USEC;176 unsigned int idle_duration_us = TICK_USEC;
178 unsigned int latency_us = UINT_MAX;177 unsigned int latency_us = UINT_MAX;
179 char dev_name[THERMAL_NAME_LENGTH];178 char *name;
180 int id, ret;179 int ret;
181 180
182 idle_cdev = kzalloc(sizeof(*idle_cdev), GFP_KERNEL);181 idle_cdev = kzalloc(sizeof(*idle_cdev), GFP_KERNEL);
183 if (!idle_cdev) {182 if (!idle_cdev) {
@@ -185,16 +184,10 @@ static int __cpuidle_cooling_register(struct device_node *np, · 1 unmodified line
185 goto out;184 goto out;
186 }185 }
187 186
188 id = ida_simple_get(&cpuidle_ida, 0, 0, GFP_KERNEL);
189 if (id < 0) {
190 ret = id;
191 goto out_kfree;
192 }
193
194 ii_dev = idle_inject_register(drv->cpumask);187 ii_dev = idle_inject_register(drv->cpumask);
195 if (!ii_dev) {188 if (!ii_dev) {
196 ret = -EINVAL;189 ret = -EINVAL;
197 goto out_id;190 goto out_kfree;
198 }191 }
199 192
200 of_property_read_u32(np, "duration-us", &idle_duration_us);193 of_property_read_u32(np, "duration-us", &idle_duration_us);
@@ -205,24 +198,32 @@ static int __cpuidle_cooling_register(struct device_node *np, · 4 unmodified lines
205 198
206 idle_cdev->ii_dev = ii_dev;199 idle_cdev->ii_dev = ii_dev;
207 200
208 snprintf(dev_name, sizeof(dev_name), "thermal-idle-%d", id);201 dev = get_cpu_device(cpumask_first(drv->cpumask));
209 202
210 cdev = thermal_of_cooling_device_register(np, dev_name, idle_cdev,203 name = kasprintf(GFP_KERNEL, "idle-%s", dev_name(dev));
204 if (!name) {
205 ret = -ENOMEM;
206 goto out_unregister;
207 }
208
209 cdev = thermal_of_cooling_device_register(np, name, idle_cdev,
211 &cpuidle_cooling_ops);210 &cpuidle_cooling_ops);
212 if (IS_ERR(cdev)) {211 if (IS_ERR(cdev)) {
213 ret = PTR_ERR(cdev);212 ret = PTR_ERR(cdev);
214 goto out_unregister;213 goto out_kfree_name;
215 }214 }
216 215
217 pr_debug("%s: Idle injection set with idle duration=%u, latency=%u\n",216 pr_debug("%s: Idle injection set with idle duration=%u, latency=%u\n",
218 dev_name, idle_duration_us, latency_us);217 name, idle_duration_us, latency_us);
218
219 kfree(name);
219 220
220 return 0;221 return 0;
221 222
223out_kfree_name:
224 kfree(name);
222out_unregister:225out_unregister:
223 idle_inject_unregister(ii_dev);226 idle_inject_unregister(ii_dev);
224out_id:
225 ida_simple_remove(&cpuidle_ida, id);
226out_kfree:227out_kfree:
227 kfree(idle_cdev);228 kfree(idle_cdev);
228out:229out:
drivers/thermal/devfreq_cooling.c+8−17
@@ -14,7 +14,6 @@ · 13 unmodified lines
14#include <linux/devfreq_cooling.h>14#include <linux/devfreq_cooling.h>
15#include <linux/energy_model.h>15#include <linux/energy_model.h>
16#include <linux/export.h>16#include <linux/export.h>
17#include <linux/idr.h>
18#include <linux/slab.h>17#include <linux/slab.h>
19#include <linux/pm_opp.h>18#include <linux/pm_opp.h>
20#include <linux/pm_qos.h>19#include <linux/pm_qos.h>
@@ -25,11 +24,8 @@ · 4 unmodified lines
25#define HZ_PER_KHZ 100024#define HZ_PER_KHZ 1000
26#define SCALE_ERROR_MITIGATION 10025#define SCALE_ERROR_MITIGATION 100
27 26
28static DEFINE_IDA(devfreq_ida);
29
30/**27/**
31 * struct devfreq_cooling_device - Devfreq cooling device28 * struct devfreq_cooling_device - Devfreq cooling device
32 * @id: unique integer value corresponding to each
33 * devfreq_cooling_device registered.29 * devfreq_cooling_device registered.
34 * @cdev: Pointer to associated thermal cooling device.30 * @cdev: Pointer to associated thermal cooling device.
35 * @devfreq: Pointer to associated devfreq device.31 * @devfreq: Pointer to associated devfreq device.
@@ -51,7 +47,6 @@ static DEFINE_IDA(devfreq_ida); · 15 unmodified lines
51 * @em_pd: Energy Model for the associated Devfreq device47 * @em_pd: Energy Model for the associated Devfreq device
52 */48 */
53struct devfreq_cooling_device {49struct devfreq_cooling_device {
54 int id;
55 struct thermal_cooling_device *cdev;50 struct thermal_cooling_device *cdev;
56 struct devfreq *devfreq;51 struct devfreq *devfreq;
57 unsigned long cooling_state;52 unsigned long cooling_state;
@@ -363,7 +358,7 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, · 305 unmodified lines
363 struct thermal_cooling_device *cdev;358 struct thermal_cooling_device *cdev;
364 struct device *dev = df->dev.parent;359 struct device *dev = df->dev.parent;
365 struct devfreq_cooling_device *dfc;360 struct devfreq_cooling_device *dfc;
366 char dev_name[THERMAL_NAME_LENGTH];361 char *name;
367 int err, num_opps;362 int err, num_opps;
368 363
369 dfc = kzalloc(sizeof(*dfc), GFP_KERNEL);364 dfc = kzalloc(sizeof(*dfc), GFP_KERNEL);
@@ -407,30 +402,27 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, · 37 unmodified lines
407 if (err < 0)402 if (err < 0)
408 goto free_table;403 goto free_table;
409 404
410 err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL);405 err = -ENOMEM;
411 if (err < 0)406 name = kasprintf(GFP_KERNEL, "devfreq-%s", dev_name(dev));
407 if (!name)
412 goto remove_qos_req;408 goto remove_qos_req;
413 409
414 dfc->id = err;410 cdev = thermal_of_cooling_device_register(np, name, dfc,
415
416 snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d", dfc->id);
417
418 cdev = thermal_of_cooling_device_register(np, dev_name, dfc,
419 &devfreq_cooling_ops);411 &devfreq_cooling_ops);
412 kfree(name);
413
420 if (IS_ERR(cdev)) {414 if (IS_ERR(cdev)) {
421 err = PTR_ERR(cdev);415 err = PTR_ERR(cdev);
422 dev_err(dev,416 dev_err(dev,
423 "Failed to register devfreq cooling device (%d)\n",417 "Failed to register devfreq cooling device (%d)\n",
424 err);418 err);
425 goto release_ida;419 goto remove_qos_req;
426 }420 }
427 421
428 dfc->cdev = cdev;422 dfc->cdev = cdev;
429 423
430 return cdev;424 return cdev;
431 425
432release_ida:
433 ida_simple_remove(&devfreq_ida, dfc->id);
434remove_qos_req:426remove_qos_req:
435 dev_pm_qos_remove_request(&dfc->req_max_freq);427 dev_pm_qos_remove_request(&dfc->req_max_freq);
436free_table:428free_table:
@@ -527,7 +519,6 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev) · 90 unmodified lines
527 dev = dfc->devfreq->dev.parent;519 dev = dfc->devfreq->dev.parent;
528 520
529 thermal_cooling_device_unregister(dfc->cdev);521 thermal_cooling_device_unregister(dfc->cdev);
530 ida_simple_remove(&devfreq_ida, dfc->id);
531 dev_pm_qos_remove_request(&dfc->req_max_freq);522 dev_pm_qos_remove_request(&dfc->req_max_freq);
532 523
533 em_dev_unregister_perf_domain(dev);524 em_dev_unregister_perf_domain(dev);
drivers/thermal/gov_fair_share.c+7−4
@@ -82,6 +82,8 @@ static int fair_share_throttle(struct thermal_zone_device *tz, int trip) · 81 unmodified lines
82 int total_instance = 0;82 int total_instance = 0;
83 int cur_trip_level = get_trip_level(tz);83 int cur_trip_level = get_trip_level(tz);
84 84
85 mutex_lock(&tz->lock);
86
85 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {87 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
86 if (instance->trip != trip)88 if (instance->trip != trip)
87 continue;89 continue;
@@ -105,11 +107,12 @@ static int fair_share_throttle(struct thermal_zone_device *tz, int trip) · 17 unmodified lines
105 instance->target = get_target_state(tz, cdev, percentage,107 instance->target = get_target_state(tz, cdev, percentage,
106 cur_trip_level);108 cur_trip_level);
107 109
108 mutex_lock(&instance->cdev->lock);110 mutex_lock(&cdev->lock);
109 instance->cdev->updated = false;111 __thermal_cdev_update(cdev);
110 mutex_unlock(&instance->cdev->lock);112 mutex_unlock(&cdev->lock);
111 thermal_cdev_update(cdev);
112 }113 }
114
115 mutex_unlock(&tz->lock);
113 return 0;116 return 0;
114}117}
115 118
drivers/thermal/gov_power_allocator.c+23−9
@@ -301,9 +301,8 @@ power_actor_set_power(struct thermal_cooling_device *cdev, · 300 unmodified lines
301 301
302 instance->target = clamp_val(state, instance->lower, instance->upper);302 instance->target = clamp_val(state, instance->lower, instance->upper);
303 mutex_lock(&cdev->lock);303 mutex_lock(&cdev->lock);
304 cdev->updated = false;304 __thermal_cdev_update(cdev);
305 mutex_unlock(&cdev->lock);305 mutex_unlock(&cdev->lock);
306 thermal_cdev_update(cdev);
307 306
308 return 0;307 return 0;
309}308}
@@ -374,9 +373,11 @@ static void divvy_up_power(u32 *req_power, u32 *max_power, int num_actors, · 64 unmodified lines
374 */373 */
375 extra_power = min(extra_power, capped_extra_power);374 extra_power = min(extra_power, capped_extra_power);
376 if (capped_extra_power > 0)375 if (capped_extra_power > 0)
377 for (i = 0; i < num_actors; i++)376 for (i = 0; i < num_actors; i++) {
378 granted_power[i] += (extra_actor_power[i] *377 u64 extra_range = (u64)extra_actor_power[i] * extra_power;
379 extra_power) / capped_extra_power;378 granted_power[i] += DIV_ROUND_CLOSEST_ULL(extra_range,
379 capped_extra_power);
380 }
380}381}
381 382
382static int allocate_power(struct thermal_zone_device *tz,383static int allocate_power(struct thermal_zone_device *tz,
@@ -569,22 +570,33 @@ static void reset_pid_controller(struct power_allocator_params *params) · 186 unmodified lines
569 params->prev_err = 0;570 params->prev_err = 0;
570}571}
571 572
572static void allow_maximum_power(struct thermal_zone_device *tz)573static void allow_maximum_power(struct thermal_zone_device *tz, bool update)
573{574{
574 struct thermal_instance *instance;575 struct thermal_instance *instance;
575 struct power_allocator_params *params = tz->governor_data;576 struct power_allocator_params *params = tz->governor_data;
577 u32 req_power;
576 578
577 mutex_lock(&tz->lock);579 mutex_lock(&tz->lock);
578 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {580 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
581 struct thermal_cooling_device *cdev = instance->cdev;
582
579 if ((instance->trip != params->trip_max_desired_temperature) ||583 if ((instance->trip != params->trip_max_desired_temperature) ||
580 (!cdev_is_power_actor(instance->cdev)))584 (!cdev_is_power_actor(instance->cdev)))
581 continue;585 continue;
582 586
583 instance->target = 0;587 instance->target = 0;
584 mutex_lock(&instance->cdev->lock);588 mutex_lock(&instance->cdev->lock);
585 instance->cdev->updated = false;589 /*
590 * Call for updating the cooling devices local stats and avoid
591 * periods of dozen of seconds when those have not been
592 * maintained.
593 */
594 cdev->ops->get_requested_power(cdev, &req_power);
595
596 if (update)
597 __thermal_cdev_update(instance->cdev);
598
586 mutex_unlock(&instance->cdev->lock);599 mutex_unlock(&instance->cdev->lock);
587 thermal_cdev_update(instance->cdev);
588 }600 }
589 mutex_unlock(&tz->lock);601 mutex_unlock(&tz->lock);
590}602}
@@ -698,6 +710,7 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) · 107 unmodified lines
698 int ret;710 int ret;
699 int switch_on_temp, control_temp;711 int switch_on_temp, control_temp;
700 struct power_allocator_params *params = tz->governor_data;712 struct power_allocator_params *params = tz->governor_data;
713 bool update;
701 714
702 /*715 /*
703 * We get called for every trip point but we only need to do716 * We get called for every trip point but we only need to do
@@ -709,9 +722,10 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) · 5 unmodified lines
709 ret = tz->ops->get_trip_temp(tz, params->trip_switch_on,722 ret = tz->ops->get_trip_temp(tz, params->trip_switch_on,
710 &switch_on_temp);723 &switch_on_temp);
711 if (!ret && (tz->temperature < switch_on_temp)) {724 if (!ret && (tz->temperature < switch_on_temp)) {
725 update = (tz->last_temperature >= switch_on_temp);
712 tz->passive = 0;726 tz->passive = 0;
713 reset_pid_controller(params);727 reset_pid_controller(params);
714 allow_maximum_power(tz);728 allow_maximum_power(tz, update);
715 return 0;729 return 0;
716 }730 }
717 731
drivers/thermal/hisi_thermal.c+4−6
@@ -1,7 +1,7 @@
1/*1/*
2 * Hisilicon thermal sensor driver2 * HiSilicon thermal sensor driver
3 *3 *
4 * Copyright (c) 2014-2015 Hisilicon Limited.4 * Copyright (c) 2014-2015 HiSilicon Limited.
5 * Copyright (c) 2014-2015 Linaro Limited.5 * Copyright (c) 2014-2015 Linaro Limited.
6 *6 *
7 * Xinwei Kong <kong.kongxinwei@hisilicon.com>7 * Xinwei Kong <kong.kongxinwei@hisilicon.com>
@@ -572,10 +572,8 @@ static int hisi_thermal_probe(struct platform_device *pdev) · 564 unmodified lines
572 572
573 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);573 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
574 data->regs = devm_ioremap_resource(dev, res);574 data->regs = devm_ioremap_resource(dev, res);
575 if (IS_ERR(data->regs)) {575 if (IS_ERR(data->regs))
576 dev_err(dev, "failed to get io address\n");
577 return PTR_ERR(data->regs);576 return PTR_ERR(data->regs);
578 }
579 577
580 ret = data->ops->probe(data);578 ret = data->ops->probe(data);
581 if (ret)579 if (ret)
@@ -672,5 +670,5 @@ module_platform_driver(hisi_thermal_driver); · 90 unmodified lines
672 670
673MODULE_AUTHOR("Xinwei Kong <kong.kongxinwei@hisilicon.com>");671MODULE_AUTHOR("Xinwei Kong <kong.kongxinwei@hisilicon.com>");
674MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>");672MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>");
675MODULE_DESCRIPTION("Hisilicon thermal driver");673MODULE_DESCRIPTION("HiSilicon thermal driver");
676MODULE_LICENSE("GPL v2");674MODULE_LICENSE("GPL v2");
drivers/thermal/intel/Kconfig+11−0
@@ -79,3 +79,14 @@ config INTEL_PCH_THERMAL · 78 unmodified lines
79 Enable this to support thermal reporting on certain intel PCHs.79 Enable this to support thermal reporting on certain intel PCHs.
80 Thermal reporting device will provide temperature reading,80 Thermal reporting device will provide temperature reading,
81 programmable trip points and other information.81 programmable trip points and other information.
82
83config INTEL_TCC_COOLING
84 tristate "Intel TCC offset cooling Driver"
85 depends on X86
86 help
87 Enable this to support system cooling by adjusting the effective TCC
88 activation temperature via the TCC Offset register, which is widely
89 supported on modern Intel platforms.
90 Note that, on different platforms, the behavior might be different
91 on how fast the setting takes effect, and how much the CPU frequency
92 is reduced.
drivers/thermal/intel/Makefile+1−0
@@ -10,4 +10,5 @@ obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL) += intel_quark_dts_thermal.o · 9 unmodified lines
10obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/10obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/
11obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o11obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o
12obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o12obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o
13obj-$(CONFIG_INTEL_TCC_COOLING) += intel_tcc_cooling.o
13obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o14obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o
drivers/thermal/intel/intel_tcc_cooling.c+129−0
@@ -0,0 +1,129 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * cooling device driver that activates the processor throttling by
4 * programming the TCC Offset register.
5 * Copyright (c) 2021, Intel Corporation.
6 */
7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8
9#include <linux/device.h>
10#include <linux/module.h>
11#include <linux/thermal.h>
12#include <asm/cpu_device_id.h>
13
14#define TCC_SHIFT 24
15#define TCC_MASK (0x3fULL<<24)
16#define TCC_PROGRAMMABLE BIT(30)
17
18static struct thermal_cooling_device *tcc_cdev;
19
20static int tcc_get_max_state(struct thermal_cooling_device *cdev, unsigned long
21 *state)
22{
23 *state = TCC_MASK >> TCC_SHIFT;
24 return 0;
25}
26
27static int tcc_offset_update(int tcc)
28{
29 u64 val;
30 int err;
31
32 err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
33 if (err)
34 return err;
35
36 val &= ~TCC_MASK;
37 val |= tcc << TCC_SHIFT;
38
39 err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val);
40 if (err)
41 return err;
42
43 return 0;
44}
45
46static int tcc_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
47 *state)
48{
49 u64 val;
50 int err;
51
52 err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
53 if (err)
54 return err;
55
56 *state = (val & TCC_MASK) >> TCC_SHIFT;
57 return 0;
58}
59
60static int tcc_set_cur_state(struct thermal_cooling_device *cdev, unsigned long
61 state)
62{
63 return tcc_offset_update(state);
64}
65
66static const struct thermal_cooling_device_ops tcc_cooling_ops = {
67 .get_max_state = tcc_get_max_state,
68 .get_cur_state = tcc_get_cur_state,
69 .set_cur_state = tcc_set_cur_state,
70};
71
72static const struct x86_cpu_id tcc_ids[] __initconst = {
73 X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, NULL),
74 X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, NULL),
75 X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, NULL),
76 X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, NULL),
77 X86_MATCH_INTEL_FAM6_MODEL(ICELAKE, NULL),
78 X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, NULL),
79 X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, NULL),
80 X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, NULL),
81 X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, NULL),
82 {}
83};
84
85MODULE_DEVICE_TABLE(x86cpu, tcc_ids);
86
87static int __init tcc_cooling_init(void)
88{
89 int ret;
90 u64 val;
91 const struct x86_cpu_id *id;
92
93 int err;
94
95 id = x86_match_cpu(tcc_ids);
96 if (!id)
97 return -ENODEV;
98
99 err = rdmsrl_safe(MSR_PLATFORM_INFO, &val);
100 if (err)
101 return err;
102
103 if (!(val & TCC_PROGRAMMABLE))
104 return -ENODEV;
105
106 pr_info("Programmable TCC Offset detected\n");
107
108 tcc_cdev =
109 thermal_cooling_device_register("TCC Offset", NULL,
110 &tcc_cooling_ops);
111 if (IS_ERR(tcc_cdev)) {
112 ret = PTR_ERR(tcc_cdev);
113 return ret;
114 }
115 return 0;
116}
117
118module_init(tcc_cooling_init)
119
120static void __exit tcc_cooling_exit(void)
121{
122 thermal_cooling_device_unregister(tcc_cdev);
123}
124
125module_exit(tcc_cooling_exit)
126
127MODULE_DESCRIPTION("TCC offset cooling device Driver");
128MODULE_AUTHOR("Zhang Rui <rui.zhang@intel.com>");
129MODULE_LICENSE("GPL v2");
drivers/thermal/mtk_thermal.c+6−6
@@ -573,12 +573,12 @@ static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw) · 572 unmodified lines
573 573
574static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)574static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
575{575{
576 s32 format_1 = 0;576 s32 format_1;
577 s32 format_2 = 0;577 s32 format_2;
578 s32 g_oe = 1;578 s32 g_oe;
579 s32 g_gain = 1;579 s32 g_gain;
580 s32 g_x_roomt = 0;580 s32 g_x_roomt;
581 s32 tmp = 0;581 s32 tmp;
582 582
583 if (raw == 0)583 if (raw == 0)
584 return 0;584 return 0;
drivers/thermal/qcom/qcom-spmi-temp-alarm.c+61−30
@@ -17,6 +17,7 @@ · 16 unmodified lines
17 17
18#include "../thermal_core.h"18#include "../thermal_core.h"
19 19
20#define QPNP_TM_REG_DIG_MAJOR 0x01
20#define QPNP_TM_REG_TYPE 0x0421#define QPNP_TM_REG_TYPE 0x04
21#define QPNP_TM_REG_SUBTYPE 0x0522#define QPNP_TM_REG_SUBTYPE 0x05
22#define QPNP_TM_REG_STATUS 0x0823#define QPNP_TM_REG_STATUS 0x08
@@ -38,26 +39,30 @@ · 15 unmodified lines
38 39
39#define ALARM_CTRL_FORCE_ENABLE BIT(7)40#define ALARM_CTRL_FORCE_ENABLE BIT(7)
40 41
41/*42#define THRESH_COUNT 4
42 * Trip point values based on threshold control43#define STAGE_COUNT 3
43 * 0 = {105 C, 125 C, 145 C}44
44 * 1 = {110 C, 130 C, 150 C}45/* Over-temperature trip point values in mC */
45 * 2 = {115 C, 135 C, 155 C}46static const long temp_map_gen1[THRESH_COUNT][STAGE_COUNT] = {
46 * 3 = {120 C, 140 C, 160 C}47 { 105000, 125000, 145000 },
47*/48 { 110000, 130000, 150000 },
48#define TEMP_STAGE_STEP 20000 /* Stage step: 20.000 C */49 { 115000, 135000, 155000 },
49#define TEMP_STAGE_HYSTERESIS 200050 { 120000, 140000, 160000 },
51};
52
53static const long temp_map_gen2_v1[THRESH_COUNT][STAGE_COUNT] = {
54 { 90000, 110000, 140000 },
55 { 95000, 115000, 145000 },
56 { 100000, 120000, 150000 },
57 { 105000, 125000, 155000 },
58};
50 59
51#define TEMP_THRESH_MIN 105000 /* Threshold Min: 105 C */60#define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */
52#define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */
53 61
54#define THRESH_MIN 062#define THRESH_MIN 0
55#define THRESH_MAX 363#define THRESH_MAX 3
56 64
57/* Stage 2 Threshold Min: 125 C */65#define TEMP_STAGE_HYSTERESIS 2000
58#define STAGE2_THRESHOLD_MIN 125000
59/* Stage 2 Threshold Max: 140 C */
60#define STAGE2_THRESHOLD_MAX 140000
61 66
62/* Temperature in Milli Celsius reported during stage 0 if no ADC is present */67/* Temperature in Milli Celsius reported during stage 0 if no ADC is present */
63#define DEFAULT_TEMP 3700068#define DEFAULT_TEMP 37000
@@ -77,6 +82,7 @@ struct qpnp_tm_chip { · 13 unmodified lines
77 bool initialized;82 bool initialized;
78 83
79 struct iio_channel *adc;84 struct iio_channel *adc;
85 const long (*temp_map)[THRESH_COUNT][STAGE_COUNT];
80};86};
81 87
82/* This array maps from GEN2 alarm state to GEN1 alarm stage */88/* This array maps from GEN2 alarm state to GEN1 alarm stage */
@@ -100,6 +106,23 @@ static int qpnp_tm_write(struct qpnp_tm_chip *chip, u16 addr, u8 data) · 17 unmodified lines
100 return regmap_write(chip->map, chip->base + addr, data);106 return regmap_write(chip->map, chip->base + addr, data);
101}107}
102 108
109/**
110 * qpnp_tm_decode_temp() - return temperature in mC corresponding to the
111 * specified over-temperature stage
112 * @chip: Pointer to the qpnp_tm chip
113 * @stage: Over-temperature stage
114 *
115 * Return: temperature in mC
116 */
117static long qpnp_tm_decode_temp(struct qpnp_tm_chip *chip, unsigned int stage)
118{
119 if (!chip->temp_map || chip->thresh >= THRESH_COUNT || stage == 0 ||
120 stage > STAGE_COUNT)
121 return 0;
122
123 return (*chip->temp_map)[chip->thresh][stage - 1];
124}
125
103/**126/**
104 * qpnp_tm_get_temp_stage() - return over-temperature stage127 * qpnp_tm_get_temp_stage() - return over-temperature stage
105 * @chip: Pointer to the qpnp_tm chip128 * @chip: Pointer to the qpnp_tm chip
@@ -149,14 +172,12 @@ static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip) · 43 unmodified lines
149 172
150 if (stage_new > stage_old) {173 if (stage_new > stage_old) {
151 /* increasing stage, use lower bound */174 /* increasing stage, use lower bound */
152 chip->temp = (stage_new - 1) * TEMP_STAGE_STEP +175 chip->temp = qpnp_tm_decode_temp(chip, stage_new)
153 chip->thresh * TEMP_THRESH_STEP +176 + TEMP_STAGE_HYSTERESIS;
154 TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN;
155 } else if (stage_new < stage_old) {177 } else if (stage_new < stage_old) {
156 /* decreasing stage, use upper bound */178 /* decreasing stage, use upper bound */
157 chip->temp = stage_new * TEMP_STAGE_STEP +179 chip->temp = qpnp_tm_decode_temp(chip, stage_new + 1)
158 chip->thresh * TEMP_THRESH_STEP -180 - TEMP_STAGE_HYSTERESIS;
159 TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN;
160 }181 }
161 182
162 chip->stage = stage;183 chip->stage = stage;
@@ -199,26 +220,28 @@ static int qpnp_tm_get_temp(void *data, int *temp) · 36 unmodified lines
199static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,220static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
200 int temp)221 int temp)
201{222{
202 u8 reg;223 long stage2_threshold_min = (*chip->temp_map)[THRESH_MIN][1];
224 long stage2_threshold_max = (*chip->temp_map)[THRESH_MAX][1];
203 bool disable_s2_shutdown = false;225 bool disable_s2_shutdown = false;
226 u8 reg;
204 227
205 WARN_ON(!mutex_is_locked(&chip->lock));228 WARN_ON(!mutex_is_locked(&chip->lock));
206 229
207 /*230 /*
208 * Default: S2 and S3 shutdown enabled, thresholds at231 * Default: S2 and S3 shutdown enabled, thresholds at
209 * 105C/125C/145C, monitoring at 25Hz232 * lowest threshold set, monitoring at 25Hz
210 */233 */
211 reg = SHUTDOWN_CTRL1_RATE_25HZ;234 reg = SHUTDOWN_CTRL1_RATE_25HZ;
212 235
213 if (temp == THERMAL_TEMP_INVALID ||236 if (temp == THERMAL_TEMP_INVALID ||
214 temp < STAGE2_THRESHOLD_MIN) {237 temp < stage2_threshold_min) {
215 chip->thresh = THRESH_MIN;238 chip->thresh = THRESH_MIN;
216 goto skip;239 goto skip;
217 }240 }
218 241
219 if (temp <= STAGE2_THRESHOLD_MAX) {242 if (temp <= stage2_threshold_max) {
220 chip->thresh = THRESH_MAX -243 chip->thresh = THRESH_MAX -
221 ((STAGE2_THRESHOLD_MAX - temp) /244 ((stage2_threshold_max - temp) /
222 TEMP_THRESH_STEP);245 TEMP_THRESH_STEP);
223 disable_s2_shutdown = true;246 disable_s2_shutdown = true;
224 } else {247 } else {
@@ -326,9 +349,7 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip) · 101 unmodified lines
326 ? chip->stage : alarm_state_map[chip->stage];349 ? chip->stage : alarm_state_map[chip->stage];
327 350
328 if (stage)351 if (stage)
329 chip->temp = chip->thresh * TEMP_THRESH_STEP +352 chip->temp = qpnp_tm_decode_temp(chip, stage);
330 (stage - 1) * TEMP_STAGE_STEP +
331 TEMP_THRESH_MIN;
332 353
333 crit_temp = qpnp_tm_get_critical_trip_temp(chip);354 crit_temp = qpnp_tm_get_critical_trip_temp(chip);
334 ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp);355 ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp);
@@ -350,7 +371,7 @@ static int qpnp_tm_probe(struct platform_device *pdev) · 15 unmodified lines
350{371{
351 struct qpnp_tm_chip *chip;372 struct qpnp_tm_chip *chip;
352 struct device_node *node;373 struct device_node *node;
353 u8 type, subtype;374 u8 type, subtype, dig_major;
354 u32 res;375 u32 res;
355 int ret, irq;376 int ret, irq;
356 377
@@ -400,6 +421,12 @@ static int qpnp_tm_probe(struct platform_device *pdev) · 43 unmodified lines
400 return ret;421 return ret;
401 }422 }
402 423
424 ret = qpnp_tm_read(chip, QPNP_TM_REG_DIG_MAJOR, &dig_major);
425 if (ret < 0) {
426 dev_err(&pdev->dev, "could not read dig_major\n");
427 return ret;
428 }
429
403 if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1430 if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1
404 && subtype != QPNP_TM_SUBTYPE_GEN2)) {431 && subtype != QPNP_TM_SUBTYPE_GEN2)) {
405 dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n",432 dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n",
@@ -408,6 +435,10 @@ static int qpnp_tm_probe(struct platform_device *pdev) · 2 unmodified lines
408 }435 }
409 436
410 chip->subtype = subtype;437 chip->subtype = subtype;
438 if (subtype == QPNP_TM_SUBTYPE_GEN2 && dig_major >= 1)
439 chip->temp_map = &temp_map_gen2_v1;
440 else
441 chip->temp_map = &temp_map_gen1;
411 442
412 /*443 /*
413 * Register the sensor before initializing the hardware to be able to444 * Register the sensor before initializing the hardware to be able to
drivers/thermal/qcom/tsens-8960.c+116−119
@@ -10,8 +10,6 @@ · 9 unmodified lines
10#include <linux/thermal.h>10#include <linux/thermal.h>
11#include "tsens.h"11#include "tsens.h"
12 12
13#define CAL_MDEGC 30000
14
15#define CONFIG_ADDR 0x364013#define CONFIG_ADDR 0x3640
16#define CONFIG_ADDR_8660 0x362014#define CONFIG_ADDR_8660 0x3620
17/* CONFIG_ADDR bitmasks */15/* CONFIG_ADDR bitmasks */
@@ -21,40 +19,38 @@ · 3 unmodified lines
21#define CONFIG_SHIFT_8660 2819#define CONFIG_SHIFT_8660 28
22#define CONFIG_MASK_8660 (3 << CONFIG_SHIFT_8660)20#define CONFIG_MASK_8660 (3 << CONFIG_SHIFT_8660)
23 21
24#define STATUS_CNTL_ADDR_8064 0x3660
25#define CNTL_ADDR 0x362022#define CNTL_ADDR 0x3620
26/* CNTL_ADDR bitmasks */23/* CNTL_ADDR bitmasks */
27#define EN BIT(0)24#define EN BIT(0)
28#define SW_RST BIT(1)25#define SW_RST BIT(1)
29#define SENSOR0_EN BIT(3)26
27#define MEASURE_PERIOD BIT(18)
30#define SLP_CLK_ENA BIT(26)28#define SLP_CLK_ENA BIT(26)
31#define SLP_CLK_ENA_8660 BIT(24)29#define SLP_CLK_ENA_8660 BIT(24)
32#define MEASURE_PERIOD 1
33#define SENSOR0_SHIFT 330#define SENSOR0_SHIFT 3
34 31
35/* INT_STATUS_ADDR bitmasks */
36#define MIN_STATUS_MASK BIT(0)
37#define LOWER_STATUS_CLR BIT(1)
38#define UPPER_STATUS_CLR BIT(2)
39#define MAX_STATUS_MASK BIT(3)
40
41#define THRESHOLD_ADDR 0x362432#define THRESHOLD_ADDR 0x3624
42/* THRESHOLD_ADDR bitmasks */33
43#define THRESHOLD_MAX_LIMIT_SHIFT 24
44#define THRESHOLD_MIN_LIMIT_SHIFT 16
45#define THRESHOLD_UPPER_LIMIT_SHIFT 8
46#define THRESHOLD_LOWER_LIMIT_SHIFT 0
47
48/* Initial temperature threshold values */
49#define LOWER_LIMIT_TH 0x50
50#define UPPER_LIMIT_TH 0xdf
51#define MIN_LIMIT_TH 0x0
52#define MAX_LIMIT_TH 0xff
53
54#define S0_STATUS_ADDR 0x3628
55#define INT_STATUS_ADDR 0x363c34#define INT_STATUS_ADDR 0x363c
56#define TRDY_MASK BIT(7)35
57#define TIMEOUT_US 10036#define S0_STATUS_OFF 0x3628
37#define S1_STATUS_OFF 0x362c
38#define S2_STATUS_OFF 0x3630
39#define S3_STATUS_OFF 0x3634
40#define S4_STATUS_OFF 0x3638
41#define S5_STATUS_OFF 0x3664 /* Sensors 5-10 found on apq8064/msm8960 */
42#define S6_STATUS_OFF 0x3668
43#define S7_STATUS_OFF 0x366c
44#define S8_STATUS_OFF 0x3670
45#define S9_STATUS_OFF 0x3674
46#define S10_STATUS_OFF 0x3678
47
48/* Original slope - 350 to compensate mC to C inaccuracy */
49static u32 tsens_msm8960_slope[] = {
50 826, 826, 804, 826,
51 761, 782, 782, 849,
52 782, 849, 782
53 };
58 54
59static int suspend_8960(struct tsens_priv *priv)55static int suspend_8960(struct tsens_priv *priv)
60{56{
@@ -115,17 +111,34 @@ static int resume_8960(struct tsens_priv *priv) · 54 unmodified lines
115static int enable_8960(struct tsens_priv *priv, int id)111static int enable_8960(struct tsens_priv *priv, int id)
116{112{
117 int ret;113 int ret;
118 u32 reg, mask;114 u32 reg, mask = BIT(id);
119 115
120 ret = regmap_read(priv->tm_map, CNTL_ADDR, &reg);116 ret = regmap_read(priv->tm_map, CNTL_ADDR, &reg);
121 if (ret)117 if (ret)
122 return ret;118 return ret;
123 119
124 mask = BIT(id + SENSOR0_SHIFT);120 /* HARDWARE BUG:
121 * On platforms with more than 6 sensors, all remaining sensors
122 * must be enabled together, otherwise undefined results are expected.
123 * (Sensor 6-7 disabled, Sensor 3 disabled...) In the original driver,
124 * all the sensors are enabled in one step hence this bug is not
125 * triggered.
126 */
127 if (id > 5)
128 mask = GENMASK(10, 6);
129
130 mask <<= SENSOR0_SHIFT;
131
132 /* Sensors already enabled. Skip. */
133 if ((reg & mask) == mask)
134 return 0;
135
125 ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST);136 ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST);
126 if (ret)137 if (ret)
127 return ret;138 return ret;
128 139
140 reg |= MEASURE_PERIOD;
141
129 if (priv->num_sensors > 1)142 if (priv->num_sensors > 1)
130 reg |= mask | SLP_CLK_ENA | EN;143 reg |= mask | SLP_CLK_ENA | EN;
131 else144 else
@@ -162,63 +175,11 @@ static void disable_8960(struct tsens_priv *priv) · 30 unmodified lines
162 regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);175 regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
163}176}
164 177
165static int init_8960(struct tsens_priv *priv)
166{
167 int ret, i;
168 u32 reg_cntl;
169
170 priv->tm_map = dev_get_regmap(priv->dev, NULL);
171 if (!priv->tm_map)
172 return -ENODEV;
173
174 /*
175 * The status registers for each sensor are discontiguous
176 * because some SoCs have 5 sensors while others have more
177 * but the control registers stay in the same place, i.e
178 * directly after the first 5 status registers.
179 */
180 for (i = 0; i < priv->num_sensors; i++) {
181 if (i >= 5)
182 priv->sensor[i].status = S0_STATUS_ADDR + 40;
183 priv->sensor[i].status += i * 4;
184 }
185
186 reg_cntl = SW_RST;
187 ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl);
188 if (ret)
189 return ret;
190
191 if (priv->num_sensors > 1) {
192 reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
193 reg_cntl &= ~SW_RST;
194 ret = regmap_update_bits(priv->tm_map, CONFIG_ADDR,
195 CONFIG_MASK, CONFIG);
196 } else {
197 reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16);
198 reg_cntl &= ~CONFIG_MASK_8660;
199 reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660;
200 }
201
202 reg_cntl |= GENMASK(priv->num_sensors - 1, 0) << SENSOR0_SHIFT;
203 ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
204 if (ret)
205 return ret;
206
207 reg_cntl |= EN;
208 ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
209 if (ret)
210 return ret;
211
212 return 0;
213}
214
215static int calibrate_8960(struct tsens_priv *priv)178static int calibrate_8960(struct tsens_priv *priv)
216{179{
217 int i;180 int i;
218 char *data;181 char *data;
219 182 u32 p1[11];
220 ssize_t num_read = priv->num_sensors;
221 struct tsens_sensor *s = priv->sensor;
222 183
223 data = qfprom_read(priv->dev, "calib");184 data = qfprom_read(priv->dev, "calib");
224 if (IS_ERR(data))185 if (IS_ERR(data))
@@ -226,60 +187,96 @@ static int calibrate_8960(struct tsens_priv *priv) · 1 unmodified line
226 if (IS_ERR(data))187 if (IS_ERR(data))
227 return PTR_ERR(data);188 return PTR_ERR(data);
228 189
229 for (i = 0; i < num_read; i++, s++)190 for (i = 0; i < priv->num_sensors; i++) {
230 s->offset = data[i];191 p1[i] = data[i];
192 priv->sensor[i].slope = tsens_msm8960_slope[i];
193 }
194
195 compute_intercept_slope(priv, p1, NULL, ONE_PT_CALIB);
231 196
232 kfree(data);197 kfree(data);
233 198
234 return 0;199 return 0;
235}200}
236 201
237/* Temperature on y axis and ADC-code on x-axis */202static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = {
238static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)203 /* ----- SROT ------ */
239{204 /* No VERSION information */
240 int slope, offset;205
241 206 /* CNTL */
242 slope = thermal_zone_get_slope(s->tzd);207 [TSENS_EN] = REG_FIELD(CNTL_ADDR, 0, 0),
243 offset = CAL_MDEGC - slope * s->offset;208 [TSENS_SW_RST] = REG_FIELD(CNTL_ADDR, 1, 1),
244 209 /* 8960 has 5 sensors, 8660 has 11, we only handle 5 */
245 return adc_code * slope + offset;210 [SENSOR_EN] = REG_FIELD(CNTL_ADDR, 3, 7),
246}211
247 212 /* ----- TM ------ */
248static int get_temp_8960(const struct tsens_sensor *s, int *temp)213 /* INTERRUPT ENABLE */
249{214 /* NO INTERRUPT ENABLE */
250 int ret;215
251 u32 code, trdy;216 /* Single UPPER/LOWER TEMPERATURE THRESHOLD for all sensors */
252 struct tsens_priv *priv = s->priv;217 [LOW_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 0, 7),
253 unsigned long timeout;218 [UP_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 8, 15),
254 219 /* MIN_THRESH_0 and MAX_THRESH_0 are not present in the regfield
255 timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);220 * Recycle CRIT_THRESH_0 and 1 to set the required regs to hardcoded temp
256 do {221 * MIN_THRESH_0 -> CRIT_THRESH_1
257 ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy);222 * MAX_THRESH_0 -> CRIT_THRESH_0
258 if (ret)223 */
259 return ret;224 [CRIT_THRESH_1] = REG_FIELD(THRESHOLD_ADDR, 16, 23),
260 if (!(trdy & TRDY_MASK))225 [CRIT_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 24, 31),
261 continue;226
262 ret = regmap_read(priv->tm_map, s->status, &code);227 /* UPPER/LOWER INTERRUPT [CLEAR/STATUS] */
263 if (ret)228 /* 1 == clear, 0 == normal operation */
264 return ret;229 [LOW_INT_CLEAR_0] = REG_FIELD(CNTL_ADDR, 9, 9),
265 *temp = code_to_mdegC(code, s);230 [UP_INT_CLEAR_0] = REG_FIELD(CNTL_ADDR, 10, 10),
266 return 0;231
267 } while (time_before(jiffies, timeout));232 /* NO CRITICAL INTERRUPT SUPPORT on 8960 */
268 233
269 return -ETIMEDOUT;234 /* Sn_STATUS */
270}235 [LAST_TEMP_0] = REG_FIELD(S0_STATUS_OFF, 0, 7),
236 [LAST_TEMP_1] = REG_FIELD(S1_STATUS_OFF, 0, 7),
237 [LAST_TEMP_2] = REG_FIELD(S2_STATUS_OFF, 0, 7),
238 [LAST_TEMP_3] = REG_FIELD(S3_STATUS_OFF, 0, 7),
239 [LAST_TEMP_4] = REG_FIELD(S4_STATUS_OFF, 0, 7),
240 [LAST_TEMP_5] = REG_FIELD(S5_STATUS_OFF, 0, 7),
241 [LAST_TEMP_6] = REG_FIELD(S6_STATUS_OFF, 0, 7),
242 [LAST_TEMP_7] = REG_FIELD(S7_STATUS_OFF, 0, 7),
243 [LAST_TEMP_8] = REG_FIELD(S8_STATUS_OFF, 0, 7),
244 [LAST_TEMP_9] = REG_FIELD(S9_STATUS_OFF, 0, 7),
245 [LAST_TEMP_10] = REG_FIELD(S10_STATUS_OFF, 0, 7),
246
247 /* No VALID field on 8960 */
248 /* TSENS_INT_STATUS bits: 1 == threshold violated */
249 [MIN_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 0, 0),
250 [LOWER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 1, 1),
251 [UPPER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 2, 2),
252 /* No CRITICAL field on 8960 */
253 [MAX_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 3, 3),
254
255 /* TRDY: 1=ready, 0=in progress */
256 [TRDY] = REG_FIELD(INT_STATUS_ADDR, 7, 7),
257};
271 258
272static const struct tsens_ops ops_8960 = {259static const struct tsens_ops ops_8960 = {
273 .init = init_8960,260 .init = init_common,
274 .calibrate = calibrate_8960,261 .calibrate = calibrate_8960,
275 .get_temp = get_temp_8960,262 .get_temp = get_temp_common,
276 .enable = enable_8960,263 .enable = enable_8960,
277 .disable = disable_8960,264 .disable = disable_8960,
278 .suspend = suspend_8960,265 .suspend = suspend_8960,
279 .resume = resume_8960,266 .resume = resume_8960,
280};267};
281 268
269static struct tsens_features tsens_8960_feat = {
270 .ver_major = VER_0,
271 .crit_int = 0,
272 .adc = 1,
273 .srot_split = 0,
274 .max_sensors = 11,
275};
276
282struct tsens_plat_data data_8960 = {277struct tsens_plat_data data_8960 = {
283 .num_sensors = 11,278 .num_sensors = 11,
284 .ops = &ops_8960,279 .ops = &ops_8960,
280 .feat = &tsens_8960_feat,
281 .fields = tsens_8960_regfields,
285};282};
drivers/thermal/qcom/tsens-v0_1.c+97−1
@@ -190,6 +190,39 @@ · 189 unmodified lines
190 190
191#define BIT_APPEND 0x3191#define BIT_APPEND 0x3
192 192
193/* eeprom layout data for mdm9607 */
194#define MDM9607_BASE0_MASK 0x000000ff
195#define MDM9607_BASE1_MASK 0x000ff000
196#define MDM9607_BASE0_SHIFT 0
197#define MDM9607_BASE1_SHIFT 12
198
199#define MDM9607_S0_P1_MASK 0x00003f00
200#define MDM9607_S1_P1_MASK 0x03f00000
201#define MDM9607_S2_P1_MASK 0x0000003f
202#define MDM9607_S3_P1_MASK 0x0003f000
203#define MDM9607_S4_P1_MASK 0x0000003f
204
205#define MDM9607_S0_P2_MASK 0x000fc000
206#define MDM9607_S1_P2_MASK 0xfc000000
207#define MDM9607_S2_P2_MASK 0x00000fc0
208#define MDM9607_S3_P2_MASK 0x00fc0000
209#define MDM9607_S4_P2_MASK 0x00000fc0
210
211#define MDM9607_S0_P1_SHIFT 8
212#define MDM9607_S1_P1_SHIFT 20
213#define MDM9607_S2_P1_SHIFT 0
214#define MDM9607_S3_P1_SHIFT 12
215#define MDM9607_S4_P1_SHIFT 0
216
217#define MDM9607_S0_P2_SHIFT 14
218#define MDM9607_S1_P2_SHIFT 26
219#define MDM9607_S2_P2_SHIFT 6
220#define MDM9607_S3_P2_SHIFT 18
221#define MDM9607_S4_P2_SHIFT 6
222
223#define MDM9607_CAL_SEL_MASK 0x00700000
224#define MDM9607_CAL_SEL_SHIFT 20
225
193static int calibrate_8916(struct tsens_priv *priv)226static int calibrate_8916(struct tsens_priv *priv)
194{227{
195 int base0 = 0, base1 = 0, i;228 int base0 = 0, base1 = 0, i;
@@ -452,7 +485,56 @@ static int calibrate_8974(struct tsens_priv *priv) · 256 unmodified lines
452 return 0;485 return 0;
453}486}
454 487
455/* v0.1: 8916, 8939, 8974 */488static int calibrate_9607(struct tsens_priv *priv)
489{
490 int base, i;
491 u32 p1[5], p2[5];
492 int mode = 0;
493 u32 *qfprom_cdata;
494
495 qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
496 if (IS_ERR(qfprom_cdata))
497 return PTR_ERR(qfprom_cdata);
498
499 mode = (qfprom_cdata[2] & MDM9607_CAL_SEL_MASK) >> MDM9607_CAL_SEL_SHIFT;
500 dev_dbg(priv->dev, "calibration mode is %d\n", mode);
501
502 switch (mode) {
503 case TWO_PT_CALIB:
504 base = (qfprom_cdata[2] & MDM9607_BASE1_MASK) >> MDM9607_BASE1_SHIFT;
505 p2[0] = (qfprom_cdata[0] & MDM9607_S0_P2_MASK) >> MDM9607_S0_P2_SHIFT;
506 p2[1] = (qfprom_cdata[0] & MDM9607_S1_P2_MASK) >> MDM9607_S1_P2_SHIFT;
507 p2[2] = (qfprom_cdata[1] & MDM9607_S2_P2_MASK) >> MDM9607_S2_P2_SHIFT;
508 p2[3] = (qfprom_cdata[1] & MDM9607_S3_P2_MASK) >> MDM9607_S3_P2_SHIFT;
509 p2[4] = (qfprom_cdata[2] & MDM9607_S4_P2_MASK) >> MDM9607_S4_P2_SHIFT;
510 for (i = 0; i < priv->num_sensors; i++)
511 p2[i] = ((base + p2[i]) << 2);
512 fallthrough;
513 case ONE_PT_CALIB2:
514 base = (qfprom_cdata[0] & MDM9607_BASE0_MASK);
515 p1[0] = (qfprom_cdata[0] & MDM9607_S0_P1_MASK) >> MDM9607_S0_P1_SHIFT;
516 p1[1] = (qfprom_cdata[0] & MDM9607_S1_P1_MASK) >> MDM9607_S1_P1_SHIFT;
517 p1[2] = (qfprom_cdata[1] & MDM9607_S2_P1_MASK) >> MDM9607_S2_P1_SHIFT;
518 p1[3] = (qfprom_cdata[1] & MDM9607_S3_P1_MASK) >> MDM9607_S3_P1_SHIFT;
519 p1[4] = (qfprom_cdata[2] & MDM9607_S4_P1_MASK) >> MDM9607_S4_P1_SHIFT;
520 for (i = 0; i < priv->num_sensors; i++)
521 p1[i] = ((base + p1[i]) << 2);
522 break;
523 default:
524 for (i = 0; i < priv->num_sensors; i++) {
525 p1[i] = 500;
526 p2[i] = 780;
527 }
528 break;
529 }
530
531 compute_intercept_slope(priv, p1, p2, mode);
532 kfree(qfprom_cdata);
533
534 return 0;
535}
536
537/* v0.1: 8916, 8939, 8974, 9607 */
456 538
457static struct tsens_features tsens_v0_1_feat = {539static struct tsens_features tsens_v0_1_feat = {
458 .ver_major = VER_0_1,540 .ver_major = VER_0_1,
@@ -540,3 +622,17 @@ struct tsens_plat_data data_8974 = { · 81 unmodified lines
540 .feat = &tsens_v0_1_feat,622 .feat = &tsens_v0_1_feat,
541 .fields = tsens_v0_1_regfields,623 .fields = tsens_v0_1_regfields,
542};624};
625
626static const struct tsens_ops ops_9607 = {
627 .init = init_common,
628 .calibrate = calibrate_9607,
629 .get_temp = get_temp_common,
630};
631
632struct tsens_plat_data data_9607 = {
633 .num_sensors = 5,
634 .ops = &ops_9607,
635 .hw_ids = (unsigned int []){ 0, 1, 2, 3, 4 },
636 .feat = &tsens_v0_1_feat,
637 .fields = tsens_v0_1_regfields,
638};
drivers/thermal/qcom/tsens-v1.c+2−2
@@ -380,11 +380,11 @@ static const struct tsens_ops ops_8976 = { · 379 unmodified lines
380 .get_temp = get_temp_tsens_valid,380 .get_temp = get_temp_tsens_valid,
381};381};
382 382
383/* Valid for both MSM8956 and MSM8976. Sensor ID 3 is unused. */383/* Valid for both MSM8956 and MSM8976. */
384struct tsens_plat_data data_8976 = {384struct tsens_plat_data data_8976 = {
385 .num_sensors = 11,385 .num_sensors = 11,
386 .ops = &ops_8976,386 .ops = &ops_8976,
387 .hw_ids = (unsigned int[]){0, 1, 2, 4, 5, 6, 7, 8, 9, 10},387 .hw_ids = (unsigned int[]){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
388 .feat = &tsens_v1_feat,388 .feat = &tsens_v1_feat,
389 .fields = tsens_v1_regfields,389 .fields = tsens_v1_regfields,
390};390};
drivers/thermal/qcom/tsens.c+133−32
@@ -12,6 +12,7 @@ · 11 unmodified lines
12#include <linux/of.h>12#include <linux/of.h>
13#include <linux/of_address.h>13#include <linux/of_address.h>
14#include <linux/of_platform.h>14#include <linux/of_platform.h>
15#include <linux/mfd/syscon.h>
15#include <linux/platform_device.h>16#include <linux/platform_device.h>
16#include <linux/pm.h>17#include <linux/pm.h>
17#include <linux/regmap.h>18#include <linux/regmap.h>
@@ -85,7 +86,8 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1, · 67 unmodified lines
85 "%s: sensor%d - data_point1:%#x data_point2:%#x\n",86 "%s: sensor%d - data_point1:%#x data_point2:%#x\n",
86 __func__, i, p1[i], p2[i]);87 __func__, i, p1[i], p2[i]);
87 88
88 priv->sensor[i].slope = SLOPE_DEFAULT;89 if (!priv->sensor[i].slope)
90 priv->sensor[i].slope = SLOPE_DEFAULT;
89 if (mode == TWO_PT_CALIB) {91 if (mode == TWO_PT_CALIB) {
90 /*92 /*
91 * slope (m) = adc_code2 - adc_code1 (y2 - y1)/93 * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
@@ -515,6 +517,15 @@ static irqreturn_t tsens_irq_thread(int irq, void *data) · 423 unmodified lines
515 dev_dbg(priv->dev, "[%u] %s: no violation: %d\n",517 dev_dbg(priv->dev, "[%u] %s: no violation: %d\n",
516 hw_id, __func__, temp);518 hw_id, __func__, temp);
517 }519 }
520
521 if (tsens_version(priv) < VER_0_1) {
522 /* Constraint: There is only 1 interrupt control register for all
523 * 11 temperature sensor. So monitoring more than 1 sensor based
524 * on interrupts will yield inconsistent result. To overcome this
525 * issue we will monitor only sensor 0 which is the master sensor.
526 */
527 break;
528 }
518 }529 }
519 530
520 return IRQ_HANDLED;531 return IRQ_HANDLED;
@@ -530,6 +541,13 @@ static int tsens_set_trips(void *_sensor, int low, int high) · 9 unmodified lines
530 int high_val, low_val, cl_high, cl_low;541 int high_val, low_val, cl_high, cl_low;
531 u32 hw_id = s->hw_id;542 u32 hw_id = s->hw_id;
532 543
544 if (tsens_version(priv) < VER_0_1) {
545 /* Pre v0.1 IP had a single register for each type of interrupt
546 * and thresholds
547 */
548 hw_id = 0;
549 }
550
533 dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",551 dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
534 hw_id, __func__, low, high);552 hw_id, __func__, low, high);
535 553
@@ -584,18 +602,21 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp) · 48 unmodified lines
584 u32 valid;602 u32 valid;
585 int ret;603 int ret;
586 604
587 ret = regmap_field_read(priv->rf[valid_idx], &valid);605 /* VER_0 doesn't have VALID bit */
588 if (ret)606 if (tsens_version(priv) >= VER_0_1) {
589 return ret;
590 while (!valid) {
591 /* Valid bit is 0 for 6 AHB clock cycles.
592 * At 19.2MHz, 1 AHB clock is ~60ns.
593 * We should enter this loop very, very rarely.
594 */
595 ndelay(400);
596 ret = regmap_field_read(priv->rf[valid_idx], &valid);607 ret = regmap_field_read(priv->rf[valid_idx], &valid);
597 if (ret)608 if (ret)
598 return ret;609 return ret;
610 while (!valid) {
611 /* Valid bit is 0 for 6 AHB clock cycles.
612 * At 19.2MHz, 1 AHB clock is ~60ns.
613 * We should enter this loop very, very rarely.
614 */
615 ndelay(400);
616 ret = regmap_field_read(priv->rf[valid_idx], &valid);
617 if (ret)
618 return ret;
619 }
599 }620 }
600 621
601 /* Valid bit is set, OK to read the temperature */622 /* Valid bit is set, OK to read the temperature */
@@ -608,15 +629,29 @@ int get_temp_common(const struct tsens_sensor *s, int *temp) · 6 unmodified lines
608{629{
609 struct tsens_priv *priv = s->priv;630 struct tsens_priv *priv = s->priv;
610 int hw_id = s->hw_id;631 int hw_id = s->hw_id;
611 int last_temp = 0, ret;632 int last_temp = 0, ret, trdy;
633 unsigned long timeout;
612 634
613 ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);635 timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
614 if (ret)636 do {
615 return ret;637 if (tsens_version(priv) == VER_0) {
638 ret = regmap_field_read(priv->rf[TRDY], &trdy);
639 if (ret)
640 return ret;
641 if (!trdy)
642 continue;
643 }
616 644
617 *temp = code_to_degc(last_temp, s) * 1000;645 ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);
646 if (ret)
647 return ret;
618 648
619 return 0;649 *temp = code_to_degc(last_temp, s) * 1000;
650
651 return 0;
652 } while (time_before(jiffies, timeout));
653
654 return -ETIMEDOUT;
620}655}
621 656
622#ifdef CONFIG_DEBUG_FS657#ifdef CONFIG_DEBUG_FS
@@ -738,25 +773,42 @@ int __init init_common(struct tsens_priv *priv) · 115 unmodified lines
738 priv->tm_offset = 0x1000;773 priv->tm_offset = 0x1000;
739 }774 }
740 775
741 res = platform_get_resource(op, IORESOURCE_MEM, 0);776 if (tsens_version(priv) >= VER_0_1) {
742 tm_base = devm_ioremap_resource(dev, res);777 res = platform_get_resource(op, IORESOURCE_MEM, 0);
743 if (IS_ERR(tm_base)) {778 tm_base = devm_ioremap_resource(dev, res);
744 ret = PTR_ERR(tm_base);779 if (IS_ERR(tm_base)) {
745 goto err_put_device;780 ret = PTR_ERR(tm_base);
781 goto err_put_device;
782 }
783
784 priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);
785 } else { /* VER_0 share the same gcc regs using a syscon */
786 struct device *parent = priv->dev->parent;
787
788 if (parent)
789 priv->tm_map = syscon_node_to_regmap(parent->of_node);
746 }790 }
747 791
748 priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);792 if (IS_ERR_OR_NULL(priv->tm_map)) {
749 if (IS_ERR(priv->tm_map)) {793 if (!priv->tm_map)
750 ret = PTR_ERR(priv->tm_map);794 ret = -ENODEV;
795 else
796 ret = PTR_ERR(priv->tm_map);
751 goto err_put_device;797 goto err_put_device;
752 }798 }
753 799
800 /* VER_0 have only tm_map */
801 if (!priv->srot_map)
802 priv->srot_map = priv->tm_map;
803
754 if (tsens_version(priv) > VER_0_1) {804 if (tsens_version(priv) > VER_0_1) {
755 for (i = VER_MAJOR; i <= VER_STEP; i++) {805 for (i = VER_MAJOR; i <= VER_STEP; i++) {
756 priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,806 priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,
757 priv->fields[i]);807 priv->fields[i]);
758 if (IS_ERR(priv->rf[i]))808 if (IS_ERR(priv->rf[i])) {
759 return PTR_ERR(priv->rf[i]);809 ret = PTR_ERR(priv->rf[i]);
810 goto err_put_device;
811 }
760 }812 }
761 ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor);813 ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor);
762 if (ret)814 if (ret)
@@ -769,6 +821,10 @@ int __init init_common(struct tsens_priv *priv) · 6 unmodified lines
769 ret = PTR_ERR(priv->rf[TSENS_EN]);821 ret = PTR_ERR(priv->rf[TSENS_EN]);
770 goto err_put_device;822 goto err_put_device;
771 }823 }
824 /* in VER_0 TSENS need to be explicitly enabled */
825 if (tsens_version(priv) == VER_0)
826 regmap_field_write(priv->rf[TSENS_EN], 1);
827
772 ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);828 ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
773 if (ret)829 if (ret)
774 goto err_put_device;830 goto err_put_device;
@@ -791,6 +847,19 @@ int __init init_common(struct tsens_priv *priv) · 16 unmodified lines
791 goto err_put_device;847 goto err_put_device;
792 }848 }
793 849
850 priv->rf[TSENS_SW_RST] =
851 devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[TSENS_SW_RST]);
852 if (IS_ERR(priv->rf[TSENS_SW_RST])) {
853 ret = PTR_ERR(priv->rf[TSENS_SW_RST]);
854 goto err_put_device;
855 }
856
857 priv->rf[TRDY] = devm_regmap_field_alloc(dev, priv->tm_map, priv->fields[TRDY]);
858 if (IS_ERR(priv->rf[TRDY])) {
859 ret = PTR_ERR(priv->rf[TRDY]);
860 goto err_put_device;
861 }
862
794 /* This loop might need changes if enum regfield_ids is reordered */863 /* This loop might need changes if enum regfield_ids is reordered */
795 for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {864 for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {
796 for (i = 0; i < priv->feat->max_sensors; i++) {865 for (i = 0; i < priv->feat->max_sensors; i++) {
@@ -806,7 +875,7 @@ int __init init_common(struct tsens_priv *priv) · 9 unmodified lines
806 }875 }
807 }876 }
808 877
809 if (priv->feat->crit_int) {878 if (priv->feat->crit_int || tsens_version(priv) < VER_0_1) {
810 /* Loop might need changes if enum regfield_ids is reordered */879 /* Loop might need changes if enum regfield_ids is reordered */
811 for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) {880 for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) {
812 for (i = 0; i < priv->feat->max_sensors; i++) {881 for (i = 0; i < priv->feat->max_sensors; i++) {
@@ -844,7 +913,11 @@ int __init init_common(struct tsens_priv *priv) · 31 unmodified lines
844 }913 }
845 914
846 spin_lock_init(&priv->ul_lock);915 spin_lock_init(&priv->ul_lock);
847 tsens_enable_irq(priv);916
917 /* VER_0 interrupt doesn't need to be enabled */
918 if (tsens_version(priv) >= VER_0_1)
919 tsens_enable_irq(priv);
920
848 tsens_debug_init(op);921 tsens_debug_init(op);
849 922
850err_put_device:923err_put_device:
@@ -895,6 +968,12 @@ static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume); · 44 unmodified lines
895 968
896static const struct of_device_id tsens_table[] = {969static const struct of_device_id tsens_table[] = {
897 {970 {
971 .compatible = "qcom,ipq8064-tsens",
972 .data = &data_8960,
973 }, {
974 .compatible = "qcom,mdm9607-tsens",
975 .data = &data_9607,
976 }, {
898 .compatible = "qcom,msm8916-tsens",977 .compatible = "qcom,msm8916-tsens",
899 .data = &data_8916,978 .data = &data_8916,
900 }, {979 }, {
@@ -943,10 +1022,19 @@ static int tsens_register_irq(struct tsens_priv *priv, char *irqname, · 42 unmodified lines
943 if (irq == -ENXIO)1022 if (irq == -ENXIO)
944 ret = 0;1023 ret = 0;
945 } else {1024 } else {
946 ret = devm_request_threaded_irq(&pdev->dev, irq,1025 /* VER_0 interrupt is TRIGGER_RISING, VER_0_1 and up is ONESHOT */
947 NULL, thread_fn,1026 if (tsens_version(priv) == VER_0)
948 IRQF_ONESHOT,1027 ret = devm_request_threaded_irq(&pdev->dev, irq,
949 dev_name(&pdev->dev), priv);1028 thread_fn, NULL,
1029 IRQF_TRIGGER_RISING,
1030 dev_name(&pdev->dev),
1031 priv);
1032 else
1033 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
1034 thread_fn, IRQF_ONESHOT,
1035 dev_name(&pdev->dev),
1036 priv);
1037
950 if (ret)1038 if (ret)
951 dev_err(&pdev->dev, "%s: failed to get irq\n",1039 dev_err(&pdev->dev, "%s: failed to get irq\n",
952 __func__);1040 __func__);
@@ -975,6 +1063,19 @@ static int tsens_register(struct tsens_priv *priv) · 22 unmodified lines
975 priv->ops->enable(priv, i);1063 priv->ops->enable(priv, i);
976 }1064 }
977 1065
1066 /* VER_0 require to set MIN and MAX THRESH
1067 * These 2 regs are set using the:
1068 * - CRIT_THRESH_0 for MAX THRESH hardcoded to 120°C
1069 * - CRIT_THRESH_1 for MIN THRESH hardcoded to 0°C
1070 */
1071 if (tsens_version(priv) < VER_0_1) {
1072 regmap_field_write(priv->rf[CRIT_THRESH_0],
1073 tsens_mC_to_hw(priv->sensor, 120000));
1074
1075 regmap_field_write(priv->rf[CRIT_THRESH_1],
1076 tsens_mC_to_hw(priv->sensor, 0));
1077 }
1078
978 ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);1079 ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
979 if (ret < 0)1080 if (ret < 0)
980 return ret;1081 return ret;
drivers/thermal/qcom/tsens.h+4−2
@@ -13,6 +13,7 @@ · 12 unmodified lines
13#define CAL_DEGC_PT2 12013#define CAL_DEGC_PT2 120
14#define SLOPE_FACTOR 100014#define SLOPE_FACTOR 1000
15#define SLOPE_DEFAULT 320015#define SLOPE_DEFAULT 3200
16#define TIMEOUT_US 100
16#define THRESHOLD_MAX_ADC_CODE 0x3ff17#define THRESHOLD_MAX_ADC_CODE 0x3ff
17#define THRESHOLD_MIN_ADC_CODE 0x018#define THRESHOLD_MIN_ADC_CODE 0x0
18 19
@@ -25,7 +26,8 @@ struct tsens_priv; · 6 unmodified lines
25 26
26/* IP version numbers in ascending order */27/* IP version numbers in ascending order */
27enum tsens_ver {28enum tsens_ver {
28 VER_0_1 = 0,29 VER_0 = 0,
30 VER_0_1,
29 VER_1_X,31 VER_1_X,
30 VER_2_X,32 VER_2_X,
31};33};
@@ -585,7 +587,7 @@ int get_temp_common(const struct tsens_sensor *s, int *temp); · 553 unmodified lines
585extern struct tsens_plat_data data_8960;587extern struct tsens_plat_data data_8960;
586 588
587/* TSENS v0.1 targets */589/* TSENS v0.1 targets */
588extern struct tsens_plat_data data_8916, data_8939, data_8974;590extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607;
589 591
590/* TSENS v1 targets */592/* TSENS v1 targets */
591extern struct tsens_plat_data data_tsens_v1, data_8976;593extern struct tsens_plat_data data_tsens_v1, data_8976;
drivers/thermal/rcar_gen3_thermal.c+2−1
@@ -60,7 +60,7 @@ · 59 unmodified lines
60#define MCELSIUS(temp) ((temp) * 1000)60#define MCELSIUS(temp) ((temp) * 1000)
61#define GEN3_FUSE_MASK 0xFFF61#define GEN3_FUSE_MASK 0xFFF
62 62
63#define TSC_MAX_NUM 463#define TSC_MAX_NUM 5
64 64
65/* default THCODE values if FUSEs are missing */65/* default THCODE values if FUSEs are missing */
66static const int thcodes[TSC_MAX_NUM][3] = {66static const int thcodes[TSC_MAX_NUM][3] = {
@@ -68,6 +68,7 @@ static const int thcodes[TSC_MAX_NUM][3] = { · 1 unmodified line
68 { 3393, 2795, 2216 },68 { 3393, 2795, 2216 },
69 { 3389, 2805, 2237 },69 { 3389, 2805, 2237 },
70 { 3415, 2694, 2195 },70 { 3415, 2694, 2195 },
71 { 3356, 2724, 2244 },
71};72};
72 73
73/* Structure for thermal temperature calculation */74/* Structure for thermal temperature calculation */
drivers/thermal/sun8i_thermal.c+2−2
@@ -300,7 +300,7 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev) · 299 unmodified lines
300 * or 0x8xx, so they won't be away from the default value300 * or 0x8xx, so they won't be away from the default value
301 * for a lot.301 * for a lot.
302 *302 *
303 * So here we do not return error if the calibartion data is303 * So here we do not return error if the calibration data is
304 * not available, except the probe needs deferring.304 * not available, except the probe needs deferring.
305 */305 */
306 goto out;306 goto out;
@@ -418,7 +418,7 @@ static int sun8i_h3_thermal_init(struct ths_device *tmdev) · 111 unmodified lines
418}418}
419 419
420/*420/*
421 * Without this undocummented value, the returned temperatures would421 * Without this undocumented value, the returned temperatures would
422 * be higher than real ones by about 20C.422 * be higher than real ones by about 20C.
423 */423 */
424#define SUN50I_H6_CTRL0_UNK 0x0000002f424#define SUN50I_H6_CTRL0_UNK 0x0000002f
drivers/thermal/tegra/soctherm.c+4−11
@@ -2118,7 +2118,6 @@ static int tegra_soctherm_probe(struct platform_device *pdev) · 2117 unmodified lines
2118 struct tegra_soctherm *tegra;2118 struct tegra_soctherm *tegra;
2119 struct thermal_zone_device *z;2119 struct thermal_zone_device *z;
2120 struct tsensor_shared_calib shared_calib;2120 struct tsensor_shared_calib shared_calib;
2121 struct resource *res;
2122 struct tegra_soctherm_soc *soc;2121 struct tegra_soctherm_soc *soc;
2123 unsigned int i;2122 unsigned int i;
2124 int err;2123 int err;
@@ -2140,26 +2139,20 @@ static int tegra_soctherm_probe(struct platform_device *pdev) · 15 unmodified lines
2140 2139
2141 tegra->soc = soc;2140 tegra->soc = soc;
2142 2141
2143 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,2142 tegra->regs = devm_platform_ioremap_resource_byname(pdev, "soctherm-reg");
2144 "soctherm-reg");
2145 tegra->regs = devm_ioremap_resource(&pdev->dev, res);
2146 if (IS_ERR(tegra->regs)) {2143 if (IS_ERR(tegra->regs)) {
2147 dev_err(&pdev->dev, "can't get soctherm registers");2144 dev_err(&pdev->dev, "can't get soctherm registers");
2148 return PTR_ERR(tegra->regs);2145 return PTR_ERR(tegra->regs);
2149 }2146 }
2150 2147
2151 if (!tegra->soc->use_ccroc) {2148 if (!tegra->soc->use_ccroc) {
2152 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,2149 tegra->clk_regs = devm_platform_ioremap_resource_byname(pdev, "car-reg");
2153 "car-reg");
2154 tegra->clk_regs = devm_ioremap_resource(&pdev->dev, res);
2155 if (IS_ERR(tegra->clk_regs)) {2150 if (IS_ERR(tegra->clk_regs)) {
2156 dev_err(&pdev->dev, "can't get car clk registers");2151 dev_err(&pdev->dev, "can't get car clk registers");
2157 return PTR_ERR(tegra->clk_regs);2152 return PTR_ERR(tegra->clk_regs);
2158 }2153 }
2159 } else {2154 } else {
2160 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,2155 tegra->ccroc_regs = devm_platform_ioremap_resource_byname(pdev, "ccroc-reg");
2161 "ccroc-reg");
2162 tegra->ccroc_regs = devm_ioremap_resource(&pdev->dev, res);
2163 if (IS_ERR(tegra->ccroc_regs)) {2156 if (IS_ERR(tegra->ccroc_regs)) {
2164 dev_err(&pdev->dev, "can't get ccroc registers");2157 dev_err(&pdev->dev, "can't get ccroc registers");
2165 return PTR_ERR(tegra->ccroc_regs);2158 return PTR_ERR(tegra->ccroc_regs);
@@ -2195,7 +2188,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev) · 29 unmodified lines
2195 if (err)2188 if (err)
2196 return err;2189 return err;
2197 2190
2198 /* calculate tsensor calibaration data */2191 /* calculate tsensor calibration data */
2199 for (i = 0; i < soc->num_tsensors; ++i) {2192 for (i = 0; i < soc->num_tsensors; ++i) {
2200 err = tegra_calc_tsensor_calib(&soc->tsensors[i],2193 err = tegra_calc_tsensor_calib(&soc->tsensors[i],
2201 &shared_calib,2194 &shared_calib,
drivers/thermal/thermal_core.c+23−34
@@ -561,24 +561,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz, · 560 unmodified lines
561}561}
562EXPORT_SYMBOL_GPL(thermal_zone_device_update);562EXPORT_SYMBOL_GPL(thermal_zone_device_update);
563 563
564/**
565 * thermal_notify_framework - Sensor drivers use this API to notify framework
566 * @tz: thermal zone device
567 * @trip: indicates which trip point has been crossed
568 *
569 * This function handles the trip events from sensor drivers. It starts
570 * throttling the cooling devices according to the policy configured.
571 * For CRITICAL and HOT trip points, this notifies the respective drivers,
572 * and does actual throttling for other trip points i.e ACTIVE and PASSIVE.
573 * The throttling policy is based on the configured platform data; if no
574 * platform data is provided, this uses the step_wise throttling policy.
575 */
576void thermal_notify_framework(struct thermal_zone_device *tz, int trip)
577{
578 handle_thermal_trip(tz, trip);
579}
580EXPORT_SYMBOL_GPL(thermal_notify_framework);
581
582static void thermal_zone_device_check(struct work_struct *work)564static void thermal_zone_device_check(struct work_struct *work)
583{565{
584 struct thermal_zone_device *tz = container_of(work, struct566 struct thermal_zone_device *tz = container_of(work, struct
@@ -960,10 +942,7 @@ __thermal_cooling_device_register(struct device_node *np, · 375 unmodified lines
960{942{
961 struct thermal_cooling_device *cdev;943 struct thermal_cooling_device *cdev;
962 struct thermal_zone_device *pos = NULL;944 struct thermal_zone_device *pos = NULL;
963 int result;945 int ret;
964
965 if (type && strlen(type) >= THERMAL_NAME_LENGTH)
966 return ERR_PTR(-EINVAL);
967 946
968 if (!ops || !ops->get_max_state || !ops->get_cur_state ||947 if (!ops || !ops->get_max_state || !ops->get_cur_state ||
969 !ops->set_cur_state)948 !ops->set_cur_state)
@@ -973,14 +952,17 @@ __thermal_cooling_device_register(struct device_node *np, · 3 unmodified lines
973 if (!cdev)952 if (!cdev)
974 return ERR_PTR(-ENOMEM);953 return ERR_PTR(-ENOMEM);
975 954
976 result = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);955 ret = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
977 if (result < 0) {956 if (ret < 0)
978 kfree(cdev);957 goto out_kfree_cdev;
979 return ERR_PTR(result);958 cdev->id = ret;
959
960 cdev->type = kstrdup(type ? type : "", GFP_KERNEL);
961 if (!cdev->type) {
962 ret = -ENOMEM;
963 goto out_ida_remove;
980 }964 }
981 965
982 cdev->id = result;
983 strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
984 mutex_init(&cdev->lock);966 mutex_init(&cdev->lock);
985 INIT_LIST_HEAD(&cdev->thermal_instances);967 INIT_LIST_HEAD(&cdev->thermal_instances);
986 cdev->np = np;968 cdev->np = np;
@@ -990,12 +972,9 @@ __thermal_cooling_device_register(struct device_node *np, · 3 unmodified lines
990 cdev->devdata = devdata;972 cdev->devdata = devdata;
991 thermal_cooling_device_setup_sysfs(cdev);973 thermal_cooling_device_setup_sysfs(cdev);
992 dev_set_name(&cdev->device, "cooling_device%d", cdev->id);974 dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
993 result = device_register(&cdev->device);975 ret = device_register(&cdev->device);
994 if (result) {976 if (ret)
995 ida_simple_remove(&thermal_cdev_ida, cdev->id);977 goto out_kfree_type;
996 put_device(&cdev->device);
997 return ERR_PTR(result);
998 }
999 978
1000 /* Add 'this' new cdev to the global cdev list */979 /* Add 'this' new cdev to the global cdev list */
1001 mutex_lock(&thermal_list_lock);980 mutex_lock(&thermal_list_lock);
@@ -1013,6 +992,15 @@ __thermal_cooling_device_register(struct device_node *np, · 11 unmodified lines
1013 mutex_unlock(&thermal_list_lock);992 mutex_unlock(&thermal_list_lock);
1014 993
1015 return cdev;994 return cdev;
995
996out_kfree_type:
997 kfree(cdev->type);
998 put_device(&cdev->device);
999out_ida_remove:
1000 ida_simple_remove(&thermal_cdev_ida, cdev->id);
1001out_kfree_cdev:
1002 kfree(cdev);
1003 return ERR_PTR(ret);
1016}1004}
1017 1005
1018/**1006/**
@@ -1171,6 +1159,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) · 152 unmodified lines
1171 ida_simple_remove(&thermal_cdev_ida, cdev->id);1159 ida_simple_remove(&thermal_cdev_ida, cdev->id);
1172 device_del(&cdev->device);1160 device_del(&cdev->device);
1173 thermal_cooling_device_destroy_sysfs(cdev);1161 thermal_cooling_device_destroy_sysfs(cdev);
1162 kfree(cdev->type);
1174 put_device(&cdev->device);1163 put_device(&cdev->device);
1175}1164}
1176EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister);1165EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister);
drivers/thermal/thermal_core.h+1−0
@@ -66,6 +66,7 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) · 65 unmodified lines
66}66}
67 67
68void thermal_cdev_update(struct thermal_cooling_device *);68void thermal_cdev_update(struct thermal_cooling_device *);
69void __thermal_cdev_update(struct thermal_cooling_device *cdev);
69 70
70/**71/**
71 * struct thermal_trip - representation of a point in temperature domain72 * struct thermal_trip - representation of a point in temperature domain
drivers/thermal/thermal_helpers.c+17−10
@@ -192,18 +192,11 @@ static void thermal_cdev_set_cur_state(struct thermal_cooling_device *cdev, · 191 unmodified lines
192 thermal_cooling_device_stats_update(cdev, target);192 thermal_cooling_device_stats_update(cdev, target);
193}193}
194 194
195void thermal_cdev_update(struct thermal_cooling_device *cdev)195void __thermal_cdev_update(struct thermal_cooling_device *cdev)
196{196{
197 struct thermal_instance *instance;197 struct thermal_instance *instance;
198 unsigned long target = 0;198 unsigned long target = 0;
199 199
200 mutex_lock(&cdev->lock);
201 /* cooling device is updated*/
202 if (cdev->updated) {
203 mutex_unlock(&cdev->lock);
204 return;
205 }
206
207 /* Make sure cdev enters the deepest cooling state */200 /* Make sure cdev enters the deepest cooling state */
208 list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {201 list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
209 dev_dbg(&cdev->device, "zone%d->target=%lu\n",202 dev_dbg(&cdev->device, "zone%d->target=%lu\n",
@@ -216,11 +209,25 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev) · 6 unmodified lines
216 209
217 thermal_cdev_set_cur_state(cdev, target);210 thermal_cdev_set_cur_state(cdev, target);
218 211
219 cdev->updated = true;
220 mutex_unlock(&cdev->lock);
221 trace_cdev_update(cdev, target);212 trace_cdev_update(cdev, target);
222 dev_dbg(&cdev->device, "set to state %lu\n", target);213 dev_dbg(&cdev->device, "set to state %lu\n", target);
223}214}
215
216/**
217 * thermal_cdev_update - update cooling device state if needed
218 * @cdev: pointer to struct thermal_cooling_device
219 *
220 * Update the cooling device state if there is a need.
221 */
222void thermal_cdev_update(struct thermal_cooling_device *cdev)
223{
224 mutex_lock(&cdev->lock);
225 if (!cdev->updated) {
226 __thermal_cdev_update(cdev);
227 cdev->updated = true;
228 }
229 mutex_unlock(&cdev->lock);
230}
224EXPORT_SYMBOL(thermal_cdev_update);231EXPORT_SYMBOL(thermal_cdev_update);
225 232
226/**233/**
drivers/thermal/thermal_mmio.c+1−4
@@ -54,11 +54,8 @@ static int thermal_mmio_probe(struct platform_device *pdev) · 53 unmodified lines
54 54
55 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);55 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
56 sensor->mmio_base = devm_ioremap_resource(&pdev->dev, resource);56 sensor->mmio_base = devm_ioremap_resource(&pdev->dev, resource);
57 if (IS_ERR(sensor->mmio_base)) {57 if (IS_ERR(sensor->mmio_base))
58 dev_err(&pdev->dev, "failed to ioremap memory (%ld)\n",
59 PTR_ERR(sensor->mmio_base));
60 return PTR_ERR(sensor->mmio_base);58 return PTR_ERR(sensor->mmio_base);
61 }
62 59
63 sensor_init_func = device_get_match_data(&pdev->dev);60 sensor_init_func = device_get_match_data(&pdev->dev);
64 if (sensor_init_func) {61 if (sensor_init_func) {
drivers/thermal/thermal_of.c+5−2
@@ -704,14 +704,17 @@ static int thermal_of_populate_bind_params(struct device_node *np, · 703 unmodified lines
704 704
705 count = of_count_phandle_with_args(np, "cooling-device",705 count = of_count_phandle_with_args(np, "cooling-device",
706 "#cooling-cells");706 "#cooling-cells");
707 if (!count) {707 if (count <= 0) {
708 pr_err("Add a cooling_device property with at least one device\n");708 pr_err("Add a cooling_device property with at least one device\n");
709 ret = -ENOENT;
709 goto end;710 goto end;
710 }711 }
711 712
712 __tcbp = kcalloc(count, sizeof(*__tcbp), GFP_KERNEL);713 __tcbp = kcalloc(count, sizeof(*__tcbp), GFP_KERNEL);
713 if (!__tcbp)714 if (!__tcbp) {
715 ret = -ENOMEM;
714 goto end;716 goto end;
717 }
715 718
716 for (i = 0; i < count; i++) {719 for (i = 0; i < count; i++) {
717 ret = of_parse_phandle_with_args(np, "cooling-device",720 ret = of_parse_phandle_with_args(np, "cooling-device",
drivers/thermal/ti-soc-thermal/ti-bandgap.c+16−21
@@ -9,30 +9,29 @@ · 8 unmodified lines
9 * Eduardo Valentin <eduardo.valentin@ti.com>9 * Eduardo Valentin <eduardo.valentin@ti.com>
10 */10 */
11 11
12#include <linux/module.h>12#include <linux/clk.h>
13#include <linux/cpu_pm.h>
14#include <linux/device.h>
15#include <linux/err.h>
13#include <linux/export.h>16#include <linux/export.h>
17#include <linux/gpio/consumer.h>
14#include <linux/init.h>18#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/interrupt.h>19#include <linux/interrupt.h>
17#include <linux/clk.h>
18#include <linux/gpio/consumer.h>
19#include <linux/platform_device.h>
20#include <linux/err.h>
21#include <linux/types.h>
22#include <linux/spinlock.h>
23#include <linux/sys_soc.h>
24#include <linux/reboot.h>
25#include <linux/of_device.h>
26#include <linux/of_platform.h>
27#include <linux/of_irq.h>
28#include <linux/io.h>20#include <linux/io.h>
29#include <linux/iopoll.h>21#include <linux/iopoll.h>
30#include <linux/cpu_pm.h>22#include <linux/kernel.h>
31#include <linux/device.h>23#include <linux/module.h>
32#include <linux/pm_runtime.h>
33#include <linux/pm.h>
34#include <linux/of.h>24#include <linux/of.h>
35#include <linux/of_device.h>25#include <linux/of_device.h>
26#include <linux/of_irq.h>
27#include <linux/of_platform.h>
28#include <linux/platform_device.h>
29#include <linux/pm.h>
30#include <linux/pm_runtime.h>
31#include <linux/reboot.h>
32#include <linux/spinlock.h>
33#include <linux/sys_soc.h>
34#include <linux/types.h>
36 35
37#include "ti-bandgap.h"36#include "ti-bandgap.h"
38 37
@@ -1143,14 +1142,10 @@ static int ti_bandgap_restore_ctxt(struct ti_bandgap *bgp) · 1104 unmodified lines
1143 for (i = 0; i < bgp->conf->sensor_count; i++) {1142 for (i = 0; i < bgp->conf->sensor_count; i++) {
1144 struct temp_sensor_registers *tsr;1143 struct temp_sensor_registers *tsr;
1145 struct temp_sensor_regval *rval;1144 struct temp_sensor_regval *rval;
1146 u32 val = 0;
1147 1145
1148 rval = &bgp->regval[i];1146 rval = &bgp->regval[i];
1149 tsr = bgp->conf->sensors[i].registers;1147 tsr = bgp->conf->sensors[i].registers;
1150 1148
1151 if (TI_BANDGAP_HAS(bgp, COUNTER))
1152 val = ti_bandgap_readl(bgp, tsr->bgap_counter);
1153
1154 if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG))1149 if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG))
1155 ti_bandgap_writel(bgp, rval->tshut_threshold,1150 ti_bandgap_writel(bgp, rval->tshut_threshold,
1156 tsr->tshut_threshold);1151 tsr->tshut_threshold);
include/linux/thermal.h+1−6
@@ -91,7 +91,7 @@ struct thermal_cooling_device_ops { · 90 unmodified lines
91 91
92struct thermal_cooling_device {92struct thermal_cooling_device {
93 int id;93 int id;
94 char type[THERMAL_NAME_LENGTH];94 char *type;
95 struct device device;95 struct device device;
96 struct device_node *np;96 struct device_node *np;
97 void *devdata;97 void *devdata;
@@ -390,7 +390,6 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); · 292 unmodified lines
390int thermal_zone_get_slope(struct thermal_zone_device *tz);390int thermal_zone_get_slope(struct thermal_zone_device *tz);
391int thermal_zone_get_offset(struct thermal_zone_device *tz);391int thermal_zone_get_offset(struct thermal_zone_device *tz);
392 392
393void thermal_notify_framework(struct thermal_zone_device *, int);
394int thermal_zone_device_enable(struct thermal_zone_device *tz);393int thermal_zone_device_enable(struct thermal_zone_device *tz);
395int thermal_zone_device_disable(struct thermal_zone_device *tz);394int thermal_zone_device_disable(struct thermal_zone_device *tz);
396void thermal_zone_device_critical(struct thermal_zone_device *tz);395void thermal_zone_device_critical(struct thermal_zone_device *tz);
@@ -436,10 +435,6 @@ static inline int thermal_zone_get_offset( · 39 unmodified lines
436 struct thermal_zone_device *tz)435 struct thermal_zone_device *tz)
437{ return -ENODEV; }436{ return -ENODEV; }
438 437
439static inline void thermal_notify_framework(struct thermal_zone_device *tz,
440 int trip)
441{ }
442
443static inline int thermal_zone_device_enable(struct thermal_zone_device *tz)438static inline int thermal_zone_device_enable(struct thermal_zone_device *tz)
444{ return -ENODEV; }439{ return -ENODEV; }
445 440
include/uapi/linux/thermal.h+1−1
@@ -60,7 +60,7 @@ enum thermal_genl_event { · 59 unmodified lines
60 THERMAL_GENL_EVENT_UNSPEC,60 THERMAL_GENL_EVENT_UNSPEC,
61 THERMAL_GENL_EVENT_TZ_CREATE, /* Thermal zone creation */61 THERMAL_GENL_EVENT_TZ_CREATE, /* Thermal zone creation */
62 THERMAL_GENL_EVENT_TZ_DELETE, /* Thermal zone deletion */62 THERMAL_GENL_EVENT_TZ_DELETE, /* Thermal zone deletion */
63 THERMAL_GENL_EVENT_TZ_DISABLE, /* Thermal zone disabed */63 THERMAL_GENL_EVENT_TZ_DISABLE, /* Thermal zone disabled */
64 THERMAL_GENL_EVENT_TZ_ENABLE, /* Thermal zone enabled */64 THERMAL_GENL_EVENT_TZ_ENABLE, /* Thermal zone enabled */
65 THERMAL_GENL_EVENT_TZ_TRIP_UP, /* Trip point crossed the way up */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 */66 THERMAL_GENL_EVENT_TZ_TRIP_DOWN, /* Trip point crossed the way down */

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