summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-27 14:35:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-27 14:35:13 -0400
commitd0e00bc5ada53bda296ce8bfffc2f2be9eb22632 (patch)
tree7b00f11f0406f21ae1ebf5f376a963f439fddeef
parent7bccb9f10c8f36ee791769b531ed4d28f6379aae (diff)
parent0f84d1d18c46d0f995962c876c8b2900fd183fd7 (diff)
Merge branch 'for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management updates from Zhang Rui: - Add Amit Kucheria as thermal subsystem Reviewer (Amit Kucheria) - Fix a use after free bug when unregistering thermal zone devices (Ido Schimmel) - Fix thermal core framework to use put_device() when device_register() fails (Yue Hu) - Enable intel_pch_thermal and MMIO RAPL support for Intel Icelake platform (Srinivas Pandruvada) - Add clock operations in qorip thermal driver, for some platforms with clock control like i.MX8MQ (Anson Huang) - A couple of trivial fixes and cleanups for thermal core and different soc thermal drivers (Amit Kucheria, Christophe JAILLET, Chuhong Yuan, Fuqian Huang, Kelsey Skunberg, Nathan Huckleberry, Rishi Gupta, Srinivas Kandagatla) * 'for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: MAINTAINERS: Add Amit Kucheria as reviewer for thermal thermal: Add some error messages thermal: Fix use-after-free when unregistering thermal zone device thermal/drivers/core: Use put_device() if device_register() fails thermal_hwmon: Sanitize thermal_zone type thermal: intel: Use dev_get_drvdata thermal: intel: int3403: replace printk(KERN_WARN...) with pr_warn(...) thermal: intel: int340x_thermal: Remove unnecessary acpi_has_method() uses thermal: int340x: processor_thermal: Add Ice Lake support drivers: thermal: qcom: tsens: Fix memory leak from qfprom read thermal: tegra: Fix a typo thermal: rcar_gen3_thermal: Replace devm_add_action() followed by failure action with devm_add_action_or_reset() thermal: armada: Fix -Wshift-negative-value dt-bindings: thermal: qoriq: Add optional clocks property thermal: qoriq: Use __maybe_unused instead of #if CONFIG_PM_SLEEP thermal: qoriq: Use devm_platform_ioremap_resource() instead of of_iomap() thermal: qoriq: Fix error path of calling qoriq_tmu_register_tmu_zone fail thermal: qoriq: Add clock operations drivers: thermal: processor_thermal_device: Export sysfs interface for TCC offset
-rw-r--r--Documentation/devicetree/bindings/thermal/qoriq-thermal.txt1
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/thermal/armada_thermal.c5
-rw-r--r--drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c6
-rw-r--r--drivers/thermal/intel/int340x_thermal/int3403_thermal.c2
-rw-r--r--drivers/thermal/intel/int340x_thermal/processor_thermal_device.c96
-rw-r--r--drivers/thermal/intel/intel_pch_thermal.c6
-rw-r--r--drivers/thermal/qcom/tsens-8960.c2
-rw-r--r--drivers/thermal/qcom/tsens-v0_1.c12
-rw-r--r--drivers/thermal/qcom/tsens-v1.c1
-rw-r--r--drivers/thermal/qcom/tsens.h1
-rw-r--r--drivers/thermal/qoriq_thermal.c45
-rw-r--r--drivers/thermal/rcar_gen3_thermal.c3
-rw-r--r--drivers/thermal/tegra/soctherm.c2
-rw-r--r--drivers/thermal/thermal_core.c44
-rw-r--r--drivers/thermal/thermal_hwmon.c8
16 files changed, 178 insertions, 57 deletions
diff --git a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
index 04cbb90a5d3e..28f2cbaf1702 100644
--- a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
@@ -23,6 +23,7 @@ Required properties:
23Optional property: 23Optional property:
24- little-endian : If present, the TMU registers are little endian. If absent, 24- little-endian : If present, the TMU registers are little endian. If absent,
25 the default is big endian. 25 the default is big endian.
26- clocks : the clock for clocking the TMU silicon.
26 27
27Example: 28Example:
28 29
diff --git a/MAINTAINERS b/MAINTAINERS
index d9ebe514708b..ee3971d8d335 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16072,6 +16072,7 @@ THERMAL
16072M: Zhang Rui <rui.zhang@intel.com> 16072M: Zhang Rui <rui.zhang@intel.com>
16073M: Eduardo Valentin <edubezval@gmail.com> 16073M: Eduardo Valentin <edubezval@gmail.com>
16074R: Daniel Lezcano <daniel.lezcano@linaro.org> 16074R: Daniel Lezcano <daniel.lezcano@linaro.org>
16075R: Amit Kucheria <amit.kucheria@verdurent.com>
16075L: linux-pm@vger.kernel.org 16076L: linux-pm@vger.kernel.org
16076T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git 16077T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git
16077T: git git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git 16078T: git git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 8c07a393dc2e..709a22f455e9 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -53,7 +53,6 @@
53#define CONTROL0_TSEN_MODE_EXTERNAL 0x2 53#define CONTROL0_TSEN_MODE_EXTERNAL 0x2
54#define CONTROL0_TSEN_MODE_MASK 0x3 54#define CONTROL0_TSEN_MODE_MASK 0x3
55 55
56#define CONTROL1_TSEN_AVG_SHIFT 0
57#define CONTROL1_TSEN_AVG_MASK 0x7 56#define CONTROL1_TSEN_AVG_MASK 0x7
58#define CONTROL1_EXT_TSEN_SW_RESET BIT(7) 57#define CONTROL1_EXT_TSEN_SW_RESET BIT(7)
59#define CONTROL1_EXT_TSEN_HW_RESETn BIT(8) 58#define CONTROL1_EXT_TSEN_HW_RESETn BIT(8)
@@ -267,8 +266,8 @@ static void armada_cp110_init(struct platform_device *pdev,
267 266
268 /* Average the output value over 2^1 = 2 samples */ 267 /* Average the output value over 2^1 = 2 samples */
269 regmap_read(priv->syscon, data->syscon_control1_off, &reg); 268 regmap_read(priv->syscon, data->syscon_control1_off, &reg);
270 reg &= ~CONTROL1_TSEN_AVG_MASK << CONTROL1_TSEN_AVG_SHIFT; 269 reg &= ~CONTROL1_TSEN_AVG_MASK;
271 reg |= 1 << CONTROL1_TSEN_AVG_SHIFT; 270 reg |= 1;
272 regmap_write(priv->syscon, data->syscon_control1_off, reg); 271 regmap_write(priv->syscon, data->syscon_control1_off, reg);
273} 272}
274 273
diff --git a/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c
index 9716bc3abaf9..7130e90773ed 100644
--- a/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c
+++ b/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c
@@ -77,9 +77,6 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp,
77 struct acpi_buffer element = { 0, NULL }; 77 struct acpi_buffer element = { 0, NULL };
78 struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" }; 78 struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" };
79 79
80 if (!acpi_has_method(handle, "_TRT"))
81 return -ENODEV;
82
83 status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer); 80 status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer);
84 if (ACPI_FAILURE(status)) 81 if (ACPI_FAILURE(status))
85 return -ENODEV; 82 return -ENODEV;
@@ -158,9 +155,6 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,
158 struct acpi_buffer art_format = { 155 struct acpi_buffer art_format = {
159 sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" }; 156 sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" };
160 157
161 if (!acpi_has_method(handle, "_ART"))
162 return -ENODEV;
163
164 status = acpi_evaluate_object(handle, "_ART", NULL, &buffer); 158 status = acpi_evaluate_object(handle, "_ART", NULL, &buffer);
165 if (ACPI_FAILURE(status)) 159 if (ACPI_FAILURE(status))
166 return -ENODEV; 160 return -ENODEV;
diff --git a/drivers/thermal/intel/int340x_thermal/int3403_thermal.c b/drivers/thermal/intel/int340x_thermal/int3403_thermal.c
index f5749d4418ae..a7bbd8584ae2 100644
--- a/drivers/thermal/intel/int340x_thermal/int3403_thermal.c
+++ b/drivers/thermal/intel/int340x_thermal/int3403_thermal.c
@@ -181,7 +181,7 @@ static int int3403_cdev_add(struct int3403_priv *priv)
181 181
182 p = buf.pointer; 182 p = buf.pointer;
183 if (!p || (p->type != ACPI_TYPE_PACKAGE)) { 183 if (!p || (p->type != ACPI_TYPE_PACKAGE)) {
184 printk(KERN_WARNING "Invalid PPSS data\n"); 184 pr_warn("Invalid PPSS data\n");
185 kfree(buf.pointer); 185 kfree(buf.pointer);
186 return -EFAULT; 186 return -EFAULT;
187 } 187 }
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
index d3446acf9bbd..89a015387283 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
@@ -39,6 +39,9 @@
39/* GeminiLake thermal reporting device */ 39/* GeminiLake thermal reporting device */
40#define PCI_DEVICE_ID_PROC_GLK_THERMAL 0x318C 40#define PCI_DEVICE_ID_PROC_GLK_THERMAL 0x318C
41 41
42/* IceLake thermal reporting device */
43#define PCI_DEVICE_ID_PROC_ICL_THERMAL 0x8a03
44
42#define DRV_NAME "proc_thermal" 45#define DRV_NAME "proc_thermal"
43 46
44struct power_config { 47struct power_config {
@@ -137,6 +140,72 @@ static const struct attribute_group power_limit_attribute_group = {
137 .name = "power_limits" 140 .name = "power_limits"
138}; 141};
139 142
143static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
144 struct device_attribute *attr, char *buf)
145{
146 u64 val;
147 int err;
148
149 err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
150 if (err)
151 return err;
152
153 val = (val >> 24) & 0xff;
154 return sprintf(buf, "%d\n", (int)val);
155}
156
157static int tcc_offset_update(int tcc)
158{
159 u64 val;
160 int err;
161
162 if (!tcc)
163 return -EINVAL;
164
165 err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
166 if (err)
167 return err;
168
169 val &= ~GENMASK_ULL(31, 24);
170 val |= (tcc & 0xff) << 24;
171
172 err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val);
173 if (err)
174 return err;
175
176 return 0;
177}
178
179static int tcc_offset_save;
180
181static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
182 struct device_attribute *attr, const char *buf,
183 size_t count)
184{
185 u64 val;
186 int tcc, err;
187
188 err = rdmsrl_safe(MSR_PLATFORM_INFO, &val);
189 if (err)
190 return err;
191
192 if (!(val & BIT(30)))
193 return -EACCES;
194
195 if (kstrtoint(buf, 0, &tcc))
196 return -EINVAL;
197
198 err = tcc_offset_update(tcc);
199 if (err)
200 return err;
201
202 tcc_offset_save = tcc;
203
204 return count;
205}
206
207static DEVICE_ATTR_RW(tcc_offset_degree_celsius);
208
140static int stored_tjmax; /* since it is fixed, we can have local storage */ 209static int stored_tjmax; /* since it is fixed, we can have local storage */
141 210
142static int get_tjmax(void) 211static int get_tjmax(void)
@@ -332,6 +401,7 @@ static void proc_thermal_remove(struct proc_thermal_device *proc_priv)
332 acpi_remove_notify_handler(proc_priv->adev->handle, 401 acpi_remove_notify_handler(proc_priv->adev->handle,
333 ACPI_DEVICE_NOTIFY, proc_thermal_notify); 402 ACPI_DEVICE_NOTIFY, proc_thermal_notify);
334 int340x_thermal_zone_remove(proc_priv->int340x_zone); 403 int340x_thermal_zone_remove(proc_priv->int340x_zone);
404 sysfs_remove_file(&proc_priv->dev->kobj, &dev_attr_tcc_offset_degree_celsius.attr);
335 sysfs_remove_group(&proc_priv->dev->kobj, 405 sysfs_remove_group(&proc_priv->dev->kobj,
336 &power_limit_attribute_group); 406 &power_limit_attribute_group);
337} 407}
@@ -355,8 +425,15 @@ static int int3401_add(struct platform_device *pdev)
355 425
356 dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PLATFORM_DEV\n"); 426 dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PLATFORM_DEV\n");
357 427
358 return sysfs_create_group(&pdev->dev.kobj, 428 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
359 &power_limit_attribute_group); 429 if (ret)
430 return ret;
431
432 ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
433 if (ret)
434 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
435
436 return ret;
360} 437}
361 438
362static int int3401_remove(struct platform_device *pdev) 439static int int3401_remove(struct platform_device *pdev)
@@ -588,8 +665,15 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev,
588 665
589 dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PCI\n"); 666 dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PCI\n");
590 667
591 return sysfs_create_group(&pdev->dev.kobj, 668 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
592 &power_limit_attribute_group); 669 if (ret)
670 return ret;
671
672 ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
673 if (ret)
674 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
675
676 return ret;
593} 677}
594 678
595static void proc_thermal_pci_remove(struct pci_dev *pdev) 679static void proc_thermal_pci_remove(struct pci_dev *pdev)
@@ -615,6 +699,8 @@ static int proc_thermal_resume(struct device *dev)
615 proc_dev = dev_get_drvdata(dev); 699 proc_dev = dev_get_drvdata(dev);
616 proc_thermal_read_ppcc(proc_dev); 700 proc_thermal_read_ppcc(proc_dev);
617 701
702 tcc_offset_update(tcc_offset_save);
703
618 return 0; 704 return 0;
619} 705}
620#else 706#else
@@ -636,6 +722,8 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
636 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CNL_THERMAL)}, 722 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CNL_THERMAL)},
637 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CFL_THERMAL)}, 723 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CFL_THERMAL)},
638 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_GLK_THERMAL)}, 724 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_GLK_THERMAL)},
725 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_ICL_THERMAL),
726 .driver_data = (kernel_ulong_t)&rapl_mmio_hsw, },
639 { 0, }, 727 { 0, },
640}; 728};
641 729
diff --git a/drivers/thermal/intel/intel_pch_thermal.c b/drivers/thermal/intel/intel_pch_thermal.c
index 99f8b2540f18..4f0bb8f502e1 100644
--- a/drivers/thermal/intel/intel_pch_thermal.c
+++ b/drivers/thermal/intel/intel_pch_thermal.c
@@ -371,16 +371,14 @@ static void intel_pch_thermal_remove(struct pci_dev *pdev)
371 371
372static int intel_pch_thermal_suspend(struct device *device) 372static int intel_pch_thermal_suspend(struct device *device)
373{ 373{
374 struct pci_dev *pdev = to_pci_dev(device); 374 struct pch_thermal_device *ptd = dev_get_drvdata(device);
375 struct pch_thermal_device *ptd = pci_get_drvdata(pdev);
376 375
377 return ptd->ops->suspend(ptd); 376 return ptd->ops->suspend(ptd);
378} 377}
379 378
380static int intel_pch_thermal_resume(struct device *device) 379static int intel_pch_thermal_resume(struct device *device)
381{ 380{
382 struct pci_dev *pdev = to_pci_dev(device); 381 struct pch_thermal_device *ptd = dev_get_drvdata(device);
383 struct pch_thermal_device *ptd = pci_get_drvdata(pdev);
384 382
385 return ptd->ops->resume(ptd); 383 return ptd->ops->resume(ptd);
386} 384}
diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
index 8d9b721dadb6..e46a4e3f25c4 100644
--- a/drivers/thermal/qcom/tsens-8960.c
+++ b/drivers/thermal/qcom/tsens-8960.c
@@ -229,6 +229,8 @@ static int calibrate_8960(struct tsens_priv *priv)
229 for (i = 0; i < num_read; i++, s++) 229 for (i = 0; i < num_read; i++, s++)
230 s->offset = data[i]; 230 s->offset = data[i];
231 231
232 kfree(data);
233
232 return 0; 234 return 0;
233} 235}
234 236
diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
index 6f26fadf4c27..055647bcee67 100644
--- a/drivers/thermal/qcom/tsens-v0_1.c
+++ b/drivers/thermal/qcom/tsens-v0_1.c
@@ -145,8 +145,10 @@ static int calibrate_8916(struct tsens_priv *priv)
145 return PTR_ERR(qfprom_cdata); 145 return PTR_ERR(qfprom_cdata);
146 146
147 qfprom_csel = (u32 *)qfprom_read(priv->dev, "calib_sel"); 147 qfprom_csel = (u32 *)qfprom_read(priv->dev, "calib_sel");
148 if (IS_ERR(qfprom_csel)) 148 if (IS_ERR(qfprom_csel)) {
149 kfree(qfprom_cdata);
149 return PTR_ERR(qfprom_csel); 150 return PTR_ERR(qfprom_csel);
151 }
150 152
151 mode = (qfprom_csel[0] & MSM8916_CAL_SEL_MASK) >> MSM8916_CAL_SEL_SHIFT; 153 mode = (qfprom_csel[0] & MSM8916_CAL_SEL_MASK) >> MSM8916_CAL_SEL_SHIFT;
152 dev_dbg(priv->dev, "calibration mode is %d\n", mode); 154 dev_dbg(priv->dev, "calibration mode is %d\n", mode);
@@ -181,6 +183,8 @@ static int calibrate_8916(struct tsens_priv *priv)
181 } 183 }
182 184
183 compute_intercept_slope(priv, p1, p2, mode); 185 compute_intercept_slope(priv, p1, p2, mode);
186 kfree(qfprom_cdata);
187 kfree(qfprom_csel);
184 188
185 return 0; 189 return 0;
186} 190}
@@ -198,8 +202,10 @@ static int calibrate_8974(struct tsens_priv *priv)
198 return PTR_ERR(calib); 202 return PTR_ERR(calib);
199 203
200 bkp = (u32 *)qfprom_read(priv->dev, "calib_backup"); 204 bkp = (u32 *)qfprom_read(priv->dev, "calib_backup");
201 if (IS_ERR(bkp)) 205 if (IS_ERR(bkp)) {
206 kfree(calib);
202 return PTR_ERR(bkp); 207 return PTR_ERR(bkp);
208 }
203 209
204 calib_redun_sel = bkp[1] & BKP_REDUN_SEL; 210 calib_redun_sel = bkp[1] & BKP_REDUN_SEL;
205 calib_redun_sel >>= BKP_REDUN_SHIFT; 211 calib_redun_sel >>= BKP_REDUN_SHIFT;
@@ -313,6 +319,8 @@ static int calibrate_8974(struct tsens_priv *priv)
313 } 319 }
314 320
315 compute_intercept_slope(priv, p1, p2, mode); 321 compute_intercept_slope(priv, p1, p2, mode);
322 kfree(calib);
323 kfree(bkp);
316 324
317 return 0; 325 return 0;
318} 326}
diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
index 10b595d4f619..870f502f2cb6 100644
--- a/drivers/thermal/qcom/tsens-v1.c
+++ b/drivers/thermal/qcom/tsens-v1.c
@@ -138,6 +138,7 @@ static int calibrate_v1(struct tsens_priv *priv)
138 } 138 }
139 139
140 compute_intercept_slope(priv, p1, p2, mode); 140 compute_intercept_slope(priv, p1, p2, mode);
141 kfree(qfprom_cdata);
141 142
142 return 0; 143 return 0;
143} 144}
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 2fd94997245b..b89083b61c38 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -17,6 +17,7 @@
17 17
18#include <linux/thermal.h> 18#include <linux/thermal.h>
19#include <linux/regmap.h> 19#include <linux/regmap.h>
20#include <linux/slab.h>
20 21
21struct tsens_priv; 22struct tsens_priv;
22 23
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index 7b364933bfb1..39542c670301 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -2,6 +2,7 @@
2// 2//
3// Copyright 2016 Freescale Semiconductor, Inc. 3// Copyright 2016 Freescale Semiconductor, Inc.
4 4
5#include <linux/clk.h>
5#include <linux/module.h> 6#include <linux/module.h>
6#include <linux/platform_device.h> 7#include <linux/platform_device.h>
7#include <linux/err.h> 8#include <linux/err.h>
@@ -72,6 +73,7 @@ struct qoriq_sensor {
72 73
73struct qoriq_tmu_data { 74struct qoriq_tmu_data {
74 struct qoriq_tmu_regs __iomem *regs; 75 struct qoriq_tmu_regs __iomem *regs;
76 struct clk *clk;
75 bool little_endian; 77 bool little_endian;
76 struct qoriq_sensor *sensor[SITES_MAX]; 78 struct qoriq_sensor *sensor[SITES_MAX];
77}; 79};
@@ -202,32 +204,39 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
202 204
203 data->little_endian = of_property_read_bool(np, "little-endian"); 205 data->little_endian = of_property_read_bool(np, "little-endian");
204 206
205 data->regs = of_iomap(np, 0); 207 data->regs = devm_platform_ioremap_resource(pdev, 0);
206 if (!data->regs) { 208 if (IS_ERR(data->regs)) {
207 dev_err(&pdev->dev, "Failed to get memory region\n"); 209 dev_err(&pdev->dev, "Failed to get memory region\n");
208 ret = -ENODEV; 210 return PTR_ERR(data->regs);
209 goto err_iomap; 211 }
212
213 data->clk = devm_clk_get_optional(&pdev->dev, NULL);
214 if (IS_ERR(data->clk))
215 return PTR_ERR(data->clk);
216
217 ret = clk_prepare_enable(data->clk);
218 if (ret) {
219 dev_err(&pdev->dev, "Failed to enable clock\n");
220 return ret;
210 } 221 }
211 222
212 qoriq_tmu_init_device(data); /* TMU initialization */ 223 qoriq_tmu_init_device(data); /* TMU initialization */
213 224
214 ret = qoriq_tmu_calibration(pdev); /* TMU calibration */ 225 ret = qoriq_tmu_calibration(pdev); /* TMU calibration */
215 if (ret < 0) 226 if (ret < 0)
216 goto err_tmu; 227 goto err;
217 228
218 ret = qoriq_tmu_register_tmu_zone(pdev); 229 ret = qoriq_tmu_register_tmu_zone(pdev);
219 if (ret < 0) { 230 if (ret < 0) {
220 dev_err(&pdev->dev, "Failed to register sensors\n"); 231 dev_err(&pdev->dev, "Failed to register sensors\n");
221 ret = -ENODEV; 232 ret = -ENODEV;
222 goto err_iomap; 233 goto err;
223 } 234 }
224 235
225 return 0; 236 return 0;
226 237
227err_tmu: 238err:
228 iounmap(data->regs); 239 clk_disable_unprepare(data->clk);
229
230err_iomap:
231 platform_set_drvdata(pdev, NULL); 240 platform_set_drvdata(pdev, NULL);
232 241
233 return ret; 242 return ret;
@@ -240,14 +249,14 @@ static int qoriq_tmu_remove(struct platform_device *pdev)
240 /* Disable monitoring */ 249 /* Disable monitoring */
241 tmu_write(data, TMR_DISABLE, &data->regs->tmr); 250 tmu_write(data, TMR_DISABLE, &data->regs->tmr);
242 251
243 iounmap(data->regs); 252 clk_disable_unprepare(data->clk);
253
244 platform_set_drvdata(pdev, NULL); 254 platform_set_drvdata(pdev, NULL);
245 255
246 return 0; 256 return 0;
247} 257}
248 258
249#ifdef CONFIG_PM_SLEEP 259static int __maybe_unused qoriq_tmu_suspend(struct device *dev)
250static int qoriq_tmu_suspend(struct device *dev)
251{ 260{
252 u32 tmr; 261 u32 tmr;
253 struct qoriq_tmu_data *data = dev_get_drvdata(dev); 262 struct qoriq_tmu_data *data = dev_get_drvdata(dev);
@@ -257,14 +266,21 @@ static int qoriq_tmu_suspend(struct device *dev)
257 tmr &= ~TMR_ME; 266 tmr &= ~TMR_ME;
258 tmu_write(data, tmr, &data->regs->tmr); 267 tmu_write(data, tmr, &data->regs->tmr);
259 268
269 clk_disable_unprepare(data->clk);
270
260 return 0; 271 return 0;
261} 272}
262 273
263static int qoriq_tmu_resume(struct device *dev) 274static int __maybe_unused qoriq_tmu_resume(struct device *dev)
264{ 275{
265 u32 tmr; 276 u32 tmr;
277 int ret;
266 struct qoriq_tmu_data *data = dev_get_drvdata(dev); 278 struct qoriq_tmu_data *data = dev_get_drvdata(dev);
267 279
280 ret = clk_prepare_enable(data->clk);
281 if (ret)
282 return ret;
283
268 /* Enable monitoring */ 284 /* Enable monitoring */
269 tmr = tmu_read(data, &data->regs->tmr); 285 tmr = tmu_read(data, &data->regs->tmr);
270 tmr |= TMR_ME; 286 tmr |= TMR_ME;
@@ -272,7 +288,6 @@ static int qoriq_tmu_resume(struct device *dev)
272 288
273 return 0; 289 return 0;
274} 290}
275#endif
276 291
277static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops, 292static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,
278 qoriq_tmu_suspend, qoriq_tmu_resume); 293 qoriq_tmu_suspend, qoriq_tmu_resume);
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index a56463308694..755d2b5bd2c2 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -443,9 +443,8 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
443 if (ret) 443 if (ret)
444 goto error_unregister; 444 goto error_unregister;
445 445
446 ret = devm_add_action(dev, rcar_gen3_hwmon_action, zone); 446 ret = devm_add_action_or_reset(dev, rcar_gen3_hwmon_action, zone);
447 if (ret) { 447 if (ret) {
448 rcar_gen3_hwmon_action(zone);
449 goto error_unregister; 448 goto error_unregister;
450 } 449 }
451 450
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index 43941eb734eb..5acaad3a594f 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -202,7 +202,7 @@
202/* get dividend from the depth */ 202/* get dividend from the depth */
203#define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1) 203#define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1)
204 204
205/* gk20a nv_therm interface N:3 Mapping. Levels defined in tegra124-sochterm.h 205/* gk20a nv_therm interface N:3 Mapping. Levels defined in tegra124-soctherm.h
206 * level vector 206 * level vector
207 * NONE 3'b000 207 * NONE 3'b000
208 * LOW 3'b001 208 * LOW 3'b001
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 6bab66e84eb5..d4481cc8958f 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -304,7 +304,7 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
304 &tz->poll_queue, 304 &tz->poll_queue,
305 msecs_to_jiffies(delay)); 305 msecs_to_jiffies(delay));
306 else 306 else
307 cancel_delayed_work(&tz->poll_queue); 307 cancel_delayed_work_sync(&tz->poll_queue);
308} 308}
309 309
310static void monitor_thermal_zone(struct thermal_zone_device *tz) 310static void monitor_thermal_zone(struct thermal_zone_device *tz)
@@ -985,7 +985,7 @@ __thermal_cooling_device_register(struct device_node *np,
985 result = device_register(&cdev->device); 985 result = device_register(&cdev->device);
986 if (result) { 986 if (result) {
987 ida_simple_remove(&thermal_cdev_ida, cdev->id); 987 ida_simple_remove(&thermal_cdev_ida, cdev->id);
988 kfree(cdev); 988 put_device(&cdev->device);
989 return ERR_PTR(result); 989 return ERR_PTR(result);
990 } 990 }
991 991
@@ -1240,21 +1240,31 @@ thermal_zone_device_register(const char *type, int trips, int mask,
1240 struct thermal_zone_device *tz; 1240 struct thermal_zone_device *tz;
1241 enum thermal_trip_type trip_type; 1241 enum thermal_trip_type trip_type;
1242 int trip_temp; 1242 int trip_temp;
1243 int id;
1243 int result; 1244 int result;
1244 int count; 1245 int count;
1245 struct thermal_governor *governor; 1246 struct thermal_governor *governor;
1246 1247
1247 if (!type || strlen(type) == 0) 1248 if (!type || strlen(type) == 0) {
1249 pr_err("Error: No thermal zone type defined\n");
1248 return ERR_PTR(-EINVAL); 1250 return ERR_PTR(-EINVAL);
1251 }
1249 1252
1250 if (type && strlen(type) >= THERMAL_NAME_LENGTH) 1253 if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
1254 pr_err("Error: Thermal zone name (%s) too long, should be under %d chars\n",
1255 type, THERMAL_NAME_LENGTH);
1251 return ERR_PTR(-EINVAL); 1256 return ERR_PTR(-EINVAL);
1257 }
1252 1258
1253 if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips) 1259 if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips) {
1260 pr_err("Error: Incorrect number of thermal trips\n");
1254 return ERR_PTR(-EINVAL); 1261 return ERR_PTR(-EINVAL);
1262 }
1255 1263
1256 if (!ops) 1264 if (!ops) {
1265 pr_err("Error: Thermal zone device ops not defined\n");
1257 return ERR_PTR(-EINVAL); 1266 return ERR_PTR(-EINVAL);
1267 }
1258 1268
1259 if (trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp)) 1269 if (trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
1260 return ERR_PTR(-EINVAL); 1270 return ERR_PTR(-EINVAL);
@@ -1266,11 +1276,13 @@ thermal_zone_device_register(const char *type, int trips, int mask,
1266 INIT_LIST_HEAD(&tz->thermal_instances); 1276 INIT_LIST_HEAD(&tz->thermal_instances);
1267 ida_init(&tz->ida); 1277 ida_init(&tz->ida);
1268 mutex_init(&tz->lock); 1278 mutex_init(&tz->lock);
1269 result = ida_simple_get(&thermal_tz_ida, 0, 0, GFP_KERNEL); 1279 id = ida_simple_get(&thermal_tz_ida, 0, 0, GFP_KERNEL);
1270 if (result < 0) 1280 if (id < 0) {
1281 result = id;
1271 goto free_tz; 1282 goto free_tz;
1283 }
1272 1284
1273 tz->id = result; 1285 tz->id = id;
1274 strlcpy(tz->type, type, sizeof(tz->type)); 1286 strlcpy(tz->type, type, sizeof(tz->type));
1275 tz->ops = ops; 1287 tz->ops = ops;
1276 tz->tzp = tzp; 1288 tz->tzp = tzp;
@@ -1292,7 +1304,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
1292 dev_set_name(&tz->device, "thermal_zone%d", tz->id); 1304 dev_set_name(&tz->device, "thermal_zone%d", tz->id);
1293 result = device_register(&tz->device); 1305 result = device_register(&tz->device);
1294 if (result) 1306 if (result)
1295 goto remove_device_groups; 1307 goto release_device;
1296 1308
1297 for (count = 0; count < trips; count++) { 1309 for (count = 0; count < trips; count++) {
1298 if (tz->ops->get_trip_type(tz, count, &trip_type)) 1310 if (tz->ops->get_trip_type(tz, count, &trip_type))
@@ -1343,14 +1355,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,
1343 return tz; 1355 return tz;
1344 1356
1345unregister: 1357unregister:
1346 ida_simple_remove(&thermal_tz_ida, tz->id); 1358 device_del(&tz->device);
1347 device_unregister(&tz->device); 1359release_device:
1348 return ERR_PTR(result); 1360 put_device(&tz->device);
1349 1361 tz = NULL;
1350remove_device_groups:
1351 thermal_zone_destroy_device_groups(tz);
1352remove_id: 1362remove_id:
1353 ida_simple_remove(&thermal_tz_ida, tz->id); 1363 ida_simple_remove(&thermal_tz_ida, id);
1354free_tz: 1364free_tz:
1355 kfree(tz); 1365 kfree(tz);
1356 return ERR_PTR(result); 1366 return ERR_PTR(result);
diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c
index 40c69a533b24..dd5d8ee37928 100644
--- a/drivers/thermal/thermal_hwmon.c
+++ b/drivers/thermal/thermal_hwmon.c
@@ -87,13 +87,17 @@ static struct thermal_hwmon_device *
87thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz) 87thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz)
88{ 88{
89 struct thermal_hwmon_device *hwmon; 89 struct thermal_hwmon_device *hwmon;
90 char type[THERMAL_NAME_LENGTH];
90 91
91 mutex_lock(&thermal_hwmon_list_lock); 92 mutex_lock(&thermal_hwmon_list_lock);
92 list_for_each_entry(hwmon, &thermal_hwmon_list, node) 93 list_for_each_entry(hwmon, &thermal_hwmon_list, node) {
93 if (!strcmp(hwmon->type, tz->type)) { 94 strcpy(type, tz->type);
95 strreplace(type, '-', '_');
96 if (!strcmp(hwmon->type, type)) {
94 mutex_unlock(&thermal_hwmon_list_lock); 97 mutex_unlock(&thermal_hwmon_list_lock);
95 return hwmon; 98 return hwmon;
96 } 99 }
100 }
97 mutex_unlock(&thermal_hwmon_list_lock); 101 mutex_unlock(&thermal_hwmon_list_lock);
98 102
99 return NULL; 103 return NULL;