aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-01-05 19:01:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-01-05 19:01:16 -0500
commitc280230254635da33703dd8f4a10cad23f640fb0 (patch)
tree6f27fd600b3eaf8b00116332ca67bc8625248d87
parenta67012412e5a820c44239af9712a1a6037b33fd4 (diff)
parent9d216211fded20fff301d0317af3238d8383634c (diff)
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal
Pull thermal SoC updates from Eduardo Valentin: - Tegra DT binding documentation for Tegra194 - Armada now supports ap806 and cp110 - RCAR thermal now supports R8A774C0 and R8A77990 - Fixes on thermal_hwmon, IMX, generic-ADC, ST, RCAR, Broadcom, Uniphier, QCOM, Tegra, PowerClamp, and Armada thermal drivers. * 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal: (22 commits) thermal: generic-adc: Fix adc to temp interpolation thermal: rcar_thermal: add R8A77990 support dt-bindings: thermal: rcar-thermal: add R8A77990 support thermal: rcar_thermal: add R8A774C0 support dt-bindings: thermal: rcar-thermal: add R8A774C0 support dt-bindings: cp110: document the thermal interrupt capabilities dt-bindings: ap806: document the thermal interrupt capabilities MAINTAINERS: thermal: add entry for Marvell MVEBU thermal driver thermal: armada: add overheat interrupt support thermal: st: fix Makefile typo thermal: uniphier: Convert to SPDX identifier thermal/intel_powerclamp: Change to use DEFINE_SHOW_ATTRIBUTE macro thermal: tegra: soctherm: Change to use DEFINE_SHOW_ATTRIBUTE macro dt-bindings: thermal: tegra-bpmp: Add Tegra194 support thermal: imx: save one condition block for normal case of nvmem initialization thermal: imx: fix for dependency on cpu-freq thermal: tsens: qcom: do not create duplicate regmap debugfs entries thermal: armada: Use PTR_ERR_OR_ZERO in armada_thermal_probe_legacy() dt-bindings: thermal: rcar-gen3-thermal: All variants use 3 interrupts thermal: broadcom: use devm_thermal_zone_of_sensor_register ...
-rw-r--r--Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt7
-rw-r--r--Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt9
-rw-r--r--Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt3
-rw-r--r--Documentation/devicetree/bindings/thermal/rcar-thermal.txt6
-rw-r--r--MAINTAINERS5
-rw-r--r--drivers/thermal/Kconfig2
-rw-r--r--drivers/thermal/armada_thermal.c280
-rw-r--r--drivers/thermal/broadcom/bcm2835_thermal.c11
-rw-r--r--drivers/thermal/broadcom/brcmstb_thermal.c24
-rw-r--r--drivers/thermal/imx_thermal.c52
-rw-r--r--drivers/thermal/intel_powerclamp.c14
-rw-r--r--drivers/thermal/qcom/tsens-common.c12
-rw-r--r--drivers/thermal/rcar_thermal.c8
-rw-r--r--drivers/thermal/st/Makefile2
-rw-r--r--drivers/thermal/tegra/soctherm.c12
-rw-r--r--drivers/thermal/thermal-generic-adc.c12
-rw-r--r--drivers/thermal/thermal_hwmon.h4
-rw-r--r--drivers/thermal/uniphier_thermal.c13
18 files changed, 383 insertions, 93 deletions
diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
index 3fd21bb7cb37..7b8b8eb0191f 100644
--- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
@@ -114,12 +114,17 @@ Documentation/devicetree/bindings/thermal/thermal.txt
114The thermal IP can probe the temperature all around the processor. It 114The thermal IP can probe the temperature all around the processor. It
115may feature several channels, each of them wired to one sensor. 115may feature several channels, each of them wired to one sensor.
116 116
117It is possible to setup an overheat interrupt by giving at least one
118critical point to any subnode of the thermal-zone node.
119
117Required properties: 120Required properties:
118- compatible: must be one of: 121- compatible: must be one of:
119 * marvell,armada-ap806-thermal 122 * marvell,armada-ap806-thermal
120- reg: register range associated with the thermal functions. 123- reg: register range associated with the thermal functions.
121 124
122Optional properties: 125Optional properties:
126- interrupts: overheat interrupt handle. Should point to line 18 of the
127 SEI irqchip. See interrupt-controller/interrupts.txt
123- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer 128- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
124 to this IP and represents the channel ID. There is one sensor per 129 to this IP and represents the channel ID. There is one sensor per
125 channel. O refers to the thermal IP internal channel, while positive 130 channel. O refers to the thermal IP internal channel, while positive
@@ -133,6 +138,8 @@ ap_syscon1: system-controller@6f8000 {
133 ap_thermal: thermal-sensor@80 { 138 ap_thermal: thermal-sensor@80 {
134 compatible = "marvell,armada-ap806-thermal"; 139 compatible = "marvell,armada-ap806-thermal";
135 reg = <0x80 0x10>; 140 reg = <0x80 0x10>;
141 interrupt-parent = <&sei>;
142 interrupts = <18>;
136 #thermal-sensor-cells = <1>; 143 #thermal-sensor-cells = <1>;
137 }; 144 };
138}; 145};
diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
index 81ce742d2760..4db4119a6d19 100644
--- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
@@ -199,6 +199,9 @@ Thermal:
199The thermal IP can probe the temperature all around the processor. It 199The thermal IP can probe the temperature all around the processor. It
200may feature several channels, each of them wired to one sensor. 200may feature several channels, each of them wired to one sensor.
201 201
202It is possible to setup an overheat interrupt by giving at least one
203critical point to any subnode of the thermal-zone node.
204
202For common binding part and usage, refer to 205For common binding part and usage, refer to
203Documentation/devicetree/bindings/thermal/thermal.txt 206Documentation/devicetree/bindings/thermal/thermal.txt
204 207
@@ -208,6 +211,11 @@ Required properties:
208- reg: register range associated with the thermal functions. 211- reg: register range associated with the thermal functions.
209 212
210Optional properties: 213Optional properties:
214- interrupts-extended: overheat interrupt handle. Should point to
215 a line of the ICU-SEI irqchip (116 is what is usually used by the
216 firmware). The ICU-SEI will redirect towards interrupt line #37 of the
217 AP SEI which is shared across all CPs.
218 See interrupt-controller/interrupts.txt
211- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer 219- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
212 to this IP and represents the channel ID. There is one sensor per 220 to this IP and represents the channel ID. There is one sensor per
213 channel. O refers to the thermal IP internal channel. 221 channel. O refers to the thermal IP internal channel.
@@ -220,6 +228,7 @@ CP110_LABEL(syscon1): system-controller@6f8000 {
220 CP110_LABEL(thermal): thermal-sensor@70 { 228 CP110_LABEL(thermal): thermal-sensor@70 {
221 compatible = "marvell,armada-cp110-thermal"; 229 compatible = "marvell,armada-cp110-thermal";
222 reg = <0x70 0x10>; 230 reg = <0x70 0x10>;
231 interrupts-extended = <&CP110_LABEL(icu_sei) 116 IRQ_TYPE_LEVEL_HIGH>;
223 #thermal-sensor-cells = <1>; 232 #thermal-sensor-cells = <1>;
224 }; 233 };
225}; 234};
diff --git a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
index ad9a435afef4..b6ab60f6abbf 100644
--- a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
@@ -21,8 +21,7 @@ Required properties:
21 21
22Optional properties: 22Optional properties:
23 23
24- interrupts : interrupts routed to the TSC (3 for H3, M3-W, M3-N, 24- interrupts : interrupts routed to the TSC (must be 3).
25 and V3H)
26- power-domain : Must contain a reference to the power domain. This 25- power-domain : Must contain a reference to the power domain. This
27 property is mandatory if the thermal sensor instance 26 property is mandatory if the thermal sensor instance
28 is part of a controllable power domain. 27 is part of a controllable power domain.
diff --git a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
index 73e1613d2cb0..196112d23b1e 100644
--- a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
@@ -4,17 +4,19 @@ Required properties:
4- compatible : "renesas,thermal-<soctype>", 4- compatible : "renesas,thermal-<soctype>",
5 "renesas,rcar-gen2-thermal" (with thermal-zone) or 5 "renesas,rcar-gen2-thermal" (with thermal-zone) or
6 "renesas,rcar-thermal" (without thermal-zone) as 6 "renesas,rcar-thermal" (without thermal-zone) as
7 fallback except R-Car V3M/D3. 7 fallback except R-Car V3M/E3/D3 and RZ/G2E.
8 Examples with soctypes are: 8 Examples with soctypes are:
9 - "renesas,thermal-r8a73a4" (R-Mobile APE6) 9 - "renesas,thermal-r8a73a4" (R-Mobile APE6)
10 - "renesas,thermal-r8a7743" (RZ/G1M) 10 - "renesas,thermal-r8a7743" (RZ/G1M)
11 - "renesas,thermal-r8a7744" (RZ/G1N) 11 - "renesas,thermal-r8a7744" (RZ/G1N)
12 - "renesas,thermal-r8a774c0" (RZ/G2E)
12 - "renesas,thermal-r8a7779" (R-Car H1) 13 - "renesas,thermal-r8a7779" (R-Car H1)
13 - "renesas,thermal-r8a7790" (R-Car H2) 14 - "renesas,thermal-r8a7790" (R-Car H2)
14 - "renesas,thermal-r8a7791" (R-Car M2-W) 15 - "renesas,thermal-r8a7791" (R-Car M2-W)
15 - "renesas,thermal-r8a7792" (R-Car V2H) 16 - "renesas,thermal-r8a7792" (R-Car V2H)
16 - "renesas,thermal-r8a7793" (R-Car M2-N) 17 - "renesas,thermal-r8a7793" (R-Car M2-N)
17 - "renesas,thermal-r8a77970" (R-Car V3M) 18 - "renesas,thermal-r8a77970" (R-Car V3M)
19 - "renesas,thermal-r8a77990" (R-Car E3)
18 - "renesas,thermal-r8a77995" (R-Car D3) 20 - "renesas,thermal-r8a77995" (R-Car D3)
19- reg : Address range of the thermal registers. 21- reg : Address range of the thermal registers.
20 The 1st reg will be recognized as common register 22 The 1st reg will be recognized as common register
@@ -23,7 +25,7 @@ Required properties:
23Option properties: 25Option properties:
24 26
25- interrupts : If present should contain 3 interrupts for 27- interrupts : If present should contain 3 interrupts for
26 R-Car V3M/D3 or 1 interrupt otherwise. 28 R-Car V3M/E3/D3 and RZ/G2E or 1 interrupt otherwise.
27 29
28Example (non interrupt support): 30Example (non interrupt support):
29 31
diff --git a/MAINTAINERS b/MAINTAINERS
index bc00793a03c8..39e75bbefc3d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9109,6 +9109,11 @@ L: netdev@vger.kernel.org
9109S: Maintained 9109S: Maintained
9110F: drivers/net/phy/marvell10g.c 9110F: drivers/net/phy/marvell10g.c
9111 9111
9112MARVELL MVEBU THERMAL DRIVER
9113M: Miquel Raynal <miquel.raynal@bootlin.com>
9114S: Maintained
9115F: drivers/thermal/armada_thermal.c
9116
9112MARVELL MVNETA ETHERNET DRIVER 9117MARVELL MVNETA ETHERNET DRIVER
9113M: Thomas Petazzoni <thomas.petazzoni@bootlin.com> 9118M: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
9114L: netdev@vger.kernel.org 9119L: netdev@vger.kernel.org
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 5fbfabbf627b..fdc48a1655e7 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -212,7 +212,7 @@ config HISI_THERMAL
212 212
213config IMX_THERMAL 213config IMX_THERMAL
214 tristate "Temperature sensor driver for Freescale i.MX SoCs" 214 tristate "Temperature sensor driver for Freescale i.MX SoCs"
215 depends on (ARCH_MXC && CPU_THERMAL) || COMPILE_TEST 215 depends on ARCH_MXC || COMPILE_TEST
216 depends on NVMEM || !NVMEM 216 depends on NVMEM || !NVMEM
217 depends on MFD_SYSCON 217 depends on MFD_SYSCON
218 depends on OF 218 depends on OF
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index d7105d01859a..53129de59dd9 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -26,6 +26,11 @@
26#include <linux/iopoll.h> 26#include <linux/iopoll.h>
27#include <linux/mfd/syscon.h> 27#include <linux/mfd/syscon.h>
28#include <linux/regmap.h> 28#include <linux/regmap.h>
29#include <linux/interrupt.h>
30
31#include "thermal_core.h"
32
33#define TO_MCELSIUS(c) ((c) * 1000)
29 34
30/* Thermal Manager Control and Status Register */ 35/* Thermal Manager Control and Status Register */
31#define PMU_TDC0_SW_RST_MASK (0x1 << 1) 36#define PMU_TDC0_SW_RST_MASK (0x1 << 1)
@@ -61,9 +66,13 @@
61#define CONTROL1_TSEN_AVG_MASK 0x7 66#define CONTROL1_TSEN_AVG_MASK 0x7
62#define CONTROL1_EXT_TSEN_SW_RESET BIT(7) 67#define CONTROL1_EXT_TSEN_SW_RESET BIT(7)
63#define CONTROL1_EXT_TSEN_HW_RESETn BIT(8) 68#define CONTROL1_EXT_TSEN_HW_RESETn BIT(8)
69#define CONTROL1_TSEN_INT_EN BIT(25)
70#define CONTROL1_TSEN_SELECT_OFF 21
71#define CONTROL1_TSEN_SELECT_MASK 0x3
64 72
65#define STATUS_POLL_PERIOD_US 1000 73#define STATUS_POLL_PERIOD_US 1000
66#define STATUS_POLL_TIMEOUT_US 100000 74#define STATUS_POLL_TIMEOUT_US 100000
75#define OVERHEAT_INT_POLL_DELAY_MS 1000
67 76
68struct armada_thermal_data; 77struct armada_thermal_data;
69 78
@@ -75,7 +84,11 @@ struct armada_thermal_priv {
75 /* serialize temperature reads/updates */ 84 /* serialize temperature reads/updates */
76 struct mutex update_lock; 85 struct mutex update_lock;
77 struct armada_thermal_data *data; 86 struct armada_thermal_data *data;
87 struct thermal_zone_device *overheat_sensor;
88 int interrupt_source;
78 int current_channel; 89 int current_channel;
90 long current_threshold;
91 long current_hysteresis;
79}; 92};
80 93
81struct armada_thermal_data { 94struct armada_thermal_data {
@@ -93,12 +106,20 @@ struct armada_thermal_data {
93 /* Register shift and mask to access the sensor temperature */ 106 /* Register shift and mask to access the sensor temperature */
94 unsigned int temp_shift; 107 unsigned int temp_shift;
95 unsigned int temp_mask; 108 unsigned int temp_mask;
109 unsigned int thresh_shift;
110 unsigned int hyst_shift;
111 unsigned int hyst_mask;
96 u32 is_valid_bit; 112 u32 is_valid_bit;
97 113
98 /* Syscon access */ 114 /* Syscon access */
99 unsigned int syscon_control0_off; 115 unsigned int syscon_control0_off;
100 unsigned int syscon_control1_off; 116 unsigned int syscon_control1_off;
101 unsigned int syscon_status_off; 117 unsigned int syscon_status_off;
118 unsigned int dfx_irq_cause_off;
119 unsigned int dfx_irq_mask_off;
120 unsigned int dfx_overheat_irq;
121 unsigned int dfx_server_irq_mask_off;
122 unsigned int dfx_server_irq_en;
102 123
103 /* One sensor is in the thermal IC, the others are in the CPUs if any */ 124 /* One sensor is in the thermal IC, the others are in the CPUs if any */
104 unsigned int cpu_nr; 125 unsigned int cpu_nr;
@@ -272,6 +293,41 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
272 return reg & priv->data->is_valid_bit; 293 return reg & priv->data->is_valid_bit;
273} 294}
274 295
296static void armada_enable_overheat_interrupt(struct armada_thermal_priv *priv)
297{
298 struct armada_thermal_data *data = priv->data;
299 u32 reg;
300
301 /* Clear DFX temperature IRQ cause */
302 regmap_read(priv->syscon, data->dfx_irq_cause_off, &reg);
303
304 /* Enable DFX Temperature IRQ */
305 regmap_read(priv->syscon, data->dfx_irq_mask_off, &reg);
306 reg |= data->dfx_overheat_irq;
307 regmap_write(priv->syscon, data->dfx_irq_mask_off, reg);
308
309 /* Enable DFX server IRQ */
310 regmap_read(priv->syscon, data->dfx_server_irq_mask_off, &reg);
311 reg |= data->dfx_server_irq_en;
312 regmap_write(priv->syscon, data->dfx_server_irq_mask_off, reg);
313
314 /* Enable overheat interrupt */
315 regmap_read(priv->syscon, data->syscon_control1_off, &reg);
316 reg |= CONTROL1_TSEN_INT_EN;
317 regmap_write(priv->syscon, data->syscon_control1_off, reg);
318}
319
320static void __maybe_unused
321armada_disable_overheat_interrupt(struct armada_thermal_priv *priv)
322{
323 struct armada_thermal_data *data = priv->data;
324 u32 reg;
325
326 regmap_read(priv->syscon, data->syscon_control1_off, &reg);
327 reg &= ~CONTROL1_TSEN_INT_EN;
328 regmap_write(priv->syscon, data->syscon_control1_off, reg);
329}
330
275/* There is currently no board with more than one sensor per channel */ 331/* There is currently no board with more than one sensor per channel */
276static int armada_select_channel(struct armada_thermal_priv *priv, int channel) 332static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
277{ 333{
@@ -388,6 +444,14 @@ static int armada_get_temp(void *_sensor, int *temp)
388 444
389 /* Do the actual reading */ 445 /* Do the actual reading */
390 ret = armada_read_sensor(priv, temp); 446 ret = armada_read_sensor(priv, temp);
447 if (ret)
448 goto unlock_mutex;
449
450 /*
451 * Select back the interrupt source channel from which a potential
452 * critical trip point has been set.
453 */
454 ret = armada_select_channel(priv, priv->interrupt_source);
391 455
392unlock_mutex: 456unlock_mutex:
393 mutex_unlock(&priv->update_lock); 457 mutex_unlock(&priv->update_lock);
@@ -399,6 +463,123 @@ static const struct thermal_zone_of_device_ops of_ops = {
399 .get_temp = armada_get_temp, 463 .get_temp = armada_get_temp,
400}; 464};
401 465
466static unsigned int armada_mc_to_reg_temp(struct armada_thermal_data *data,
467 unsigned int temp_mc)
468{
469 s64 b = data->coef_b;
470 s64 m = data->coef_m;
471 s64 div = data->coef_div;
472 unsigned int sample;
473
474 if (data->inverted)
475 sample = div_s64(((temp_mc * div) + b), m);
476 else
477 sample = div_s64((b - (temp_mc * div)), m);
478
479 return sample & data->temp_mask;
480}
481
482/*
483 * The documentation states:
484 * high/low watermark = threshold +/- 0.4761 * 2^(hysteresis + 2)
485 * which is the mathematical derivation for:
486 * 0x0 <=> 1.9°C, 0x1 <=> 3.8°C, 0x2 <=> 7.6°C, 0x3 <=> 15.2°C
487 */
488static unsigned int hyst_levels_mc[] = {1900, 3800, 7600, 15200};
489
490static unsigned int armada_mc_to_reg_hyst(struct armada_thermal_data *data,
491 unsigned int hyst_mc)
492{
493 int i;
494
495 /*
496 * We will always take the smallest possible hysteresis to avoid risking
497 * the hardware integrity by enlarging the threshold by +8°C in the
498 * worst case.
499 */
500 for (i = ARRAY_SIZE(hyst_levels_mc) - 1; i > 0; i--)
501 if (hyst_mc >= hyst_levels_mc[i])
502 break;
503
504 return i & data->hyst_mask;
505}
506
507static void armada_set_overheat_thresholds(struct armada_thermal_priv *priv,
508 int thresh_mc, int hyst_mc)
509{
510 struct armada_thermal_data *data = priv->data;
511 unsigned int threshold = armada_mc_to_reg_temp(data, thresh_mc);
512 unsigned int hysteresis = armada_mc_to_reg_hyst(data, hyst_mc);
513 u32 ctrl1;
514
515 regmap_read(priv->syscon, data->syscon_control1_off, &ctrl1);
516
517 /* Set Threshold */
518 if (thresh_mc >= 0) {
519 ctrl1 &= ~(data->temp_mask << data->thresh_shift);
520 ctrl1 |= threshold << data->thresh_shift;
521 priv->current_threshold = thresh_mc;
522 }
523
524 /* Set Hysteresis */
525 if (hyst_mc >= 0) {
526 ctrl1 &= ~(data->hyst_mask << data->hyst_shift);
527 ctrl1 |= hysteresis << data->hyst_shift;
528 priv->current_hysteresis = hyst_mc;
529 }
530
531 regmap_write(priv->syscon, data->syscon_control1_off, ctrl1);
532}
533
534static irqreturn_t armada_overheat_isr(int irq, void *blob)
535{
536 /*
537 * Disable the IRQ and continue in thread context (thermal core
538 * notification and temperature monitoring).
539 */
540 disable_irq_nosync(irq);
541
542 return IRQ_WAKE_THREAD;
543}
544
545static irqreturn_t armada_overheat_isr_thread(int irq, void *blob)
546{
547 struct armada_thermal_priv *priv = blob;
548 int low_threshold = priv->current_threshold - priv->current_hysteresis;
549 int temperature;
550 u32 dummy;
551 int ret;
552
553 /* Notify the core in thread context */
554 thermal_zone_device_update(priv->overheat_sensor,
555 THERMAL_EVENT_UNSPECIFIED);
556
557 /*
558 * The overheat interrupt must be cleared by reading the DFX interrupt
559 * cause _after_ the temperature has fallen down to the low threshold.
560 * Otherwise future interrupts might not be served.
561 */
562 do {
563 msleep(OVERHEAT_INT_POLL_DELAY_MS);
564 mutex_lock(&priv->update_lock);
565 ret = armada_read_sensor(priv, &temperature);
566 mutex_unlock(&priv->update_lock);
567 if (ret)
568 goto enable_irq;
569 } while (temperature >= low_threshold);
570
571 regmap_read(priv->syscon, priv->data->dfx_irq_cause_off, &dummy);
572
573 /* Notify the thermal core that the temperature is acceptable again */
574 thermal_zone_device_update(priv->overheat_sensor,
575 THERMAL_EVENT_UNSPECIFIED);
576
577enable_irq:
578 enable_irq(irq);
579
580 return IRQ_HANDLED;
581}
582
402static const struct armada_thermal_data armadaxp_data = { 583static const struct armada_thermal_data armadaxp_data = {
403 .init = armadaxp_init, 584 .init = armadaxp_init,
404 .temp_shift = 10, 585 .temp_shift = 10,
@@ -454,6 +635,9 @@ static const struct armada_thermal_data armada_ap806_data = {
454 .is_valid_bit = BIT(16), 635 .is_valid_bit = BIT(16),
455 .temp_shift = 0, 636 .temp_shift = 0,
456 .temp_mask = 0x3ff, 637 .temp_mask = 0x3ff,
638 .thresh_shift = 3,
639 .hyst_shift = 19,
640 .hyst_mask = 0x3,
457 .coef_b = -150000LL, 641 .coef_b = -150000LL,
458 .coef_m = 423ULL, 642 .coef_m = 423ULL,
459 .coef_div = 1, 643 .coef_div = 1,
@@ -462,6 +646,11 @@ static const struct armada_thermal_data armada_ap806_data = {
462 .syscon_control0_off = 0x84, 646 .syscon_control0_off = 0x84,
463 .syscon_control1_off = 0x88, 647 .syscon_control1_off = 0x88,
464 .syscon_status_off = 0x8C, 648 .syscon_status_off = 0x8C,
649 .dfx_irq_cause_off = 0x108,
650 .dfx_irq_mask_off = 0x10C,
651 .dfx_overheat_irq = BIT(22),
652 .dfx_server_irq_mask_off = 0x104,
653 .dfx_server_irq_en = BIT(1),
465 .cpu_nr = 4, 654 .cpu_nr = 4,
466}; 655};
467 656
@@ -470,6 +659,9 @@ static const struct armada_thermal_data armada_cp110_data = {
470 .is_valid_bit = BIT(10), 659 .is_valid_bit = BIT(10),
471 .temp_shift = 0, 660 .temp_shift = 0,
472 .temp_mask = 0x3ff, 661 .temp_mask = 0x3ff,
662 .thresh_shift = 16,
663 .hyst_shift = 26,
664 .hyst_mask = 0x3,
473 .coef_b = 1172499100ULL, 665 .coef_b = 1172499100ULL,
474 .coef_m = 2000096ULL, 666 .coef_m = 2000096ULL,
475 .coef_div = 4201, 667 .coef_div = 4201,
@@ -477,6 +669,11 @@ static const struct armada_thermal_data armada_cp110_data = {
477 .syscon_control0_off = 0x70, 669 .syscon_control0_off = 0x70,
478 .syscon_control1_off = 0x74, 670 .syscon_control1_off = 0x74,
479 .syscon_status_off = 0x78, 671 .syscon_status_off = 0x78,
672 .dfx_irq_cause_off = 0x108,
673 .dfx_irq_mask_off = 0x10C,
674 .dfx_overheat_irq = BIT(20),
675 .dfx_server_irq_mask_off = 0x104,
676 .dfx_server_irq_en = BIT(1),
480}; 677};
481 678
482static const struct of_device_id armada_thermal_id_table[] = { 679static const struct of_device_id armada_thermal_id_table[] = {
@@ -543,20 +740,14 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev,
543 740
544 priv->syscon = devm_regmap_init_mmio(&pdev->dev, base, 741 priv->syscon = devm_regmap_init_mmio(&pdev->dev, base,
545 &armada_thermal_regmap_config); 742 &armada_thermal_regmap_config);
546 if (IS_ERR(priv->syscon)) 743 return PTR_ERR_OR_ZERO(priv->syscon);
547 return PTR_ERR(priv->syscon);
548
549 return 0;
550} 744}
551 745
552static int armada_thermal_probe_syscon(struct platform_device *pdev, 746static int armada_thermal_probe_syscon(struct platform_device *pdev,
553 struct armada_thermal_priv *priv) 747 struct armada_thermal_priv *priv)
554{ 748{
555 priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node); 749 priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node);
556 if (IS_ERR(priv->syscon)) 750 return PTR_ERR_OR_ZERO(priv->syscon);
557 return PTR_ERR(priv->syscon);
558
559 return 0;
560} 751}
561 752
562static void armada_set_sane_name(struct platform_device *pdev, 753static void armada_set_sane_name(struct platform_device *pdev,
@@ -590,6 +781,48 @@ static void armada_set_sane_name(struct platform_device *pdev,
590 } while (insane_char); 781 } while (insane_char);
591} 782}
592 783
784/*
785 * The IP can manage to trigger interrupts on overheat situation from all the
786 * sensors. However, the interrupt source changes along with the last selected
787 * source (ie. the last read sensor), which is an inconsistent behavior. Avoid
788 * possible glitches by always selecting back only one channel (arbitrarily: the
789 * first in the DT which has a critical trip point). We also disable sensor
790 * switch during overheat situations.
791 */
792static int armada_configure_overheat_int(struct armada_thermal_priv *priv,
793 struct thermal_zone_device *tz,
794 int sensor_id)
795{
796 /* Retrieve the critical trip point to enable the overheat interrupt */
797 const struct thermal_trip *trips = of_thermal_get_trip_points(tz);
798 int ret;
799 int i;
800
801 if (!trips)
802 return -EINVAL;
803
804 for (i = 0; i < of_thermal_get_ntrips(tz); i++)
805 if (trips[i].type == THERMAL_TRIP_CRITICAL)
806 break;
807
808 if (i == of_thermal_get_ntrips(tz))
809 return -EINVAL;
810
811 ret = armada_select_channel(priv, sensor_id);
812 if (ret)
813 return ret;
814
815 armada_set_overheat_thresholds(priv,
816 trips[i].temperature,
817 trips[i].hysteresis);
818 priv->overheat_sensor = tz;
819 priv->interrupt_source = sensor_id;
820
821 armada_enable_overheat_interrupt(priv);
822
823 return 0;
824}
825
593static int armada_thermal_probe(struct platform_device *pdev) 826static int armada_thermal_probe(struct platform_device *pdev)
594{ 827{
595 struct thermal_zone_device *tz; 828 struct thermal_zone_device *tz;
@@ -597,7 +830,7 @@ static int armada_thermal_probe(struct platform_device *pdev)
597 struct armada_drvdata *drvdata; 830 struct armada_drvdata *drvdata;
598 const struct of_device_id *match; 831 const struct of_device_id *match;
599 struct armada_thermal_priv *priv; 832 struct armada_thermal_priv *priv;
600 int sensor_id; 833 int sensor_id, irq;
601 int ret; 834 int ret;
602 835
603 match = of_match_device(armada_thermal_id_table, &pdev->dev); 836 match = of_match_device(armada_thermal_id_table, &pdev->dev);
@@ -667,6 +900,23 @@ static int armada_thermal_probe(struct platform_device *pdev)
667 drvdata->data.priv = priv; 900 drvdata->data.priv = priv;
668 platform_set_drvdata(pdev, drvdata); 901 platform_set_drvdata(pdev, drvdata);
669 902
903 irq = platform_get_irq(pdev, 0);
904 if (irq == -EPROBE_DEFER)
905 return irq;
906
907 /* The overheat interrupt feature is not mandatory */
908 if (irq > 0) {
909 ret = devm_request_threaded_irq(&pdev->dev, irq,
910 armada_overheat_isr,
911 armada_overheat_isr_thread,
912 0, NULL, priv);
913 if (ret) {
914 dev_err(&pdev->dev, "Cannot request threaded IRQ %d\n",
915 irq);
916 return ret;
917 }
918 }
919
670 /* 920 /*
671 * There is one channel for the IC and one per CPU (if any), each 921 * There is one channel for the IC and one per CPU (if any), each
672 * channel has one sensor. 922 * channel has one sensor.
@@ -690,8 +940,20 @@ static int armada_thermal_probe(struct platform_device *pdev)
690 devm_kfree(&pdev->dev, sensor); 940 devm_kfree(&pdev->dev, sensor);
691 continue; 941 continue;
692 } 942 }
943
944 /*
945 * The first channel that has a critical trip point registered
946 * in the DT will serve as interrupt source. Others possible
947 * critical trip points will simply be ignored by the driver.
948 */
949 if (irq > 0 && !priv->overheat_sensor)
950 armada_configure_overheat_int(priv, tz, sensor->id);
693 } 951 }
694 952
953 /* Just complain if no overheat interrupt was set up */
954 if (!priv->overheat_sensor)
955 dev_warn(&pdev->dev, "Overheat interrupt not available\n");
956
695 return 0; 957 return 0;
696} 958}
697 959
diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c
index b9d90f0ed504..720760cd493f 100644
--- a/drivers/thermal/broadcom/bcm2835_thermal.c
+++ b/drivers/thermal/broadcom/bcm2835_thermal.c
@@ -18,6 +18,8 @@
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/thermal.h> 19#include <linux/thermal.h>
20 20
21#include "../thermal_hwmon.h"
22
21#define BCM2835_TS_TSENSCTL 0x00 23#define BCM2835_TS_TSENSCTL 0x00
22#define BCM2835_TS_TSENSSTAT 0x04 24#define BCM2835_TS_TSENSSTAT 0x04
23 25
@@ -266,6 +268,15 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
266 268
267 platform_set_drvdata(pdev, tz); 269 platform_set_drvdata(pdev, tz);
268 270
271 /*
272 * Thermal_zone doesn't enable hwmon as default,
273 * enable it here
274 */
275 tz->tzp->no_hwmon = false;
276 err = thermal_add_hwmon_sysfs(tz);
277 if (err)
278 goto err_tz;
279
269 bcm2835_thermal_debugfs(pdev); 280 bcm2835_thermal_debugfs(pdev);
270 281
271 return 0; 282 return 0;
diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c
index e8b1570cc388..65704bdd18e4 100644
--- a/drivers/thermal/broadcom/brcmstb_thermal.c
+++ b/drivers/thermal/broadcom/brcmstb_thermal.c
@@ -329,7 +329,8 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
329 priv->dev = &pdev->dev; 329 priv->dev = &pdev->dev;
330 platform_set_drvdata(pdev, priv); 330 platform_set_drvdata(pdev, priv);
331 331
332 thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &of_ops); 332 thermal = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, priv,
333 &of_ops);
333 if (IS_ERR(thermal)) { 334 if (IS_ERR(thermal)) {
334 ret = PTR_ERR(thermal); 335 ret = PTR_ERR(thermal);
335 dev_err(&pdev->dev, "could not register sensor: %d\n", ret); 336 dev_err(&pdev->dev, "could not register sensor: %d\n", ret);
@@ -341,40 +342,23 @@ static int brcmstb_thermal_probe(struct platform_device *pdev)
341 irq = platform_get_irq(pdev, 0); 342 irq = platform_get_irq(pdev, 0);
342 if (irq < 0) { 343 if (irq < 0) {
343 dev_err(&pdev->dev, "could not get IRQ\n"); 344 dev_err(&pdev->dev, "could not get IRQ\n");
344 ret = irq; 345 return irq;
345 goto err;
346 } 346 }
347 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 347 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
348 brcmstb_tmon_irq_thread, IRQF_ONESHOT, 348 brcmstb_tmon_irq_thread, IRQF_ONESHOT,
349 DRV_NAME, priv); 349 DRV_NAME, priv);
350 if (ret < 0) { 350 if (ret < 0) {
351 dev_err(&pdev->dev, "could not request IRQ: %d\n", ret); 351 dev_err(&pdev->dev, "could not request IRQ: %d\n", ret);
352 goto err; 352 return ret;
353 } 353 }
354 354
355 dev_info(&pdev->dev, "registered AVS TMON of-sensor driver\n"); 355 dev_info(&pdev->dev, "registered AVS TMON of-sensor driver\n");
356 356
357 return 0; 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} 358}
374 359
375static struct platform_driver brcmstb_thermal_driver = { 360static struct platform_driver brcmstb_thermal_driver = {
376 .probe = brcmstb_thermal_probe, 361 .probe = brcmstb_thermal_probe,
377 .remove = brcmstb_thermal_exit,
378 .driver = { 362 .driver = {
379 .name = DRV_NAME, 363 .name = DRV_NAME,
380 .of_match_table = brcmstb_thermal_id_table, 364 .of_match_table = brcmstb_thermal_id_table,
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 15661549eb67..bb6754a5342c 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -648,15 +648,24 @@ static const struct of_device_id of_imx_thermal_match[] = {
648}; 648};
649MODULE_DEVICE_TABLE(of, of_imx_thermal_match); 649MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
650 650
651#ifdef CONFIG_CPU_FREQ
651/* 652/*
652 * Create cooling device in case no #cooling-cells property is available in 653 * Create cooling device in case no #cooling-cells property is available in
653 * CPU node 654 * CPU node
654 */ 655 */
655static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) 656static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
656{ 657{
657 struct device_node *np = of_get_cpu_node(data->policy->cpu, NULL); 658 struct device_node *np;
658 int ret; 659 int ret;
659 660
661 data->policy = cpufreq_cpu_get(0);
662 if (!data->policy) {
663 pr_debug("%s: CPUFreq policy not found\n", __func__);
664 return -EPROBE_DEFER;
665 }
666
667 np = of_get_cpu_node(data->policy->cpu, NULL);
668
660 if (!np || !of_find_property(np, "#cooling-cells", NULL)) { 669 if (!np || !of_find_property(np, "#cooling-cells", NULL)) {
661 data->cdev = cpufreq_cooling_register(data->policy); 670 data->cdev = cpufreq_cooling_register(data->policy);
662 if (IS_ERR(data->cdev)) { 671 if (IS_ERR(data->cdev)) {
@@ -669,6 +678,24 @@ static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
669 return 0; 678 return 0;
670} 679}
671 680
681static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data)
682{
683 cpufreq_cooling_unregister(data->cdev);
684 cpufreq_cpu_put(data->policy);
685}
686
687#else
688
689static inline int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
690{
691 return 0;
692}
693
694static inline void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data)
695{
696}
697#endif
698
672static int imx_thermal_probe(struct platform_device *pdev) 699static int imx_thermal_probe(struct platform_device *pdev)
673{ 700{
674 struct imx_thermal_data *data; 701 struct imx_thermal_data *data;
@@ -715,9 +742,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
715 742
716 if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) { 743 if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) {
717 ret = imx_init_from_nvmem_cells(pdev); 744 ret = imx_init_from_nvmem_cells(pdev);
718 if (ret == -EPROBE_DEFER)
719 return ret;
720 if (ret) { 745 if (ret) {
746 if (ret == -EPROBE_DEFER)
747 return ret;
748
721 dev_err(&pdev->dev, "failed to init from nvmem: %d\n", 749 dev_err(&pdev->dev, "failed to init from nvmem: %d\n",
722 ret); 750 ret);
723 return ret; 751 return ret;
@@ -743,14 +771,11 @@ static int imx_thermal_probe(struct platform_device *pdev)
743 regmap_write(map, data->socdata->sensor_ctrl + REG_SET, 771 regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
744 data->socdata->power_down_mask); 772 data->socdata->power_down_mask);
745 773
746 data->policy = cpufreq_cpu_get(0);
747 if (!data->policy) {
748 pr_debug("%s: CPUFreq policy not found\n", __func__);
749 return -EPROBE_DEFER;
750 }
751
752 ret = imx_thermal_register_legacy_cooling(data); 774 ret = imx_thermal_register_legacy_cooling(data);
753 if (ret) { 775 if (ret) {
776 if (ret == -EPROBE_DEFER)
777 return ret;
778
754 dev_err(&pdev->dev, 779 dev_err(&pdev->dev,
755 "failed to register cpufreq cooling device: %d\n", ret); 780 "failed to register cpufreq cooling device: %d\n", ret);
756 return ret; 781 return ret;
@@ -762,7 +787,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
762 if (ret != -EPROBE_DEFER) 787 if (ret != -EPROBE_DEFER)
763 dev_err(&pdev->dev, 788 dev_err(&pdev->dev,
764 "failed to get thermal clk: %d\n", ret); 789 "failed to get thermal clk: %d\n", ret);
765 goto cpufreq_put; 790 goto legacy_cleanup;
766 } 791 }
767 792
768 /* 793 /*
@@ -775,7 +800,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
775 ret = clk_prepare_enable(data->thermal_clk); 800 ret = clk_prepare_enable(data->thermal_clk);
776 if (ret) { 801 if (ret) {
777 dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret); 802 dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
778 goto cpufreq_put; 803 goto legacy_cleanup;
779 } 804 }
780 805
781 data->tz = thermal_zone_device_register("imx_thermal_zone", 806 data->tz = thermal_zone_device_register("imx_thermal_zone",
@@ -829,9 +854,8 @@ thermal_zone_unregister:
829 thermal_zone_device_unregister(data->tz); 854 thermal_zone_device_unregister(data->tz);
830clk_disable: 855clk_disable:
831 clk_disable_unprepare(data->thermal_clk); 856 clk_disable_unprepare(data->thermal_clk);
832cpufreq_put: 857legacy_cleanup:
833 cpufreq_cooling_unregister(data->cdev); 858 imx_thermal_unregister_legacy_cooling(data);
834 cpufreq_cpu_put(data->policy);
835 859
836 return ret; 860 return ret;
837} 861}
diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c
index cde891c54cde..7571f7c2e7c9 100644
--- a/drivers/thermal/intel_powerclamp.c
+++ b/drivers/thermal/intel_powerclamp.c
@@ -708,19 +708,7 @@ static int powerclamp_debug_show(struct seq_file *m, void *unused)
708 return 0; 708 return 0;
709} 709}
710 710
711static int powerclamp_debug_open(struct inode *inode, 711DEFINE_SHOW_ATTRIBUTE(powerclamp_debug);
712 struct file *file)
713{
714 return single_open(file, powerclamp_debug_show, inode->i_private);
715}
716
717static const struct file_operations powerclamp_debug_fops = {
718 .open = powerclamp_debug_open,
719 .read = seq_read,
720 .llseek = seq_lseek,
721 .release = single_release,
722 .owner = THIS_MODULE,
723};
724 712
725static inline void powerclamp_create_debug_files(void) 713static inline void powerclamp_create_debug_files(void)
726{ 714{
diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index 3be4be2e0465..78652cac7f3d 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -114,6 +114,14 @@ int get_temp_common(struct tsens_device *tmdev, int id, int *temp)
114} 114}
115 115
116static const struct regmap_config tsens_config = { 116static const struct regmap_config tsens_config = {
117 .name = "tm",
118 .reg_bits = 32,
119 .val_bits = 32,
120 .reg_stride = 4,
121};
122
123static const struct regmap_config tsens_srot_config = {
124 .name = "srot",
117 .reg_bits = 32, 125 .reg_bits = 32,
118 .val_bits = 32, 126 .val_bits = 32,
119 .reg_stride = 4, 127 .reg_stride = 4,
@@ -139,8 +147,8 @@ int __init init_common(struct tsens_device *tmdev)
139 if (IS_ERR(srot_base)) 147 if (IS_ERR(srot_base))
140 return PTR_ERR(srot_base); 148 return PTR_ERR(srot_base);
141 149
142 tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, 150 tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, srot_base,
143 srot_base, &tsens_config); 151 &tsens_srot_config);
144 if (IS_ERR(tmdev->srot_map)) 152 if (IS_ERR(tmdev->srot_map))
145 return PTR_ERR(tmdev->srot_map); 153 return PTR_ERR(tmdev->srot_map);
146 154
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 8014a207d8d9..97462e9b40d8 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -113,10 +113,18 @@ static const struct of_device_id rcar_thermal_dt_ids[] = {
113 .data = &rcar_gen2_thermal, 113 .data = &rcar_gen2_thermal,
114 }, 114 },
115 { 115 {
116 .compatible = "renesas,thermal-r8a774c0",
117 .data = &rcar_gen3_thermal,
118 },
119 {
116 .compatible = "renesas,thermal-r8a77970", 120 .compatible = "renesas,thermal-r8a77970",
117 .data = &rcar_gen3_thermal, 121 .data = &rcar_gen3_thermal,
118 }, 122 },
119 { 123 {
124 .compatible = "renesas,thermal-r8a77990",
125 .data = &rcar_gen3_thermal,
126 },
127 {
120 .compatible = "renesas,thermal-r8a77995", 128 .compatible = "renesas,thermal-r8a77995",
121 .data = &rcar_gen3_thermal, 129 .data = &rcar_gen3_thermal,
122 }, 130 },
diff --git a/drivers/thermal/st/Makefile b/drivers/thermal/st/Makefile
index b2b9e9b96296..243ca7881b12 100644
--- a/drivers/thermal/st/Makefile
+++ b/drivers/thermal/st/Makefile
@@ -1,4 +1,4 @@
1obj-$(CONFIG_ST_THERMAL) := st_thermal.o 1obj-$(CONFIG_ST_THERMAL) := st_thermal.o
2obj-$(CONFIG_ST_THERMAL_SYSCFG) += st_thermal_syscfg.o 2obj-$(CONFIG_ST_THERMAL_SYSCFG) += st_thermal_syscfg.o
3obj-$(CONFIG_ST_THERMAL_MEMMAP) += st_thermal_memmap.o 3obj-$(CONFIG_ST_THERMAL_MEMMAP) += st_thermal_memmap.o
4obj-$(CONFIG_STM32_THERMAL) := stm_thermal.o \ No newline at end of file 4obj-$(CONFIG_STM32_THERMAL) += stm_thermal.o
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index ed28110a3535..45b41b885f49 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -803,17 +803,7 @@ static int regs_show(struct seq_file *s, void *data)
803 return 0; 803 return 0;
804} 804}
805 805
806static int regs_open(struct inode *inode, struct file *file) 806DEFINE_SHOW_ATTRIBUTE(regs);
807{
808 return single_open(file, regs_show, inode->i_private);
809}
810
811static const struct file_operations regs_fops = {
812 .open = regs_open,
813 .read = seq_read,
814 .llseek = seq_lseek,
815 .release = single_release,
816};
817 807
818static void soctherm_debug_init(struct platform_device *pdev) 808static void soctherm_debug_init(struct platform_device *pdev)
819{ 809{
diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c
index bf1c628d4a7a..e22fc60ad36d 100644
--- a/drivers/thermal/thermal-generic-adc.c
+++ b/drivers/thermal/thermal-generic-adc.c
@@ -26,7 +26,7 @@ struct gadc_thermal_info {
26 26
27static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val) 27static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val)
28{ 28{
29 int temp, adc_hi, adc_lo; 29 int temp, temp_hi, temp_lo, adc_hi, adc_lo;
30 int i; 30 int i;
31 31
32 for (i = 0; i < gti->nlookup_table; i++) { 32 for (i = 0; i < gti->nlookup_table; i++) {
@@ -36,13 +36,17 @@ static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val)
36 36
37 if (i == 0) { 37 if (i == 0) {
38 temp = gti->lookup_table[0]; 38 temp = gti->lookup_table[0];
39 } else if (i >= (gti->nlookup_table - 1)) { 39 } else if (i >= gti->nlookup_table) {
40 temp = gti->lookup_table[2 * (gti->nlookup_table - 1)]; 40 temp = gti->lookup_table[2 * (gti->nlookup_table - 1)];
41 } else { 41 } else {
42 adc_hi = gti->lookup_table[2 * i - 1]; 42 adc_hi = gti->lookup_table[2 * i - 1];
43 adc_lo = gti->lookup_table[2 * i + 1]; 43 adc_lo = gti->lookup_table[2 * i + 1];
44 temp = gti->lookup_table[2 * i]; 44
45 temp -= ((val - adc_lo) * 1000) / (adc_hi - adc_lo); 45 temp_hi = gti->lookup_table[2 * i - 2];
46 temp_lo = gti->lookup_table[2 * i];
47
48 temp = temp_hi + mult_frac(temp_lo - temp_hi, val - adc_hi,
49 adc_lo - adc_hi);
46 } 50 }
47 51
48 return temp; 52 return temp;
diff --git a/drivers/thermal/thermal_hwmon.h b/drivers/thermal/thermal_hwmon.h
index 019f6f88224e..a160b9d62dd0 100644
--- a/drivers/thermal/thermal_hwmon.h
+++ b/drivers/thermal/thermal_hwmon.h
@@ -19,13 +19,13 @@
19int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz); 19int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz);
20void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz); 20void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz);
21#else 21#else
22static int 22static inline int
23thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) 23thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
24{ 24{
25 return 0; 25 return 0;
26} 26}
27 27
28static void 28static inline void
29thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) 29thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
30{ 30{
31} 31}
diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c
index 55477d74d591..bba2284412d3 100644
--- a/drivers/thermal/uniphier_thermal.c
+++ b/drivers/thermal/uniphier_thermal.c
@@ -1,21 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0
1/** 2/**
2 * uniphier_thermal.c - Socionext UniPhier thermal driver 3 * uniphier_thermal.c - Socionext UniPhier thermal driver
3 *
4 * Copyright 2014 Panasonic Corporation 4 * Copyright 2014 Panasonic Corporation
5 * Copyright 2016-2017 Socionext Inc. 5 * Copyright 2016-2017 Socionext Inc.
6 * All rights reserved.
7 *
8 * Author: 6 * Author:
9 * Kunihiko Hayashi <hayashi.kunihiko@socionext.com> 7 * Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 of
13 * the License as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */ 8 */
20 9
21#include <linux/bitops.h> 10#include <linux/bitops.h>