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−
3−This binding describes thermal sensor that is part of Northstar's DMU (Device
4−Management Unit).
5−
6−Required properties:
7−- compatible : Must be "brcm,ns-thermal"
8−- reg : iomem address range of PVTMON registers
9−- #thermal-sensor-cells : Should be <0>
10−
11−Example:
12−
13−thermal: thermal@1800c2c0 {
14− compatible = "brcm,ns-thermal";
15− reg = <0x1800c2c0 0x10>;
16− #thermal-sensor-cells = <0>;
17−};
18−
19−thermal-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+
7+title: Broadcom Northstar Thermal
8+
9+maintainers:
10+ - Rafał Miłecki <rafal@milecki.pl>
11+
12+description:
13+ Thermal sensor that is part of Northstar's DMU (Device Management Unit).
14+
15+allOf:
16+ - $ref: thermal-sensor.yaml#
17+
18+properties:
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+
29+unevaluatedProperties: false
30+
31+required:
32+ - reg
33+
34+examples:
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
1919 properties:
2020 compatible:
2121 oneOf:
22+ - description: msm9860 TSENS based
23+ items:
24+ - enum:
25+ - qcom,ipq8064-tsens
26+
2227 - description: v0.1 of TSENS
2328 items:
2429 - enum:
30+ - qcom,mdm9607-tsens
2531 - qcom,msm8916-tsens
2632 - qcom,msm8939-tsens
2733 - qcom,msm8974-tsens
@@ -43,6 +49,7 @@ properties: · 15 unmodified lines
4349 - qcom,sdm845-tsens
4450 - qcom,sm8150-tsens
4551 - qcom,sm8250-tsens
52+ - qcom,sm8350-tsens
4653 - const: qcom,tsens-v2
4754
4855 reg:
@@ -73,7 +80,9 @@ properties: · 24 unmodified lines
7380 maxItems: 2
7481 items:
7582 - const: calib
76− - const: calib_sel
83+ - enum:
84+ - calib_backup
85+ - calib_sel
7786
7887 "#qcom,sensors":
7988 description:
@@ -88,12 +97,21 @@ properties: · 8 unmodified lines
8897 Number of cells required to uniquely identify the thermal sensors. Since
8998 we have multiple sensors this is set to 1
9099
100+required:
101+ - compatible
102+ - interrupts
103+ - interrupt-names
104+ - "#thermal-sensor-cells"
105+ - "#qcom,sensors"
106+
91107 allOf:
92108 - if:
93109 properties:
94110 compatible:
95111 contains:
96112 enum:
113+ - qcom,ipq8064-tsens
114+ - qcom,mdm9607-tsens
97115 - qcom,msm8916-tsens
98116 - qcom,msm8974-tsens
99117 - qcom,msm8976-tsens
@@ -114,17 +132,42 @@ allOf: · 14 unmodified lines
114132 interrupt-names:
115133 minItems: 2
116134
117−required:
118− - compatible
119− - reg
120− - "#qcom,sensors"
121− - interrupts
122− - interrupt-names
123− - "#thermal-sensor-cells"
135+ - if:
136+ properties:
137+ compatible:
138+ contains:
139+ enum:
140+ - qcom,tsens-v0_1
141+ - qcom,tsens-v1
142+ - qcom,tsens-v2
143+
144+ then:
145+ required:
146+ - reg
124147
125148 additionalProperties: false
126149
127150 examples:
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+
128171 - |
129172 #include <dt-bindings/interrupt-controller/arm-gic.h>
130173 // 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
2828 - renesas,r8a77980-thermal # R-Car V3H
2929 - renesas,r8a779a0-thermal # R-Car V3U
3030
31− reg:
32− minItems: 2
33− maxItems: 4
34− items:
35− - description: TSC1 registers
36− - description: TSC2 registers
37− - description: TSC3 registers
38− - description: TSC4 registers
31+ reg: true
3932
4033 interrupts:
4134 items:
@@ -71,8 +64,25 @@ if: · 29 unmodified lines
7164 enum:
7265 - renesas,r8a779a0-thermal
7366 then:
67+ properties:
68+ reg:
69+ minItems: 2
70+ maxItems: 3
71+ items:
72+ - description: TSC1 registers
73+ - description: TSC2 registers
74+ - description: TSC3 registers
7475 required:
7576 - interrupts
77+else:
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
7686
7787 additionalProperties: false
7888
@@ -111,3 +121,20 @@ examples: · 32 unmodified lines
111121 };
112122 };
113123 };
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
3636 containing several internal sensors.
3737 enum: [0, 1]
3838
39+required:
40+ - "#thermal-sensor-cells"
41+
3942 additionalProperties: true
4043
4144 examples:
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
730730 {thermal_zone, cooling_device, trip_point} combination. Returns NULL
731731 if such an instance does not exist.
732732
733−4.3. thermal_notify_framework
734−-----------------------------
735−
736−This function handles the trip events from sensor drivers. It starts
737−throttling the cooling devices according to the policy configured.
738−For CRITICAL and HOT trip points, this notifies the respective drivers,
739−and does actual throttling for other trip points i.e ACTIVE and PASSIVE.
740−The throttling policy is based on the configured platform data; if no
741−platform data is provided, this uses the step_wise throttling policy.
742−
743−4.4. thermal_cdev_update
733+4.3. thermal_cdev_update
744734 ------------------------
745735
746736 This 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
1519715197
1519815198 QUALCOMM TSENS THERMAL DRIVER
1519915199 M: Amit Kucheria <amitk@kernel.org>
15200+M: Thara Gopinath <thara.gopinath@linaro.org>
1520015201 L: linux-pm@vger.kernel.org
1520115202 L: linux-arm-msm@vger.kernel.org
1520215203 S: Maintained
@@ -18101,7 +18102,7 @@ THERMAL/CPU_COOLING · 2898 unmodified lines
1810118102 M: Amit Daniel Kachhap <amit.kachhap@gmail.com>
1810218103 M: Daniel Lezcano <daniel.lezcano@linaro.org>
1810318104 M: Viresh Kumar <viresh.kumar@linaro.org>
18104−M: Javi Merino <javi.merino@kernel.org>
18105+R: Lukasz Luba <lukasz.luba@arm.com>
1810518106 L: linux-pm@vger.kernel.org
1810618107 S: Supported
1810718108 F: 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
132132 /* Allow mlxsw thermal zone binding to an external cooling device */
133133 for (i = 0; i < ARRAY_SIZE(mlxsw_thermal_external_allowed_cdev); i++) {
134134 if (strnstr(cdev->type, mlxsw_thermal_external_allowed_cdev[i],
135− sizeof(cdev->type)))
135+ strlen(cdev->type)))
136136 return 0;
137137 }
138138
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
146146 if (mvm->tz_device.tzone) {
147147 struct iwl_mvm_thermal_device *tz_dev = &mvm->tz_device;
148148
149− thermal_notify_framework(tz_dev->tzone,
150− tz_dev->fw_trips_index[ths_crossed]);
149+ thermal_zone_device_update(tz_dev->tzone,
150+ THERMAL_TRIP_VIOLATED);
151151 }
152152 #endif /* CONFIG_THERMAL */
153153 }
drivers/thermal/amlogic_thermal.c+1−3
@@ -254,10 +254,8 @@ static int amlogic_thermal_probe(struct platform_device *pdev) · 253 unmodified lines
254254 platform_set_drvdata(pdev, pdata);
255255
256256 base = devm_platform_ioremap_resource(pdev, 0);
257− if (IS_ERR(base)) {
258− dev_err(dev, "failed to get io address\n");
257+ if (IS_ERR(base))
259258 return PTR_ERR(base);
260− }
261259
262260 pdata->regmap = devm_regmap_init_mmio(dev, base,
263261 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
184184 data->regs = devm_ioremap_resource(&pdev->dev, res);
185185 if (IS_ERR(data->regs)) {
186186 err = PTR_ERR(data->regs);
187− dev_err(&pdev->dev, "Could not get registers: %d\n", err);
188187 return err;
189188 }
190189
drivers/thermal/cpufreq_cooling.c+13−36
@@ -13,10 +13,10 @@ · 12 unmodified lines
1313 #include <linux/cpu.h>
1414 #include <linux/cpufreq.h>
1515 #include <linux/cpu_cooling.h>
16+#include <linux/device.h>
1617 #include <linux/energy_model.h>
1718 #include <linux/err.h>
1819 #include <linux/export.h>
19−#include <linux/idr.h>
2020 #include <linux/pm_opp.h>
2121 #include <linux/pm_qos.h>
2222 #include <linux/slab.h>
@@ -50,8 +50,6 @@ struct time_in_idle { · 27 unmodified lines
5050
5151 /**
5252 * struct cpufreq_cooling_device - data for cooling device with cpufreq
53− * @id: unique integer value corresponding to each cpufreq_cooling_device
54− * registered.
5553 * @last_load: load measured by the latest call to cpufreq_get_requested_power()
5654 * @cpufreq_state: integer value representing the current state of cpufreq
5755 * cooling devices.
@@ -61,7 +59,6 @@ struct time_in_idle { · 3 unmodified lines
6159 * @cdev: thermal_cooling_device pointer to keep track of the
6260 * registered cooling device.
6361 * @policy: cpufreq policy.
64− * @node: list_head to link all cpufreq_cooling_device together.
6562 * @idle_time: idle time stats
6663 * @qos_req: PM QoS contraint to apply
6764 *
@@ -69,23 +66,17 @@ struct time_in_idle { · 1 unmodified line
6966 * cpufreq_cooling_device.
7067 */
7168 struct cpufreq_cooling_device {
72− int id;
7369 u32 last_load;
7470 unsigned int cpufreq_state;
7571 unsigned int max_level;
7672 struct em_perf_domain *em;
7773 struct cpufreq_policy *policy;
78− struct list_head node;
7974 #ifndef CONFIG_SMP
8075 struct time_in_idle *idle_time;
8176 #endif
8277 struct freq_qos_request qos_req;
8378 };
8479
85−static DEFINE_IDA(cpufreq_ida);
86−static DEFINE_MUTEX(cooling_list_lock);
87−static LIST_HEAD(cpufreq_cdev_list);
88−
8980 #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
9081 /**
9182 * 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
125116 {
126117 int i;
127118
128− for (i = cpufreq_cdev->max_level; i >= 0; i--) {
119+ for (i = cpufreq_cdev->max_level; i > 0; i--) {
129120 if (power >= cpufreq_cdev->em->table[i].power)
130121 break;
131122 }
@@ -528,11 +519,11 @@ __cpufreq_cooling_register(struct device_node *np, · 396 unmodified lines
528519 {
529520 struct thermal_cooling_device *cdev;
530521 struct cpufreq_cooling_device *cpufreq_cdev;
531− char dev_name[THERMAL_NAME_LENGTH];
532522 unsigned int i;
533523 struct device *dev;
534524 int ret;
535525 struct thermal_cooling_device_ops *cooling_ops;
526+ char *name;
536527
537528 dev = get_cpu_device(policy->cpu);
538529 if (unlikely(!dev)) {
@@ -567,16 +558,6 @@ __cpufreq_cooling_register(struct device_node *np, · 28 unmodified lines
567558 /* max_level is an index, not a counter */
568559 cpufreq_cdev->max_level = i - 1;
569560
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−
580561 cooling_ops = &cpufreq_cooling_ops;
581562
582563 #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
@@ -591,7 +572,7 @@ __cpufreq_cooling_register(struct device_node *np, · 8 unmodified lines
591572 pr_err("%s: unsorted frequency tables are not supported\n",
592573 __func__);
593574 cdev = ERR_PTR(-EINVAL);
594− goto remove_ida;
575+ goto free_idle_time;
595576 }
596577
597578 ret = freq_qos_add_request(&policy->constraints,
@@ -601,24 +582,25 @@ __cpufreq_cooling_register(struct device_node *np, · 3 unmodified lines
601582 pr_err("%s: Failed to add freq constraint (%d)\n", __func__,
602583 ret);
603584 cdev = ERR_PTR(ret);
604− goto remove_ida;
585+ goto free_idle_time;
605586 }
606587
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,
608594 cooling_ops);
595+ kfree(name);
596+
609597 if (IS_ERR(cdev))
610598 goto remove_qos_req;
611599
612− mutex_lock(&cooling_list_lock);
613− list_add(&cpufreq_cdev->node, &cpufreq_cdev_list);
614− mutex_unlock(&cooling_list_lock);
615−
616600 return cdev;
617601
618602 remove_qos_req:
619603 freq_qos_remove_request(&cpufreq_cdev->qos_req);
620−remove_ida:
621− ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
622604 free_idle_time:
623605 free_idle_time(cpufreq_cdev);
624606 free_cdev:
@@ -706,13 +688,8 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) · 81 unmodified lines
706688
707689 cpufreq_cdev = cdev->devdata;
708690
709− mutex_lock(&cooling_list_lock);
710− list_del(&cpufreq_cdev->node);
711− mutex_unlock(&cooling_list_lock);
712−
713691 thermal_cooling_device_unregister(cdev);
714692 freq_qos_remove_request(&cpufreq_cdev->qos_req);
715− ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
716693 free_idle_time(cpufreq_cdev);
717694 kfree(cpufreq_cdev);
718695 }
drivers/thermal/cpuidle_cooling.c+19−18
@@ -9,9 +9,9 @@ · 8 unmodified lines
99
1010 #include <linux/cpu_cooling.h>
1111 #include <linux/cpuidle.h>
12+#include <linux/device.h>
1213 #include <linux/err.h>
1314 #include <linux/idle_inject.h>
14−#include <linux/idr.h>
1515 #include <linux/of_device.h>
1616 #include <linux/slab.h>
1717 #include <linux/thermal.h>
@@ -26,8 +26,6 @@ struct cpuidle_cooling_device { · 8 unmodified lines
2626 unsigned long state;
2727 };
2828
29−static DEFINE_IDA(cpuidle_ida);
30−
3129 /**
3230 * cpuidle_cooling_runtime - Running time computation
3331 * @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
174172 struct idle_inject_device *ii_dev;
175173 struct cpuidle_cooling_device *idle_cdev;
176174 struct thermal_cooling_device *cdev;
175+ struct device *dev;
177176 unsigned int idle_duration_us = TICK_USEC;
178177 unsigned int latency_us = UINT_MAX;
179− char dev_name[THERMAL_NAME_LENGTH];
180− int id, ret;
178+ char *name;
179+ int ret;
181180
182181 idle_cdev = kzalloc(sizeof(*idle_cdev), GFP_KERNEL);
183182 if (!idle_cdev) {
@@ -185,16 +184,10 @@ static int __cpuidle_cooling_register(struct device_node *np, · 1 unmodified line
185184 goto out;
186185 }
187186
188− id = ida_simple_get(&cpuidle_ida, 0, 0, GFP_KERNEL);
189− if (id < 0) {
190− ret = id;
191− goto out_kfree;
192− }
193−
194187 ii_dev = idle_inject_register(drv->cpumask);
195188 if (!ii_dev) {
196189 ret = -EINVAL;
197− goto out_id;
190+ goto out_kfree;
198191 }
199192
200193 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
205198
206199 idle_cdev->ii_dev = ii_dev;
207200
208− snprintf(dev_name, sizeof(dev_name), "thermal-idle-%d", id);
201+ dev = get_cpu_device(cpumask_first(drv->cpumask));
209202
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,
211210 &cpuidle_cooling_ops);
212211 if (IS_ERR(cdev)) {
213212 ret = PTR_ERR(cdev);
214− goto out_unregister;
213+ goto out_kfree_name;
215214 }
216215
217216 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);
219220
220221 return 0;
221222
223+out_kfree_name:
224+ kfree(name);
222225 out_unregister:
223226 idle_inject_unregister(ii_dev);
224−out_id:
225− ida_simple_remove(&cpuidle_ida, id);
226227 out_kfree:
227228 kfree(idle_cdev);
228229 out:
drivers/thermal/devfreq_cooling.c+8−17
@@ -14,7 +14,6 @@ · 13 unmodified lines
1414 #include <linux/devfreq_cooling.h>
1515 #include <linux/energy_model.h>
1616 #include <linux/export.h>
17−#include <linux/idr.h>
1817 #include <linux/slab.h>
1918 #include <linux/pm_opp.h>
2019 #include <linux/pm_qos.h>
@@ -25,11 +24,8 @@ · 4 unmodified lines
2524 #define HZ_PER_KHZ 1000
2625 #define SCALE_ERROR_MITIGATION 100
2726
28−static DEFINE_IDA(devfreq_ida);
29−
3027 /**
3128 * struct devfreq_cooling_device - Devfreq cooling device
32− * @id: unique integer value corresponding to each
3329 * devfreq_cooling_device registered.
3430 * @cdev: Pointer to associated thermal cooling device.
3531 * @devfreq: Pointer to associated devfreq device.
@@ -51,7 +47,6 @@ static DEFINE_IDA(devfreq_ida); · 15 unmodified lines
5147 * @em_pd: Energy Model for the associated Devfreq device
5248 */
5349 struct devfreq_cooling_device {
54− int id;
5550 struct thermal_cooling_device *cdev;
5651 struct devfreq *devfreq;
5752 unsigned long cooling_state;
@@ -363,7 +358,7 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, · 305 unmodified lines
363358 struct thermal_cooling_device *cdev;
364359 struct device *dev = df->dev.parent;
365360 struct devfreq_cooling_device *dfc;
366− char dev_name[THERMAL_NAME_LENGTH];
361+ char *name;
367362 int err, num_opps;
368363
369364 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
407402 if (err < 0)
408403 goto free_table;
409404
410− err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL);
411− if (err < 0)
405+ err = -ENOMEM;
406+ name = kasprintf(GFP_KERNEL, "devfreq-%s", dev_name(dev));
407+ if (!name)
412408 goto remove_qos_req;
413409
414− dfc->id = err;
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,
410+ cdev = thermal_of_cooling_device_register(np, name, dfc,
419411 &devfreq_cooling_ops);
412+ kfree(name);
413+
420414 if (IS_ERR(cdev)) {
421415 err = PTR_ERR(cdev);
422416 dev_err(dev,
423417 "Failed to register devfreq cooling device (%d)\n",
424418 err);
425− goto release_ida;
419+ goto remove_qos_req;
426420 }
427421
428422 dfc->cdev = cdev;
429423
430424 return cdev;
431425
432−release_ida:
433− ida_simple_remove(&devfreq_ida, dfc->id);
434426 remove_qos_req:
435427 dev_pm_qos_remove_request(&dfc->req_max_freq);
436428 free_table:
@@ -527,7 +519,6 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev) · 90 unmodified lines
527519 dev = dfc->devfreq->dev.parent;
528520
529521 thermal_cooling_device_unregister(dfc->cdev);
530− ida_simple_remove(&devfreq_ida, dfc->id);
531522 dev_pm_qos_remove_request(&dfc->req_max_freq);
532523
533524 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
8282 int total_instance = 0;
8383 int cur_trip_level = get_trip_level(tz);
8484
85+ mutex_lock(&tz->lock);
86+
8587 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
8688 if (instance->trip != trip)
8789 continue;
@@ -105,11 +107,12 @@ static int fair_share_throttle(struct thermal_zone_device *tz, int trip) · 17 unmodified lines
105107 instance->target = get_target_state(tz, cdev, percentage,
106108 cur_trip_level);
107109
108− mutex_lock(&instance->cdev->lock);
109− instance->cdev->updated = false;
110− mutex_unlock(&instance->cdev->lock);
111− thermal_cdev_update(cdev);
110+ mutex_lock(&cdev->lock);
111+ __thermal_cdev_update(cdev);
112+ mutex_unlock(&cdev->lock);
112113 }
114+
115+ mutex_unlock(&tz->lock);
113116 return 0;
114117 }
115118
drivers/thermal/gov_power_allocator.c+23−9
@@ -301,9 +301,8 @@ power_actor_set_power(struct thermal_cooling_device *cdev, · 300 unmodified lines
301301
302302 instance->target = clamp_val(state, instance->lower, instance->upper);
303303 mutex_lock(&cdev->lock);
304− cdev->updated = false;
304+ __thermal_cdev_update(cdev);
305305 mutex_unlock(&cdev->lock);
306− thermal_cdev_update(cdev);
307306
308307 return 0;
309308 }
@@ -374,9 +373,11 @@ static void divvy_up_power(u32 *req_power, u32 *max_power, int num_actors, · 64 unmodified lines
374373 */
375374 extra_power = min(extra_power, capped_extra_power);
376375 if (capped_extra_power > 0)
377− for (i = 0; i < num_actors; i++)
378− granted_power[i] += (extra_actor_power[i] *
379− extra_power) / capped_extra_power;
376+ for (i = 0; i < num_actors; i++) {
377+ u64 extra_range = (u64)extra_actor_power[i] * extra_power;
378+ granted_power[i] += DIV_ROUND_CLOSEST_ULL(extra_range,
379+ capped_extra_power);
380+ }
380381 }
381382
382383 static 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
569570 params->prev_err = 0;
570571 }
571572
572−static void allow_maximum_power(struct thermal_zone_device *tz)
573+static void allow_maximum_power(struct thermal_zone_device *tz, bool update)
573574 {
574575 struct thermal_instance *instance;
575576 struct power_allocator_params *params = tz->governor_data;
577+ u32 req_power;
576578
577579 mutex_lock(&tz->lock);
578580 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
581+ struct thermal_cooling_device *cdev = instance->cdev;
582+
579583 if ((instance->trip != params->trip_max_desired_temperature) ||
580584 (!cdev_is_power_actor(instance->cdev)))
581585 continue;
582586
583587 instance->target = 0;
584588 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+
586599 mutex_unlock(&instance->cdev->lock);
587− thermal_cdev_update(instance->cdev);
588600 }
589601 mutex_unlock(&tz->lock);
590602 }
@@ -698,6 +710,7 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) · 107 unmodified lines
698710 int ret;
699711 int switch_on_temp, control_temp;
700712 struct power_allocator_params *params = tz->governor_data;
713+ bool update;
701714
702715 /*
703716 * 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
709722 ret = tz->ops->get_trip_temp(tz, params->trip_switch_on,
710723 &switch_on_temp);
711724 if (!ret && (tz->temperature < switch_on_temp)) {
725+ update = (tz->last_temperature >= switch_on_temp);
712726 tz->passive = 0;
713727 reset_pid_controller(params);
714− allow_maximum_power(tz);
728+ allow_maximum_power(tz, update);
715729 return 0;
716730 }
717731
drivers/thermal/hisi_thermal.c+4−6
@@ -1,7 +1,7 @@
11 /*
2− * Hisilicon thermal sensor driver
2+ * HiSilicon thermal sensor driver
33 *
4− * Copyright (c) 2014-2015 Hisilicon Limited.
4+ * Copyright (c) 2014-2015 HiSilicon Limited.
55 * Copyright (c) 2014-2015 Linaro Limited.
66 *
77 * Xinwei Kong <kong.kongxinwei@hisilicon.com>
@@ -572,10 +572,8 @@ static int hisi_thermal_probe(struct platform_device *pdev) · 564 unmodified lines
572572
573573 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
574574 data->regs = devm_ioremap_resource(dev, res);
575− if (IS_ERR(data->regs)) {
576− dev_err(dev, "failed to get io address\n");
575+ if (IS_ERR(data->regs))
577576 return PTR_ERR(data->regs);
578− }
579577
580578 ret = data->ops->probe(data);
581579 if (ret)
@@ -672,5 +670,5 @@ module_platform_driver(hisi_thermal_driver); · 90 unmodified lines
672670
673671 MODULE_AUTHOR("Xinwei Kong <kong.kongxinwei@hisilicon.com>");
674672 MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>");
675−MODULE_DESCRIPTION("Hisilicon thermal driver");
673+MODULE_DESCRIPTION("HiSilicon thermal driver");
676674 MODULE_LICENSE("GPL v2");
drivers/thermal/intel/Kconfig+11−0
@@ -79,3 +79,14 @@ config INTEL_PCH_THERMAL · 78 unmodified lines
7979 Enable this to support thermal reporting on certain intel PCHs.
8080 Thermal reporting device will provide temperature reading,
8181 programmable trip points and other information.
82+
83+config 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
1010 obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/
1111 obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o
1212 obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o
13+obj-$(CONFIG_INTEL_TCC_COOLING) += intel_tcc_cooling.o
1314 obj-$(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+
18+static struct thermal_cooling_device *tcc_cdev;
19+
20+static 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+
27+static 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+
46+static 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+
60+static int tcc_set_cur_state(struct thermal_cooling_device *cdev, unsigned long
61+ state)
62+{
63+ return tcc_offset_update(state);
64+}
65+
66+static 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+
72+static 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+
85+MODULE_DEVICE_TABLE(x86cpu, tcc_ids);
86+
87+static 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+
118+module_init(tcc_cooling_init)
119+
120+static void __exit tcc_cooling_exit(void)
121+{
122+ thermal_cooling_device_unregister(tcc_cdev);
123+}
124+
125+module_exit(tcc_cooling_exit)
126+
127+MODULE_DESCRIPTION("TCC offset cooling device Driver");
128+MODULE_AUTHOR("Zhang Rui <rui.zhang@intel.com>");
129+MODULE_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
573573
574574 static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
575575 {
576− s32 format_1 = 0;
577− s32 format_2 = 0;
578− s32 g_oe = 1;
579− s32 g_gain = 1;
580− s32 g_x_roomt = 0;
581− s32 tmp = 0;
576+ s32 format_1;
577+ s32 format_2;
578+ s32 g_oe;
579+ s32 g_gain;
580+ s32 g_x_roomt;
581+ s32 tmp;
582582
583583 if (raw == 0)
584584 return 0;
drivers/thermal/qcom/qcom-spmi-temp-alarm.c+61−30
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717
1818 #include "../thermal_core.h"
1919
20+#define QPNP_TM_REG_DIG_MAJOR 0x01
2021 #define QPNP_TM_REG_TYPE 0x04
2122 #define QPNP_TM_REG_SUBTYPE 0x05
2223 #define QPNP_TM_REG_STATUS 0x08
@@ -38,26 +39,30 @@ · 15 unmodified lines
3839
3940 #define ALARM_CTRL_FORCE_ENABLE BIT(7)
4041
41−/*
42− * Trip point values based on threshold control
43− * 0 = {105 C, 125 C, 145 C}
44− * 1 = {110 C, 130 C, 150 C}
45− * 2 = {115 C, 135 C, 155 C}
46− * 3 = {120 C, 140 C, 160 C}
47−*/
48−#define TEMP_STAGE_STEP 20000 /* Stage step: 20.000 C */
49−#define TEMP_STAGE_HYSTERESIS 2000
42+#define THRESH_COUNT 4
43+#define STAGE_COUNT 3
44+
45+/* Over-temperature trip point values in mC */
46+static const long temp_map_gen1[THRESH_COUNT][STAGE_COUNT] = {
47+ { 105000, 125000, 145000 },
48+ { 110000, 130000, 150000 },
49+ { 115000, 135000, 155000 },
50+ { 120000, 140000, 160000 },
51+};
52+
53+static 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+};
5059
51−#define TEMP_THRESH_MIN 105000 /* Threshold Min: 105 C */
52−#define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */
60+#define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */
5361
5462 #define THRESH_MIN 0
5563 #define THRESH_MAX 3
5664
57−/* Stage 2 Threshold Min: 125 C */
58−#define STAGE2_THRESHOLD_MIN 125000
59−/* Stage 2 Threshold Max: 140 C */
60−#define STAGE2_THRESHOLD_MAX 140000
65+#define TEMP_STAGE_HYSTERESIS 2000
6166
6267 /* Temperature in Milli Celsius reported during stage 0 if no ADC is present */
6368 #define DEFAULT_TEMP 37000
@@ -77,6 +82,7 @@ struct qpnp_tm_chip { · 13 unmodified lines
7782 bool initialized;
7883
7984 struct iio_channel *adc;
85+ const long (*temp_map)[THRESH_COUNT][STAGE_COUNT];
8086 };
8187
8288 /* 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
100106 return regmap_write(chip->map, chip->base + addr, data);
101107 }
102108
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+ */
117+static 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+
103126 /**
104127 * qpnp_tm_get_temp_stage() - return over-temperature stage
105128 * @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
149172
150173 if (stage_new > stage_old) {
151174 /* increasing stage, use lower bound */
152− chip->temp = (stage_new - 1) * TEMP_STAGE_STEP +
153− chip->thresh * TEMP_THRESH_STEP +
154− TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN;
175+ chip->temp = qpnp_tm_decode_temp(chip, stage_new)
176+ + TEMP_STAGE_HYSTERESIS;
155177 } else if (stage_new < stage_old) {
156178 /* decreasing stage, use upper bound */
157− chip->temp = stage_new * TEMP_STAGE_STEP +
158− chip->thresh * TEMP_THRESH_STEP -
159− TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN;
179+ chip->temp = qpnp_tm_decode_temp(chip, stage_new + 1)
180+ - TEMP_STAGE_HYSTERESIS;
160181 }
161182
162183 chip->stage = stage;
@@ -199,26 +220,28 @@ static int qpnp_tm_get_temp(void *data, int *temp) · 36 unmodified lines
199220 static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
200221 int temp)
201222 {
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];
203225 bool disable_s2_shutdown = false;
226+ u8 reg;
204227
205228 WARN_ON(!mutex_is_locked(&chip->lock));
206229
207230 /*
208231 * Default: S2 and S3 shutdown enabled, thresholds at
209− * 105C/125C/145C, monitoring at 25Hz
232+ * lowest threshold set, monitoring at 25Hz
210233 */
211234 reg = SHUTDOWN_CTRL1_RATE_25HZ;
212235
213236 if (temp == THERMAL_TEMP_INVALID ||
214− temp < STAGE2_THRESHOLD_MIN) {
237+ temp < stage2_threshold_min) {
215238 chip->thresh = THRESH_MIN;
216239 goto skip;
217240 }
218241
219− if (temp <= STAGE2_THRESHOLD_MAX) {
242+ if (temp <= stage2_threshold_max) {
220243 chip->thresh = THRESH_MAX -
221− ((STAGE2_THRESHOLD_MAX - temp) /
244+ ((stage2_threshold_max - temp) /
222245 TEMP_THRESH_STEP);
223246 disable_s2_shutdown = true;
224247 } else {
@@ -326,9 +349,7 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip) · 101 unmodified lines
326349 ? chip->stage : alarm_state_map[chip->stage];
327350
328351 if (stage)
329− chip->temp = chip->thresh * TEMP_THRESH_STEP +
330− (stage - 1) * TEMP_STAGE_STEP +
331− TEMP_THRESH_MIN;
352+ chip->temp = qpnp_tm_decode_temp(chip, stage);
332353
333354 crit_temp = qpnp_tm_get_critical_trip_temp(chip);
334355 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
350371 {
351372 struct qpnp_tm_chip *chip;
352373 struct device_node *node;
353− u8 type, subtype;
374+ u8 type, subtype, dig_major;
354375 u32 res;
355376 int ret, irq;
356377
@@ -400,6 +421,12 @@ static int qpnp_tm_probe(struct platform_device *pdev) · 43 unmodified lines
400421 return ret;
401422 }
402423
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+
403430 if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1
404431 && subtype != QPNP_TM_SUBTYPE_GEN2)) {
405432 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
408435 }
409436
410437 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;
411442
412443 /*
413444 * 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
1010 #include <linux/thermal.h>
1111 #include "tsens.h"
1212
13−#define CAL_MDEGC 30000
14−
1513 #define CONFIG_ADDR 0x3640
1614 #define CONFIG_ADDR_8660 0x3620
1715 /* CONFIG_ADDR bitmasks */
@@ -21,40 +19,38 @@ · 3 unmodified lines
2119 #define CONFIG_SHIFT_8660 28
2220 #define CONFIG_MASK_8660 (3 << CONFIG_SHIFT_8660)
2321
24−#define STATUS_CNTL_ADDR_8064 0x3660
2522 #define CNTL_ADDR 0x3620
2623 /* CNTL_ADDR bitmasks */
2724 #define EN BIT(0)
2825 #define SW_RST BIT(1)
29−#define SENSOR0_EN BIT(3)
26+
27+#define MEASURE_PERIOD BIT(18)
3028 #define SLP_CLK_ENA BIT(26)
3129 #define SLP_CLK_ENA_8660 BIT(24)
32−#define MEASURE_PERIOD 1
3330 #define SENSOR0_SHIFT 3
3431
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−
4132 #define THRESHOLD_ADDR 0x3624
42−/* THRESHOLD_ADDR bitmasks */
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
33+
5534 #define INT_STATUS_ADDR 0x363c
56−#define TRDY_MASK BIT(7)
57−#define TIMEOUT_US 100
35+
36+#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 */
49+static u32 tsens_msm8960_slope[] = {
50+ 826, 826, 804, 826,
51+ 761, 782, 782, 849,
52+ 782, 849, 782
53+ };
5854
5955 static int suspend_8960(struct tsens_priv *priv)
6056 {
@@ -115,17 +111,34 @@ static int resume_8960(struct tsens_priv *priv) · 54 unmodified lines
115111 static int enable_8960(struct tsens_priv *priv, int id)
116112 {
117113 int ret;
118− u32 reg, mask;
114+ u32 reg, mask = BIT(id);
119115
120116 ret = regmap_read(priv->tm_map, CNTL_ADDR, &reg);
121117 if (ret)
122118 return ret;
123119
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+
125136 ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST);
126137 if (ret)
127138 return ret;
128139
140+ reg |= MEASURE_PERIOD;
141+
129142 if (priv->num_sensors > 1)
130143 reg |= mask | SLP_CLK_ENA | EN;
131144 else
@@ -162,63 +175,11 @@ static void disable_8960(struct tsens_priv *priv) · 30 unmodified lines
162175 regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
163176 }
164177
165−static 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−
215178 static int calibrate_8960(struct tsens_priv *priv)
216179 {
217180 int i;
218181 char *data;
219−
220− ssize_t num_read = priv->num_sensors;
221− struct tsens_sensor *s = priv->sensor;
182+ u32 p1[11];
222183
223184 data = qfprom_read(priv->dev, "calib");
224185 if (IS_ERR(data))
@@ -226,60 +187,96 @@ static int calibrate_8960(struct tsens_priv *priv) · 1 unmodified line
226187 if (IS_ERR(data))
227188 return PTR_ERR(data);
228189
229− for (i = 0; i < num_read; i++, s++)
230− s->offset = data[i];
190+ for (i = 0; i < priv->num_sensors; 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);
231196
232197 kfree(data);
233198
234199 return 0;
235200 }
236201
237−/* Temperature on y axis and ADC-code on x-axis */
238−static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)
239−{
240− int slope, offset;
241−
242− slope = thermal_zone_get_slope(s->tzd);
243− offset = CAL_MDEGC - slope * s->offset;
244−
245− return adc_code * slope + offset;
246−}
247−
248−static int get_temp_8960(const struct tsens_sensor *s, int *temp)
249−{
250− int ret;
251− u32 code, trdy;
252− struct tsens_priv *priv = s->priv;
253− unsigned long timeout;
254−
255− timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
256− do {
257− ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy);
258− if (ret)
259− return ret;
260− if (!(trdy & TRDY_MASK))
261− continue;
262− ret = regmap_read(priv->tm_map, s->status, &code);
263− if (ret)
264− return ret;
265− *temp = code_to_mdegC(code, s);
266− return 0;
267− } while (time_before(jiffies, timeout));
268−
269− return -ETIMEDOUT;
270−}
202+static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = {
203+ /* ----- SROT ------ */
204+ /* No VERSION information */
205+
206+ /* CNTL */
207+ [TSENS_EN] = REG_FIELD(CNTL_ADDR, 0, 0),
208+ [TSENS_SW_RST] = REG_FIELD(CNTL_ADDR, 1, 1),
209+ /* 8960 has 5 sensors, 8660 has 11, we only handle 5 */
210+ [SENSOR_EN] = REG_FIELD(CNTL_ADDR, 3, 7),
211+
212+ /* ----- TM ------ */
213+ /* INTERRUPT ENABLE */
214+ /* NO INTERRUPT ENABLE */
215+
216+ /* Single UPPER/LOWER TEMPERATURE THRESHOLD for all sensors */
217+ [LOW_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 0, 7),
218+ [UP_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 8, 15),
219+ /* MIN_THRESH_0 and MAX_THRESH_0 are not present in the regfield
220+ * Recycle CRIT_THRESH_0 and 1 to set the required regs to hardcoded temp
221+ * MIN_THRESH_0 -> CRIT_THRESH_1
222+ * MAX_THRESH_0 -> CRIT_THRESH_0
223+ */
224+ [CRIT_THRESH_1] = REG_FIELD(THRESHOLD_ADDR, 16, 23),
225+ [CRIT_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 24, 31),
226+
227+ /* UPPER/LOWER INTERRUPT [CLEAR/STATUS] */
228+ /* 1 == clear, 0 == normal operation */
229+ [LOW_INT_CLEAR_0] = REG_FIELD(CNTL_ADDR, 9, 9),
230+ [UP_INT_CLEAR_0] = REG_FIELD(CNTL_ADDR, 10, 10),
231+
232+ /* NO CRITICAL INTERRUPT SUPPORT on 8960 */
233+
234+ /* Sn_STATUS */
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+};
271258
272259 static const struct tsens_ops ops_8960 = {
273− .init = init_8960,
260+ .init = init_common,
274261 .calibrate = calibrate_8960,
275− .get_temp = get_temp_8960,
262+ .get_temp = get_temp_common,
276263 .enable = enable_8960,
277264 .disable = disable_8960,
278265 .suspend = suspend_8960,
279266 .resume = resume_8960,
280267 };
281268
269+static 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+
282277 struct tsens_plat_data data_8960 = {
283278 .num_sensors = 11,
284279 .ops = &ops_8960,
280+ .feat = &tsens_8960_feat,
281+ .fields = tsens_8960_regfields,
285282 };
drivers/thermal/qcom/tsens-v0_1.c+97−1
@@ -190,6 +190,39 @@ · 189 unmodified lines
190190
191191 #define BIT_APPEND 0x3
192192
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+
193226 static int calibrate_8916(struct tsens_priv *priv)
194227 {
195228 int base0 = 0, base1 = 0, i;
@@ -452,7 +485,56 @@ static int calibrate_8974(struct tsens_priv *priv) · 256 unmodified lines
452485 return 0;
453486 }
454487
455−/* v0.1: 8916, 8939, 8974 */
488+static 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 */
456538
457539 static struct tsens_features tsens_v0_1_feat = {
458540 .ver_major = VER_0_1,
@@ -540,3 +622,17 @@ struct tsens_plat_data data_8974 = { · 81 unmodified lines
540622 .feat = &tsens_v0_1_feat,
541623 .fields = tsens_v0_1_regfields,
542624 };
625+
626+static const struct tsens_ops ops_9607 = {
627+ .init = init_common,
628+ .calibrate = calibrate_9607,
629+ .get_temp = get_temp_common,
630+};
631+
632+struct 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
380380 .get_temp = get_temp_tsens_valid,
381381 };
382382
383−/* Valid for both MSM8956 and MSM8976. Sensor ID 3 is unused. */
383+/* Valid for both MSM8956 and MSM8976. */
384384 struct tsens_plat_data data_8976 = {
385385 .num_sensors = 11,
386386 .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},
388388 .feat = &tsens_v1_feat,
389389 .fields = tsens_v1_regfields,
390390 };
drivers/thermal/qcom/tsens.c+133−32
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include <linux/of.h>
1313 #include <linux/of_address.h>
1414 #include <linux/of_platform.h>
15+#include <linux/mfd/syscon.h>
1516 #include <linux/platform_device.h>
1617 #include <linux/pm.h>
1718 #include <linux/regmap.h>
@@ -85,7 +86,8 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1, · 67 unmodified lines
8586 "%s: sensor%d - data_point1:%#x data_point2:%#x\n",
8687 __func__, i, p1[i], p2[i]);
8788
88− priv->sensor[i].slope = SLOPE_DEFAULT;
89+ if (!priv->sensor[i].slope)
90+ priv->sensor[i].slope = SLOPE_DEFAULT;
8991 if (mode == TWO_PT_CALIB) {
9092 /*
9193 * 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
515517 dev_dbg(priv->dev, "[%u] %s: no violation: %d\n",
516518 hw_id, __func__, temp);
517519 }
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+ }
518529 }
519530
520531 return IRQ_HANDLED;
@@ -530,6 +541,13 @@ static int tsens_set_trips(void *_sensor, int low, int high) · 9 unmodified lines
530541 int high_val, low_val, cl_high, cl_low;
531542 u32 hw_id = s->hw_id;
532543
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+
533551 dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
534552 hw_id, __func__, low, high);
535553
@@ -584,18 +602,21 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp) · 48 unmodified lines
584602 u32 valid;
585603 int ret;
586604
587− ret = regmap_field_read(priv->rf[valid_idx], &valid);
588− if (ret)
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);
605+ /* VER_0 doesn't have VALID bit */
606+ if (tsens_version(priv) >= VER_0_1) {
596607 ret = regmap_field_read(priv->rf[valid_idx], &valid);
597608 if (ret)
598609 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+ }
599620 }
600621
601622 /* 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
608629 {
609630 struct tsens_priv *priv = s->priv;
610631 int hw_id = s->hw_id;
611− int last_temp = 0, ret;
632+ int last_temp = 0, ret, trdy;
633+ unsigned long timeout;
612634
613− ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);
614− if (ret)
615− return ret;
635+ timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
636+ do {
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+ }
616644
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;
618648
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;
620655 }
621656
622657 #ifdef CONFIG_DEBUG_FS
@@ -738,25 +773,42 @@ int __init init_common(struct tsens_priv *priv) · 115 unmodified lines
738773 priv->tm_offset = 0x1000;
739774 }
740775
741− res = platform_get_resource(op, IORESOURCE_MEM, 0);
742− tm_base = devm_ioremap_resource(dev, res);
743− if (IS_ERR(tm_base)) {
744− ret = PTR_ERR(tm_base);
745− goto err_put_device;
776+ if (tsens_version(priv) >= VER_0_1) {
777+ res = platform_get_resource(op, IORESOURCE_MEM, 0);
778+ tm_base = devm_ioremap_resource(dev, res);
779+ if (IS_ERR(tm_base)) {
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);
746790 }
747791
748− priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);
749− if (IS_ERR(priv->tm_map)) {
750− ret = PTR_ERR(priv->tm_map);
792+ if (IS_ERR_OR_NULL(priv->tm_map)) {
793+ if (!priv->tm_map)
794+ ret = -ENODEV;
795+ else
796+ ret = PTR_ERR(priv->tm_map);
751797 goto err_put_device;
752798 }
753799
800+ /* VER_0 have only tm_map */
801+ if (!priv->srot_map)
802+ priv->srot_map = priv->tm_map;
803+
754804 if (tsens_version(priv) > VER_0_1) {
755805 for (i = VER_MAJOR; i <= VER_STEP; i++) {
756806 priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,
757807 priv->fields[i]);
758− if (IS_ERR(priv->rf[i]))
759− return PTR_ERR(priv->rf[i]);
808+ if (IS_ERR(priv->rf[i])) {
809+ ret = PTR_ERR(priv->rf[i]);
810+ goto err_put_device;
811+ }
760812 }
761813 ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor);
762814 if (ret)
@@ -769,6 +821,10 @@ int __init init_common(struct tsens_priv *priv) · 6 unmodified lines
769821 ret = PTR_ERR(priv->rf[TSENS_EN]);
770822 goto err_put_device;
771823 }
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+
772828 ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
773829 if (ret)
774830 goto err_put_device;
@@ -791,6 +847,19 @@ int __init init_common(struct tsens_priv *priv) · 16 unmodified lines
791847 goto err_put_device;
792848 }
793849
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+
794863 /* This loop might need changes if enum regfield_ids is reordered */
795864 for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {
796865 for (i = 0; i < priv->feat->max_sensors; i++) {
@@ -806,7 +875,7 @@ int __init init_common(struct tsens_priv *priv) · 9 unmodified lines
806875 }
807876 }
808877
809− if (priv->feat->crit_int) {
878+ if (priv->feat->crit_int || tsens_version(priv) < VER_0_1) {
810879 /* Loop might need changes if enum regfield_ids is reordered */
811880 for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) {
812881 for (i = 0; i < priv->feat->max_sensors; i++) {
@@ -844,7 +913,11 @@ int __init init_common(struct tsens_priv *priv) · 31 unmodified lines
844913 }
845914
846915 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+
848921 tsens_debug_init(op);
849922
850923 err_put_device:
@@ -895,6 +968,12 @@ static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume); · 44 unmodified lines
895968
896969 static const struct of_device_id tsens_table[] = {
897970 {
971+ .compatible = "qcom,ipq8064-tsens",
972+ .data = &data_8960,
973+ }, {
974+ .compatible = "qcom,mdm9607-tsens",
975+ .data = &data_9607,
976+ }, {
898977 .compatible = "qcom,msm8916-tsens",
899978 .data = &data_8916,
900979 }, {
@@ -943,10 +1022,19 @@ static int tsens_register_irq(struct tsens_priv *priv, char *irqname, · 42 unmodified lines
9431022 if (irq == -ENXIO)
9441023 ret = 0;
9451024 } else {
946− ret = devm_request_threaded_irq(&pdev->dev, irq,
947− NULL, thread_fn,
948− IRQF_ONESHOT,
949− dev_name(&pdev->dev), priv);
1025+ /* VER_0 interrupt is TRIGGER_RISING, VER_0_1 and up is ONESHOT */
1026+ if (tsens_version(priv) == VER_0)
1027+ ret = devm_request_threaded_irq(&pdev->dev, irq,
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+
9501038 if (ret)
9511039 dev_err(&pdev->dev, "%s: failed to get irq\n",
9521040 __func__);
@@ -975,6 +1063,19 @@ static int tsens_register(struct tsens_priv *priv) · 22 unmodified lines
9751063 priv->ops->enable(priv, i);
9761064 }
9771065
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+
9781079 ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
9791080 if (ret < 0)
9801081 return ret;
drivers/thermal/qcom/tsens.h+4−2
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #define CAL_DEGC_PT2 120
1414 #define SLOPE_FACTOR 1000
1515 #define SLOPE_DEFAULT 3200
16+#define TIMEOUT_US 100
1617 #define THRESHOLD_MAX_ADC_CODE 0x3ff
1718 #define THRESHOLD_MIN_ADC_CODE 0x0
1819
@@ -25,7 +26,8 @@ struct tsens_priv; · 6 unmodified lines
2526
2627 /* IP version numbers in ascending order */
2728 enum tsens_ver {
28− VER_0_1 = 0,
29+ VER_0 = 0,
30+ VER_0_1,
2931 VER_1_X,
3032 VER_2_X,
3133 };
@@ -585,7 +587,7 @@ int get_temp_common(const struct tsens_sensor *s, int *temp); · 553 unmodified lines
585587 extern struct tsens_plat_data data_8960;
586588
587589 /* TSENS v0.1 targets */
588−extern struct tsens_plat_data data_8916, data_8939, data_8974;
590+extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607;
589591
590592 /* TSENS v1 targets */
591593 extern struct tsens_plat_data data_tsens_v1, data_8976;
drivers/thermal/rcar_gen3_thermal.c+2−1
@@ -60,7 +60,7 @@ · 59 unmodified lines
6060 #define MCELSIUS(temp) ((temp) * 1000)
6161 #define GEN3_FUSE_MASK 0xFFF
6262
63−#define TSC_MAX_NUM 4
63+#define TSC_MAX_NUM 5
6464
6565 /* default THCODE values if FUSEs are missing */
6666 static const int thcodes[TSC_MAX_NUM][3] = {
@@ -68,6 +68,7 @@ static const int thcodes[TSC_MAX_NUM][3] = { · 1 unmodified line
6868 { 3393, 2795, 2216 },
6969 { 3389, 2805, 2237 },
7070 { 3415, 2694, 2195 },
71+ { 3356, 2724, 2244 },
7172 };
7273
7374 /* 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
300300 * or 0x8xx, so they won't be away from the default value
301301 * for a lot.
302302 *
303− * So here we do not return error if the calibartion data is
303+ * So here we do not return error if the calibration data is
304304 * not available, except the probe needs deferring.
305305 */
306306 goto out;
@@ -418,7 +418,7 @@ static int sun8i_h3_thermal_init(struct ths_device *tmdev) · 111 unmodified lines
418418 }
419419
420420 /*
421− * Without this undocummented value, the returned temperatures would
421+ * Without this undocumented value, the returned temperatures would
422422 * be higher than real ones by about 20C.
423423 */
424424 #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
21182118 struct tegra_soctherm *tegra;
21192119 struct thermal_zone_device *z;
21202120 struct tsensor_shared_calib shared_calib;
2121− struct resource *res;
21222121 struct tegra_soctherm_soc *soc;
21232122 unsigned int i;
21242123 int err;
@@ -2140,26 +2139,20 @@ static int tegra_soctherm_probe(struct platform_device *pdev) · 15 unmodified lines
21402139
21412140 tegra->soc = soc;
21422141
2143− res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2144− "soctherm-reg");
2145− tegra->regs = devm_ioremap_resource(&pdev->dev, res);
2142+ tegra->regs = devm_platform_ioremap_resource_byname(pdev, "soctherm-reg");
21462143 if (IS_ERR(tegra->regs)) {
21472144 dev_err(&pdev->dev, "can't get soctherm registers");
21482145 return PTR_ERR(tegra->regs);
21492146 }
21502147
21512148 if (!tegra->soc->use_ccroc) {
2152− res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2153− "car-reg");
2154− tegra->clk_regs = devm_ioremap_resource(&pdev->dev, res);
2149+ tegra->clk_regs = devm_platform_ioremap_resource_byname(pdev, "car-reg");
21552150 if (IS_ERR(tegra->clk_regs)) {
21562151 dev_err(&pdev->dev, "can't get car clk registers");
21572152 return PTR_ERR(tegra->clk_regs);
21582153 }
21592154 } else {
2160− res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2161− "ccroc-reg");
2162− tegra->ccroc_regs = devm_ioremap_resource(&pdev->dev, res);
2155+ tegra->ccroc_regs = devm_platform_ioremap_resource_byname(pdev, "ccroc-reg");
21632156 if (IS_ERR(tegra->ccroc_regs)) {
21642157 dev_err(&pdev->dev, "can't get ccroc registers");
21652158 return PTR_ERR(tegra->ccroc_regs);
@@ -2195,7 +2188,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev) · 29 unmodified lines
21952188 if (err)
21962189 return err;
21972190
2198− /* calculate tsensor calibaration data */
2191+ /* calculate tsensor calibration data */
21992192 for (i = 0; i < soc->num_tsensors; ++i) {
22002193 err = tegra_calc_tsensor_calib(&soc->tsensors[i],
22012194 &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
561561 }
562562 EXPORT_SYMBOL_GPL(thermal_zone_device_update);
563563
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− */
576−void thermal_notify_framework(struct thermal_zone_device *tz, int trip)
577−{
578− handle_thermal_trip(tz, trip);
579−}
580−EXPORT_SYMBOL_GPL(thermal_notify_framework);
581−
582564 static void thermal_zone_device_check(struct work_struct *work)
583565 {
584566 struct thermal_zone_device *tz = container_of(work, struct
@@ -960,10 +942,7 @@ __thermal_cooling_device_register(struct device_node *np, · 375 unmodified lines
960942 {
961943 struct thermal_cooling_device *cdev;
962944 struct thermal_zone_device *pos = NULL;
963− int result;
964−
965− if (type && strlen(type) >= THERMAL_NAME_LENGTH)
966− return ERR_PTR(-EINVAL);
945+ int ret;
967946
968947 if (!ops || !ops->get_max_state || !ops->get_cur_state ||
969948 !ops->set_cur_state)
@@ -973,14 +952,17 @@ __thermal_cooling_device_register(struct device_node *np, · 3 unmodified lines
973952 if (!cdev)
974953 return ERR_PTR(-ENOMEM);
975954
976− result = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
977− if (result < 0) {
978− kfree(cdev);
979− return ERR_PTR(result);
955+ ret = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
956+ if (ret < 0)
957+ goto out_kfree_cdev;
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;
980964 }
981965
982− cdev->id = result;
983− strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
984966 mutex_init(&cdev->lock);
985967 INIT_LIST_HEAD(&cdev->thermal_instances);
986968 cdev->np = np;
@@ -990,12 +972,9 @@ __thermal_cooling_device_register(struct device_node *np, · 3 unmodified lines
990972 cdev->devdata = devdata;
991973 thermal_cooling_device_setup_sysfs(cdev);
992974 dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
993− result = device_register(&cdev->device);
994− if (result) {
995− ida_simple_remove(&thermal_cdev_ida, cdev->id);
996− put_device(&cdev->device);
997− return ERR_PTR(result);
998− }
975+ ret = device_register(&cdev->device);
976+ if (ret)
977+ goto out_kfree_type;
999978
1000979 /* Add 'this' new cdev to the global cdev list */
1001980 mutex_lock(&thermal_list_lock);
@@ -1013,6 +992,15 @@ __thermal_cooling_device_register(struct device_node *np, · 11 unmodified lines
1013992 mutex_unlock(&thermal_list_lock);
1014993
1015994 return cdev;
995+
996+out_kfree_type:
997+ kfree(cdev->type);
998+ put_device(&cdev->device);
999+out_ida_remove:
1000+ ida_simple_remove(&thermal_cdev_ida, cdev->id);
1001+out_kfree_cdev:
1002+ kfree(cdev);
1003+ return ERR_PTR(ret);
10161004 }
10171005
10181006 /**
@@ -1171,6 +1159,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) · 152 unmodified lines
11711159 ida_simple_remove(&thermal_cdev_ida, cdev->id);
11721160 device_del(&cdev->device);
11731161 thermal_cooling_device_destroy_sysfs(cdev);
1162+ kfree(cdev->type);
11741163 put_device(&cdev->device);
11751164 }
11761165 EXPORT_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
6666 }
6767
6868 void thermal_cdev_update(struct thermal_cooling_device *);
69+void __thermal_cdev_update(struct thermal_cooling_device *cdev);
6970
7071 /**
7172 * 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
192192 thermal_cooling_device_stats_update(cdev, target);
193193 }
194194
195−void thermal_cdev_update(struct thermal_cooling_device *cdev)
195+void __thermal_cdev_update(struct thermal_cooling_device *cdev)
196196 {
197197 struct thermal_instance *instance;
198198 unsigned long target = 0;
199199
200− mutex_lock(&cdev->lock);
201− /* cooling device is updated*/
202− if (cdev->updated) {
203− mutex_unlock(&cdev->lock);
204− return;
205− }
206−
207200 /* Make sure cdev enters the deepest cooling state */
208201 list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
209202 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
216209
217210 thermal_cdev_set_cur_state(cdev, target);
218211
219− cdev->updated = true;
220− mutex_unlock(&cdev->lock);
221212 trace_cdev_update(cdev, target);
222213 dev_dbg(&cdev->device, "set to state %lu\n", target);
223214 }
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+ */
222+void 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+}
224231 EXPORT_SYMBOL(thermal_cdev_update);
225232
226233 /**
drivers/thermal/thermal_mmio.c+1−4
@@ -54,11 +54,8 @@ static int thermal_mmio_probe(struct platform_device *pdev) · 53 unmodified lines
5454
5555 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
5656 sensor->mmio_base = devm_ioremap_resource(&pdev->dev, resource);
57− if (IS_ERR(sensor->mmio_base)) {
58− dev_err(&pdev->dev, "failed to ioremap memory (%ld)\n",
59− PTR_ERR(sensor->mmio_base));
57+ if (IS_ERR(sensor->mmio_base))
6058 return PTR_ERR(sensor->mmio_base);
61− }
6259
6360 sensor_init_func = device_get_match_data(&pdev->dev);
6461 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
704704
705705 count = of_count_phandle_with_args(np, "cooling-device",
706706 "#cooling-cells");
707− if (!count) {
707+ if (count <= 0) {
708708 pr_err("Add a cooling_device property with at least one device\n");
709+ ret = -ENOENT;
709710 goto end;
710711 }
711712
712713 __tcbp = kcalloc(count, sizeof(*__tcbp), GFP_KERNEL);
713− if (!__tcbp)
714+ if (!__tcbp) {
715+ ret = -ENOMEM;
714716 goto end;
717+ }
715718
716719 for (i = 0; i < count; i++) {
717720 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
99 * Eduardo Valentin <eduardo.valentin@ti.com>
1010 */
1111
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>
1316 #include <linux/export.h>
17+#include <linux/gpio/consumer.h>
1418 #include <linux/init.h>
15−#include <linux/kernel.h>
1619 #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>
2820 #include <linux/io.h>
2921 #include <linux/iopoll.h>
30−#include <linux/cpu_pm.h>
31−#include <linux/device.h>
32−#include <linux/pm_runtime.h>
33−#include <linux/pm.h>
22+#include <linux/kernel.h>
23+#include <linux/module.h>
3424 #include <linux/of.h>
3525 #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>
3635
3736 #include "ti-bandgap.h"
3837
@@ -1143,14 +1142,10 @@ static int ti_bandgap_restore_ctxt(struct ti_bandgap *bgp) · 1104 unmodified lines
11431142 for (i = 0; i < bgp->conf->sensor_count; i++) {
11441143 struct temp_sensor_registers *tsr;
11451144 struct temp_sensor_regval *rval;
1146− u32 val = 0;
11471145
11481146 rval = &bgp->regval[i];
11491147 tsr = bgp->conf->sensors[i].registers;
11501148
1151− if (TI_BANDGAP_HAS(bgp, COUNTER))
1152− val = ti_bandgap_readl(bgp, tsr->bgap_counter);
1153−
11541149 if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG))
11551150 ti_bandgap_writel(bgp, rval->tshut_threshold,
11561151 tsr->tshut_threshold);
include/linux/thermal.h+1−6
@@ -91,7 +91,7 @@ struct thermal_cooling_device_ops { · 90 unmodified lines
9191
9292 struct thermal_cooling_device {
9393 int id;
94− char type[THERMAL_NAME_LENGTH];
94+ char *type;
9595 struct device device;
9696 struct device_node *np;
9797 void *devdata;
@@ -390,7 +390,6 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); · 292 unmodified lines
390390 int thermal_zone_get_slope(struct thermal_zone_device *tz);
391391 int thermal_zone_get_offset(struct thermal_zone_device *tz);
392392
393−void thermal_notify_framework(struct thermal_zone_device *, int);
394393 int thermal_zone_device_enable(struct thermal_zone_device *tz);
395394 int thermal_zone_device_disable(struct thermal_zone_device *tz);
396395 void thermal_zone_device_critical(struct thermal_zone_device *tz);
@@ -436,10 +435,6 @@ static inline int thermal_zone_get_offset( · 39 unmodified lines
436435 struct thermal_zone_device *tz)
437436 { return -ENODEV; }
438437
439−static inline void thermal_notify_framework(struct thermal_zone_device *tz,
440− int trip)
441−{ }
442−
443438 static inline int thermal_zone_device_enable(struct thermal_zone_device *tz)
444439 { return -ENODEV; }
445440
include/uapi/linux/thermal.h+1−1
@@ -60,7 +60,7 @@ enum thermal_genl_event { · 59 unmodified lines
6060 THERMAL_GENL_EVENT_UNSPEC,
6161 THERMAL_GENL_EVENT_TZ_CREATE, /* Thermal zone creation */
6262 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 */
6464 THERMAL_GENL_EVENT_TZ_ENABLE, /* Thermal zone enabled */
6565 THERMAL_GENL_EVENT_TZ_TRIP_UP, /* Trip point crossed the way up */
6666 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