diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-27 14:35:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-27 14:35:13 -0400 |
commit | d0e00bc5ada53bda296ce8bfffc2f2be9eb22632 (patch) | |
tree | 7b00f11f0406f21ae1ebf5f376a963f439fddeef | |
parent | 7bccb9f10c8f36ee791769b531ed4d28f6379aae (diff) | |
parent | 0f84d1d18c46d0f995962c876c8b2900fd183fd7 (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.txt | 1 | ||||
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/thermal/armada_thermal.c | 5 | ||||
-rw-r--r-- | drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c | 6 | ||||
-rw-r--r-- | drivers/thermal/intel/int340x_thermal/int3403_thermal.c | 2 | ||||
-rw-r--r-- | drivers/thermal/intel/int340x_thermal/processor_thermal_device.c | 96 | ||||
-rw-r--r-- | drivers/thermal/intel/intel_pch_thermal.c | 6 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens-8960.c | 2 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens-v0_1.c | 12 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens-v1.c | 1 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens.h | 1 | ||||
-rw-r--r-- | drivers/thermal/qoriq_thermal.c | 45 | ||||
-rw-r--r-- | drivers/thermal/rcar_gen3_thermal.c | 3 | ||||
-rw-r--r-- | drivers/thermal/tegra/soctherm.c | 2 | ||||
-rw-r--r-- | drivers/thermal/thermal_core.c | 44 | ||||
-rw-r--r-- | drivers/thermal/thermal_hwmon.c | 8 |
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: | |||
23 | Optional property: | 23 | Optional 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 | ||
27 | Example: | 28 | Example: |
28 | 29 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index d9ebe514708b..ee3971d8d335 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -16072,6 +16072,7 @@ THERMAL | |||
16072 | M: Zhang Rui <rui.zhang@intel.com> | 16072 | M: Zhang Rui <rui.zhang@intel.com> |
16073 | M: Eduardo Valentin <edubezval@gmail.com> | 16073 | M: Eduardo Valentin <edubezval@gmail.com> |
16074 | R: Daniel Lezcano <daniel.lezcano@linaro.org> | 16074 | R: Daniel Lezcano <daniel.lezcano@linaro.org> |
16075 | R: Amit Kucheria <amit.kucheria@verdurent.com> | ||
16075 | L: linux-pm@vger.kernel.org | 16076 | L: linux-pm@vger.kernel.org |
16076 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git | 16077 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git |
16077 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git | 16078 | T: 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, ®); | 268 | regmap_read(priv->syscon, data->syscon_control1_off, ®); |
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 | ||
44 | struct power_config { | 47 | struct 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 | ||
143 | static 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 | |||
157 | static 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 | |||
179 | static int tcc_offset_save; | ||
180 | |||
181 | static 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 | |||
207 | static DEVICE_ATTR_RW(tcc_offset_degree_celsius); | ||
208 | |||
140 | static int stored_tjmax; /* since it is fixed, we can have local storage */ | 209 | static int stored_tjmax; /* since it is fixed, we can have local storage */ |
141 | 210 | ||
142 | static int get_tjmax(void) | 211 | static 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 | ||
362 | static int int3401_remove(struct platform_device *pdev) | 439 | static 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 | ||
595 | static void proc_thermal_pci_remove(struct pci_dev *pdev) | 679 | static 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 | ||
372 | static int intel_pch_thermal_suspend(struct device *device) | 372 | static 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 | ||
380 | static int intel_pch_thermal_resume(struct device *device) | 379 | static 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 | ||
21 | struct tsens_priv; | 22 | struct 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 | ||
73 | struct qoriq_tmu_data { | 74 | struct 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 | ||
227 | err_tmu: | 238 | err: |
228 | iounmap(data->regs); | 239 | clk_disable_unprepare(data->clk); |
229 | |||
230 | err_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 | 259 | static int __maybe_unused qoriq_tmu_suspend(struct device *dev) |
250 | static 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 | ||
263 | static int qoriq_tmu_resume(struct device *dev) | 274 | static 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 | ||
277 | static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops, | 292 | static 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 | ||
310 | static void monitor_thermal_zone(struct thermal_zone_device *tz) | 310 | static 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 | ||
1345 | unregister: | 1357 | unregister: |
1346 | ida_simple_remove(&thermal_tz_ida, tz->id); | 1358 | device_del(&tz->device); |
1347 | device_unregister(&tz->device); | 1359 | release_device: |
1348 | return ERR_PTR(result); | 1360 | put_device(&tz->device); |
1349 | 1361 | tz = NULL; | |
1350 | remove_device_groups: | ||
1351 | thermal_zone_destroy_device_groups(tz); | ||
1352 | remove_id: | 1362 | remove_id: |
1353 | ida_simple_remove(&thermal_tz_ida, tz->id); | 1363 | ida_simple_remove(&thermal_tz_ida, id); |
1354 | free_tz: | 1364 | free_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 * | |||
87 | thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz) | 87 | thermal_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; |