aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-17 17:31:27 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-17 17:31:27 -0500
commitbec04432cb9036dedf89140c102b5ac03e4b3626 (patch)
tree390d76ddf5f302577efc704a78251f099bfecbf5 /drivers
parente29116758c4e06be9ba6358350f9d9f466414efb (diff)
parent1e032393d9680c1f3b5238ec0f3f4eb006ee83d2 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management updates from Zhang Rui: - introduce brcmstb AVS TMON thermal driver (Brian Norris) - add Rockchip RV1108 support in rockchip thermal driver (Rocky Hao) - major rework on HISI driver plus additional support of hisi3660 (Daniel Lezcano) - add nvmem-cells binding on imx6sx (Leonard Crestez) - fix a NULL pointer dereference on ti thermal driver unloading (Tony Lindgren) - improve tmon tool to make it easier to cross-compile tmon (Markus Mayer) - add Coffee Lake and Cannon Lake support for intel processor and pch thermal drivers (Srinivas Pandruvada) - other small fixes and cleanups (Arvind Yadav, Colin Ian King, Allen Wild, Nicolin Chen, Baruch SiachNiklas Söderlund, Arnd Bergmann) * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: (44 commits) thermal: pch: Add Cannon Lake support thermal: int340x: processor_thermal: Add Coffee Lake support thermal: int340x: processor_thermal: Add Cannon Lake support thermal: bxt: remove redundant variable trip thermal: cpu_cooling: pr_err() strings should end with newlines thermal: add brcmstb AVS TMON driver Documentation: devicetree: add binding for Broadcom STB AVS TMON thermal/drivers/hisi: Add support for hi3660 SoC thermal/drivers/hisi: Prepare to add support for other hisi platforms thermal/drivers/hisi: Add platform prefix to function name thermal/drivers/hisi: Put platform code together thermal/drivers/qcom-spmi: Use devm_iio_channel_get thermal/drivers/generic-iio-adc: Switch tz request to devm version thermal/drivers/step_wise: Fix temperature regulation misbehavior thermal/drivers/hisi: Use round up step value thermal/drivers/hisi: Move the clk setup in the corresponding functions thermal/drivers/hisi: Remove mutex_lock in the code thermal/drivers/hisi: Remove thermal data back pointer thermal/drivers/hisi: Convert long to int thermal/drivers/hisi: Rename and remove unused field ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/thermal/Kconfig3
-rw-r--r--drivers/thermal/armada_thermal.c2
-rw-r--r--drivers/thermal/broadcom/Kconfig7
-rw-r--r--drivers/thermal/broadcom/Makefile1
-rw-r--r--drivers/thermal/broadcom/brcmstb_thermal.c387
-rw-r--r--drivers/thermal/cpu_cooling.c2
-rw-r--r--drivers/thermal/hisi_thermal.c612
-rw-r--r--drivers/thermal/imx_thermal.c104
-rw-r--r--drivers/thermal/int340x_thermal/processor_thermal_device.c6
-rw-r--r--drivers/thermal/intel_bxt_pmic_thermal.c3
-rw-r--r--drivers/thermal/intel_pch_thermal.c11
-rw-r--r--drivers/thermal/intel_powerclamp.c4
-rw-r--r--drivers/thermal/qcom-spmi-temp-alarm.c43
-rw-r--r--drivers/thermal/rcar_gen3_thermal.c34
-rw-r--r--drivers/thermal/rockchip_thermal.c67
-rw-r--r--drivers/thermal/step_wise.c11
-rw-r--r--drivers/thermal/tegra/soctherm.c2
-rw-r--r--drivers/thermal/thermal-generic-adc.c24
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-thermal-common.c3
19 files changed, 1006 insertions, 320 deletions
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 07002df4f83a..315ae2926e20 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -206,6 +206,7 @@ config HISI_THERMAL
206config IMX_THERMAL 206config IMX_THERMAL
207 tristate "Temperature sensor driver for Freescale i.MX SoCs" 207 tristate "Temperature sensor driver for Freescale i.MX SoCs"
208 depends on (ARCH_MXC && CPU_THERMAL) || COMPILE_TEST 208 depends on (ARCH_MXC && CPU_THERMAL) || COMPILE_TEST
209 depends on NVMEM || !NVMEM
209 depends on MFD_SYSCON 210 depends on MFD_SYSCON
210 depends on OF 211 depends on OF
211 help 212 help
@@ -408,7 +409,7 @@ config MTK_THERMAL
408 controller present in Mediatek SoCs 409 controller present in Mediatek SoCs
409 410
410menu "Broadcom thermal drivers" 411menu "Broadcom thermal drivers"
411depends on ARCH_BCM || COMPILE_TEST 412depends on ARCH_BCM || ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST
412source "drivers/thermal/broadcom/Kconfig" 413source "drivers/thermal/broadcom/Kconfig"
413endmenu 414endmenu
414 415
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index ae75328945f7..706d74798cbe 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -58,7 +58,7 @@ struct armada_thermal_data {
58 /* Test for a valid sensor value (optional) */ 58 /* Test for a valid sensor value (optional) */
59 bool (*is_valid)(struct armada_thermal_priv *); 59 bool (*is_valid)(struct armada_thermal_priv *);
60 60
61 /* Formula coeficients: temp = (b + m * reg) / div */ 61 /* Formula coeficients: temp = (b - m * reg) / div */
62 unsigned long coef_b; 62 unsigned long coef_b;
63 unsigned long coef_m; 63 unsigned long coef_m;
64 unsigned long coef_div; 64 unsigned long coef_div;
diff --git a/drivers/thermal/broadcom/Kconfig b/drivers/thermal/broadcom/Kconfig
index 42c098e86f84..c106a15bf7f9 100644
--- a/drivers/thermal/broadcom/Kconfig
+++ b/drivers/thermal/broadcom/Kconfig
@@ -6,6 +6,13 @@ config BCM2835_THERMAL
6 help 6 help
7 Support for thermal sensors on Broadcom bcm2835 SoCs. 7 Support for thermal sensors on Broadcom bcm2835 SoCs.
8 8
9config BRCMSTB_THERMAL
10 tristate "Broadcom STB AVS TMON thermal driver"
11 depends on ARCH_BRCMSTB || COMPILE_TEST
12 help
13 Enable this driver if you have a Broadcom STB SoC and would like
14 thermal framework support.
15
9config BCM_NS_THERMAL 16config BCM_NS_THERMAL
10 tristate "Northstar thermal driver" 17 tristate "Northstar thermal driver"
11 depends on ARCH_BCM_IPROC || COMPILE_TEST 18 depends on ARCH_BCM_IPROC || COMPILE_TEST
diff --git a/drivers/thermal/broadcom/Makefile b/drivers/thermal/broadcom/Makefile
index c6f62e4fd0ee..fae10ecafaef 100644
--- a/drivers/thermal/broadcom/Makefile
+++ b/drivers/thermal/broadcom/Makefile
@@ -1,2 +1,3 @@
1obj-$(CONFIG_BCM2835_THERMAL) += bcm2835_thermal.o 1obj-$(CONFIG_BCM2835_THERMAL) += bcm2835_thermal.o
2obj-$(CONFIG_BRCMSTB_THERMAL) += brcmstb_thermal.o
2obj-$(CONFIG_BCM_NS_THERMAL) += ns-thermal.o 3obj-$(CONFIG_BCM_NS_THERMAL) += ns-thermal.o
diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c
new file mode 100644
index 000000000000..1919f91fa756
--- /dev/null
+++ b/drivers/thermal/broadcom/brcmstb_thermal.c
@@ -0,0 +1,387 @@
1/*
2 * Broadcom STB AVS TMON thermal sensor driver
3 *
4 * Copyright (c) 2015-2017 Broadcom
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#define DRV_NAME "brcmstb_thermal"
18
19#define pr_fmt(fmt) DRV_NAME ": " fmt
20
21#include <linux/bitops.h>
22#include <linux/device.h>
23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/irqreturn.h>
26#include <linux/interrupt.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/platform_device.h>
30#include <linux/of_device.h>
31#include <linux/thermal.h>
32
33#define AVS_TMON_STATUS 0x00
34 #define AVS_TMON_STATUS_valid_msk BIT(11)
35 #define AVS_TMON_STATUS_data_msk GENMASK(10, 1)
36 #define AVS_TMON_STATUS_data_shift 1
37
38#define AVS_TMON_EN_OVERTEMP_RESET 0x04
39 #define AVS_TMON_EN_OVERTEMP_RESET_msk BIT(0)
40
41#define AVS_TMON_RESET_THRESH 0x08
42 #define AVS_TMON_RESET_THRESH_msk GENMASK(10, 1)
43 #define AVS_TMON_RESET_THRESH_shift 1
44
45#define AVS_TMON_INT_IDLE_TIME 0x10
46
47#define AVS_TMON_EN_TEMP_INT_SRCS 0x14
48 #define AVS_TMON_EN_TEMP_INT_SRCS_high BIT(1)
49 #define AVS_TMON_EN_TEMP_INT_SRCS_low BIT(0)
50
51#define AVS_TMON_INT_THRESH 0x18
52 #define AVS_TMON_INT_THRESH_high_msk GENMASK(26, 17)
53 #define AVS_TMON_INT_THRESH_high_shift 17
54 #define AVS_TMON_INT_THRESH_low_msk GENMASK(10, 1)
55 #define AVS_TMON_INT_THRESH_low_shift 1
56
57#define AVS_TMON_TEMP_INT_CODE 0x1c
58#define AVS_TMON_TP_TEST_ENABLE 0x20
59
60/* Default coefficients */
61#define AVS_TMON_TEMP_SLOPE -487
62#define AVS_TMON_TEMP_OFFSET 410040
63
64/* HW related temperature constants */
65#define AVS_TMON_TEMP_MAX 0x3ff
66#define AVS_TMON_TEMP_MIN -88161
67#define AVS_TMON_TEMP_MASK AVS_TMON_TEMP_MAX
68
69enum avs_tmon_trip_type {
70 TMON_TRIP_TYPE_LOW = 0,
71 TMON_TRIP_TYPE_HIGH,
72 TMON_TRIP_TYPE_RESET,
73 TMON_TRIP_TYPE_MAX,
74};
75
76struct avs_tmon_trip {
77 /* HW bit to enable the trip */
78 u32 enable_offs;
79 u32 enable_mask;
80
81 /* HW field to read the trip temperature */
82 u32 reg_offs;
83 u32 reg_msk;
84 int reg_shift;
85};
86
87static struct avs_tmon_trip avs_tmon_trips[] = {
88 /* Trips when temperature is below threshold */
89 [TMON_TRIP_TYPE_LOW] = {
90 .enable_offs = AVS_TMON_EN_TEMP_INT_SRCS,
91 .enable_mask = AVS_TMON_EN_TEMP_INT_SRCS_low,
92 .reg_offs = AVS_TMON_INT_THRESH,
93 .reg_msk = AVS_TMON_INT_THRESH_low_msk,
94 .reg_shift = AVS_TMON_INT_THRESH_low_shift,
95 },
96 /* Trips when temperature is above threshold */
97 [TMON_TRIP_TYPE_HIGH] = {
98 .enable_offs = AVS_TMON_EN_TEMP_INT_SRCS,
99 .enable_mask = AVS_TMON_EN_TEMP_INT_SRCS_high,
100 .reg_offs = AVS_TMON_INT_THRESH,
101 .reg_msk = AVS_TMON_INT_THRESH_high_msk,
102 .reg_shift = AVS_TMON_INT_THRESH_high_shift,
103 },
104 /* Automatically resets chip when above threshold */
105 [TMON_TRIP_TYPE_RESET] = {
106 .enable_offs = AVS_TMON_EN_OVERTEMP_RESET,
107 .enable_mask = AVS_TMON_EN_OVERTEMP_RESET_msk,
108 .reg_offs = AVS_TMON_RESET_THRESH,
109 .reg_msk = AVS_TMON_RESET_THRESH_msk,
110 .reg_shift = AVS_TMON_RESET_THRESH_shift,
111 },
112};
113
114struct brcmstb_thermal_priv {
115 void __iomem *tmon_base;
116 struct device *dev;
117 struct thermal_zone_device *thermal;
118};
119
120static void avs_tmon_get_coeffs(struct thermal_zone_device *tz, int *slope,
121 int *offset)
122{
123 *slope = thermal_zone_get_slope(tz);
124 *offset = thermal_zone_get_offset(tz);
125}
126
127/* Convert a HW code to a temperature reading (millidegree celsius) */
128static inline int avs_tmon_code_to_temp(struct thermal_zone_device *tz,
129 u32 code)
130{
131 const int val = code & AVS_TMON_TEMP_MASK;
132 int slope, offset;
133
134 avs_tmon_get_coeffs(tz, &slope, &offset);
135
136 return slope * val + offset;
137}
138
139/*
140 * Convert a temperature value (millidegree celsius) to a HW code
141 *
142 * @temp: temperature to convert
143 * @low: if true, round toward the low side
144 */
145static inline u32 avs_tmon_temp_to_code(struct thermal_zone_device *tz,
146 int temp, bool low)
147{
148 int slope, offset;
149
150 if (temp < AVS_TMON_TEMP_MIN)
151 return AVS_TMON_TEMP_MAX; /* Maximum code value */
152
153 avs_tmon_get_coeffs(tz, &slope, &offset);
154
155 if (temp >= offset)
156 return 0; /* Minimum code value */
157
158 if (low)
159 return (u32)(DIV_ROUND_UP(offset - temp, abs(slope)));
160 else
161 return (u32)((offset - temp) / abs(slope));
162}
163
164static int brcmstb_get_temp(void *data, int *temp)
165{
166 struct brcmstb_thermal_priv *priv = data;
167 u32 val;
168 long t;
169
170 val = __raw_readl(priv->tmon_base + AVS_TMON_STATUS);
171
172 if (!(val & AVS_TMON_STATUS_valid_msk)) {
173 dev_err(priv->dev, "reading not valid\n");
174 return -EIO;
175 }
176
177 val = (val & AVS_TMON_STATUS_data_msk) >> AVS_TMON_STATUS_data_shift;
178
179 t = avs_tmon_code_to_temp(priv->thermal, val);
180 if (t < 0)
181 *temp = 0;
182 else
183 *temp = t;
184
185 return 0;
186}
187
188static void avs_tmon_trip_enable(struct brcmstb_thermal_priv *priv,
189 enum avs_tmon_trip_type type, int en)
190{
191 struct avs_tmon_trip *trip = &avs_tmon_trips[type];
192 u32 val = __raw_readl(priv->tmon_base + trip->enable_offs);
193
194 dev_dbg(priv->dev, "%sable trip, type %d\n", en ? "en" : "dis", type);
195
196 if (en)
197 val |= trip->enable_mask;
198 else
199 val &= ~trip->enable_mask;
200
201 __raw_writel(val, priv->tmon_base + trip->enable_offs);
202}
203
204static int avs_tmon_get_trip_temp(struct brcmstb_thermal_priv *priv,
205 enum avs_tmon_trip_type type)
206{
207 struct avs_tmon_trip *trip = &avs_tmon_trips[type];
208 u32 val = __raw_readl(priv->tmon_base + trip->reg_offs);
209
210 val &= trip->reg_msk;
211 val >>= trip->reg_shift;
212
213 return avs_tmon_code_to_temp(priv->thermal, val);
214}
215
216static void avs_tmon_set_trip_temp(struct brcmstb_thermal_priv *priv,
217 enum avs_tmon_trip_type type,
218 int temp)
219{
220 struct avs_tmon_trip *trip = &avs_tmon_trips[type];
221 u32 val, orig;
222
223 dev_dbg(priv->dev, "set temp %d to %d\n", type, temp);
224
225 /* round toward low temp for the low interrupt */
226 val = avs_tmon_temp_to_code(priv->thermal, temp,
227 type == TMON_TRIP_TYPE_LOW);
228
229 val <<= trip->reg_shift;
230 val &= trip->reg_msk;
231
232 orig = __raw_readl(priv->tmon_base + trip->reg_offs);
233 orig &= ~trip->reg_msk;
234 orig |= val;
235 __raw_writel(orig, priv->tmon_base + trip->reg_offs);
236}
237
238static int avs_tmon_get_intr_temp(struct brcmstb_thermal_priv *priv)
239{
240 u32 val;
241
242 val = __raw_readl(priv->tmon_base + AVS_TMON_TEMP_INT_CODE);
243 return avs_tmon_code_to_temp(priv->thermal, val);
244}
245
246static irqreturn_t brcmstb_tmon_irq_thread(int irq, void *data)
247{
248 struct brcmstb_thermal_priv *priv = data;
249 int low, high, intr;
250
251 low = avs_tmon_get_trip_temp(priv, TMON_TRIP_TYPE_LOW);
252 high = avs_tmon_get_trip_temp(priv, TMON_TRIP_TYPE_HIGH);
253 intr = avs_tmon_get_intr_temp(priv);
254
255 dev_dbg(priv->dev, "low/intr/high: %d/%d/%d\n",
256 low, intr, high);
257
258 /* Disable high-temp until next threshold shift */
259 if (intr >= high)
260 avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_HIGH, 0);
261 /* Disable low-temp until next threshold shift */
262 if (intr <= low)
263 avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_LOW, 0);
264
265 /*
266 * Notify using the interrupt temperature, in case the temperature
267 * changes before it can next be read out
268 */
269 thermal_zone_device_update(priv->thermal, intr);
270
271 return IRQ_HANDLED;
272}
273
274static int brcmstb_set_trips(void *data, int low, int high)
275{
276 struct brcmstb_thermal_priv *priv = data;
277
278 dev_dbg(priv->dev, "set trips %d <--> %d\n", low, high);
279
280 /*
281 * Disable low-temp if "low" is too small. As per thermal framework
282 * API, we use -INT_MAX rather than INT_MIN.
283 */
284 if (low <= -INT_MAX) {
285 avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_LOW, 0);
286 } else {
287 avs_tmon_set_trip_temp(priv, TMON_TRIP_TYPE_LOW, low);
288 avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_LOW, 1);
289 }
290
291 /* Disable high-temp if "high" is too big. */
292 if (high == INT_MAX) {
293 avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_HIGH, 0);
294 } else {
295 avs_tmon_set_trip_temp(priv, TMON_TRIP_TYPE_HIGH, high);
296 avs_tmon_trip_enable(priv, TMON_TRIP_TYPE_HIGH, 1);
297 }
298
299 return 0;
300}
301
302static struct thermal_zone_of_device_ops of_ops = {
303 .get_temp = brcmstb_get_temp,
304 .set_trips = brcmstb_set_trips,
305};
306
307static const struct of_device_id brcmstb_thermal_id_table[] = {
308 { .compatible = "brcm,avs-tmon" },
309 {},
310};
311MODULE_DEVICE_TABLE(of, brcmstb_thermal_id_table);
312
313static int brcmstb_thermal_probe(struct platform_device *pdev)
314{
315 struct thermal_zone_device *thermal;
316 struct brcmstb_thermal_priv *priv;
317 struct resource *res;
318 int irq, ret;
319
320 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
321 if (!priv)
322 return -ENOMEM;
323
324 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
325 priv->tmon_base = devm_ioremap_resource(&pdev->dev, res);
326 if (IS_ERR(priv->tmon_base))
327 return PTR_ERR(priv->tmon_base);
328
329 priv->dev = &pdev->dev;
330 platform_set_drvdata(pdev, priv);
331
332 thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &of_ops);
333 if (IS_ERR(thermal)) {
334 ret = PTR_ERR(thermal);
335 dev_err(&pdev->dev, "could not register sensor: %d\n", ret);
336 return ret;
337 }
338
339 priv->thermal = thermal;
340
341 irq = platform_get_irq(pdev, 0);
342 if (irq < 0) {
343 dev_err(&pdev->dev, "could not get IRQ\n");
344 ret = irq;
345 goto err;
346 }
347 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
348 brcmstb_tmon_irq_thread, IRQF_ONESHOT,
349 DRV_NAME, priv);
350 if (ret < 0) {
351 dev_err(&pdev->dev, "could not request IRQ: %d\n", ret);
352 goto err;
353 }
354
355 dev_info(&pdev->dev, "registered AVS TMON of-sensor driver\n");
356
357 return 0;
358
359err:
360 thermal_zone_of_sensor_unregister(&pdev->dev, thermal);
361 return ret;
362}
363
364static int brcmstb_thermal_exit(struct platform_device *pdev)
365{
366 struct brcmstb_thermal_priv *priv = platform_get_drvdata(pdev);
367 struct thermal_zone_device *thermal = priv->thermal;
368
369 if (thermal)
370 thermal_zone_of_sensor_unregister(&pdev->dev, priv->thermal);
371
372 return 0;
373}
374
375static struct platform_driver brcmstb_thermal_driver = {
376 .probe = brcmstb_thermal_probe,
377 .remove = brcmstb_thermal_exit,
378 .driver = {
379 .name = DRV_NAME,
380 .of_match_table = brcmstb_thermal_id_table,
381 },
382};
383module_platform_driver(brcmstb_thermal_driver);
384
385MODULE_LICENSE("GPL v2");
386MODULE_AUTHOR("Brian Norris");
387MODULE_DESCRIPTION("Broadcom STB AVS TMON thermal driver");
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 908a8014cf76..dc63aba092e4 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -696,7 +696,7 @@ __cpufreq_cooling_register(struct device_node *np,
696 bool first; 696 bool first;
697 697
698 if (IS_ERR_OR_NULL(policy)) { 698 if (IS_ERR_OR_NULL(policy)) {
699 pr_err("%s: cpufreq policy isn't valid: %p", __func__, policy); 699 pr_err("%s: cpufreq policy isn't valid: %p\n", __func__, policy);
700 return ERR_PTR(-EINVAL); 700 return ERR_PTR(-EINVAL);
701 } 701 }
702 702
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index bd3572c41585..2d855a96cdd9 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -23,222 +23,450 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/of_device.h>
26 27
27#include "thermal_core.h" 28#include "thermal_core.h"
28 29
29#define TEMP0_TH (0x4) 30#define HI6220_TEMP0_LAG (0x0)
30#define TEMP0_RST_TH (0x8) 31#define HI6220_TEMP0_TH (0x4)
31#define TEMP0_CFG (0xC) 32#define HI6220_TEMP0_RST_TH (0x8)
32#define TEMP0_EN (0x10) 33#define HI6220_TEMP0_CFG (0xC)
33#define TEMP0_INT_EN (0x14) 34#define HI6220_TEMP0_CFG_SS_MSK (0xF000)
34#define TEMP0_INT_CLR (0x18) 35#define HI6220_TEMP0_CFG_HDAK_MSK (0x30)
35#define TEMP0_RST_MSK (0x1C) 36#define HI6220_TEMP0_EN (0x10)
36#define TEMP0_VALUE (0x28) 37#define HI6220_TEMP0_INT_EN (0x14)
37 38#define HI6220_TEMP0_INT_CLR (0x18)
38#define HISI_TEMP_BASE (-60) 39#define HI6220_TEMP0_RST_MSK (0x1C)
39#define HISI_TEMP_RESET (100000) 40#define HI6220_TEMP0_VALUE (0x28)
40 41
41#define HISI_MAX_SENSORS 4 42#define HI3660_OFFSET(chan) ((chan) * 0x40)
43#define HI3660_TEMP(chan) (HI3660_OFFSET(chan) + 0x1C)
44#define HI3660_TH(chan) (HI3660_OFFSET(chan) + 0x20)
45#define HI3660_LAG(chan) (HI3660_OFFSET(chan) + 0x28)
46#define HI3660_INT_EN(chan) (HI3660_OFFSET(chan) + 0x2C)
47#define HI3660_INT_CLR(chan) (HI3660_OFFSET(chan) + 0x30)
48
49#define HI6220_TEMP_BASE (-60000)
50#define HI6220_TEMP_RESET (100000)
51#define HI6220_TEMP_STEP (785)
52#define HI6220_TEMP_LAG (3500)
53
54#define HI3660_TEMP_BASE (-63780)
55#define HI3660_TEMP_STEP (205)
56#define HI3660_TEMP_LAG (4000)
57
58#define HI6220_DEFAULT_SENSOR 2
59#define HI3660_DEFAULT_SENSOR 1
42 60
43struct hisi_thermal_sensor { 61struct hisi_thermal_sensor {
44 struct hisi_thermal_data *thermal;
45 struct thermal_zone_device *tzd; 62 struct thermal_zone_device *tzd;
46
47 long sensor_temp;
48 uint32_t id; 63 uint32_t id;
49 uint32_t thres_temp; 64 uint32_t thres_temp;
50}; 65};
51 66
52struct hisi_thermal_data { 67struct hisi_thermal_data {
53 struct mutex thermal_lock; /* protects register data */ 68 int (*get_temp)(struct hisi_thermal_data *data);
69 int (*enable_sensor)(struct hisi_thermal_data *data);
70 int (*disable_sensor)(struct hisi_thermal_data *data);
71 int (*irq_handler)(struct hisi_thermal_data *data);
54 struct platform_device *pdev; 72 struct platform_device *pdev;
55 struct clk *clk; 73 struct clk *clk;
56 struct hisi_thermal_sensor sensors[HISI_MAX_SENSORS]; 74 struct hisi_thermal_sensor sensor;
57
58 int irq, irq_bind_sensor;
59 bool irq_enabled;
60
61 void __iomem *regs; 75 void __iomem *regs;
76 int irq;
62}; 77};
63 78
64/* in millicelsius */ 79/*
65static inline int _step_to_temp(int step) 80 * The temperature computation on the tsensor is as follow:
81 * Unit: millidegree Celsius
82 * Step: 200/255 (0.7843)
83 * Temperature base: -60°C
84 *
85 * The register is programmed in temperature steps, every step is 785
86 * millidegree and begins at -60 000 m°C
87 *
88 * The temperature from the steps:
89 *
90 * Temp = TempBase + (steps x 785)
91 *
92 * and the steps from the temperature:
93 *
94 * steps = (Temp - TempBase) / 785
95 *
96 */
97static inline int hi6220_thermal_step_to_temp(int step)
66{ 98{
67 /* 99 return HI6220_TEMP_BASE + (step * HI6220_TEMP_STEP);
68 * Every step equals (1 * 200) / 255 celsius, and finally
69 * need convert to millicelsius.
70 */
71 return (HISI_TEMP_BASE * 1000 + (step * 200000 / 255));
72} 100}
73 101
74static inline long _temp_to_step(long temp) 102static inline int hi6220_thermal_temp_to_step(int temp)
75{ 103{
76 return ((temp - HISI_TEMP_BASE * 1000) * 255) / 200000; 104 return DIV_ROUND_UP(temp - HI6220_TEMP_BASE, HI6220_TEMP_STEP);
77} 105}
78 106
79static long hisi_thermal_get_sensor_temp(struct hisi_thermal_data *data, 107/*
80 struct hisi_thermal_sensor *sensor) 108 * for Hi3660,
109 * Step: 189/922 (0.205)
110 * Temperature base: -63.780°C
111 *
112 * The register is programmed in temperature steps, every step is 205
113 * millidegree and begins at -63 780 m°C
114 */
115static inline int hi3660_thermal_step_to_temp(int step)
81{ 116{
82 long val; 117 return HI3660_TEMP_BASE + step * HI3660_TEMP_STEP;
118}
83 119
84 mutex_lock(&data->thermal_lock); 120static inline int hi3660_thermal_temp_to_step(int temp)
121{
122 return DIV_ROUND_UP(temp - HI3660_TEMP_BASE, HI3660_TEMP_STEP);
123}
85 124
86 /* disable interrupt */ 125/*
87 writel(0x0, data->regs + TEMP0_INT_EN); 126 * The lag register contains 5 bits encoding the temperature in steps.
88 writel(0x1, data->regs + TEMP0_INT_CLR); 127 *
128 * Each time the temperature crosses the threshold boundary, an
129 * interrupt is raised. It could be when the temperature is going
130 * above the threshold or below. However, if the temperature is
131 * fluctuating around this value due to the load, we can receive
132 * several interrupts which may not desired.
133 *
134 * We can setup a temperature representing the delta between the
135 * threshold and the current temperature when the temperature is
136 * decreasing.
137 *
138 * For instance: the lag register is 5°C, the threshold is 65°C, when
139 * the temperature reaches 65°C an interrupt is raised and when the
140 * temperature decrease to 65°C - 5°C another interrupt is raised.
141 *
142 * A very short lag can lead to an interrupt storm, a long lag
143 * increase the latency to react to the temperature changes. In our
144 * case, that is not really a problem as we are polling the
145 * temperature.
146 *
147 * [0:4] : lag register
148 *
149 * The temperature is coded in steps, cf. HI6220_TEMP_STEP.
150 *
151 * Min : 0x00 : 0.0 °C
152 * Max : 0x1F : 24.3 °C
153 *
154 * The 'value' parameter is in milliCelsius.
155 */
156static inline void hi6220_thermal_set_lag(void __iomem *addr, int value)
157{
158 writel(DIV_ROUND_UP(value, HI6220_TEMP_STEP) & 0x1F,
159 addr + HI6220_TEMP0_LAG);
160}
89 161
90 /* disable module firstly */ 162static inline void hi6220_thermal_alarm_clear(void __iomem *addr, int value)
91 writel(0x0, data->regs + TEMP0_EN); 163{
164 writel(value, addr + HI6220_TEMP0_INT_CLR);
165}
92 166
93 /* select sensor id */ 167static inline void hi6220_thermal_alarm_enable(void __iomem *addr, int value)
94 writel((sensor->id << 12), data->regs + TEMP0_CFG); 168{
169 writel(value, addr + HI6220_TEMP0_INT_EN);
170}
95 171
96 /* enable module */ 172static inline void hi6220_thermal_alarm_set(void __iomem *addr, int temp)
97 writel(0x1, data->regs + TEMP0_EN); 173{
174 writel(hi6220_thermal_temp_to_step(temp) | 0x0FFFFFF00,
175 addr + HI6220_TEMP0_TH);
176}
98 177
99 usleep_range(3000, 5000); 178static inline void hi6220_thermal_reset_set(void __iomem *addr, int temp)
179{
180 writel(hi6220_thermal_temp_to_step(temp), addr + HI6220_TEMP0_RST_TH);
181}
100 182
101 val = readl(data->regs + TEMP0_VALUE); 183static inline void hi6220_thermal_reset_enable(void __iomem *addr, int value)
102 val = _step_to_temp(val); 184{
185 writel(value, addr + HI6220_TEMP0_RST_MSK);
186}
103 187
104 mutex_unlock(&data->thermal_lock); 188static inline void hi6220_thermal_enable(void __iomem *addr, int value)
189{
190 writel(value, addr + HI6220_TEMP0_EN);
191}
105 192
106 return val; 193static inline int hi6220_thermal_get_temperature(void __iomem *addr)
194{
195 return hi6220_thermal_step_to_temp(readl(addr + HI6220_TEMP0_VALUE));
107} 196}
108 197
109static void hisi_thermal_enable_bind_irq_sensor 198/*
110 (struct hisi_thermal_data *data) 199 * [0:6] lag register
200 *
201 * The temperature is coded in steps, cf. HI3660_TEMP_STEP.
202 *
203 * Min : 0x00 : 0.0 °C
204 * Max : 0x7F : 26.0 °C
205 *
206 */
207static inline void hi3660_thermal_set_lag(void __iomem *addr,
208 int id, int value)
111{ 209{
112 struct hisi_thermal_sensor *sensor; 210 writel(DIV_ROUND_UP(value, HI3660_TEMP_STEP) & 0x7F,
211 addr + HI3660_LAG(id));
212}
113 213
114 mutex_lock(&data->thermal_lock); 214static inline void hi3660_thermal_alarm_clear(void __iomem *addr,
215 int id, int value)
216{
217 writel(value, addr + HI3660_INT_CLR(id));
218}
115 219
116 sensor = &data->sensors[data->irq_bind_sensor]; 220static inline void hi3660_thermal_alarm_enable(void __iomem *addr,
221 int id, int value)
222{
223 writel(value, addr + HI3660_INT_EN(id));
224}
117 225
118 /* setting the hdak time */ 226static inline void hi3660_thermal_alarm_set(void __iomem *addr,
119 writel(0x0, data->regs + TEMP0_CFG); 227 int id, int value)
228{
229 writel(value, addr + HI3660_TH(id));
230}
231
232static inline int hi3660_thermal_get_temperature(void __iomem *addr, int id)
233{
234 return hi3660_thermal_step_to_temp(readl(addr + HI3660_TEMP(id)));
235}
236
237/*
238 * Temperature configuration register - Sensor selection
239 *
240 * Bits [19:12]
241 *
242 * 0x0: local sensor (default)
243 * 0x1: remote sensor 1 (ACPU cluster 1)
244 * 0x2: remote sensor 2 (ACPU cluster 0)
245 * 0x3: remote sensor 3 (G3D)
246 */
247static inline void hi6220_thermal_sensor_select(void __iomem *addr, int sensor)
248{
249 writel((readl(addr + HI6220_TEMP0_CFG) & ~HI6220_TEMP0_CFG_SS_MSK) |
250 (sensor << 12), addr + HI6220_TEMP0_CFG);
251}
252
253/*
254 * Temperature configuration register - Hdak conversion polling interval
255 *
256 * Bits [5:4]
257 *
258 * 0x0 : 0.768 ms
259 * 0x1 : 6.144 ms
260 * 0x2 : 49.152 ms
261 * 0x3 : 393.216 ms
262 */
263static inline void hi6220_thermal_hdak_set(void __iomem *addr, int value)
264{
265 writel((readl(addr + HI6220_TEMP0_CFG) & ~HI6220_TEMP0_CFG_HDAK_MSK) |
266 (value << 4), addr + HI6220_TEMP0_CFG);
267}
268
269static int hi6220_thermal_irq_handler(struct hisi_thermal_data *data)
270{
271 hi6220_thermal_alarm_clear(data->regs, 1);
272 return 0;
273}
274
275static int hi3660_thermal_irq_handler(struct hisi_thermal_data *data)
276{
277 hi3660_thermal_alarm_clear(data->regs, data->sensor.id, 1);
278 return 0;
279}
280
281static int hi6220_thermal_get_temp(struct hisi_thermal_data *data)
282{
283 return hi6220_thermal_get_temperature(data->regs);
284}
285
286static int hi3660_thermal_get_temp(struct hisi_thermal_data *data)
287{
288 return hi3660_thermal_get_temperature(data->regs, data->sensor.id);
289}
290
291static int hi6220_thermal_disable_sensor(struct hisi_thermal_data *data)
292{
293 /* disable sensor module */
294 hi6220_thermal_enable(data->regs, 0);
295 hi6220_thermal_alarm_enable(data->regs, 0);
296 hi6220_thermal_reset_enable(data->regs, 0);
297
298 clk_disable_unprepare(data->clk);
299
300 return 0;
301}
302
303static int hi3660_thermal_disable_sensor(struct hisi_thermal_data *data)
304{
305 /* disable sensor module */
306 hi3660_thermal_alarm_enable(data->regs, data->sensor.id, 0);
307 return 0;
308}
309
310static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data)
311{
312 struct hisi_thermal_sensor *sensor = &data->sensor;
313 int ret;
314
315 /* enable clock for tsensor */
316 ret = clk_prepare_enable(data->clk);
317 if (ret)
318 return ret;
120 319
121 /* disable module firstly */ 320 /* disable module firstly */
122 writel(0x0, data->regs + TEMP0_RST_MSK); 321 hi6220_thermal_reset_enable(data->regs, 0);
123 writel(0x0, data->regs + TEMP0_EN); 322 hi6220_thermal_enable(data->regs, 0);
124 323
125 /* select sensor id */ 324 /* select sensor id */
126 writel((sensor->id << 12), data->regs + TEMP0_CFG); 325 hi6220_thermal_sensor_select(data->regs, sensor->id);
326
327 /* setting the hdak time */
328 hi6220_thermal_hdak_set(data->regs, 0);
329
330 /* setting lag value between current temp and the threshold */
331 hi6220_thermal_set_lag(data->regs, HI6220_TEMP_LAG);
127 332
128 /* enable for interrupt */ 333 /* enable for interrupt */
129 writel(_temp_to_step(sensor->thres_temp) | 0x0FFFFFF00, 334 hi6220_thermal_alarm_set(data->regs, sensor->thres_temp);
130 data->regs + TEMP0_TH);
131 335
132 writel(_temp_to_step(HISI_TEMP_RESET), data->regs + TEMP0_RST_TH); 336 hi6220_thermal_reset_set(data->regs, HI6220_TEMP_RESET);
133 337
134 /* enable module */ 338 /* enable module */
135 writel(0x1, data->regs + TEMP0_RST_MSK); 339 hi6220_thermal_reset_enable(data->regs, 1);
136 writel(0x1, data->regs + TEMP0_EN); 340 hi6220_thermal_enable(data->regs, 1);
137
138 writel(0x0, data->regs + TEMP0_INT_CLR);
139 writel(0x1, data->regs + TEMP0_INT_EN);
140 341
141 usleep_range(3000, 5000); 342 hi6220_thermal_alarm_clear(data->regs, 0);
343 hi6220_thermal_alarm_enable(data->regs, 1);
142 344
143 mutex_unlock(&data->thermal_lock); 345 return 0;
144} 346}
145 347
146static void hisi_thermal_disable_sensor(struct hisi_thermal_data *data) 348static int hi3660_thermal_enable_sensor(struct hisi_thermal_data *data)
147{ 349{
148 mutex_lock(&data->thermal_lock); 350 unsigned int value;
351 struct hisi_thermal_sensor *sensor = &data->sensor;
149 352
150 /* disable sensor module */ 353 /* disable interrupt */
151 writel(0x0, data->regs + TEMP0_INT_EN); 354 hi3660_thermal_alarm_enable(data->regs, sensor->id, 0);
152 writel(0x0, data->regs + TEMP0_RST_MSK);
153 writel(0x0, data->regs + TEMP0_EN);
154 355
155 mutex_unlock(&data->thermal_lock); 356 /* setting lag value between current temp and the threshold */
156} 357 hi3660_thermal_set_lag(data->regs, sensor->id, HI3660_TEMP_LAG);
157 358
158static int hisi_thermal_get_temp(void *_sensor, int *temp) 359 /* set interrupt threshold */
159{ 360 value = hi3660_thermal_temp_to_step(sensor->thres_temp);
160 struct hisi_thermal_sensor *sensor = _sensor; 361 hi3660_thermal_alarm_set(data->regs, sensor->id, value);
161 struct hisi_thermal_data *data = sensor->thermal;
162 362
163 int sensor_id = -1, i; 363 /* enable interrupt */
164 long max_temp = 0; 364 hi3660_thermal_alarm_clear(data->regs, sensor->id, 1);
365 hi3660_thermal_alarm_enable(data->regs, sensor->id, 1);
165 366
166 *temp = hisi_thermal_get_sensor_temp(data, sensor); 367 return 0;
368}
167 369
168 sensor->sensor_temp = *temp; 370static int hi6220_thermal_probe(struct hisi_thermal_data *data)
371{
372 struct platform_device *pdev = data->pdev;
373 struct device *dev = &pdev->dev;
374 struct resource *res;
375 int ret;
169 376
170 for (i = 0; i < HISI_MAX_SENSORS; i++) { 377 data->get_temp = hi6220_thermal_get_temp;
171 if (!data->sensors[i].tzd) 378 data->enable_sensor = hi6220_thermal_enable_sensor;
172 continue; 379 data->disable_sensor = hi6220_thermal_disable_sensor;
380 data->irq_handler = hi6220_thermal_irq_handler;
173 381
174 if (data->sensors[i].sensor_temp >= max_temp) { 382 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
175 max_temp = data->sensors[i].sensor_temp; 383 data->regs = devm_ioremap_resource(dev, res);
176 sensor_id = i; 384 if (IS_ERR(data->regs)) {
177 } 385 dev_err(dev, "failed to get io address\n");
386 return PTR_ERR(data->regs);
178 } 387 }
179 388
180 /* If no sensor has been enabled, then skip to enable irq */ 389 data->clk = devm_clk_get(dev, "thermal_clk");
181 if (sensor_id == -1) 390 if (IS_ERR(data->clk)) {
182 return 0; 391 ret = PTR_ERR(data->clk);
183 392 if (ret != -EPROBE_DEFER)
184 mutex_lock(&data->thermal_lock); 393 dev_err(dev, "failed to get thermal clk: %d\n", ret);
185 data->irq_bind_sensor = sensor_id; 394 return ret;
186 mutex_unlock(&data->thermal_lock);
187
188 dev_dbg(&data->pdev->dev, "id=%d, irq=%d, temp=%d, thres=%d\n",
189 sensor->id, data->irq_enabled, *temp, sensor->thres_temp);
190 /*
191 * Bind irq to sensor for two cases:
192 * Reenable alarm IRQ if temperature below threshold;
193 * if irq has been enabled, always set it;
194 */
195 if (data->irq_enabled) {
196 hisi_thermal_enable_bind_irq_sensor(data);
197 return 0;
198 } 395 }
199 396
200 if (max_temp < sensor->thres_temp) { 397 data->irq = platform_get_irq(pdev, 0);
201 data->irq_enabled = true; 398 if (data->irq < 0)
202 hisi_thermal_enable_bind_irq_sensor(data); 399 return data->irq;
203 enable_irq(data->irq); 400
204 } 401 data->sensor.id = HI6220_DEFAULT_SENSOR;
205 402
206 return 0; 403 return 0;
207} 404}
208 405
209static const struct thermal_zone_of_device_ops hisi_of_thermal_ops = { 406static int hi3660_thermal_probe(struct hisi_thermal_data *data)
210 .get_temp = hisi_thermal_get_temp, 407{
211}; 408 struct platform_device *pdev = data->pdev;
409 struct device *dev = &pdev->dev;
410 struct resource *res;
411
412 data->get_temp = hi3660_thermal_get_temp;
413 data->enable_sensor = hi3660_thermal_enable_sensor;
414 data->disable_sensor = hi3660_thermal_disable_sensor;
415 data->irq_handler = hi3660_thermal_irq_handler;
416
417 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
418 data->regs = devm_ioremap_resource(dev, res);
419 if (IS_ERR(data->regs)) {
420 dev_err(dev, "failed to get io address\n");
421 return PTR_ERR(data->regs);
422 }
212 423
213static irqreturn_t hisi_thermal_alarm_irq(int irq, void *dev) 424 data->irq = platform_get_irq(pdev, 0);
425 if (data->irq < 0)
426 return data->irq;
427
428 data->sensor.id = HI3660_DEFAULT_SENSOR;
429
430 return 0;
431}
432
433static int hisi_thermal_get_temp(void *__data, int *temp)
214{ 434{
215 struct hisi_thermal_data *data = dev; 435 struct hisi_thermal_data *data = __data;
436 struct hisi_thermal_sensor *sensor = &data->sensor;
216 437
217 disable_irq_nosync(irq); 438 *temp = data->get_temp(data);
218 data->irq_enabled = false;
219 439
220 return IRQ_WAKE_THREAD; 440 dev_dbg(&data->pdev->dev, "id=%d, temp=%d, thres=%d\n",
441 sensor->id, *temp, sensor->thres_temp);
442
443 return 0;
221} 444}
222 445
446static const struct thermal_zone_of_device_ops hisi_of_thermal_ops = {
447 .get_temp = hisi_thermal_get_temp,
448};
449
223static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev) 450static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev)
224{ 451{
225 struct hisi_thermal_data *data = dev; 452 struct hisi_thermal_data *data = dev;
226 struct hisi_thermal_sensor *sensor; 453 struct hisi_thermal_sensor *sensor = &data->sensor;
227 int i; 454 int temp = 0;
228 455
229 mutex_lock(&data->thermal_lock); 456 data->irq_handler(data);
230 sensor = &data->sensors[data->irq_bind_sensor];
231 457
232 dev_crit(&data->pdev->dev, "THERMAL ALARM: T > %d\n", 458 hisi_thermal_get_temp(data, &temp);
233 sensor->thres_temp / 1000);
234 mutex_unlock(&data->thermal_lock);
235 459
236 for (i = 0; i < HISI_MAX_SENSORS; i++) { 460 if (temp >= sensor->thres_temp) {
237 if (!data->sensors[i].tzd) 461 dev_crit(&data->pdev->dev, "THERMAL ALARM: %d > %d\n",
238 continue; 462 temp, sensor->thres_temp);
239 463
240 thermal_zone_device_update(data->sensors[i].tzd, 464 thermal_zone_device_update(data->sensor.tzd,
241 THERMAL_EVENT_UNSPECIFIED); 465 THERMAL_EVENT_UNSPECIFIED);
466
467 } else {
468 dev_crit(&data->pdev->dev, "THERMAL ALARM stopped: %d < %d\n",
469 temp, sensor->thres_temp);
242 } 470 }
243 471
244 return IRQ_HANDLED; 472 return IRQ_HANDLED;
@@ -246,17 +474,14 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev)
246 474
247static int hisi_thermal_register_sensor(struct platform_device *pdev, 475static int hisi_thermal_register_sensor(struct platform_device *pdev,
248 struct hisi_thermal_data *data, 476 struct hisi_thermal_data *data,
249 struct hisi_thermal_sensor *sensor, 477 struct hisi_thermal_sensor *sensor)
250 int index)
251{ 478{
252 int ret, i; 479 int ret, i;
253 const struct thermal_trip *trip; 480 const struct thermal_trip *trip;
254 481
255 sensor->id = index;
256 sensor->thermal = data;
257
258 sensor->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 482 sensor->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev,
259 sensor->id, sensor, &hisi_of_thermal_ops); 483 sensor->id, data,
484 &hisi_of_thermal_ops);
260 if (IS_ERR(sensor->tzd)) { 485 if (IS_ERR(sensor->tzd)) {
261 ret = PTR_ERR(sensor->tzd); 486 ret = PTR_ERR(sensor->tzd);
262 sensor->tzd = NULL; 487 sensor->tzd = NULL;
@@ -278,7 +503,14 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
278} 503}
279 504
280static const struct of_device_id of_hisi_thermal_match[] = { 505static const struct of_device_id of_hisi_thermal_match[] = {
281 { .compatible = "hisilicon,tsensor" }, 506 {
507 .compatible = "hisilicon,tsensor",
508 .data = hi6220_thermal_probe
509 },
510 {
511 .compatible = "hisilicon,hi3660-tsensor",
512 .data = hi3660_thermal_probe
513 },
282 { /* end */ } 514 { /* end */ }
283}; 515};
284MODULE_DEVICE_TABLE(of, of_hisi_thermal_match); 516MODULE_DEVICE_TABLE(of, of_hisi_thermal_match);
@@ -295,88 +527,63 @@ static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor,
295static int hisi_thermal_probe(struct platform_device *pdev) 527static int hisi_thermal_probe(struct platform_device *pdev)
296{ 528{
297 struct hisi_thermal_data *data; 529 struct hisi_thermal_data *data;
298 struct resource *res; 530 int const (*platform_probe)(struct hisi_thermal_data *);
299 int i; 531 struct device *dev = &pdev->dev;
300 int ret; 532 int ret;
301 533
302 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 534 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
303 if (!data) 535 if (!data)
304 return -ENOMEM; 536 return -ENOMEM;
305 537
306 mutex_init(&data->thermal_lock);
307 data->pdev = pdev; 538 data->pdev = pdev;
539 platform_set_drvdata(pdev, data);
308 540
309 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 541 platform_probe = of_device_get_match_data(dev);
310 data->regs = devm_ioremap_resource(&pdev->dev, res); 542 if (!platform_probe) {
311 if (IS_ERR(data->regs)) { 543 dev_err(dev, "failed to get probe func\n");
312 dev_err(&pdev->dev, "failed to get io address\n"); 544 return -EINVAL;
313 return PTR_ERR(data->regs);
314 } 545 }
315 546
316 data->irq = platform_get_irq(pdev, 0); 547 ret = platform_probe(data);
317 if (data->irq < 0) 548 if (ret)
318 return data->irq;
319
320 ret = devm_request_threaded_irq(&pdev->dev, data->irq,
321 hisi_thermal_alarm_irq,
322 hisi_thermal_alarm_irq_thread,
323 0, "hisi_thermal", data);
324 if (ret < 0) {
325 dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
326 return ret; 549 return ret;
327 }
328 550
329 platform_set_drvdata(pdev, data); 551 ret = hisi_thermal_register_sensor(pdev, data,
330 552 &data->sensor);
331 data->clk = devm_clk_get(&pdev->dev, "thermal_clk"); 553 if (ret) {
332 if (IS_ERR(data->clk)) { 554 dev_err(dev, "failed to register thermal sensor: %d\n", ret);
333 ret = PTR_ERR(data->clk);
334 if (ret != -EPROBE_DEFER)
335 dev_err(&pdev->dev,
336 "failed to get thermal clk: %d\n", ret);
337 return ret; 555 return ret;
338 } 556 }
339 557
340 /* enable clock for thermal */ 558 ret = data->enable_sensor(data);
341 ret = clk_prepare_enable(data->clk);
342 if (ret) { 559 if (ret) {
343 dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret); 560 dev_err(dev, "Failed to setup the sensor: %d\n", ret);
344 return ret; 561 return ret;
345 } 562 }
346 563
347 hisi_thermal_enable_bind_irq_sensor(data); 564 if (data->irq) {
348 irq_get_irqchip_state(data->irq, IRQCHIP_STATE_MASKED, 565 ret = devm_request_threaded_irq(dev, data->irq, NULL,
349 &data->irq_enabled); 566 hisi_thermal_alarm_irq_thread,
350 567 IRQF_ONESHOT, "hisi_thermal", data);
351 for (i = 0; i < HISI_MAX_SENSORS; ++i) { 568 if (ret < 0) {
352 ret = hisi_thermal_register_sensor(pdev, data, 569 dev_err(dev, "failed to request alarm irq: %d\n", ret);
353 &data->sensors[i], i); 570 return ret;
354 if (ret) 571 }
355 dev_err(&pdev->dev,
356 "failed to register thermal sensor: %d\n", ret);
357 else
358 hisi_thermal_toggle_sensor(&data->sensors[i], true);
359 } 572 }
360 573
574 hisi_thermal_toggle_sensor(&data->sensor, true);
575
361 return 0; 576 return 0;
362} 577}
363 578
364static int hisi_thermal_remove(struct platform_device *pdev) 579static int hisi_thermal_remove(struct platform_device *pdev)
365{ 580{
366 struct hisi_thermal_data *data = platform_get_drvdata(pdev); 581 struct hisi_thermal_data *data = platform_get_drvdata(pdev);
367 int i; 582 struct hisi_thermal_sensor *sensor = &data->sensor;
368 583
369 for (i = 0; i < HISI_MAX_SENSORS; i++) { 584 hisi_thermal_toggle_sensor(sensor, false);
370 struct hisi_thermal_sensor *sensor = &data->sensors[i];
371 585
372 if (!sensor->tzd) 586 data->disable_sensor(data);
373 continue;
374
375 hisi_thermal_toggle_sensor(sensor, false);
376 }
377
378 hisi_thermal_disable_sensor(data);
379 clk_disable_unprepare(data->clk);
380 587
381 return 0; 588 return 0;
382} 589}
@@ -386,10 +593,7 @@ static int hisi_thermal_suspend(struct device *dev)
386{ 593{
387 struct hisi_thermal_data *data = dev_get_drvdata(dev); 594 struct hisi_thermal_data *data = dev_get_drvdata(dev);
388 595
389 hisi_thermal_disable_sensor(data); 596 data->disable_sensor(data);
390 data->irq_enabled = false;
391
392 clk_disable_unprepare(data->clk);
393 597
394 return 0; 598 return 0;
395} 599}
@@ -397,16 +601,8 @@ static int hisi_thermal_suspend(struct device *dev)
397static int hisi_thermal_resume(struct device *dev) 601static int hisi_thermal_resume(struct device *dev)
398{ 602{
399 struct hisi_thermal_data *data = dev_get_drvdata(dev); 603 struct hisi_thermal_data *data = dev_get_drvdata(dev);
400 int ret;
401 604
402 ret = clk_prepare_enable(data->clk); 605 return data->enable_sensor(data);
403 if (ret)
404 return ret;
405
406 data->irq_enabled = true;
407 hisi_thermal_enable_bind_irq_sensor(data);
408
409 return 0;
410} 606}
411#endif 607#endif
412 608
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 4798b4b1fd77..e7d4ffc3de7f 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -25,6 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/thermal.h> 26#include <linux/thermal.h>
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/nvmem-consumer.h>
28 29
29#define REG_SET 0x4 30#define REG_SET 0x4
30#define REG_CLR 0x8 31#define REG_CLR 0x8
@@ -94,7 +95,7 @@ struct imx_thermal_data {
94 struct thermal_cooling_device *cdev; 95 struct thermal_cooling_device *cdev;
95 enum thermal_device_mode mode; 96 enum thermal_device_mode mode;
96 struct regmap *tempmon; 97 struct regmap *tempmon;
97 u32 c1, c2; /* See formula in imx_get_sensor_data() */ 98 u32 c1, c2; /* See formula in imx_init_calib() */
98 int temp_passive; 99 int temp_passive;
99 int temp_critical; 100 int temp_critical;
100 int temp_max; 101 int temp_max;
@@ -177,7 +178,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
177 178
178 n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT; 179 n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT;
179 180
180 /* See imx_get_sensor_data() for formula derivation */ 181 /* See imx_init_calib() for formula derivation */
181 *temp = data->c2 - n_meas * data->c1; 182 *temp = data->c2 - n_meas * data->c1;
182 183
183 /* Update alarm value to next higher trip point for TEMPMON_IMX6Q */ 184 /* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
@@ -346,29 +347,12 @@ static struct thermal_zone_device_ops imx_tz_ops = {
346 .set_trip_temp = imx_set_trip_temp, 347 .set_trip_temp = imx_set_trip_temp,
347}; 348};
348 349
349static int imx_get_sensor_data(struct platform_device *pdev) 350static int imx_init_calib(struct platform_device *pdev, u32 val)
350{ 351{
351 struct imx_thermal_data *data = platform_get_drvdata(pdev); 352 struct imx_thermal_data *data = platform_get_drvdata(pdev);
352 struct regmap *map;
353 int t1, n1; 353 int t1, n1;
354 int ret;
355 u32 val;
356 u64 temp64; 354 u64 temp64;
357 355
358 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
359 "fsl,tempmon-data");
360 if (IS_ERR(map)) {
361 ret = PTR_ERR(map);
362 dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret);
363 return ret;
364 }
365
366 ret = regmap_read(map, OCOTP_ANA1, &val);
367 if (ret) {
368 dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
369 return ret;
370 }
371
372 if (val == 0 || val == ~0) { 356 if (val == 0 || val == ~0) {
373 dev_err(&pdev->dev, "invalid sensor calibration data\n"); 357 dev_err(&pdev->dev, "invalid sensor calibration data\n");
374 return -EINVAL; 358 return -EINVAL;
@@ -405,12 +389,12 @@ static int imx_get_sensor_data(struct platform_device *pdev)
405 data->c1 = temp64; 389 data->c1 = temp64;
406 data->c2 = n1 * data->c1 + 1000 * t1; 390 data->c2 = n1 * data->c1 + 1000 * t1;
407 391
408 /* use OTP for thermal grade */ 392 return 0;
409 ret = regmap_read(map, OCOTP_MEM0, &val); 393}
410 if (ret) { 394
411 dev_err(&pdev->dev, "failed to read temp grade: %d\n", ret); 395static void imx_init_temp_grade(struct platform_device *pdev, u32 val)
412 return ret; 396{
413 } 397 struct imx_thermal_data *data = platform_get_drvdata(pdev);
414 398
415 /* The maximum die temp is specified by the Temperature Grade */ 399 /* The maximum die temp is specified by the Temperature Grade */
416 switch ((val >> 6) & 0x3) { 400 switch ((val >> 6) & 0x3) {
@@ -438,6 +422,55 @@ static int imx_get_sensor_data(struct platform_device *pdev)
438 */ 422 */
439 data->temp_critical = data->temp_max - (1000 * 5); 423 data->temp_critical = data->temp_max - (1000 * 5);
440 data->temp_passive = data->temp_max - (1000 * 10); 424 data->temp_passive = data->temp_max - (1000 * 10);
425}
426
427static int imx_init_from_tempmon_data(struct platform_device *pdev)
428{
429 struct regmap *map;
430 int ret;
431 u32 val;
432
433 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
434 "fsl,tempmon-data");
435 if (IS_ERR(map)) {
436 ret = PTR_ERR(map);
437 dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret);
438 return ret;
439 }
440
441 ret = regmap_read(map, OCOTP_ANA1, &val);
442 if (ret) {
443 dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
444 return ret;
445 }
446 ret = imx_init_calib(pdev, val);
447 if (ret)
448 return ret;
449
450 ret = regmap_read(map, OCOTP_MEM0, &val);
451 if (ret) {
452 dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
453 return ret;
454 }
455 imx_init_temp_grade(pdev, val);
456
457 return 0;
458}
459
460static int imx_init_from_nvmem_cells(struct platform_device *pdev)
461{
462 int ret;
463 u32 val;
464
465 ret = nvmem_cell_read_u32(&pdev->dev, "calib", &val);
466 if (ret)
467 return ret;
468 imx_init_calib(pdev, val);
469
470 ret = nvmem_cell_read_u32(&pdev->dev, "temp_grade", &val);
471 if (ret)
472 return ret;
473 imx_init_temp_grade(pdev, val);
441 474
442 return 0; 475 return 0;
443} 476}
@@ -514,10 +547,21 @@ static int imx_thermal_probe(struct platform_device *pdev)
514 547
515 platform_set_drvdata(pdev, data); 548 platform_set_drvdata(pdev, data);
516 549
517 ret = imx_get_sensor_data(pdev); 550 if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) {
518 if (ret) { 551 ret = imx_init_from_nvmem_cells(pdev);
519 dev_err(&pdev->dev, "failed to get sensor data\n"); 552 if (ret == -EPROBE_DEFER)
520 return ret; 553 return ret;
554 if (ret) {
555 dev_err(&pdev->dev, "failed to init from nvmem: %d\n",
556 ret);
557 return ret;
558 }
559 } else {
560 ret = imx_init_from_tempmon_data(pdev);
561 if (ret) {
562 dev_err(&pdev->dev, "failed to init from from fsl,tempmon-data\n");
563 return ret;
564 }
521 } 565 }
522 566
523 /* Make sure sensor is in known good state for measurements */ 567 /* Make sure sensor is in known good state for measurements */
diff --git a/drivers/thermal/int340x_thermal/processor_thermal_device.c b/drivers/thermal/int340x_thermal/processor_thermal_device.c
index f02341f7134d..80bbf9ce2fb6 100644
--- a/drivers/thermal/int340x_thermal/processor_thermal_device.c
+++ b/drivers/thermal/int340x_thermal/processor_thermal_device.c
@@ -30,6 +30,10 @@
30/* Skylake thermal reporting device */ 30/* Skylake thermal reporting device */
31#define PCI_DEVICE_ID_PROC_SKL_THERMAL 0x1903 31#define PCI_DEVICE_ID_PROC_SKL_THERMAL 0x1903
32 32
33/* CannonLake thermal reporting device */
34#define PCI_DEVICE_ID_PROC_CNL_THERMAL 0x5a03
35#define PCI_DEVICE_ID_PROC_CFL_THERMAL 0x3E83
36
33/* Braswell thermal reporting device */ 37/* Braswell thermal reporting device */
34#define PCI_DEVICE_ID_PROC_BSW_THERMAL 0x22DC 38#define PCI_DEVICE_ID_PROC_BSW_THERMAL 0x22DC
35 39
@@ -461,6 +465,8 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
461 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXT1_THERMAL)}, 465 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXT1_THERMAL)},
462 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXTX_THERMAL)}, 466 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXTX_THERMAL)},
463 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXTP_THERMAL)}, 467 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXTP_THERMAL)},
468 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CNL_THERMAL)},
469 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CFL_THERMAL)},
464 { 0, }, 470 { 0, },
465}; 471};
466 472
diff --git a/drivers/thermal/intel_bxt_pmic_thermal.c b/drivers/thermal/intel_bxt_pmic_thermal.c
index ef6b32242ccb..94cfd0064c43 100644
--- a/drivers/thermal/intel_bxt_pmic_thermal.c
+++ b/drivers/thermal/intel_bxt_pmic_thermal.c
@@ -166,7 +166,7 @@ static irqreturn_t pmic_thermal_irq_handler(int irq, void *data)
166 struct pmic_thermal_data *td; 166 struct pmic_thermal_data *td;
167 struct intel_soc_pmic *pmic; 167 struct intel_soc_pmic *pmic;
168 struct regmap *regmap; 168 struct regmap *regmap;
169 u8 reg_val, mask, irq_stat, trip; 169 u8 reg_val, mask, irq_stat;
170 u16 reg, evt_stat_reg; 170 u16 reg, evt_stat_reg;
171 int i, j, ret; 171 int i, j, ret;
172 172
@@ -201,7 +201,6 @@ static irqreturn_t pmic_thermal_irq_handler(int irq, void *data)
201 if (regmap_read(regmap, evt_stat_reg, &ret)) 201 if (regmap_read(regmap, evt_stat_reg, &ret))
202 return IRQ_HANDLED; 202 return IRQ_HANDLED;
203 203
204 trip = td->maps[i].trip_config[j].trip_num;
205 tzd = thermal_zone_get_zone_by_name(td->maps[i].handle); 204 tzd = thermal_zone_get_zone_by_name(td->maps[i].handle);
206 if (!IS_ERR(tzd)) 205 if (!IS_ERR(tzd))
207 thermal_zone_device_update(tzd, 206 thermal_zone_device_update(tzd,
diff --git a/drivers/thermal/intel_pch_thermal.c b/drivers/thermal/intel_pch_thermal.c
index c60b1cfcc64e..8a7f69b4b022 100644
--- a/drivers/thermal/intel_pch_thermal.c
+++ b/drivers/thermal/intel_pch_thermal.c
@@ -30,6 +30,8 @@
30#define PCH_THERMAL_DID_WPT 0x9CA4 /* Wildcat Point */ 30#define PCH_THERMAL_DID_WPT 0x9CA4 /* Wildcat Point */
31#define PCH_THERMAL_DID_SKL 0x9D31 /* Skylake PCH */ 31#define PCH_THERMAL_DID_SKL 0x9D31 /* Skylake PCH */
32#define PCH_THERMAL_DID_SKL_H 0xA131 /* Skylake PCH 100 series */ 32#define PCH_THERMAL_DID_SKL_H 0xA131 /* Skylake PCH 100 series */
33#define PCH_THERMAL_DID_CNL 0x9Df9 /* CNL PCH */
34#define PCH_THERMAL_DID_CNL_H 0xA379 /* CNL-H PCH */
33 35
34/* Wildcat Point-LP PCH Thermal registers */ 36/* Wildcat Point-LP PCH Thermal registers */
35#define WPT_TEMP 0x0000 /* Temperature */ 37#define WPT_TEMP 0x0000 /* Temperature */
@@ -278,6 +280,7 @@ enum board_ids {
278 board_hsw, 280 board_hsw,
279 board_wpt, 281 board_wpt,
280 board_skl, 282 board_skl,
283 board_cnl,
281}; 284};
282 285
283static const struct board_info { 286static const struct board_info {
@@ -296,6 +299,10 @@ static const struct board_info {
296 .name = "pch_skylake", 299 .name = "pch_skylake",
297 .ops = &pch_dev_ops_wpt, 300 .ops = &pch_dev_ops_wpt,
298 }, 301 },
302 [board_cnl] = {
303 .name = "pch_cannonlake",
304 .ops = &pch_dev_ops_wpt,
305 },
299}; 306};
300 307
301static int intel_pch_thermal_probe(struct pci_dev *pdev, 308static int intel_pch_thermal_probe(struct pci_dev *pdev,
@@ -398,6 +405,10 @@ static const struct pci_device_id intel_pch_thermal_id[] = {
398 .driver_data = board_skl, }, 405 .driver_data = board_skl, },
399 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_SKL_H), 406 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_SKL_H),
400 .driver_data = board_skl, }, 407 .driver_data = board_skl, },
408 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_CNL),
409 .driver_data = board_cnl, },
410 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_CNL_H),
411 .driver_data = board_cnl, },
401 { 0, }, 412 { 0, },
402}; 413};
403MODULE_DEVICE_TABLE(pci, intel_pch_thermal_id); 414MODULE_DEVICE_TABLE(pci, intel_pch_thermal_id);
diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c
index d718cd179ddb..4540e892b61d 100644
--- a/drivers/thermal/intel_powerclamp.c
+++ b/drivers/thermal/intel_powerclamp.c
@@ -675,13 +675,13 @@ static int __init powerclamp_probe(void)
675{ 675{
676 676
677 if (!x86_match_cpu(intel_powerclamp_ids)) { 677 if (!x86_match_cpu(intel_powerclamp_ids)) {
678 pr_err("CPU does not support MWAIT"); 678 pr_err("CPU does not support MWAIT\n");
679 return -ENODEV; 679 return -ENODEV;
680 } 680 }
681 681
682 /* The goal for idle time alignment is to achieve package cstate. */ 682 /* The goal for idle time alignment is to achieve package cstate. */
683 if (!has_pkg_state_counter()) { 683 if (!has_pkg_state_counter()) {
684 pr_info("No package C-state available"); 684 pr_info("No package C-state available\n");
685 return -ENODEV; 685 return -ENODEV;
686 } 686 }
687 687
diff --git a/drivers/thermal/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom-spmi-temp-alarm.c
index f50241962ad2..95f987d5aa71 100644
--- a/drivers/thermal/qcom-spmi-temp-alarm.c
+++ b/drivers/thermal/qcom-spmi-temp-alarm.c
@@ -125,7 +125,7 @@ static int qpnp_tm_get_temp(void *data, int *temp)
125 if (!temp) 125 if (!temp)
126 return -EINVAL; 126 return -EINVAL;
127 127
128 if (IS_ERR(chip->adc)) { 128 if (!chip->adc) {
129 ret = qpnp_tm_update_temp_no_adc(chip); 129 ret = qpnp_tm_update_temp_no_adc(chip);
130 if (ret < 0) 130 if (ret < 0)
131 return ret; 131 return ret;
@@ -224,67 +224,53 @@ static int qpnp_tm_probe(struct platform_device *pdev)
224 return irq; 224 return irq;
225 225
226 /* ADC based measurements are optional */ 226 /* ADC based measurements are optional */
227 chip->adc = iio_channel_get(&pdev->dev, "thermal"); 227 chip->adc = devm_iio_channel_get(&pdev->dev, "thermal");
228 if (PTR_ERR(chip->adc) == -EPROBE_DEFER) 228 if (IS_ERR(chip->adc)) {
229 return PTR_ERR(chip->adc); 229 ret = PTR_ERR(chip->adc);
230 chip->adc = NULL;
231 if (ret == -EPROBE_DEFER)
232 return ret;
233 }
230 234
231 chip->base = res; 235 chip->base = res;
232 236
233 ret = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, &type); 237 ret = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, &type);
234 if (ret < 0) { 238 if (ret < 0) {
235 dev_err(&pdev->dev, "could not read type\n"); 239 dev_err(&pdev->dev, "could not read type\n");
236 goto fail; 240 return ret;
237 } 241 }
238 242
239 ret = qpnp_tm_read(chip, QPNP_TM_REG_SUBTYPE, &subtype); 243 ret = qpnp_tm_read(chip, QPNP_TM_REG_SUBTYPE, &subtype);
240 if (ret < 0) { 244 if (ret < 0) {
241 dev_err(&pdev->dev, "could not read subtype\n"); 245 dev_err(&pdev->dev, "could not read subtype\n");
242 goto fail; 246 return ret;
243 } 247 }
244 248
245 if (type != QPNP_TM_TYPE || subtype != QPNP_TM_SUBTYPE) { 249 if (type != QPNP_TM_TYPE || subtype != QPNP_TM_SUBTYPE) {
246 dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n", 250 dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n",
247 type, subtype); 251 type, subtype);
248 ret = -ENODEV; 252 return -ENODEV;
249 goto fail;
250 } 253 }
251 254
252 ret = qpnp_tm_init(chip); 255 ret = qpnp_tm_init(chip);
253 if (ret < 0) { 256 if (ret < 0) {
254 dev_err(&pdev->dev, "init failed\n"); 257 dev_err(&pdev->dev, "init failed\n");
255 goto fail; 258 return ret;
256 } 259 }
257 260
258 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, qpnp_tm_isr, 261 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, qpnp_tm_isr,
259 IRQF_ONESHOT, node->name, chip); 262 IRQF_ONESHOT, node->name, chip);
260 if (ret < 0) 263 if (ret < 0)
261 goto fail; 264 return ret;
262 265
263 chip->tz_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, chip, 266 chip->tz_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, chip,
264 &qpnp_tm_sensor_ops); 267 &qpnp_tm_sensor_ops);
265 if (IS_ERR(chip->tz_dev)) { 268 if (IS_ERR(chip->tz_dev)) {
266 dev_err(&pdev->dev, "failed to register sensor\n"); 269 dev_err(&pdev->dev, "failed to register sensor\n");
267 ret = PTR_ERR(chip->tz_dev); 270 return PTR_ERR(chip->tz_dev);
268 goto fail;
269 } 271 }
270 272
271 return 0; 273 return 0;
272
273fail:
274 if (!IS_ERR(chip->adc))
275 iio_channel_release(chip->adc);
276
277 return ret;
278}
279
280static int qpnp_tm_remove(struct platform_device *pdev)
281{
282 struct qpnp_tm_chip *chip = dev_get_drvdata(&pdev->dev);
283
284 if (!IS_ERR(chip->adc))
285 iio_channel_release(chip->adc);
286
287 return 0;
288} 274}
289 275
290static const struct of_device_id qpnp_tm_match_table[] = { 276static const struct of_device_id qpnp_tm_match_table[] = {
@@ -299,7 +285,6 @@ static struct platform_driver qpnp_tm_driver = {
299 .of_match_table = qpnp_tm_match_table, 285 .of_match_table = qpnp_tm_match_table,
300 }, 286 },
301 .probe = qpnp_tm_probe, 287 .probe = qpnp_tm_probe,
302 .remove = qpnp_tm_remove,
303}; 288};
304module_platform_driver(qpnp_tm_driver); 289module_platform_driver(qpnp_tm_driver);
305 290
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index 203aca44a2bb..561a0a332208 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -24,6 +24,7 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/pm_runtime.h> 25#include <linux/pm_runtime.h>
26#include <linux/spinlock.h> 26#include <linux/spinlock.h>
27#include <linux/sys_soc.h>
27#include <linux/thermal.h> 28#include <linux/thermal.h>
28 29
29#include "thermal_core.h" 30#include "thermal_core.h"
@@ -90,10 +91,6 @@ struct rcar_gen3_thermal_priv {
90 struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM]; 91 struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM];
91 unsigned int num_tscs; 92 unsigned int num_tscs;
92 spinlock_t lock; /* Protect interrupts on and off */ 93 spinlock_t lock; /* Protect interrupts on and off */
93 const struct rcar_gen3_thermal_data *data;
94};
95
96struct rcar_gen3_thermal_data {
97 void (*thermal_init)(struct rcar_gen3_thermal_tsc *tsc); 94 void (*thermal_init)(struct rcar_gen3_thermal_tsc *tsc);
98}; 95};
99 96
@@ -278,7 +275,12 @@ static irqreturn_t rcar_gen3_thermal_irq_thread(int irq, void *data)
278 return IRQ_HANDLED; 275 return IRQ_HANDLED;
279} 276}
280 277
281static void r8a7795_thermal_init(struct rcar_gen3_thermal_tsc *tsc) 278static const struct soc_device_attribute r8a7795es1[] = {
279 { .soc_id = "r8a7795", .revision = "ES1.*" },
280 { /* sentinel */ }
281};
282
283static void rcar_gen3_thermal_init_r8a7795es1(struct rcar_gen3_thermal_tsc *tsc)
282{ 284{
283 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_THBGR); 285 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_THBGR);
284 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, 0x0); 286 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, 0x0);
@@ -303,7 +305,7 @@ static void r8a7795_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
303 usleep_range(1000, 2000); 305 usleep_range(1000, 2000);
304} 306}
305 307
306static void r8a7796_thermal_init(struct rcar_gen3_thermal_tsc *tsc) 308static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
307{ 309{
308 u32 reg_val; 310 u32 reg_val;
309 311
@@ -324,17 +326,9 @@ static void r8a7796_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
324 usleep_range(1000, 2000); 326 usleep_range(1000, 2000);
325} 327}
326 328
327static const struct rcar_gen3_thermal_data r8a7795_data = {
328 .thermal_init = r8a7795_thermal_init,
329};
330
331static const struct rcar_gen3_thermal_data r8a7796_data = {
332 .thermal_init = r8a7796_thermal_init,
333};
334
335static const struct of_device_id rcar_gen3_thermal_dt_ids[] = { 329static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
336 { .compatible = "renesas,r8a7795-thermal", .data = &r8a7795_data}, 330 { .compatible = "renesas,r8a7795-thermal", },
337 { .compatible = "renesas,r8a7796-thermal", .data = &r8a7796_data}, 331 { .compatible = "renesas,r8a7796-thermal", },
338 {}, 332 {},
339}; 333};
340MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids); 334MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids);
@@ -371,7 +365,9 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
371 if (!priv) 365 if (!priv)
372 return -ENOMEM; 366 return -ENOMEM;
373 367
374 priv->data = of_device_get_match_data(dev); 368 priv->thermal_init = rcar_gen3_thermal_init;
369 if (soc_device_match(r8a7795es1))
370 priv->thermal_init = rcar_gen3_thermal_init_r8a7795es1;
375 371
376 spin_lock_init(&priv->lock); 372 spin_lock_init(&priv->lock);
377 373
@@ -423,7 +419,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
423 419
424 priv->tscs[i] = tsc; 420 priv->tscs[i] = tsc;
425 421
426 priv->data->thermal_init(tsc); 422 priv->thermal_init(tsc);
427 rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]); 423 rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]);
428 424
429 zone = devm_thermal_zone_of_sensor_register(dev, i, tsc, 425 zone = devm_thermal_zone_of_sensor_register(dev, i, tsc,
@@ -476,7 +472,7 @@ static int __maybe_unused rcar_gen3_thermal_resume(struct device *dev)
476 for (i = 0; i < priv->num_tscs; i++) { 472 for (i = 0; i < priv->num_tscs; i++) {
477 struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; 473 struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
478 474
479 priv->data->thermal_init(tsc); 475 priv->thermal_init(tsc);
480 rcar_gen3_thermal_set_trips(tsc, tsc->low, tsc->high); 476 rcar_gen3_thermal_set_trips(tsc, tsc->low, tsc->high);
481 } 477 }
482 478
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 206035139110..f36375d5a16c 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -242,6 +242,45 @@ struct tsadc_table {
242 int temp; 242 int temp;
243}; 243};
244 244
245static const struct tsadc_table rv1108_table[] = {
246 {0, -40000},
247 {374, -40000},
248 {382, -35000},
249 {389, -30000},
250 {397, -25000},
251 {405, -20000},
252 {413, -15000},
253 {421, -10000},
254 {429, -5000},
255 {436, 0},
256 {444, 5000},
257 {452, 10000},
258 {460, 15000},
259 {468, 20000},
260 {476, 25000},
261 {483, 30000},
262 {491, 35000},
263 {499, 40000},
264 {507, 45000},
265 {515, 50000},
266 {523, 55000},
267 {531, 60000},
268 {539, 65000},
269 {547, 70000},
270 {555, 75000},
271 {562, 80000},
272 {570, 85000},
273 {578, 90000},
274 {586, 95000},
275 {594, 100000},
276 {602, 105000},
277 {610, 110000},
278 {618, 115000},
279 {626, 120000},
280 {634, 125000},
281 {TSADCV2_DATA_MASK, 125000},
282};
283
245static const struct tsadc_table rk3228_code_table[] = { 284static const struct tsadc_table rk3228_code_table[] = {
246 {0, -40000}, 285 {0, -40000},
247 {588, -40000}, 286 {588, -40000},
@@ -779,6 +818,30 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
779 writel_relaxed(val, regs + TSADCV2_INT_EN); 818 writel_relaxed(val, regs + TSADCV2_INT_EN);
780} 819}
781 820
821static const struct rockchip_tsadc_chip rv1108_tsadc_data = {
822 .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
823 .chn_num = 1, /* one channel for tsadc */
824
825 .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
826 .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
827 .tshut_temp = 95000,
828
829 .initialize = rk_tsadcv2_initialize,
830 .irq_ack = rk_tsadcv3_irq_ack,
831 .control = rk_tsadcv3_control,
832 .get_temp = rk_tsadcv2_get_temp,
833 .set_alarm_temp = rk_tsadcv2_alarm_temp,
834 .set_tshut_temp = rk_tsadcv2_tshut_temp,
835 .set_tshut_mode = rk_tsadcv2_tshut_mode,
836
837 .table = {
838 .id = rv1108_table,
839 .length = ARRAY_SIZE(rv1108_table),
840 .data_mask = TSADCV2_DATA_MASK,
841 .mode = ADC_INCREMENT,
842 },
843};
844
782static const struct rockchip_tsadc_chip rk3228_tsadc_data = { 845static const struct rockchip_tsadc_chip rk3228_tsadc_data = {
783 .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ 846 .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
784 .chn_num = 1, /* one channel for tsadc */ 847 .chn_num = 1, /* one channel for tsadc */
@@ -928,6 +991,10 @@ static const struct rockchip_tsadc_chip rk3399_tsadc_data = {
928 991
929static const struct of_device_id of_rockchip_thermal_match[] = { 992static const struct of_device_id of_rockchip_thermal_match[] = {
930 { 993 {
994 .compatible = "rockchip,rv1108-tsadc",
995 .data = (void *)&rv1108_tsadc_data,
996 },
997 {
931 .compatible = "rockchip,rk3228-tsadc", 998 .compatible = "rockchip,rk3228-tsadc",
932 .data = (void *)&rk3228_tsadc_data, 999 .data = (void *)&rk3228_tsadc_data,
933 }, 1000 },
diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
index be95826631b7..ee047ca43084 100644
--- a/drivers/thermal/step_wise.c
+++ b/drivers/thermal/step_wise.c
@@ -31,8 +31,7 @@
31 * If the temperature is higher than a trip point, 31 * If the temperature is higher than a trip point,
32 * a. if the trend is THERMAL_TREND_RAISING, use higher cooling 32 * a. if the trend is THERMAL_TREND_RAISING, use higher cooling
33 * state for this trip point 33 * state for this trip point
34 * b. if the trend is THERMAL_TREND_DROPPING, use lower cooling 34 * b. if the trend is THERMAL_TREND_DROPPING, do nothing
35 * state for this trip point
36 * c. if the trend is THERMAL_TREND_RAISE_FULL, use upper limit 35 * c. if the trend is THERMAL_TREND_RAISE_FULL, use upper limit
37 * for this trip point 36 * for this trip point
38 * d. if the trend is THERMAL_TREND_DROP_FULL, use lower limit 37 * d. if the trend is THERMAL_TREND_DROP_FULL, use lower limit
@@ -94,9 +93,11 @@ static unsigned long get_target_state(struct thermal_instance *instance,
94 if (!throttle) 93 if (!throttle)
95 next_target = THERMAL_NO_TARGET; 94 next_target = THERMAL_NO_TARGET;
96 } else { 95 } else {
97 next_target = cur_state - 1; 96 if (!throttle) {
98 if (next_target > instance->upper) 97 next_target = cur_state - 1;
99 next_target = instance->upper; 98 if (next_target > instance->upper)
99 next_target = instance->upper;
100 }
100 } 101 }
101 break; 102 break;
102 case THERMAL_TREND_DROP_FULL: 103 case THERMAL_TREND_DROP_FULL:
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index 7d2db23d71a3..075db1de5e53 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -483,7 +483,7 @@ static int throttrip_program(struct device *dev,
483 unsigned int throt; 483 unsigned int throt;
484 u32 r, reg_off; 484 u32 r, reg_off;
485 485
486 if (!dev || !sg || !stc || !stc->init) 486 if (!sg || !stc || !stc->init)
487 return -EINVAL; 487 return -EINVAL;
488 488
489 temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain; 489 temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c
index 73f55d6a1721..46d3005335c7 100644
--- a/drivers/thermal/thermal-generic-adc.c
+++ b/drivers/thermal/thermal-generic-adc.c
@@ -126,38 +126,23 @@ static int gadc_thermal_probe(struct platform_device *pdev)
126 gti->dev = &pdev->dev; 126 gti->dev = &pdev->dev;
127 platform_set_drvdata(pdev, gti); 127 platform_set_drvdata(pdev, gti);
128 128
129 gti->channel = iio_channel_get(&pdev->dev, "sensor-channel"); 129 gti->channel = devm_iio_channel_get(&pdev->dev, "sensor-channel");
130 if (IS_ERR(gti->channel)) { 130 if (IS_ERR(gti->channel)) {
131 ret = PTR_ERR(gti->channel); 131 ret = PTR_ERR(gti->channel);
132 dev_err(&pdev->dev, "IIO channel not found: %d\n", ret); 132 dev_err(&pdev->dev, "IIO channel not found: %d\n", ret);
133 return ret; 133 return ret;
134 } 134 }
135 135
136 gti->tz_dev = thermal_zone_of_sensor_register(&pdev->dev, 0, 136 gti->tz_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, gti,
137 gti, &gadc_thermal_ops); 137 &gadc_thermal_ops);
138 if (IS_ERR(gti->tz_dev)) { 138 if (IS_ERR(gti->tz_dev)) {
139 ret = PTR_ERR(gti->tz_dev); 139 ret = PTR_ERR(gti->tz_dev);
140 dev_err(&pdev->dev, "Thermal zone sensor register failed: %d\n", 140 dev_err(&pdev->dev, "Thermal zone sensor register failed: %d\n",
141 ret); 141 ret);
142 goto sensor_fail; 142 return ret;
143 } 143 }
144 144
145 return 0; 145 return 0;
146
147sensor_fail:
148 iio_channel_release(gti->channel);
149
150 return ret;
151}
152
153static int gadc_thermal_remove(struct platform_device *pdev)
154{
155 struct gadc_thermal_info *gti = platform_get_drvdata(pdev);
156
157 thermal_zone_of_sensor_unregister(&pdev->dev, gti->tz_dev);
158 iio_channel_release(gti->channel);
159
160 return 0;
161} 146}
162 147
163static const struct of_device_id of_adc_thermal_match[] = { 148static const struct of_device_id of_adc_thermal_match[] = {
@@ -172,7 +157,6 @@ static struct platform_driver gadc_thermal_driver = {
172 .of_match_table = of_adc_thermal_match, 157 .of_match_table = of_adc_thermal_match,
173 }, 158 },
174 .probe = gadc_thermal_probe, 159 .probe = gadc_thermal_probe,
175 .remove = gadc_thermal_remove,
176}; 160};
177 161
178module_platform_driver(gadc_thermal_driver); 162module_platform_driver(gadc_thermal_driver);
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
index c211a8e4a210..b4f981daeaf2 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
@@ -278,7 +278,8 @@ int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id)
278 278
279 if (data) { 279 if (data) {
280 cpufreq_cooling_unregister(data->cool_dev); 280 cpufreq_cooling_unregister(data->cool_dev);
281 cpufreq_cpu_put(data->policy); 281 if (data->policy)
282 cpufreq_cpu_put(data->policy);
282 } 283 }
283 284
284 return 0; 285 return 0;