aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-10-26 15:04:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-26 15:04:29 -0400
commit0ef7791e2bfb2e10aa95dc492eab72074cef9942 (patch)
tree8b14a15cddceaf05c116b57ad59212fe651fb26a
parentbefa93633193e5327e4045d1e5fa29114580fa5d (diff)
parent760eea43f8c6d48684f1f34b8a02fddc1456e849 (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: "Several new things coming up. Specifics: - Rework of tsens and hisi thermal drivers - OF-thermal now allows sharing multiple cooling devices on maps - Added support for r8a7744 and R8A77970 on rcar thermal driver - Added support for r8a774a1 on rcar_gen3 thermal driver - New thermal driver stm32 - Fixes on multiple thermal drivers: of-thermal, imx, qoriq, armada, qcom-spmi, rcar, da9062/61" * 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal: (41 commits) thermal: da9062/61: Prevent hardware access during system suspend thermal: rcar_thermal: Prevent doing work after unbind thermal: rcar_thermal: Prevent hardware access during system suspend thermal: rcar_gen3_thermal: add R8A77980 support dt-bindings: thermal: rcar-gen3-thermal: document R8A77980 bindings thermal: add stm32 thermal driver dt-bindings: stm32-thermal: add binding documentation thermal: rcar_thermal: add R8A77970 support dt-bindings: thermal: rcar-thermal: document R8A77970 bindings thermal: rcar_thermal: fix duplicate IRQ request dt-bindings: thermal: rcar: Add device tree support for r8a7744 thermal/drivers/hisi: Add the dual clusters sensors for hi3660 thermal/drivers/hisi: Add more sensors channel thermal/drivers/hisi: Remove pointless irq field thermal/drivers/hisi: Use platform_get_irq_byname thermal/drivers/hisi: Replace macro name with relevant sensor location thermal/drivers/hisi: Add multiple sensors support thermal/drivers/hisi: Prepare to support multiple sensors thermal/drivers/hisi: Factor out the probe functions thermal/drivers/hisi: Set the thermal zone private data to the sensor pointer ...
-rw-r--r--Documentation/devicetree/bindings/thermal/qcom-spmi-temp-alarm.txt16
-rw-r--r--Documentation/devicetree/bindings/thermal/qoriq-thermal.txt6
-rw-r--r--Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt5
-rw-r--r--Documentation/devicetree/bindings/thermal/rcar-thermal.txt6
-rw-r--r--Documentation/devicetree/bindings/thermal/stm32-thermal.txt61
-rw-r--r--Documentation/devicetree/bindings/thermal/thermal.txt2
-rw-r--r--drivers/thermal/Kconfig2
-rw-r--r--drivers/thermal/Makefile2
-rw-r--r--drivers/thermal/armada_thermal.c4
-rw-r--r--drivers/thermal/da9062-thermal.c4
-rw-r--r--drivers/thermal/hisi_thermal.c249
-rw-r--r--drivers/thermal/imx_thermal.c31
-rw-r--r--drivers/thermal/of-thermal.c152
-rw-r--r--drivers/thermal/qcom-spmi-temp-alarm.c158
-rw-r--r--drivers/thermal/qcom/tsens-8916.c12
-rw-r--r--drivers/thermal/qcom/tsens-8960.c41
-rw-r--r--drivers/thermal/qcom/tsens-8974.c12
-rw-r--r--drivers/thermal/qcom/tsens-common.c62
-rw-r--r--drivers/thermal/qcom/tsens-v2.c8
-rw-r--r--drivers/thermal/qcom/tsens.c19
-rw-r--r--drivers/thermal/qcom/tsens.h23
-rw-r--r--drivers/thermal/qoriq_thermal.c5
-rw-r--r--drivers/thermal/rcar_gen3_thermal.c2
-rw-r--r--drivers/thermal/rcar_thermal.c11
-rw-r--r--drivers/thermal/st/Kconfig14
-rw-r--r--drivers/thermal/st/Makefile1
-rw-r--r--drivers/thermal/st/stm_thermal.c760
27 files changed, 1365 insertions, 303 deletions
diff --git a/Documentation/devicetree/bindings/thermal/qcom-spmi-temp-alarm.txt b/Documentation/devicetree/bindings/thermal/qcom-spmi-temp-alarm.txt
index 290ec06fa33a..0273a92a2a84 100644
--- a/Documentation/devicetree/bindings/thermal/qcom-spmi-temp-alarm.txt
+++ b/Documentation/devicetree/bindings/thermal/qcom-spmi-temp-alarm.txt
@@ -6,8 +6,7 @@ interrupt signal and status register to identify high PMIC die temperature.
6 6
7Required properties: 7Required properties:
8- compatible: Should contain "qcom,spmi-temp-alarm". 8- compatible: Should contain "qcom,spmi-temp-alarm".
9- reg: Specifies the SPMI address and length of the controller's 9- reg: Specifies the SPMI address.
10 registers.
11- interrupts: PMIC temperature alarm interrupt. 10- interrupts: PMIC temperature alarm interrupt.
12- #thermal-sensor-cells: Should be 0. See thermal.txt for a description. 11- #thermal-sensor-cells: Should be 0. See thermal.txt for a description.
13 12
@@ -20,7 +19,7 @@ Example:
20 19
21 pm8941_temp: thermal-alarm@2400 { 20 pm8941_temp: thermal-alarm@2400 {
22 compatible = "qcom,spmi-temp-alarm"; 21 compatible = "qcom,spmi-temp-alarm";
23 reg = <0x2400 0x100>; 22 reg = <0x2400>;
24 interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; 23 interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>;
25 #thermal-sensor-cells = <0>; 24 #thermal-sensor-cells = <0>;
26 25
@@ -36,19 +35,14 @@ Example:
36 thermal-sensors = <&pm8941_temp>; 35 thermal-sensors = <&pm8941_temp>;
37 36
38 trips { 37 trips {
39 passive { 38 stage1 {
40 temperature = <1050000>; 39 temperature = <105000>;
41 hysteresis = <2000>; 40 hysteresis = <2000>;
42 type = "passive"; 41 type = "passive";
43 }; 42 };
44 alert { 43 stage2 {
45 temperature = <125000>; 44 temperature = <125000>;
46 hysteresis = <2000>; 45 hysteresis = <2000>;
47 type = "hot";
48 };
49 crit {
50 temperature = <145000>;
51 hysteresis = <2000>;
52 type = "critical"; 46 type = "critical";
53 }; 47 };
54 }; 48 };
diff --git a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
index 20ca4ef9d776..04cbb90a5d3e 100644
--- a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
@@ -1,9 +1,9 @@
1* Thermal Monitoring Unit (TMU) on Freescale QorIQ SoCs 1* Thermal Monitoring Unit (TMU) on Freescale QorIQ SoCs
2 2
3Required properties: 3Required properties:
4- compatible : Must include "fsl,qoriq-tmu". The version of the device is 4- compatible : Must include "fsl,qoriq-tmu" or "fsl,imx8mq-tmu". The
5 determined by the TMU IP Block Revision Register (IPBRR0) at 5 version of the device is determined by the TMU IP Block Revision
6 offset 0x0BF8. 6 Register (IPBRR0) at offset 0x0BF8.
7 Table of correspondences between IPBRR0 values and example chips: 7 Table of correspondences between IPBRR0 values and example chips:
8 Value Device 8 Value Device
9 ---------- ----- 9 ---------- -----
diff --git a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
index cfa154bb0fa7..ad9a435afef4 100644
--- a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
@@ -7,9 +7,11 @@ inside the LSI.
7Required properties: 7Required properties:
8- compatible : "renesas,<soctype>-thermal", 8- compatible : "renesas,<soctype>-thermal",
9 Examples with soctypes are: 9 Examples with soctypes are:
10 - "renesas,r8a774a1-thermal" (RZ/G2M)
10 - "renesas,r8a7795-thermal" (R-Car H3) 11 - "renesas,r8a7795-thermal" (R-Car H3)
11 - "renesas,r8a7796-thermal" (R-Car M3-W) 12 - "renesas,r8a7796-thermal" (R-Car M3-W)
12 - "renesas,r8a77965-thermal" (R-Car M3-N) 13 - "renesas,r8a77965-thermal" (R-Car M3-N)
14 - "renesas,r8a77980-thermal" (R-Car V3H)
13- reg : Address ranges of the thermal registers. Each sensor 15- reg : Address ranges of the thermal registers. Each sensor
14 needs one address range. Sorting must be done in 16 needs one address range. Sorting must be done in
15 increasing order according to datasheet, i.e. 17 increasing order according to datasheet, i.e.
@@ -19,7 +21,8 @@ Required properties:
19 21
20Optional properties: 22Optional properties:
21 23
22- interrupts : interrupts routed to the TSC (3 for H3, M3-W and M3-N) 24- interrupts : interrupts routed to the TSC (3 for H3, M3-W, M3-N,
25 and V3H)
23- power-domain : Must contain a reference to the power domain. This 26- power-domain : Must contain a reference to the power domain. This
24 property is mandatory if the thermal sensor instance 27 property is mandatory if the thermal sensor instance
25 is part of a controllable power domain. 28 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 67c563f1b4c4..73e1613d2cb0 100644
--- a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
@@ -4,15 +4,17 @@ 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 D3. 7 fallback except R-Car V3M/D3.
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-r8a7779" (R-Car H1) 12 - "renesas,thermal-r8a7779" (R-Car H1)
12 - "renesas,thermal-r8a7790" (R-Car H2) 13 - "renesas,thermal-r8a7790" (R-Car H2)
13 - "renesas,thermal-r8a7791" (R-Car M2-W) 14 - "renesas,thermal-r8a7791" (R-Car M2-W)
14 - "renesas,thermal-r8a7792" (R-Car V2H) 15 - "renesas,thermal-r8a7792" (R-Car V2H)
15 - "renesas,thermal-r8a7793" (R-Car M2-N) 16 - "renesas,thermal-r8a7793" (R-Car M2-N)
17 - "renesas,thermal-r8a77970" (R-Car V3M)
16 - "renesas,thermal-r8a77995" (R-Car D3) 18 - "renesas,thermal-r8a77995" (R-Car D3)
17- reg : Address range of the thermal registers. 19- reg : Address range of the thermal registers.
18 The 1st reg will be recognized as common register 20 The 1st reg will be recognized as common register
@@ -21,7 +23,7 @@ Required properties:
21Option properties: 23Option properties:
22 24
23- interrupts : If present should contain 3 interrupts for 25- interrupts : If present should contain 3 interrupts for
24 R-Car D3 or 1 interrupt otherwise. 26 R-Car V3M/D3 or 1 interrupt otherwise.
25 27
26Example (non interrupt support): 28Example (non interrupt support):
27 29
diff --git a/Documentation/devicetree/bindings/thermal/stm32-thermal.txt b/Documentation/devicetree/bindings/thermal/stm32-thermal.txt
new file mode 100644
index 000000000000..8c0d5a4d8031
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/stm32-thermal.txt
@@ -0,0 +1,61 @@
1Binding for Thermal Sensor for STMicroelectronics STM32 series of SoCs.
2
3On STM32 SoCs, the Digital Temperature Sensor (DTS) is in charge of managing an
4analog block which delivers a frequency depending on the internal SoC's
5temperature. By using a reference frequency, DTS is able to provide a sample
6number which can be translated into a temperature by the user.
7
8DTS provides interrupt notification mechanism by threshold. This mechanism
9offers two temperature trip points: passive and critical. The first is intended
10for passive cooling notification while the second is used for over-temperature
11reset.
12
13Required parameters:
14-------------------
15
16compatible: Should be "st,stm32-thermal"
17reg: This should be the physical base address and length of the
18 sensor's registers.
19clocks: Phandle of the clock used by the thermal sensor.
20 See: Documentation/devicetree/bindings/clock/clock-bindings.txt
21clock-names: Should be "pclk" for register access clock and reference clock.
22 See: Documentation/devicetree/bindings/resource-names.txt
23#thermal-sensor-cells: Should be 0. See ./thermal.txt for a description.
24interrupts: Standard way to define interrupt number.
25
26Example:
27
28 thermal-zones {
29 cpu_thermal: cpu-thermal {
30 polling-delay-passive = <0>;
31 polling-delay = <0>;
32
33 thermal-sensors = <&thermal>;
34
35 trips {
36 cpu_alert1: cpu-alert1 {
37 temperature = <85000>;
38 hysteresis = <0>;
39 type = "passive";
40 };
41
42 cpu-crit: cpu-crit {
43 temperature = <120000>;
44 hysteresis = <0>;
45 type = "critical";
46 };
47 };
48
49 cooling-maps {
50 };
51 };
52 };
53
54 thermal: thermal@50028000 {
55 compatible = "st,stm32-thermal";
56 reg = <0x50028000 0x100>;
57 clocks = <&rcc TMPSENS>;
58 clock-names = "pclk";
59 #thermal-sensor-cells = <0>;
60 interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
61 };
diff --git a/Documentation/devicetree/bindings/thermal/thermal.txt b/Documentation/devicetree/bindings/thermal/thermal.txt
index eb7ee91556a5..ca14ba959e0d 100644
--- a/Documentation/devicetree/bindings/thermal/thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/thermal.txt
@@ -152,7 +152,7 @@ Optional property:
152 Elem size: one cell the sensors listed in the thermal-sensors property. 152 Elem size: one cell the sensors listed in the thermal-sensors property.
153 Elem type: signed Coefficients defaults to 1, in case this property 153 Elem type: signed Coefficients defaults to 1, in case this property
154 is not specified. A simple linear polynomial is used: 154 is not specified. A simple linear polynomial is used:
155 Z = c0 * x0 + c1 + x1 + ... + c(n-1) * x(n-1) + cn. 155 Z = c0 * x0 + c1 * x1 + ... + c(n-1) * x(n-1) + cn.
156 156
157 The coefficients are ordered and they match with sensors 157 The coefficients are ordered and they match with sensors
158 by means of sensor ID. Additional coefficients are 158 by means of sensor ID. Additional coefficients are
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 0e69edc77d18..5422523c03f8 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -432,7 +432,7 @@ source "drivers/thermal/samsung/Kconfig"
432endmenu 432endmenu
433 433
434menu "STMicroelectronics thermal drivers" 434menu "STMicroelectronics thermal drivers"
435depends on ARCH_STI && OF 435depends on (ARCH_STI || ARCH_STM32) && OF
436source "drivers/thermal/st/Kconfig" 436source "drivers/thermal/st/Kconfig"
437endmenu 437endmenu
438 438
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 610344eb3e03..82bb50dc6423 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -53,7 +53,7 @@ obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/
53obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/ 53obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/
54obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o 54obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o
55obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o 55obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o
56obj-$(CONFIG_ST_THERMAL) += st/ 56obj-y += st/
57obj-$(CONFIG_QCOM_TSENS) += qcom/ 57obj-$(CONFIG_QCOM_TSENS) += qcom/
58obj-y += tegra/ 58obj-y += tegra/
59obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o 59obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 2c2f6d93034e..92f67d40f2e9 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -526,8 +526,8 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev,
526 526
527 /* First memory region points towards the status register */ 527 /* First memory region points towards the status register */
528 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 528 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
529 if (IS_ERR(res)) 529 if (!res)
530 return PTR_ERR(res); 530 return -EIO;
531 531
532 /* 532 /*
533 * Edit the resource start address and length to map over all the 533 * Edit the resource start address and length to map over all the
diff --git a/drivers/thermal/da9062-thermal.c b/drivers/thermal/da9062-thermal.c
index dd8dd947b7f0..01b0cb994457 100644
--- a/drivers/thermal/da9062-thermal.c
+++ b/drivers/thermal/da9062-thermal.c
@@ -106,7 +106,7 @@ static void da9062_thermal_poll_on(struct work_struct *work)
106 THERMAL_EVENT_UNSPECIFIED); 106 THERMAL_EVENT_UNSPECIFIED);
107 107
108 delay = msecs_to_jiffies(thermal->zone->passive_delay); 108 delay = msecs_to_jiffies(thermal->zone->passive_delay);
109 schedule_delayed_work(&thermal->work, delay); 109 queue_delayed_work(system_freezable_wq, &thermal->work, delay);
110 return; 110 return;
111 } 111 }
112 112
@@ -125,7 +125,7 @@ static irqreturn_t da9062_thermal_irq_handler(int irq, void *data)
125 struct da9062_thermal *thermal = data; 125 struct da9062_thermal *thermal = data;
126 126
127 disable_irq_nosync(thermal->irq); 127 disable_irq_nosync(thermal->irq);
128 schedule_delayed_work(&thermal->work, 0); 128 queue_delayed_work(system_freezable_wq, &thermal->work, 0);
129 129
130 return IRQ_HANDLED; 130 return IRQ_HANDLED;
131} 131}
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index 761d0559c268..c4111a98f1a7 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -55,25 +55,39 @@
55#define HI3660_TEMP_STEP (205) 55#define HI3660_TEMP_STEP (205)
56#define HI3660_TEMP_LAG (4000) 56#define HI3660_TEMP_LAG (4000)
57 57
58#define HI6220_DEFAULT_SENSOR 2 58#define HI6220_CLUSTER0_SENSOR 2
59#define HI3660_DEFAULT_SENSOR 1 59#define HI6220_CLUSTER1_SENSOR 1
60
61#define HI3660_LITTLE_SENSOR 0
62#define HI3660_BIG_SENSOR 1
63#define HI3660_G3D_SENSOR 2
64#define HI3660_MODEM_SENSOR 3
65
66struct hisi_thermal_data;
60 67
61struct hisi_thermal_sensor { 68struct hisi_thermal_sensor {
69 struct hisi_thermal_data *data;
62 struct thermal_zone_device *tzd; 70 struct thermal_zone_device *tzd;
71 const char *irq_name;
63 uint32_t id; 72 uint32_t id;
64 uint32_t thres_temp; 73 uint32_t thres_temp;
65}; 74};
66 75
76struct hisi_thermal_ops {
77 int (*get_temp)(struct hisi_thermal_sensor *sensor);
78 int (*enable_sensor)(struct hisi_thermal_sensor *sensor);
79 int (*disable_sensor)(struct hisi_thermal_sensor *sensor);
80 int (*irq_handler)(struct hisi_thermal_sensor *sensor);
81 int (*probe)(struct hisi_thermal_data *data);
82};
83
67struct hisi_thermal_data { 84struct hisi_thermal_data {
68 int (*get_temp)(struct hisi_thermal_data *data); 85 const struct hisi_thermal_ops *ops;
69 int (*enable_sensor)(struct hisi_thermal_data *data); 86 struct hisi_thermal_sensor *sensor;
70 int (*disable_sensor)(struct hisi_thermal_data *data);
71 int (*irq_handler)(struct hisi_thermal_data *data);
72 struct platform_device *pdev; 87 struct platform_device *pdev;
73 struct clk *clk; 88 struct clk *clk;
74 struct hisi_thermal_sensor sensor;
75 void __iomem *regs; 89 void __iomem *regs;
76 int irq; 90 int nr_sensors;
77}; 91};
78 92
79/* 93/*
@@ -266,30 +280,40 @@ static inline void hi6220_thermal_hdak_set(void __iomem *addr, int value)
266 (value << 4), addr + HI6220_TEMP0_CFG); 280 (value << 4), addr + HI6220_TEMP0_CFG);
267} 281}
268 282
269static int hi6220_thermal_irq_handler(struct hisi_thermal_data *data) 283static int hi6220_thermal_irq_handler(struct hisi_thermal_sensor *sensor)
270{ 284{
285 struct hisi_thermal_data *data = sensor->data;
286
271 hi6220_thermal_alarm_clear(data->regs, 1); 287 hi6220_thermal_alarm_clear(data->regs, 1);
272 return 0; 288 return 0;
273} 289}
274 290
275static int hi3660_thermal_irq_handler(struct hisi_thermal_data *data) 291static int hi3660_thermal_irq_handler(struct hisi_thermal_sensor *sensor)
276{ 292{
277 hi3660_thermal_alarm_clear(data->regs, data->sensor.id, 1); 293 struct hisi_thermal_data *data = sensor->data;
294
295 hi3660_thermal_alarm_clear(data->regs, sensor->id, 1);
278 return 0; 296 return 0;
279} 297}
280 298
281static int hi6220_thermal_get_temp(struct hisi_thermal_data *data) 299static int hi6220_thermal_get_temp(struct hisi_thermal_sensor *sensor)
282{ 300{
301 struct hisi_thermal_data *data = sensor->data;
302
283 return hi6220_thermal_get_temperature(data->regs); 303 return hi6220_thermal_get_temperature(data->regs);
284} 304}
285 305
286static int hi3660_thermal_get_temp(struct hisi_thermal_data *data) 306static int hi3660_thermal_get_temp(struct hisi_thermal_sensor *sensor)
287{ 307{
288 return hi3660_thermal_get_temperature(data->regs, data->sensor.id); 308 struct hisi_thermal_data *data = sensor->data;
309
310 return hi3660_thermal_get_temperature(data->regs, sensor->id);
289} 311}
290 312
291static int hi6220_thermal_disable_sensor(struct hisi_thermal_data *data) 313static int hi6220_thermal_disable_sensor(struct hisi_thermal_sensor *sensor)
292{ 314{
315 struct hisi_thermal_data *data = sensor->data;
316
293 /* disable sensor module */ 317 /* disable sensor module */
294 hi6220_thermal_enable(data->regs, 0); 318 hi6220_thermal_enable(data->regs, 0);
295 hi6220_thermal_alarm_enable(data->regs, 0); 319 hi6220_thermal_alarm_enable(data->regs, 0);
@@ -300,16 +324,18 @@ static int hi6220_thermal_disable_sensor(struct hisi_thermal_data *data)
300 return 0; 324 return 0;
301} 325}
302 326
303static int hi3660_thermal_disable_sensor(struct hisi_thermal_data *data) 327static int hi3660_thermal_disable_sensor(struct hisi_thermal_sensor *sensor)
304{ 328{
329 struct hisi_thermal_data *data = sensor->data;
330
305 /* disable sensor module */ 331 /* disable sensor module */
306 hi3660_thermal_alarm_enable(data->regs, data->sensor.id, 0); 332 hi3660_thermal_alarm_enable(data->regs, sensor->id, 0);
307 return 0; 333 return 0;
308} 334}
309 335
310static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data) 336static int hi6220_thermal_enable_sensor(struct hisi_thermal_sensor *sensor)
311{ 337{
312 struct hisi_thermal_sensor *sensor = &data->sensor; 338 struct hisi_thermal_data *data = sensor->data;
313 int ret; 339 int ret;
314 340
315 /* enable clock for tsensor */ 341 /* enable clock for tsensor */
@@ -345,10 +371,10 @@ static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data)
345 return 0; 371 return 0;
346} 372}
347 373
348static int hi3660_thermal_enable_sensor(struct hisi_thermal_data *data) 374static int hi3660_thermal_enable_sensor(struct hisi_thermal_sensor *sensor)
349{ 375{
350 unsigned int value; 376 unsigned int value;
351 struct hisi_thermal_sensor *sensor = &data->sensor; 377 struct hisi_thermal_data *data = sensor->data;
352 378
353 /* disable interrupt */ 379 /* disable interrupt */
354 hi3660_thermal_alarm_enable(data->regs, sensor->id, 0); 380 hi3660_thermal_alarm_enable(data->regs, sensor->id, 0);
@@ -371,21 +397,8 @@ static int hi6220_thermal_probe(struct hisi_thermal_data *data)
371{ 397{
372 struct platform_device *pdev = data->pdev; 398 struct platform_device *pdev = data->pdev;
373 struct device *dev = &pdev->dev; 399 struct device *dev = &pdev->dev;
374 struct resource *res;
375 int ret; 400 int ret;
376 401
377 data->get_temp = hi6220_thermal_get_temp;
378 data->enable_sensor = hi6220_thermal_enable_sensor;
379 data->disable_sensor = hi6220_thermal_disable_sensor;
380 data->irq_handler = hi6220_thermal_irq_handler;
381
382 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
383 data->regs = devm_ioremap_resource(dev, res);
384 if (IS_ERR(data->regs)) {
385 dev_err(dev, "failed to get io address\n");
386 return PTR_ERR(data->regs);
387 }
388
389 data->clk = devm_clk_get(dev, "thermal_clk"); 402 data->clk = devm_clk_get(dev, "thermal_clk");
390 if (IS_ERR(data->clk)) { 403 if (IS_ERR(data->clk)) {
391 ret = PTR_ERR(data->clk); 404 ret = PTR_ERR(data->clk);
@@ -394,11 +407,14 @@ static int hi6220_thermal_probe(struct hisi_thermal_data *data)
394 return ret; 407 return ret;
395 } 408 }
396 409
397 data->irq = platform_get_irq(pdev, 0); 410 data->sensor = devm_kzalloc(dev, sizeof(*data->sensor), GFP_KERNEL);
398 if (data->irq < 0) 411 if (!data->sensor)
399 return data->irq; 412 return -ENOMEM;
400 413
401 data->sensor.id = HI6220_DEFAULT_SENSOR; 414 data->sensor[0].id = HI6220_CLUSTER0_SENSOR;
415 data->sensor[0].irq_name = "tsensor_intr";
416 data->sensor[0].data = data;
417 data->nr_sensors = 1;
402 418
403 return 0; 419 return 0;
404} 420}
@@ -407,38 +423,34 @@ static int hi3660_thermal_probe(struct hisi_thermal_data *data)
407{ 423{
408 struct platform_device *pdev = data->pdev; 424 struct platform_device *pdev = data->pdev;
409 struct device *dev = &pdev->dev; 425 struct device *dev = &pdev->dev;
410 struct resource *res;
411 426
412 data->get_temp = hi3660_thermal_get_temp; 427 data->nr_sensors = 2;
413 data->enable_sensor = hi3660_thermal_enable_sensor;
414 data->disable_sensor = hi3660_thermal_disable_sensor;
415 data->irq_handler = hi3660_thermal_irq_handler;
416 428
417 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 429 data->sensor = devm_kzalloc(dev, sizeof(*data->sensor) *
418 data->regs = devm_ioremap_resource(dev, res); 430 data->nr_sensors, GFP_KERNEL);
419 if (IS_ERR(data->regs)) { 431 if (!data->sensor)
420 dev_err(dev, "failed to get io address\n"); 432 return -ENOMEM;
421 return PTR_ERR(data->regs);
422 }
423 433
424 data->irq = platform_get_irq(pdev, 0); 434 data->sensor[0].id = HI3660_BIG_SENSOR;
425 if (data->irq < 0) 435 data->sensor[0].irq_name = "tsensor_a73";
426 return data->irq; 436 data->sensor[0].data = data;
427 437
428 data->sensor.id = HI3660_DEFAULT_SENSOR; 438 data->sensor[1].id = HI3660_LITTLE_SENSOR;
439 data->sensor[1].irq_name = "tsensor_a53";
440 data->sensor[1].data = data;
429 441
430 return 0; 442 return 0;
431} 443}
432 444
433static int hisi_thermal_get_temp(void *__data, int *temp) 445static int hisi_thermal_get_temp(void *__data, int *temp)
434{ 446{
435 struct hisi_thermal_data *data = __data; 447 struct hisi_thermal_sensor *sensor = __data;
436 struct hisi_thermal_sensor *sensor = &data->sensor; 448 struct hisi_thermal_data *data = sensor->data;
437 449
438 *temp = data->get_temp(data); 450 *temp = data->ops->get_temp(sensor);
439 451
440 dev_dbg(&data->pdev->dev, "id=%d, temp=%d, thres=%d\n", 452 dev_dbg(&data->pdev->dev, "tzd=%p, id=%d, temp=%d, thres=%d\n",
441 sensor->id, *temp, sensor->thres_temp); 453 sensor->tzd, sensor->id, *temp, sensor->thres_temp);
442 454
443 return 0; 455 return 0;
444} 456}
@@ -449,38 +461,39 @@ static const struct thermal_zone_of_device_ops hisi_of_thermal_ops = {
449 461
450static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev) 462static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev)
451{ 463{
452 struct hisi_thermal_data *data = dev; 464 struct hisi_thermal_sensor *sensor = dev;
453 struct hisi_thermal_sensor *sensor = &data->sensor; 465 struct hisi_thermal_data *data = sensor->data;
454 int temp = 0; 466 int temp = 0;
455 467
456 data->irq_handler(data); 468 data->ops->irq_handler(sensor);
457 469
458 hisi_thermal_get_temp(data, &temp); 470 hisi_thermal_get_temp(sensor, &temp);
459 471
460 if (temp >= sensor->thres_temp) { 472 if (temp >= sensor->thres_temp) {
461 dev_crit(&data->pdev->dev, "THERMAL ALARM: %d > %d\n", 473 dev_crit(&data->pdev->dev,
462 temp, sensor->thres_temp); 474 "sensor <%d> THERMAL ALARM: %d > %d\n",
475 sensor->id, temp, sensor->thres_temp);
463 476
464 thermal_zone_device_update(data->sensor.tzd, 477 thermal_zone_device_update(sensor->tzd,
465 THERMAL_EVENT_UNSPECIFIED); 478 THERMAL_EVENT_UNSPECIFIED);
466 479
467 } else { 480 } else {
468 dev_crit(&data->pdev->dev, "THERMAL ALARM stopped: %d < %d\n", 481 dev_crit(&data->pdev->dev,
469 temp, sensor->thres_temp); 482 "sensor <%d> THERMAL ALARM stopped: %d < %d\n",
483 sensor->id, temp, sensor->thres_temp);
470 } 484 }
471 485
472 return IRQ_HANDLED; 486 return IRQ_HANDLED;
473} 487}
474 488
475static int hisi_thermal_register_sensor(struct platform_device *pdev, 489static int hisi_thermal_register_sensor(struct platform_device *pdev,
476 struct hisi_thermal_data *data,
477 struct hisi_thermal_sensor *sensor) 490 struct hisi_thermal_sensor *sensor)
478{ 491{
479 int ret, i; 492 int ret, i;
480 const struct thermal_trip *trip; 493 const struct thermal_trip *trip;
481 494
482 sensor->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 495 sensor->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev,
483 sensor->id, data, 496 sensor->id, sensor,
484 &hisi_of_thermal_ops); 497 &hisi_of_thermal_ops);
485 if (IS_ERR(sensor->tzd)) { 498 if (IS_ERR(sensor->tzd)) {
486 ret = PTR_ERR(sensor->tzd); 499 ret = PTR_ERR(sensor->tzd);
@@ -502,14 +515,30 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
502 return 0; 515 return 0;
503} 516}
504 517
518static const struct hisi_thermal_ops hi6220_ops = {
519 .get_temp = hi6220_thermal_get_temp,
520 .enable_sensor = hi6220_thermal_enable_sensor,
521 .disable_sensor = hi6220_thermal_disable_sensor,
522 .irq_handler = hi6220_thermal_irq_handler,
523 .probe = hi6220_thermal_probe,
524};
525
526static const struct hisi_thermal_ops hi3660_ops = {
527 .get_temp = hi3660_thermal_get_temp,
528 .enable_sensor = hi3660_thermal_enable_sensor,
529 .disable_sensor = hi3660_thermal_disable_sensor,
530 .irq_handler = hi3660_thermal_irq_handler,
531 .probe = hi3660_thermal_probe,
532};
533
505static const struct of_device_id of_hisi_thermal_match[] = { 534static const struct of_device_id of_hisi_thermal_match[] = {
506 { 535 {
507 .compatible = "hisilicon,tsensor", 536 .compatible = "hisilicon,tsensor",
508 .data = hi6220_thermal_probe 537 .data = &hi6220_ops,
509 }, 538 },
510 { 539 {
511 .compatible = "hisilicon,hi3660-tsensor", 540 .compatible = "hisilicon,hi3660-tsensor",
512 .data = hi3660_thermal_probe 541 .data = &hi3660_ops,
513 }, 542 },
514 { /* end */ } 543 { /* end */ }
515}; 544};
@@ -527,9 +556,9 @@ static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor,
527static int hisi_thermal_probe(struct platform_device *pdev) 556static int hisi_thermal_probe(struct platform_device *pdev)
528{ 557{
529 struct hisi_thermal_data *data; 558 struct hisi_thermal_data *data;
530 int (*platform_probe)(struct hisi_thermal_data *);
531 struct device *dev = &pdev->dev; 559 struct device *dev = &pdev->dev;
532 int ret; 560 struct resource *res;
561 int i, ret;
533 562
534 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 563 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
535 if (!data) 564 if (!data)
@@ -537,41 +566,50 @@ static int hisi_thermal_probe(struct platform_device *pdev)
537 566
538 data->pdev = pdev; 567 data->pdev = pdev;
539 platform_set_drvdata(pdev, data); 568 platform_set_drvdata(pdev, data);
569 data->ops = of_device_get_match_data(dev);
540 570
541 platform_probe = of_device_get_match_data(dev); 571 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
542 if (!platform_probe) { 572 data->regs = devm_ioremap_resource(dev, res);
543 dev_err(dev, "failed to get probe func\n"); 573 if (IS_ERR(data->regs)) {
544 return -EINVAL; 574 dev_err(dev, "failed to get io address\n");
575 return PTR_ERR(data->regs);
545 } 576 }
546 577
547 ret = platform_probe(data); 578 ret = data->ops->probe(data);
548 if (ret) 579 if (ret)
549 return ret; 580 return ret;
550 581
551 ret = hisi_thermal_register_sensor(pdev, data, 582 for (i = 0; i < data->nr_sensors; i++) {
552 &data->sensor); 583 struct hisi_thermal_sensor *sensor = &data->sensor[i];
553 if (ret) {
554 dev_err(dev, "failed to register thermal sensor: %d\n", ret);
555 return ret;
556 }
557 584
558 ret = data->enable_sensor(data); 585 ret = hisi_thermal_register_sensor(pdev, sensor);
559 if (ret) { 586 if (ret) {
560 dev_err(dev, "Failed to setup the sensor: %d\n", ret); 587 dev_err(dev, "failed to register thermal sensor: %d\n",
561 return ret; 588 ret);
562 } 589 return ret;
590 }
591
592 ret = platform_get_irq_byname(pdev, sensor->irq_name);
593 if (ret < 0)
594 return ret;
563 595
564 if (data->irq) { 596 ret = devm_request_threaded_irq(dev, ret, NULL,
565 ret = devm_request_threaded_irq(dev, data->irq, NULL, 597 hisi_thermal_alarm_irq_thread,
566 hisi_thermal_alarm_irq_thread, 598 IRQF_ONESHOT, sensor->irq_name,
567 IRQF_ONESHOT, "hisi_thermal", data); 599 sensor);
568 if (ret < 0) { 600 if (ret < 0) {
569 dev_err(dev, "failed to request alarm irq: %d\n", ret); 601 dev_err(dev, "Failed to request alarm irq: %d\n", ret);
570 return ret; 602 return ret;
571 } 603 }
572 }
573 604
574 hisi_thermal_toggle_sensor(&data->sensor, true); 605 ret = data->ops->enable_sensor(sensor);
606 if (ret) {
607 dev_err(dev, "Failed to setup the sensor: %d\n", ret);
608 return ret;
609 }
610
611 hisi_thermal_toggle_sensor(sensor, true);
612 }
575 613
576 return 0; 614 return 0;
577} 615}
@@ -579,11 +617,14 @@ static int hisi_thermal_probe(struct platform_device *pdev)
579static int hisi_thermal_remove(struct platform_device *pdev) 617static int hisi_thermal_remove(struct platform_device *pdev)
580{ 618{
581 struct hisi_thermal_data *data = platform_get_drvdata(pdev); 619 struct hisi_thermal_data *data = platform_get_drvdata(pdev);
582 struct hisi_thermal_sensor *sensor = &data->sensor; 620 int i;
583 621
584 hisi_thermal_toggle_sensor(sensor, false); 622 for (i = 0; i < data->nr_sensors; i++) {
623 struct hisi_thermal_sensor *sensor = &data->sensor[i];
585 624
586 data->disable_sensor(data); 625 hisi_thermal_toggle_sensor(sensor, false);
626 data->ops->disable_sensor(sensor);
627 }
587 628
588 return 0; 629 return 0;
589} 630}
@@ -592,8 +633,10 @@ static int hisi_thermal_remove(struct platform_device *pdev)
592static int hisi_thermal_suspend(struct device *dev) 633static int hisi_thermal_suspend(struct device *dev)
593{ 634{
594 struct hisi_thermal_data *data = dev_get_drvdata(dev); 635 struct hisi_thermal_data *data = dev_get_drvdata(dev);
636 int i;
595 637
596 data->disable_sensor(data); 638 for (i = 0; i < data->nr_sensors; i++)
639 data->ops->disable_sensor(&data->sensor[i]);
597 640
598 return 0; 641 return 0;
599} 642}
@@ -601,8 +644,12 @@ static int hisi_thermal_suspend(struct device *dev)
601static int hisi_thermal_resume(struct device *dev) 644static int hisi_thermal_resume(struct device *dev)
602{ 645{
603 struct hisi_thermal_data *data = dev_get_drvdata(dev); 646 struct hisi_thermal_data *data = dev_get_drvdata(dev);
647 int i, ret = 0;
648
649 for (i = 0; i < data->nr_sensors; i++)
650 ret |= data->ops->enable_sensor(&data->sensor[i]);
604 651
605 return data->enable_sensor(data); 652 return ret;
606} 653}
607#endif 654#endif
608 655
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index aa452acb60b6..15661549eb67 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -725,7 +725,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
725 } else { 725 } else {
726 ret = imx_init_from_tempmon_data(pdev); 726 ret = imx_init_from_tempmon_data(pdev);
727 if (ret) { 727 if (ret) {
728 dev_err(&pdev->dev, "failed to init from from fsl,tempmon-data\n"); 728 dev_err(&pdev->dev, "failed to init from fsl,tempmon-data\n");
729 return ret; 729 return ret;
730 } 730 }
731 } 731 }
@@ -762,9 +762,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
762 if (ret != -EPROBE_DEFER) 762 if (ret != -EPROBE_DEFER)
763 dev_err(&pdev->dev, 763 dev_err(&pdev->dev,
764 "failed to get thermal clk: %d\n", ret); 764 "failed to get thermal clk: %d\n", ret);
765 cpufreq_cooling_unregister(data->cdev); 765 goto cpufreq_put;
766 cpufreq_cpu_put(data->policy);
767 return ret;
768 } 766 }
769 767
770 /* 768 /*
@@ -777,9 +775,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
777 ret = clk_prepare_enable(data->thermal_clk); 775 ret = clk_prepare_enable(data->thermal_clk);
778 if (ret) { 776 if (ret) {
779 dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret); 777 dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
780 cpufreq_cooling_unregister(data->cdev); 778 goto cpufreq_put;
781 cpufreq_cpu_put(data->policy);
782 return ret;
783 } 779 }
784 780
785 data->tz = thermal_zone_device_register("imx_thermal_zone", 781 data->tz = thermal_zone_device_register("imx_thermal_zone",
@@ -792,10 +788,7 @@ static int imx_thermal_probe(struct platform_device *pdev)
792 ret = PTR_ERR(data->tz); 788 ret = PTR_ERR(data->tz);
793 dev_err(&pdev->dev, 789 dev_err(&pdev->dev,
794 "failed to register thermal zone device %d\n", ret); 790 "failed to register thermal zone device %d\n", ret);
795 clk_disable_unprepare(data->thermal_clk); 791 goto clk_disable;
796 cpufreq_cooling_unregister(data->cdev);
797 cpufreq_cpu_put(data->policy);
798 return ret;
799 } 792 }
800 793
801 dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC" 794 dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC"
@@ -827,14 +820,20 @@ static int imx_thermal_probe(struct platform_device *pdev)
827 0, "imx_thermal", data); 820 0, "imx_thermal", data);
828 if (ret < 0) { 821 if (ret < 0) {
829 dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret); 822 dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
830 clk_disable_unprepare(data->thermal_clk); 823 goto thermal_zone_unregister;
831 thermal_zone_device_unregister(data->tz);
832 cpufreq_cooling_unregister(data->cdev);
833 cpufreq_cpu_put(data->policy);
834 return ret;
835 } 824 }
836 825
837 return 0; 826 return 0;
827
828thermal_zone_unregister:
829 thermal_zone_device_unregister(data->tz);
830clk_disable:
831 clk_disable_unprepare(data->thermal_clk);
832cpufreq_put:
833 cpufreq_cooling_unregister(data->cdev);
834 cpufreq_cpu_put(data->policy);
835
836 return ret;
838} 837}
839 838
840static int imx_thermal_remove(struct platform_device *pdev) 839static int imx_thermal_remove(struct platform_device *pdev)
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index 4f2816559205..4bfdb4a1e47d 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -19,23 +19,34 @@
19/*** Private data structures to represent thermal device tree data ***/ 19/*** Private data structures to represent thermal device tree data ***/
20 20
21/** 21/**
22 * struct __thermal_bind_param - a match between trip and cooling device 22 * struct __thermal_cooling_bind_param - a cooling device for a trip point
23 * @cooling_device: a pointer to identify the referred cooling device 23 * @cooling_device: a pointer to identify the referred cooling device
24 * @trip_id: the trip point index
25 * @usage: the percentage (from 0 to 100) of cooling contribution
26 * @min: minimum cooling state used at this trip point 24 * @min: minimum cooling state used at this trip point
27 * @max: maximum cooling state used at this trip point 25 * @max: maximum cooling state used at this trip point
28 */ 26 */
29 27
30struct __thermal_bind_params { 28struct __thermal_cooling_bind_param {
31 struct device_node *cooling_device; 29 struct device_node *cooling_device;
32 unsigned int trip_id;
33 unsigned int usage;
34 unsigned long min; 30 unsigned long min;
35 unsigned long max; 31 unsigned long max;
36}; 32};
37 33
38/** 34/**
35 * struct __thermal_bind_param - a match between trip and cooling device
36 * @tcbp: a pointer to an array of cooling devices
37 * @count: number of elements in array
38 * @trip_id: the trip point index
39 * @usage: the percentage (from 0 to 100) of cooling contribution
40 */
41
42struct __thermal_bind_params {
43 struct __thermal_cooling_bind_param *tcbp;
44 unsigned int count;
45 unsigned int trip_id;
46 unsigned int usage;
47};
48
49/**
39 * struct __thermal_zone - internal representation of a thermal zone 50 * struct __thermal_zone - internal representation of a thermal zone
40 * @mode: current thermal zone device mode (enabled/disabled) 51 * @mode: current thermal zone device mode (enabled/disabled)
41 * @passive_delay: polling interval while passive cooling is activated 52 * @passive_delay: polling interval while passive cooling is activated
@@ -192,25 +203,31 @@ static int of_thermal_bind(struct thermal_zone_device *thermal,
192 struct thermal_cooling_device *cdev) 203 struct thermal_cooling_device *cdev)
193{ 204{
194 struct __thermal_zone *data = thermal->devdata; 205 struct __thermal_zone *data = thermal->devdata;
195 int i; 206 struct __thermal_bind_params *tbp;
207 struct __thermal_cooling_bind_param *tcbp;
208 int i, j;
196 209
197 if (!data || IS_ERR(data)) 210 if (!data || IS_ERR(data))
198 return -ENODEV; 211 return -ENODEV;
199 212
200 /* find where to bind */ 213 /* find where to bind */
201 for (i = 0; i < data->num_tbps; i++) { 214 for (i = 0; i < data->num_tbps; i++) {
202 struct __thermal_bind_params *tbp = data->tbps + i; 215 tbp = data->tbps + i;
203 216
204 if (tbp->cooling_device == cdev->np) { 217 for (j = 0; j < tbp->count; j++) {
205 int ret; 218 tcbp = tbp->tcbp + j;
206 219
207 ret = thermal_zone_bind_cooling_device(thermal, 220 if (tcbp->cooling_device == cdev->np) {
221 int ret;
222
223 ret = thermal_zone_bind_cooling_device(thermal,
208 tbp->trip_id, cdev, 224 tbp->trip_id, cdev,
209 tbp->max, 225 tcbp->max,
210 tbp->min, 226 tcbp->min,
211 tbp->usage); 227 tbp->usage);
212 if (ret) 228 if (ret)
213 return ret; 229 return ret;
230 }
214 } 231 }
215 } 232 }
216 233
@@ -221,22 +238,28 @@ static int of_thermal_unbind(struct thermal_zone_device *thermal,
221 struct thermal_cooling_device *cdev) 238 struct thermal_cooling_device *cdev)
222{ 239{
223 struct __thermal_zone *data = thermal->devdata; 240 struct __thermal_zone *data = thermal->devdata;
224 int i; 241 struct __thermal_bind_params *tbp;
242 struct __thermal_cooling_bind_param *tcbp;
243 int i, j;
225 244
226 if (!data || IS_ERR(data)) 245 if (!data || IS_ERR(data))
227 return -ENODEV; 246 return -ENODEV;
228 247
229 /* find where to unbind */ 248 /* find where to unbind */
230 for (i = 0; i < data->num_tbps; i++) { 249 for (i = 0; i < data->num_tbps; i++) {
231 struct __thermal_bind_params *tbp = data->tbps + i; 250 tbp = data->tbps + i;
251
252 for (j = 0; j < tbp->count; j++) {
253 tcbp = tbp->tcbp + j;
232 254
233 if (tbp->cooling_device == cdev->np) { 255 if (tcbp->cooling_device == cdev->np) {
234 int ret; 256 int ret;
235 257
236 ret = thermal_zone_unbind_cooling_device(thermal, 258 ret = thermal_zone_unbind_cooling_device(thermal,
237 tbp->trip_id, cdev); 259 tbp->trip_id, cdev);
238 if (ret) 260 if (ret)
239 return ret; 261 return ret;
262 }
240 } 263 }
241 } 264 }
242 265
@@ -486,8 +509,8 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
486 if (sensor_specs.args_count >= 1) { 509 if (sensor_specs.args_count >= 1) {
487 id = sensor_specs.args[0]; 510 id = sensor_specs.args[0];
488 WARN(sensor_specs.args_count > 1, 511 WARN(sensor_specs.args_count > 1,
489 "%s: too many cells in sensor specifier %d\n", 512 "%pOFn: too many cells in sensor specifier %d\n",
490 sensor_specs.np->name, sensor_specs.args_count); 513 sensor_specs.np, sensor_specs.args_count);
491 } else { 514 } else {
492 id = 0; 515 id = 0;
493 } 516 }
@@ -655,8 +678,9 @@ static int thermal_of_populate_bind_params(struct device_node *np,
655 int ntrips) 678 int ntrips)
656{ 679{
657 struct of_phandle_args cooling_spec; 680 struct of_phandle_args cooling_spec;
681 struct __thermal_cooling_bind_param *__tcbp;
658 struct device_node *trip; 682 struct device_node *trip;
659 int ret, i; 683 int ret, i, count;
660 u32 prop; 684 u32 prop;
661 685
662 /* Default weight. Usage is optional */ 686 /* Default weight. Usage is optional */
@@ -683,20 +707,44 @@ static int thermal_of_populate_bind_params(struct device_node *np,
683 goto end; 707 goto end;
684 } 708 }
685 709
686 ret = of_parse_phandle_with_args(np, "cooling-device", "#cooling-cells", 710 count = of_count_phandle_with_args(np, "cooling-device",
687 0, &cooling_spec); 711 "#cooling-cells");
688 if (ret < 0) { 712 if (!count) {
689 pr_err("missing cooling_device property\n"); 713 pr_err("Add a cooling_device property with at least one device\n");
690 goto end; 714 goto end;
691 } 715 }
692 __tbp->cooling_device = cooling_spec.np; 716
693 if (cooling_spec.args_count >= 2) { /* at least min and max */ 717 __tcbp = kcalloc(count, sizeof(*__tcbp), GFP_KERNEL);
694 __tbp->min = cooling_spec.args[0]; 718 if (!__tcbp)
695 __tbp->max = cooling_spec.args[1]; 719 goto end;
696 } else { 720
697 pr_err("wrong reference to cooling device, missing limits\n"); 721 for (i = 0; i < count; i++) {
722 ret = of_parse_phandle_with_args(np, "cooling-device",
723 "#cooling-cells", i, &cooling_spec);
724 if (ret < 0) {
725 pr_err("Invalid cooling-device entry\n");
726 goto free_tcbp;
727 }
728
729 __tcbp[i].cooling_device = cooling_spec.np;
730
731 if (cooling_spec.args_count >= 2) { /* at least min and max */
732 __tcbp[i].min = cooling_spec.args[0];
733 __tcbp[i].max = cooling_spec.args[1];
734 } else {
735 pr_err("wrong reference to cooling device, missing limits\n");
736 }
698 } 737 }
699 738
739 __tbp->tcbp = __tcbp;
740 __tbp->count = count;
741
742 goto end;
743
744free_tcbp:
745 for (i = i - 1; i >= 0; i--)
746 of_node_put(__tcbp[i].cooling_device);
747 kfree(__tcbp);
700end: 748end:
701 of_node_put(trip); 749 of_node_put(trip);
702 750
@@ -903,8 +951,16 @@ finish:
903 return tz; 951 return tz;
904 952
905free_tbps: 953free_tbps:
906 for (i = i - 1; i >= 0; i--) 954 for (i = i - 1; i >= 0; i--) {
907 of_node_put(tz->tbps[i].cooling_device); 955 struct __thermal_bind_params *tbp = tz->tbps + i;
956 int j;
957
958 for (j = 0; j < tbp->count; j++)
959 of_node_put(tbp->tcbp[j].cooling_device);
960
961 kfree(tbp->tcbp);
962 }
963
908 kfree(tz->tbps); 964 kfree(tz->tbps);
909free_trips: 965free_trips:
910 for (i = 0; i < tz->ntrips; i++) 966 for (i = 0; i < tz->ntrips; i++)
@@ -920,10 +976,18 @@ free_tz:
920 976
921static inline void of_thermal_free_zone(struct __thermal_zone *tz) 977static inline void of_thermal_free_zone(struct __thermal_zone *tz)
922{ 978{
923 int i; 979 struct __thermal_bind_params *tbp;
980 int i, j;
981
982 for (i = 0; i < tz->num_tbps; i++) {
983 tbp = tz->tbps + i;
984
985 for (j = 0; j < tbp->count; j++)
986 of_node_put(tbp->tcbp[j].cooling_device);
987
988 kfree(tbp->tcbp);
989 }
924 990
925 for (i = 0; i < tz->num_tbps; i++)
926 of_node_put(tz->tbps[i].cooling_device);
927 kfree(tz->tbps); 991 kfree(tz->tbps);
928 for (i = 0; i < tz->ntrips; i++) 992 for (i = 0; i < tz->ntrips; i++)
929 of_node_put(tz->trips[i].np); 993 of_node_put(tz->trips[i].np);
@@ -963,8 +1027,8 @@ int __init of_parse_thermal_zones(void)
963 1027
964 tz = thermal_of_build_thermal_zone(child); 1028 tz = thermal_of_build_thermal_zone(child);
965 if (IS_ERR(tz)) { 1029 if (IS_ERR(tz)) {
966 pr_err("failed to build thermal zone %s: %ld\n", 1030 pr_err("failed to build thermal zone %pOFn: %ld\n",
967 child->name, 1031 child,
968 PTR_ERR(tz)); 1032 PTR_ERR(tz));
969 continue; 1033 continue;
970 } 1034 }
@@ -998,7 +1062,7 @@ int __init of_parse_thermal_zones(void)
998 tz->passive_delay, 1062 tz->passive_delay,
999 tz->polling_delay); 1063 tz->polling_delay);
1000 if (IS_ERR(zone)) { 1064 if (IS_ERR(zone)) {
1001 pr_err("Failed to build %s zone %ld\n", child->name, 1065 pr_err("Failed to build %pOFn zone %ld\n", child,
1002 PTR_ERR(zone)); 1066 PTR_ERR(zone));
1003 kfree(tzp); 1067 kfree(tzp);
1004 kfree(ops); 1068 kfree(ops);
diff --git a/drivers/thermal/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom-spmi-temp-alarm.c
index ad4f3a8d6560..b2d5d5bf4a9b 100644
--- a/drivers/thermal/qcom-spmi-temp-alarm.c
+++ b/drivers/thermal/qcom-spmi-temp-alarm.c
@@ -23,6 +23,8 @@
23#include <linux/regmap.h> 23#include <linux/regmap.h>
24#include <linux/thermal.h> 24#include <linux/thermal.h>
25 25
26#include "thermal_core.h"
27
26#define QPNP_TM_REG_TYPE 0x04 28#define QPNP_TM_REG_TYPE 0x04
27#define QPNP_TM_REG_SUBTYPE 0x05 29#define QPNP_TM_REG_SUBTYPE 0x05
28#define QPNP_TM_REG_STATUS 0x08 30#define QPNP_TM_REG_STATUS 0x08
@@ -37,9 +39,11 @@
37#define STATUS_GEN2_STATE_MASK GENMASK(6, 4) 39#define STATUS_GEN2_STATE_MASK GENMASK(6, 4)
38#define STATUS_GEN2_STATE_SHIFT 4 40#define STATUS_GEN2_STATE_SHIFT 4
39 41
40#define SHUTDOWN_CTRL1_OVERRIDE_MASK GENMASK(7, 6) 42#define SHUTDOWN_CTRL1_OVERRIDE_S2 BIT(6)
41#define SHUTDOWN_CTRL1_THRESHOLD_MASK GENMASK(1, 0) 43#define SHUTDOWN_CTRL1_THRESHOLD_MASK GENMASK(1, 0)
42 44
45#define SHUTDOWN_CTRL1_RATE_25HZ BIT(3)
46
43#define ALARM_CTRL_FORCE_ENABLE BIT(7) 47#define ALARM_CTRL_FORCE_ENABLE BIT(7)
44 48
45/* 49/*
@@ -56,12 +60,19 @@
56#define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */ 60#define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */
57 61
58#define THRESH_MIN 0 62#define THRESH_MIN 0
63#define THRESH_MAX 3
64
65/* Stage 2 Threshold Min: 125 C */
66#define STAGE2_THRESHOLD_MIN 125000
67/* Stage 2 Threshold Max: 140 C */
68#define STAGE2_THRESHOLD_MAX 140000
59 69
60/* Temperature in Milli Celsius reported during stage 0 if no ADC is present */ 70/* Temperature in Milli Celsius reported during stage 0 if no ADC is present */
61#define DEFAULT_TEMP 37000 71#define DEFAULT_TEMP 37000
62 72
63struct qpnp_tm_chip { 73struct qpnp_tm_chip {
64 struct regmap *map; 74 struct regmap *map;
75 struct device *dev;
65 struct thermal_zone_device *tz_dev; 76 struct thermal_zone_device *tz_dev;
66 unsigned int subtype; 77 unsigned int subtype;
67 long temp; 78 long temp;
@@ -69,6 +80,10 @@ struct qpnp_tm_chip {
69 unsigned int stage; 80 unsigned int stage;
70 unsigned int prev_stage; 81 unsigned int prev_stage;
71 unsigned int base; 82 unsigned int base;
83 /* protects .thresh, .stage and chip registers */
84 struct mutex lock;
85 bool initialized;
86
72 struct iio_channel *adc; 87 struct iio_channel *adc;
73}; 88};
74 89
@@ -125,6 +140,8 @@ static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip)
125 unsigned int stage, stage_new, stage_old; 140 unsigned int stage, stage_new, stage_old;
126 int ret; 141 int ret;
127 142
143 WARN_ON(!mutex_is_locked(&chip->lock));
144
128 ret = qpnp_tm_get_temp_stage(chip); 145 ret = qpnp_tm_get_temp_stage(chip);
129 if (ret < 0) 146 if (ret < 0)
130 return ret; 147 return ret;
@@ -163,8 +180,15 @@ static int qpnp_tm_get_temp(void *data, int *temp)
163 if (!temp) 180 if (!temp)
164 return -EINVAL; 181 return -EINVAL;
165 182
183 if (!chip->initialized) {
184 *temp = DEFAULT_TEMP;
185 return 0;
186 }
187
166 if (!chip->adc) { 188 if (!chip->adc) {
189 mutex_lock(&chip->lock);
167 ret = qpnp_tm_update_temp_no_adc(chip); 190 ret = qpnp_tm_update_temp_no_adc(chip);
191 mutex_unlock(&chip->lock);
168 if (ret < 0) 192 if (ret < 0)
169 return ret; 193 return ret;
170 } else { 194 } else {
@@ -180,8 +204,72 @@ static int qpnp_tm_get_temp(void *data, int *temp)
180 return 0; 204 return 0;
181} 205}
182 206
207static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
208 int temp)
209{
210 u8 reg;
211 bool disable_s2_shutdown = false;
212
213 WARN_ON(!mutex_is_locked(&chip->lock));
214
215 /*
216 * Default: S2 and S3 shutdown enabled, thresholds at
217 * 105C/125C/145C, monitoring at 25Hz
218 */
219 reg = SHUTDOWN_CTRL1_RATE_25HZ;
220
221 if (temp == THERMAL_TEMP_INVALID ||
222 temp < STAGE2_THRESHOLD_MIN) {
223 chip->thresh = THRESH_MIN;
224 goto skip;
225 }
226
227 if (temp <= STAGE2_THRESHOLD_MAX) {
228 chip->thresh = THRESH_MAX -
229 ((STAGE2_THRESHOLD_MAX - temp) /
230 TEMP_THRESH_STEP);
231 disable_s2_shutdown = true;
232 } else {
233 chip->thresh = THRESH_MAX;
234
235 if (chip->adc)
236 disable_s2_shutdown = true;
237 else
238 dev_warn(chip->dev,
239 "No ADC is configured and critical temperature is above the maximum stage 2 threshold of 140 C! Configuring stage 2 shutdown at 140 C.\n");
240 }
241
242skip:
243 reg |= chip->thresh;
244 if (disable_s2_shutdown)
245 reg |= SHUTDOWN_CTRL1_OVERRIDE_S2;
246
247 return qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg);
248}
249
250static int qpnp_tm_set_trip_temp(void *data, int trip, int temp)
251{
252 struct qpnp_tm_chip *chip = data;
253 const struct thermal_trip *trip_points;
254 int ret;
255
256 trip_points = of_thermal_get_trip_points(chip->tz_dev);
257 if (!trip_points)
258 return -EINVAL;
259
260 if (trip_points[trip].type != THERMAL_TRIP_CRITICAL)
261 return 0;
262
263 mutex_lock(&chip->lock);
264 ret = qpnp_tm_update_critical_trip_temp(chip, temp);
265 mutex_unlock(&chip->lock);
266
267 return ret;
268}
269
183static const struct thermal_zone_of_device_ops qpnp_tm_sensor_ops = { 270static const struct thermal_zone_of_device_ops qpnp_tm_sensor_ops = {
184 .get_temp = qpnp_tm_get_temp, 271 .get_temp = qpnp_tm_get_temp,
272 .set_trip_temp = qpnp_tm_set_trip_temp,
185}; 273};
186 274
187static irqreturn_t qpnp_tm_isr(int irq, void *data) 275static irqreturn_t qpnp_tm_isr(int irq, void *data)
@@ -193,6 +281,29 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data)
193 return IRQ_HANDLED; 281 return IRQ_HANDLED;
194} 282}
195 283
284static int qpnp_tm_get_critical_trip_temp(struct qpnp_tm_chip *chip)
285{
286 int ntrips;
287 const struct thermal_trip *trips;
288 int i;
289
290 ntrips = of_thermal_get_ntrips(chip->tz_dev);
291 if (ntrips <= 0)
292 return THERMAL_TEMP_INVALID;
293
294 trips = of_thermal_get_trip_points(chip->tz_dev);
295 if (!trips)
296 return THERMAL_TEMP_INVALID;
297
298 for (i = 0; i < ntrips; i++) {
299 if (of_thermal_is_trip_valid(chip->tz_dev, i) &&
300 trips[i].type == THERMAL_TRIP_CRITICAL)
301 return trips[i].temperature;
302 }
303
304 return THERMAL_TEMP_INVALID;
305}
306
196/* 307/*
197 * This function initializes the internal temp value based on only the 308 * This function initializes the internal temp value based on only the
198 * current thermal stage and threshold. Setup threshold control and 309 * current thermal stage and threshold. Setup threshold control and
@@ -203,17 +314,20 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip)
203 unsigned int stage; 314 unsigned int stage;
204 int ret; 315 int ret;
205 u8 reg = 0; 316 u8 reg = 0;
317 int crit_temp;
318
319 mutex_lock(&chip->lock);
206 320
207 ret = qpnp_tm_read(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, &reg); 321 ret = qpnp_tm_read(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, &reg);
208 if (ret < 0) 322 if (ret < 0)
209 return ret; 323 goto out;
210 324
211 chip->thresh = reg & SHUTDOWN_CTRL1_THRESHOLD_MASK; 325 chip->thresh = reg & SHUTDOWN_CTRL1_THRESHOLD_MASK;
212 chip->temp = DEFAULT_TEMP; 326 chip->temp = DEFAULT_TEMP;
213 327
214 ret = qpnp_tm_get_temp_stage(chip); 328 ret = qpnp_tm_get_temp_stage(chip);
215 if (ret < 0) 329 if (ret < 0)
216 return ret; 330 goto out;
217 chip->stage = ret; 331 chip->stage = ret;
218 332
219 stage = chip->subtype == QPNP_TM_SUBTYPE_GEN1 333 stage = chip->subtype == QPNP_TM_SUBTYPE_GEN1
@@ -224,21 +338,19 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip)
224 (stage - 1) * TEMP_STAGE_STEP + 338 (stage - 1) * TEMP_STAGE_STEP +
225 TEMP_THRESH_MIN; 339 TEMP_THRESH_MIN;
226 340
227 /* 341 crit_temp = qpnp_tm_get_critical_trip_temp(chip);
228 * Set threshold and disable software override of stage 2 and 3 342 ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp);
229 * shutdowns.
230 */
231 chip->thresh = THRESH_MIN;
232 reg &= ~(SHUTDOWN_CTRL1_OVERRIDE_MASK | SHUTDOWN_CTRL1_THRESHOLD_MASK);
233 reg |= chip->thresh & SHUTDOWN_CTRL1_THRESHOLD_MASK;
234 ret = qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg);
235 if (ret < 0) 343 if (ret < 0)
236 return ret; 344 goto out;
237 345
238 /* Enable the thermal alarm PMIC module in always-on mode. */ 346 /* Enable the thermal alarm PMIC module in always-on mode. */
239 reg = ALARM_CTRL_FORCE_ENABLE; 347 reg = ALARM_CTRL_FORCE_ENABLE;
240 ret = qpnp_tm_write(chip, QPNP_TM_REG_ALARM_CTRL, reg); 348 ret = qpnp_tm_write(chip, QPNP_TM_REG_ALARM_CTRL, reg);
241 349
350 chip->initialized = true;
351
352out:
353 mutex_unlock(&chip->lock);
242 return ret; 354 return ret;
243} 355}
244 356
@@ -257,6 +369,9 @@ static int qpnp_tm_probe(struct platform_device *pdev)
257 return -ENOMEM; 369 return -ENOMEM;
258 370
259 dev_set_drvdata(&pdev->dev, chip); 371 dev_set_drvdata(&pdev->dev, chip);
372 chip->dev = &pdev->dev;
373
374 mutex_init(&chip->lock);
260 375
261 chip->map = dev_get_regmap(pdev->dev.parent, NULL); 376 chip->map = dev_get_regmap(pdev->dev.parent, NULL);
262 if (!chip->map) 377 if (!chip->map)
@@ -302,6 +417,18 @@ static int qpnp_tm_probe(struct platform_device *pdev)
302 417
303 chip->subtype = subtype; 418 chip->subtype = subtype;
304 419
420 /*
421 * Register the sensor before initializing the hardware to be able to
422 * read the trip points. get_temp() returns the default temperature
423 * before the hardware initialization is completed.
424 */
425 chip->tz_dev = devm_thermal_zone_of_sensor_register(
426 &pdev->dev, 0, chip, &qpnp_tm_sensor_ops);
427 if (IS_ERR(chip->tz_dev)) {
428 dev_err(&pdev->dev, "failed to register sensor\n");
429 return PTR_ERR(chip->tz_dev);
430 }
431
305 ret = qpnp_tm_init(chip); 432 ret = qpnp_tm_init(chip);
306 if (ret < 0) { 433 if (ret < 0) {
307 dev_err(&pdev->dev, "init failed\n"); 434 dev_err(&pdev->dev, "init failed\n");
@@ -313,12 +440,7 @@ static int qpnp_tm_probe(struct platform_device *pdev)
313 if (ret < 0) 440 if (ret < 0)
314 return ret; 441 return ret;
315 442
316 chip->tz_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, chip, 443 thermal_zone_device_update(chip->tz_dev, THERMAL_EVENT_UNSPECIFIED);
317 &qpnp_tm_sensor_ops);
318 if (IS_ERR(chip->tz_dev)) {
319 dev_err(&pdev->dev, "failed to register sensor\n");
320 return PTR_ERR(chip->tz_dev);
321 }
322 444
323 return 0; 445 return 0;
324} 446}
diff --git a/drivers/thermal/qcom/tsens-8916.c b/drivers/thermal/qcom/tsens-8916.c
index fdf561b8b81d..c6dd620ac029 100644
--- a/drivers/thermal/qcom/tsens-8916.c
+++ b/drivers/thermal/qcom/tsens-8916.c
@@ -1,15 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */ 4 */
14 5
15#include <linux/platform_device.h> 6#include <linux/platform_device.h>
@@ -109,5 +100,6 @@ static const struct tsens_ops ops_8916 = {
109const struct tsens_data data_8916 = { 100const struct tsens_data data_8916 = {
110 .num_sensors = 5, 101 .num_sensors = 5,
111 .ops = &ops_8916, 102 .ops = &ops_8916,
103 .reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 },
112 .hw_ids = (unsigned int []){0, 1, 2, 4, 5 }, 104 .hw_ids = (unsigned int []){0, 1, 2, 4, 5 },
113}; 105};
diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
index 0451277d3a8f..0f0adb302a7b 100644
--- a/drivers/thermal/qcom/tsens-8960.c
+++ b/drivers/thermal/qcom/tsens-8960.c
@@ -1,15 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */ 4 */
14 5
15#include <linux/platform_device.h> 6#include <linux/platform_device.h>
@@ -69,7 +60,7 @@ static int suspend_8960(struct tsens_device *tmdev)
69{ 60{
70 int ret; 61 int ret;
71 unsigned int mask; 62 unsigned int mask;
72 struct regmap *map = tmdev->map; 63 struct regmap *map = tmdev->tm_map;
73 64
74 ret = regmap_read(map, THRESHOLD_ADDR, &tmdev->ctx.threshold); 65 ret = regmap_read(map, THRESHOLD_ADDR, &tmdev->ctx.threshold);
75 if (ret) 66 if (ret)
@@ -94,7 +85,7 @@ static int suspend_8960(struct tsens_device *tmdev)
94static int resume_8960(struct tsens_device *tmdev) 85static int resume_8960(struct tsens_device *tmdev)
95{ 86{
96 int ret; 87 int ret;
97 struct regmap *map = tmdev->map; 88 struct regmap *map = tmdev->tm_map;
98 89
99 ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST); 90 ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
100 if (ret) 91 if (ret)
@@ -126,12 +117,12 @@ static int enable_8960(struct tsens_device *tmdev, int id)
126 int ret; 117 int ret;
127 u32 reg, mask; 118 u32 reg, mask;
128 119
129 ret = regmap_read(tmdev->map, CNTL_ADDR, &reg); 120 ret = regmap_read(tmdev->tm_map, CNTL_ADDR, &reg);
130 if (ret) 121 if (ret)
131 return ret; 122 return ret;
132 123
133 mask = BIT(id + SENSOR0_SHIFT); 124 mask = BIT(id + SENSOR0_SHIFT);
134 ret = regmap_write(tmdev->map, CNTL_ADDR, reg | SW_RST); 125 ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg | SW_RST);
135 if (ret) 126 if (ret)
136 return ret; 127 return ret;
137 128
@@ -140,7 +131,7 @@ static int enable_8960(struct tsens_device *tmdev, int id)
140 else 131 else
141 reg |= mask | SLP_CLK_ENA_8660 | EN; 132 reg |= mask | SLP_CLK_ENA_8660 | EN;
142 133
143 ret = regmap_write(tmdev->map, CNTL_ADDR, reg); 134 ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg);
144 if (ret) 135 if (ret)
145 return ret; 136 return ret;
146 137
@@ -157,7 +148,7 @@ static void disable_8960(struct tsens_device *tmdev)
157 mask <<= SENSOR0_SHIFT; 148 mask <<= SENSOR0_SHIFT;
158 mask |= EN; 149 mask |= EN;
159 150
160 ret = regmap_read(tmdev->map, CNTL_ADDR, &reg_cntl); 151 ret = regmap_read(tmdev->tm_map, CNTL_ADDR, &reg_cntl);
161 if (ret) 152 if (ret)
162 return; 153 return;
163 154
@@ -168,7 +159,7 @@ static void disable_8960(struct tsens_device *tmdev)
168 else 159 else
169 reg_cntl &= ~SLP_CLK_ENA_8660; 160 reg_cntl &= ~SLP_CLK_ENA_8660;
170 161
171 regmap_write(tmdev->map, CNTL_ADDR, reg_cntl); 162 regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl);
172} 163}
173 164
174static int init_8960(struct tsens_device *tmdev) 165static int init_8960(struct tsens_device *tmdev)
@@ -176,8 +167,8 @@ static int init_8960(struct tsens_device *tmdev)
176 int ret, i; 167 int ret, i;
177 u32 reg_cntl; 168 u32 reg_cntl;
178 169
179 tmdev->map = dev_get_regmap(tmdev->dev, NULL); 170 tmdev->tm_map = dev_get_regmap(tmdev->dev, NULL);
180 if (!tmdev->map) 171 if (!tmdev->tm_map)
181 return -ENODEV; 172 return -ENODEV;
182 173
183 /* 174 /*
@@ -193,14 +184,14 @@ static int init_8960(struct tsens_device *tmdev)
193 } 184 }
194 185
195 reg_cntl = SW_RST; 186 reg_cntl = SW_RST;
196 ret = regmap_update_bits(tmdev->map, CNTL_ADDR, SW_RST, reg_cntl); 187 ret = regmap_update_bits(tmdev->tm_map, CNTL_ADDR, SW_RST, reg_cntl);
197 if (ret) 188 if (ret)
198 return ret; 189 return ret;
199 190
200 if (tmdev->num_sensors > 1) { 191 if (tmdev->num_sensors > 1) {
201 reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18); 192 reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
202 reg_cntl &= ~SW_RST; 193 reg_cntl &= ~SW_RST;
203 ret = regmap_update_bits(tmdev->map, CONFIG_ADDR, 194 ret = regmap_update_bits(tmdev->tm_map, CONFIG_ADDR,
204 CONFIG_MASK, CONFIG); 195 CONFIG_MASK, CONFIG);
205 } else { 196 } else {
206 reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16); 197 reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16);
@@ -209,12 +200,12 @@ static int init_8960(struct tsens_device *tmdev)
209 } 200 }
210 201
211 reg_cntl |= GENMASK(tmdev->num_sensors - 1, 0) << SENSOR0_SHIFT; 202 reg_cntl |= GENMASK(tmdev->num_sensors - 1, 0) << SENSOR0_SHIFT;
212 ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl); 203 ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl);
213 if (ret) 204 if (ret)
214 return ret; 205 return ret;
215 206
216 reg_cntl |= EN; 207 reg_cntl |= EN;
217 ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl); 208 ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl);
218 if (ret) 209 if (ret)
219 return ret; 210 return ret;
220 211
@@ -261,12 +252,12 @@ static int get_temp_8960(struct tsens_device *tmdev, int id, int *temp)
261 252
262 timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); 253 timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
263 do { 254 do {
264 ret = regmap_read(tmdev->map, INT_STATUS_ADDR, &trdy); 255 ret = regmap_read(tmdev->tm_map, INT_STATUS_ADDR, &trdy);
265 if (ret) 256 if (ret)
266 return ret; 257 return ret;
267 if (!(trdy & TRDY_MASK)) 258 if (!(trdy & TRDY_MASK))
268 continue; 259 continue;
269 ret = regmap_read(tmdev->map, s->status, &code); 260 ret = regmap_read(tmdev->tm_map, s->status, &code);
270 if (ret) 261 if (ret)
271 return ret; 262 return ret;
272 *temp = code_to_mdegC(code, s); 263 *temp = code_to_mdegC(code, s);
diff --git a/drivers/thermal/qcom/tsens-8974.c b/drivers/thermal/qcom/tsens-8974.c
index 9baf77e8cbe3..3d3fda3d731b 100644
--- a/drivers/thermal/qcom/tsens-8974.c
+++ b/drivers/thermal/qcom/tsens-8974.c
@@ -1,15 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */ 4 */
14 5
15#include <linux/platform_device.h> 6#include <linux/platform_device.h>
@@ -241,4 +232,5 @@ static const struct tsens_ops ops_8974 = {
241const struct tsens_data data_8974 = { 232const struct tsens_data data_8974 = {
242 .num_sensors = 11, 233 .num_sensors = 11,
243 .ops = &ops_8974, 234 .ops = &ops_8974,
235 .reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 },
244}; 236};
diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index 6207d8d92351..3be4be2e0465 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -1,15 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */ 4 */
14 5
15#include <linux/err.h> 6#include <linux/err.h>
@@ -21,7 +12,11 @@
21#include <linux/regmap.h> 12#include <linux/regmap.h>
22#include "tsens.h" 13#include "tsens.h"
23 14
24#define S0_ST_ADDR 0x1030 15/* SROT */
16#define TSENS_EN BIT(0)
17
18/* TM */
19#define STATUS_OFFSET 0x30
25#define SN_ADDR_OFFSET 0x4 20#define SN_ADDR_OFFSET 0x4
26#define SN_ST_TEMP_MASK 0x3ff 21#define SN_ST_TEMP_MASK 0x3ff
27#define CAL_DEGC_PT1 30 22#define CAL_DEGC_PT1 30
@@ -107,8 +102,8 @@ int get_temp_common(struct tsens_device *tmdev, int id, int *temp)
107 unsigned int status_reg; 102 unsigned int status_reg;
108 int last_temp = 0, ret; 103 int last_temp = 0, ret;
109 104
110 status_reg = S0_ST_ADDR + s->hw_id * SN_ADDR_OFFSET; 105 status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * SN_ADDR_OFFSET;
111 ret = regmap_read(tmdev->map, status_reg, &code); 106 ret = regmap_read(tmdev->tm_map, status_reg, &code);
112 if (ret) 107 if (ret)
113 return ret; 108 return ret;
114 last_temp = code & SN_ST_TEMP_MASK; 109 last_temp = code & SN_ST_TEMP_MASK;
@@ -126,29 +121,52 @@ static const struct regmap_config tsens_config = {
126 121
127int __init init_common(struct tsens_device *tmdev) 122int __init init_common(struct tsens_device *tmdev)
128{ 123{
129 void __iomem *base; 124 void __iomem *tm_base, *srot_base;
130 struct resource *res; 125 struct resource *res;
126 u32 code;
127 int ret;
131 struct platform_device *op = of_find_device_by_node(tmdev->dev->of_node); 128 struct platform_device *op = of_find_device_by_node(tmdev->dev->of_node);
129 u16 ctrl_offset = tmdev->reg_offsets[SROT_CTRL_OFFSET];
132 130
133 if (!op) 131 if (!op)
134 return -EINVAL; 132 return -EINVAL;
135 133
136 /* The driver only uses the TM register address space for now */
137 if (op->num_resources > 1) { 134 if (op->num_resources > 1) {
135 /* DT with separate SROT and TM address space */
138 tmdev->tm_offset = 0; 136 tmdev->tm_offset = 0;
137 res = platform_get_resource(op, IORESOURCE_MEM, 1);
138 srot_base = devm_ioremap_resource(&op->dev, res);
139 if (IS_ERR(srot_base))
140 return PTR_ERR(srot_base);
141
142 tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev,
143 srot_base, &tsens_config);
144 if (IS_ERR(tmdev->srot_map))
145 return PTR_ERR(tmdev->srot_map);
146
139 } else { 147 } else {
140 /* old DTs where SROT and TM were in a contiguous 2K block */ 148 /* old DTs where SROT and TM were in a contiguous 2K block */
141 tmdev->tm_offset = 0x1000; 149 tmdev->tm_offset = 0x1000;
142 } 150 }
143 151
144 res = platform_get_resource(op, IORESOURCE_MEM, 0); 152 res = platform_get_resource(op, IORESOURCE_MEM, 0);
145 base = devm_ioremap_resource(&op->dev, res); 153 tm_base = devm_ioremap_resource(&op->dev, res);
146 if (IS_ERR(base)) 154 if (IS_ERR(tm_base))
147 return PTR_ERR(base); 155 return PTR_ERR(tm_base);
148 156
149 tmdev->map = devm_regmap_init_mmio(tmdev->dev, base, &tsens_config); 157 tmdev->tm_map = devm_regmap_init_mmio(tmdev->dev, tm_base, &tsens_config);
150 if (IS_ERR(tmdev->map)) 158 if (IS_ERR(tmdev->tm_map))
151 return PTR_ERR(tmdev->map); 159 return PTR_ERR(tmdev->tm_map);
160
161 if (tmdev->srot_map) {
162 ret = regmap_read(tmdev->srot_map, ctrl_offset, &code);
163 if (ret)
164 return ret;
165 if (!(code & TSENS_EN)) {
166 dev_err(tmdev->dev, "tsens device is not enabled\n");
167 return -ENODEV;
168 }
169 }
152 170
153 return 0; 171 return 0;
154} 172}
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index 44da02f594ac..381a212872bf 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -21,7 +21,7 @@ static int get_temp_tsens_v2(struct tsens_device *tmdev, int id, int *temp)
21 int ret; 21 int ret;
22 22
23 status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * 4; 23 status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * 4;
24 ret = regmap_read(tmdev->map, status_reg, &code); 24 ret = regmap_read(tmdev->tm_map, status_reg, &code);
25 if (ret) 25 if (ret)
26 return ret; 26 return ret;
27 last_temp = code & LAST_TEMP_MASK; 27 last_temp = code & LAST_TEMP_MASK;
@@ -29,7 +29,7 @@ static int get_temp_tsens_v2(struct tsens_device *tmdev, int id, int *temp)
29 goto done; 29 goto done;
30 30
31 /* Try a second time */ 31 /* Try a second time */
32 ret = regmap_read(tmdev->map, status_reg, &code); 32 ret = regmap_read(tmdev->tm_map, status_reg, &code);
33 if (ret) 33 if (ret)
34 return ret; 34 return ret;
35 if (code & STATUS_VALID_BIT) { 35 if (code & STATUS_VALID_BIT) {
@@ -40,7 +40,7 @@ static int get_temp_tsens_v2(struct tsens_device *tmdev, int id, int *temp)
40 } 40 }
41 41
42 /* Try a third/last time */ 42 /* Try a third/last time */
43 ret = regmap_read(tmdev->map, status_reg, &code); 43 ret = regmap_read(tmdev->tm_map, status_reg, &code);
44 if (ret) 44 if (ret)
45 return ret; 45 return ret;
46 if (code & STATUS_VALID_BIT) { 46 if (code & STATUS_VALID_BIT) {
@@ -68,10 +68,12 @@ static const struct tsens_ops ops_generic_v2 = {
68 68
69const struct tsens_data data_tsens_v2 = { 69const struct tsens_data data_tsens_v2 = {
70 .ops = &ops_generic_v2, 70 .ops = &ops_generic_v2,
71 .reg_offsets = { [SROT_CTRL_OFFSET] = 0x4 },
71}; 72};
72 73
73/* Kept around for backward compatibility with old msm8996.dtsi */ 74/* Kept around for backward compatibility with old msm8996.dtsi */
74const struct tsens_data data_8996 = { 75const struct tsens_data data_8996 = {
75 .num_sensors = 13, 76 .num_sensors = 13,
76 .ops = &ops_generic_v2, 77 .ops = &ops_generic_v2,
78 .reg_offsets = { [SROT_CTRL_OFFSET] = 0x4 },
77}; 79};
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index a2c9bfae3d86..f1ec9bbe4717 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -1,15 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */ 4 */
14 5
15#include <linux/err.h> 6#include <linux/err.h>
@@ -89,11 +80,6 @@ static int tsens_register(struct tsens_device *tmdev)
89{ 80{
90 int i; 81 int i;
91 struct thermal_zone_device *tzd; 82 struct thermal_zone_device *tzd;
92 u32 *hw_id, n = tmdev->num_sensors;
93
94 hw_id = devm_kcalloc(tmdev->dev, n, sizeof(u32), GFP_KERNEL);
95 if (!hw_id)
96 return -ENOMEM;
97 83
98 for (i = 0; i < tmdev->num_sensors; i++) { 84 for (i = 0; i < tmdev->num_sensors; i++) {
99 tmdev->sensor[i].tmdev = tmdev; 85 tmdev->sensor[i].tmdev = tmdev;
@@ -158,6 +144,9 @@ static int tsens_probe(struct platform_device *pdev)
158 else 144 else
159 tmdev->sensor[i].hw_id = i; 145 tmdev->sensor[i].hw_id = i;
160 } 146 }
147 for (i = 0; i < REG_ARRAY_SIZE; i++) {
148 tmdev->reg_offsets[i] = data->reg_offsets[i];
149 }
161 150
162 if (!tmdev->ops || !tmdev->ops->init || !tmdev->ops->get_temp) 151 if (!tmdev->ops || !tmdev->ops->init || !tmdev->ops->get_temp)
163 return -EINVAL; 152 return -EINVAL;
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 14331eb45a86..7b7feee5dc46 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -1,15 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */ 4 */
5
13#ifndef __QCOM_TSENS_H__ 6#ifndef __QCOM_TSENS_H__
14#define __QCOM_TSENS_H__ 7#define __QCOM_TSENS_H__
15 8
@@ -55,15 +48,23 @@ struct tsens_ops {
55 int (*get_trend)(struct tsens_device *, int, enum thermal_trend *); 48 int (*get_trend)(struct tsens_device *, int, enum thermal_trend *);
56}; 49};
57 50
51enum reg_list {
52 SROT_CTRL_OFFSET,
53
54 REG_ARRAY_SIZE,
55};
56
58/** 57/**
59 * struct tsens_data - tsens instance specific data 58 * struct tsens_data - tsens instance specific data
60 * @num_sensors: Max number of sensors supported by platform 59 * @num_sensors: Max number of sensors supported by platform
61 * @ops: operations the tsens instance supports 60 * @ops: operations the tsens instance supports
62 * @hw_ids: Subset of sensors ids supported by platform, if not the first n 61 * @hw_ids: Subset of sensors ids supported by platform, if not the first n
62 * @reg_offsets: Register offsets for commonly used registers
63 */ 63 */
64struct tsens_data { 64struct tsens_data {
65 const u32 num_sensors; 65 const u32 num_sensors;
66 const struct tsens_ops *ops; 66 const struct tsens_ops *ops;
67 const u16 reg_offsets[REG_ARRAY_SIZE];
67 unsigned int *hw_ids; 68 unsigned int *hw_ids;
68}; 69};
69 70
@@ -76,8 +77,10 @@ struct tsens_context {
76struct tsens_device { 77struct tsens_device {
77 struct device *dev; 78 struct device *dev;
78 u32 num_sensors; 79 u32 num_sensors;
79 struct regmap *map; 80 struct regmap *tm_map;
81 struct regmap *srot_map;
80 u32 tm_offset; 82 u32 tm_offset;
83 u16 reg_offsets[REG_ARRAY_SIZE];
81 struct tsens_context ctx; 84 struct tsens_context ctx;
82 const struct tsens_ops *ops; 85 const struct tsens_ops *ops;
83 struct tsens_sensor sensor[0]; 86 struct tsens_sensor sensor[0];
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index 450ed66edf58..18c711b19514 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -119,8 +119,8 @@ static int qoriq_tmu_get_sensor_id(void)
119 if (sensor_specs.args_count >= 1) { 119 if (sensor_specs.args_count >= 1) {
120 id = sensor_specs.args[0]; 120 id = sensor_specs.args[0];
121 WARN(sensor_specs.args_count > 1, 121 WARN(sensor_specs.args_count > 1,
122 "%s: too many cells in sensor specifier %d\n", 122 "%pOFn: too many cells in sensor specifier %d\n",
123 sensor_specs.np->name, sensor_specs.args_count); 123 sensor_specs.np, sensor_specs.args_count);
124 } else { 124 } else {
125 id = 0; 125 id = 0;
126 } 126 }
@@ -294,6 +294,7 @@ static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,
294 294
295static const struct of_device_id qoriq_tmu_match[] = { 295static const struct of_device_id qoriq_tmu_match[] = {
296 { .compatible = "fsl,qoriq-tmu", }, 296 { .compatible = "fsl,qoriq-tmu", },
297 { .compatible = "fsl,imx8mq-tmu", },
297 {}, 298 {},
298}; 299};
299MODULE_DEVICE_TABLE(of, qoriq_tmu_match); 300MODULE_DEVICE_TABLE(of, qoriq_tmu_match);
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index 7aed5337bdd3..75786cc8e2f9 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -318,9 +318,11 @@ static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
318} 318}
319 319
320static const struct of_device_id rcar_gen3_thermal_dt_ids[] = { 320static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
321 { .compatible = "renesas,r8a774a1-thermal", },
321 { .compatible = "renesas,r8a7795-thermal", }, 322 { .compatible = "renesas,r8a7795-thermal", },
322 { .compatible = "renesas,r8a7796-thermal", }, 323 { .compatible = "renesas,r8a7796-thermal", },
323 { .compatible = "renesas,r8a77965-thermal", }, 324 { .compatible = "renesas,r8a77965-thermal", },
325 { .compatible = "renesas,r8a77980-thermal", },
324 {}, 326 {},
325}; 327};
326MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids); 328MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids);
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 78f932822d38..8014a207d8d9 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -113,6 +113,10 @@ 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-r8a77970",
117 .data = &rcar_gen3_thermal,
118 },
119 {
116 .compatible = "renesas,thermal-r8a77995", 120 .compatible = "renesas,thermal-r8a77995",
117 .data = &rcar_gen3_thermal, 121 .data = &rcar_gen3_thermal,
118 }, 122 },
@@ -434,8 +438,8 @@ static irqreturn_t rcar_thermal_irq(int irq, void *data)
434 rcar_thermal_for_each_priv(priv, common) { 438 rcar_thermal_for_each_priv(priv, common) {
435 if (rcar_thermal_had_changed(priv, status)) { 439 if (rcar_thermal_had_changed(priv, status)) {
436 rcar_thermal_irq_disable(priv); 440 rcar_thermal_irq_disable(priv);
437 schedule_delayed_work(&priv->work, 441 queue_delayed_work(system_freezable_wq, &priv->work,
438 msecs_to_jiffies(300)); 442 msecs_to_jiffies(300));
439 } 443 }
440 } 444 }
441 445
@@ -453,6 +457,7 @@ static int rcar_thermal_remove(struct platform_device *pdev)
453 457
454 rcar_thermal_for_each_priv(priv, common) { 458 rcar_thermal_for_each_priv(priv, common) {
455 rcar_thermal_irq_disable(priv); 459 rcar_thermal_irq_disable(priv);
460 cancel_delayed_work_sync(&priv->work);
456 if (priv->chip->use_of_thermal) 461 if (priv->chip->use_of_thermal)
457 thermal_remove_hwmon_sysfs(priv->zone); 462 thermal_remove_hwmon_sysfs(priv->zone);
458 else 463 else
@@ -492,7 +497,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
492 pm_runtime_get_sync(dev); 497 pm_runtime_get_sync(dev);
493 498
494 for (i = 0; i < chip->nirqs; i++) { 499 for (i = 0; i < chip->nirqs; i++) {
495 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 500 irq = platform_get_resource(pdev, IORESOURCE_IRQ, i);
496 if (!irq) 501 if (!irq)
497 continue; 502 continue;
498 if (!common->base) { 503 if (!common->base) {
diff --git a/drivers/thermal/st/Kconfig b/drivers/thermal/st/Kconfig
index 490fdbe22eea..b80f9a9e4f8f 100644
--- a/drivers/thermal/st/Kconfig
+++ b/drivers/thermal/st/Kconfig
@@ -1,3 +1,7 @@
1#
2# STMicroelectronics thermal drivers configuration
3#
4
1config ST_THERMAL 5config ST_THERMAL
2 tristate "Thermal sensors on STMicroelectronics STi series of SoCs" 6 tristate "Thermal sensors on STMicroelectronics STi series of SoCs"
3 help 7 help
@@ -10,3 +14,13 @@ config ST_THERMAL_SYSCFG
10config ST_THERMAL_MEMMAP 14config ST_THERMAL_MEMMAP
11 select ST_THERMAL 15 select ST_THERMAL
12 tristate "STi series memory mapped access based thermal sensors" 16 tristate "STi series memory mapped access based thermal sensors"
17
18config STM32_THERMAL
19 tristate "Thermal framework support on STMicroelectronics STM32 series of SoCs"
20 depends on MACH_STM32MP157
21 default y
22 help
23 Support for thermal framework on STMicroelectronics STM32 series of
24 SoCs. This thermal driver allows to access to general thermal framework
25 functionalities and to acces to SoC sensor functionalities. This
26 configuration is fully dependent of MACH_STM32MP157.
diff --git a/drivers/thermal/st/Makefile b/drivers/thermal/st/Makefile
index b38878977bd8..b2b9e9b96296 100644
--- a/drivers/thermal/st/Makefile
+++ b/drivers/thermal/st/Makefile
@@ -1,3 +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
diff --git a/drivers/thermal/st/stm_thermal.c b/drivers/thermal/st/stm_thermal.c
new file mode 100644
index 000000000000..47623da0f91b
--- /dev/null
+++ b/drivers/thermal/st/stm_thermal.c
@@ -0,0 +1,760 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
4 * Author: David Hernandez Sanchez <david.hernandezsanchez@st.com> for
5 * STMicroelectronics.
6 */
7
8#include <linux/clk.h>
9#include <linux/clk-provider.h>
10#include <linux/delay.h>
11#include <linux/err.h>
12#include <linux/interrupt.h>
13#include <linux/io.h>
14#include <linux/iopoll.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_address.h>
18#include <linux/of_device.h>
19#include <linux/platform_device.h>
20#include <linux/thermal.h>
21
22#include "../thermal_core.h"
23#include "../thermal_hwmon.h"
24
25/* DTS register offsets */
26#define DTS_CFGR1_OFFSET 0x0
27#define DTS_T0VALR1_OFFSET 0x8
28#define DTS_RAMPVALR_OFFSET 0X10
29#define DTS_ITR1_OFFSET 0x14
30#define DTS_DR_OFFSET 0x1C
31#define DTS_SR_OFFSET 0x20
32#define DTS_ITENR_OFFSET 0x24
33#define DTS_CIFR_OFFSET 0x28
34
35/* DTS_CFGR1 register mask definitions */
36#define HSREF_CLK_DIV_MASK GENMASK(30, 24)
37#define TS1_SMP_TIME_MASK GENMASK(19, 16)
38#define TS1_INTRIG_SEL_MASK GENMASK(11, 8)
39
40/* DTS_T0VALR1 register mask definitions */
41#define TS1_T0_MASK GENMASK(17, 16)
42#define TS1_FMT0_MASK GENMASK(15, 0)
43
44/* DTS_RAMPVALR register mask definitions */
45#define TS1_RAMP_COEFF_MASK GENMASK(15, 0)
46
47/* DTS_ITR1 register mask definitions */
48#define TS1_HITTHD_MASK GENMASK(31, 16)
49#define TS1_LITTHD_MASK GENMASK(15, 0)
50
51/* DTS_DR register mask definitions */
52#define TS1_MFREQ_MASK GENMASK(15, 0)
53
54/* Less significant bit position definitions */
55#define TS1_T0_POS 16
56#define TS1_SMP_TIME_POS 16
57#define TS1_HITTHD_POS 16
58#define HSREF_CLK_DIV_POS 24
59
60/* DTS_CFGR1 bit definitions */
61#define TS1_EN BIT(0)
62#define TS1_START BIT(4)
63#define REFCLK_SEL BIT(20)
64#define REFCLK_LSE REFCLK_SEL
65#define Q_MEAS_OPT BIT(21)
66#define CALIBRATION_CONTROL Q_MEAS_OPT
67
68/* DTS_SR bit definitions */
69#define TS_RDY BIT(15)
70/* Bit definitions below are common for DTS_SR, DTS_ITENR and DTS_CIFR */
71#define HIGH_THRESHOLD BIT(2)
72#define LOW_THRESHOLD BIT(1)
73
74/* Constants */
75#define ADJUST 100
76#define ONE_MHZ 1000000
77#define POLL_TIMEOUT 5000
78#define STARTUP_TIME 40
79#define TS1_T0_VAL0 30
80#define TS1_T0_VAL1 130
81#define NO_HW_TRIG 0
82
83/* The Thermal Framework expects millidegrees */
84#define mcelsius(temp) ((temp) * 1000)
85
86/* The Sensor expects oC degrees */
87#define celsius(temp) ((temp) / 1000)
88
89struct stm_thermal_sensor {
90 struct device *dev;
91 struct thermal_zone_device *th_dev;
92 enum thermal_device_mode mode;
93 struct clk *clk;
94 int high_temp;
95 int low_temp;
96 int temp_critical;
97 int temp_passive;
98 unsigned int low_temp_enabled;
99 int num_trips;
100 int irq;
101 unsigned int irq_enabled;
102 void __iomem *base;
103 int t0, fmt0, ramp_coeff;
104};
105
106static irqreturn_t stm_thermal_alarm_irq(int irq, void *sdata)
107{
108 struct stm_thermal_sensor *sensor = sdata;
109
110 disable_irq_nosync(irq);
111 sensor->irq_enabled = false;
112
113 return IRQ_WAKE_THREAD;
114}
115
116static irqreturn_t stm_thermal_alarm_irq_thread(int irq, void *sdata)
117{
118 u32 value;
119 struct stm_thermal_sensor *sensor = sdata;
120
121 /* read IT reason in SR and clear flags */
122 value = readl_relaxed(sensor->base + DTS_SR_OFFSET);
123
124 if ((value & LOW_THRESHOLD) == LOW_THRESHOLD)
125 writel_relaxed(LOW_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
126
127 if ((value & HIGH_THRESHOLD) == HIGH_THRESHOLD)
128 writel_relaxed(HIGH_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
129
130 thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED);
131
132 return IRQ_HANDLED;
133}
134
135static int stm_sensor_power_on(struct stm_thermal_sensor *sensor)
136{
137 int ret;
138 u32 value;
139
140 /* Enable sensor */
141 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
142 value |= TS1_EN;
143 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
144
145 /*
146 * The DTS block can be enabled by setting TSx_EN bit in
147 * DTS_CFGRx register. It requires a startup time of
148 * 40μs. Use 5 ms as arbitrary timeout.
149 */
150 ret = readl_poll_timeout(sensor->base + DTS_SR_OFFSET,
151 value, (value & TS_RDY),
152 STARTUP_TIME, POLL_TIMEOUT);
153 if (ret)
154 return ret;
155
156 /* Start continuous measuring */
157 value = readl_relaxed(sensor->base +
158 DTS_CFGR1_OFFSET);
159 value |= TS1_START;
160 writel_relaxed(value, sensor->base +
161 DTS_CFGR1_OFFSET);
162
163 return 0;
164}
165
166static int stm_sensor_power_off(struct stm_thermal_sensor *sensor)
167{
168 u32 value;
169
170 /* Stop measuring */
171 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
172 value &= ~TS1_START;
173 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
174
175 /* Ensure stop is taken into account */
176 usleep_range(STARTUP_TIME, POLL_TIMEOUT);
177
178 /* Disable sensor */
179 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
180 value &= ~TS1_EN;
181 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
182
183 /* Ensure disable is taken into account */
184 return readl_poll_timeout(sensor->base + DTS_SR_OFFSET, value,
185 !(value & TS_RDY),
186 STARTUP_TIME, POLL_TIMEOUT);
187}
188
189static int stm_thermal_calibration(struct stm_thermal_sensor *sensor)
190{
191 u32 value, clk_freq;
192 u32 prescaler;
193
194 /* Figure out prescaler value for PCLK during calibration */
195 clk_freq = clk_get_rate(sensor->clk);
196 if (!clk_freq)
197 return -EINVAL;
198
199 prescaler = 0;
200 clk_freq /= ONE_MHZ;
201 if (clk_freq) {
202 while (prescaler <= clk_freq)
203 prescaler++;
204 }
205
206 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
207
208 /* Clear prescaler */
209 value &= ~HSREF_CLK_DIV_MASK;
210
211 /* Set prescaler. pclk_freq/prescaler < 1MHz */
212 value |= (prescaler << HSREF_CLK_DIV_POS);
213
214 /* Select PCLK as reference clock */
215 value &= ~REFCLK_SEL;
216
217 /* Set maximal sampling time for better precision */
218 value |= TS1_SMP_TIME_MASK;
219
220 /* Measure with calibration */
221 value &= ~CALIBRATION_CONTROL;
222
223 /* select trigger */
224 value &= ~TS1_INTRIG_SEL_MASK;
225 value |= NO_HW_TRIG;
226
227 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
228
229 return 0;
230}
231
232/* Fill in DTS structure with factory sensor values */
233static int stm_thermal_read_factory_settings(struct stm_thermal_sensor *sensor)
234{
235 /* Retrieve engineering calibration temperature */
236 sensor->t0 = readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET) &
237 TS1_T0_MASK;
238 if (!sensor->t0)
239 sensor->t0 = TS1_T0_VAL0;
240 else
241 sensor->t0 = TS1_T0_VAL1;
242
243 /* Retrieve fmt0 and put it on Hz */
244 sensor->fmt0 = ADJUST * readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET)
245 & TS1_FMT0_MASK;
246
247 /* Retrieve ramp coefficient */
248 sensor->ramp_coeff = readl_relaxed(sensor->base + DTS_RAMPVALR_OFFSET) &
249 TS1_RAMP_COEFF_MASK;
250
251 if (!sensor->fmt0 || !sensor->ramp_coeff) {
252 dev_err(sensor->dev, "%s: wrong setting\n", __func__);
253 return -EINVAL;
254 }
255
256 dev_dbg(sensor->dev, "%s: T0 = %doC, FMT0 = %dHz, RAMP_COEFF = %dHz/oC",
257 __func__, sensor->t0, sensor->fmt0, sensor->ramp_coeff);
258
259 return 0;
260}
261
262static int stm_thermal_calculate_threshold(struct stm_thermal_sensor *sensor,
263 int temp, u32 *th)
264{
265 int freqM;
266 u32 sampling_time;
267
268 /* Retrieve the number of periods to sample */
269 sampling_time = (readl_relaxed(sensor->base + DTS_CFGR1_OFFSET) &
270 TS1_SMP_TIME_MASK) >> TS1_SMP_TIME_POS;
271
272 /* Figure out the CLK_PTAT frequency for a given temperature */
273 freqM = ((temp - sensor->t0) * sensor->ramp_coeff)
274 + sensor->fmt0;
275
276 dev_dbg(sensor->dev, "%s: freqM for threshold = %d Hz",
277 __func__, freqM);
278
279 /* Figure out the threshold sample number */
280 *th = clk_get_rate(sensor->clk);
281 if (!*th)
282 return -EINVAL;
283
284 *th = *th / freqM;
285
286 *th *= sampling_time;
287
288 return 0;
289}
290
291static int stm_thermal_set_threshold(struct stm_thermal_sensor *sensor)
292{
293 u32 value, th;
294 int ret;
295
296 value = readl_relaxed(sensor->base + DTS_ITR1_OFFSET);
297
298 /* Erase threshold content */
299 value &= ~(TS1_LITTHD_MASK | TS1_HITTHD_MASK);
300
301 /* Retrieve the sample threshold number th for a given temperature */
302 ret = stm_thermal_calculate_threshold(sensor, sensor->high_temp, &th);
303 if (ret)
304 return ret;
305
306 value |= th & TS1_LITTHD_MASK;
307
308 if (sensor->low_temp_enabled) {
309 /* Retrieve the sample threshold */
310 ret = stm_thermal_calculate_threshold(sensor, sensor->low_temp,
311 &th);
312 if (ret)
313 return ret;
314
315 value |= (TS1_HITTHD_MASK & (th << TS1_HITTHD_POS));
316 }
317
318 /* Write value on the Low interrupt threshold */
319 writel_relaxed(value, sensor->base + DTS_ITR1_OFFSET);
320
321 return 0;
322}
323
324/* Disable temperature interrupt */
325static int stm_disable_irq(struct stm_thermal_sensor *sensor)
326{
327 u32 value;
328
329 /* Disable IT generation for low and high thresholds */
330 value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
331 writel_relaxed(value & ~(LOW_THRESHOLD | HIGH_THRESHOLD),
332 sensor->base + DTS_ITENR_OFFSET);
333
334 dev_dbg(sensor->dev, "%s: IT disabled on sensor side", __func__);
335
336 return 0;
337}
338
339/* Enable temperature interrupt */
340static int stm_enable_irq(struct stm_thermal_sensor *sensor)
341{
342 u32 value;
343
344 /*
345 * Code below enables High temperature threshold using a low threshold
346 * sampling value
347 */
348
349 /* Make sure LOW_THRESHOLD IT is clear before enabling */
350 writel_relaxed(LOW_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
351
352 /* Enable IT generation for low threshold */
353 value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
354 value |= LOW_THRESHOLD;
355
356 /* Enable the low temperature threshold if needed */
357 if (sensor->low_temp_enabled) {
358 /* Make sure HIGH_THRESHOLD IT is clear before enabling */
359 writel_relaxed(HIGH_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
360
361 /* Enable IT generation for high threshold */
362 value |= HIGH_THRESHOLD;
363 }
364
365 /* Enable thresholds */
366 writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET);
367
368 dev_dbg(sensor->dev, "%s: IT enabled on sensor side", __func__);
369
370 return 0;
371}
372
373static int stm_thermal_update_threshold(struct stm_thermal_sensor *sensor)
374{
375 int ret;
376
377 sensor->mode = THERMAL_DEVICE_DISABLED;
378
379 ret = stm_sensor_power_off(sensor);
380 if (ret)
381 return ret;
382
383 ret = stm_disable_irq(sensor);
384 if (ret)
385 return ret;
386
387 ret = stm_thermal_set_threshold(sensor);
388 if (ret)
389 return ret;
390
391 ret = stm_enable_irq(sensor);
392 if (ret)
393 return ret;
394
395 ret = stm_sensor_power_on(sensor);
396 if (ret)
397 return ret;
398
399 sensor->mode = THERMAL_DEVICE_ENABLED;
400
401 return 0;
402}
403
404/* Callback to get temperature from HW */
405static int stm_thermal_get_temp(void *data, int *temp)
406{
407 struct stm_thermal_sensor *sensor = data;
408 u32 sampling_time;
409 int freqM, ret;
410
411 if (sensor->mode != THERMAL_DEVICE_ENABLED)
412 return -EAGAIN;
413
414 /* Retrieve the number of samples */
415 ret = readl_poll_timeout(sensor->base + DTS_DR_OFFSET, freqM,
416 (freqM & TS1_MFREQ_MASK), STARTUP_TIME,
417 POLL_TIMEOUT);
418
419 if (ret)
420 return ret;
421
422 if (!freqM)
423 return -ENODATA;
424
425 /* Retrieve the number of periods sampled */
426 sampling_time = (readl_relaxed(sensor->base + DTS_CFGR1_OFFSET) &
427 TS1_SMP_TIME_MASK) >> TS1_SMP_TIME_POS;
428
429 /* Figure out the number of samples per period */
430 freqM /= sampling_time;
431
432 /* Figure out the CLK_PTAT frequency */
433 freqM = clk_get_rate(sensor->clk) / freqM;
434 if (!freqM)
435 return -EINVAL;
436
437 dev_dbg(sensor->dev, "%s: freqM=%d\n", __func__, freqM);
438
439 /* Figure out the temperature in mili celsius */
440 *temp = mcelsius(sensor->t0 + ((freqM - sensor->fmt0) /
441 sensor->ramp_coeff));
442
443 dev_dbg(sensor->dev, "%s: temperature = %d millicelsius",
444 __func__, *temp);
445
446 /* Update thresholds */
447 if (sensor->num_trips > 1) {
448 /* Update alarm threshold value to next higher trip point */
449 if (sensor->high_temp == sensor->temp_passive &&
450 celsius(*temp) >= sensor->temp_passive) {
451 sensor->high_temp = sensor->temp_critical;
452 sensor->low_temp = sensor->temp_passive;
453 sensor->low_temp_enabled = true;
454 ret = stm_thermal_update_threshold(sensor);
455 if (ret)
456 return ret;
457 }
458
459 if (sensor->high_temp == sensor->temp_critical &&
460 celsius(*temp) < sensor->temp_passive) {
461 sensor->high_temp = sensor->temp_passive;
462 sensor->low_temp_enabled = false;
463 ret = stm_thermal_update_threshold(sensor);
464 if (ret)
465 return ret;
466 }
467
468 /*
469 * Re-enable alarm IRQ if temperature below critical
470 * temperature
471 */
472 if (!sensor->irq_enabled &&
473 (celsius(*temp) < sensor->temp_critical)) {
474 sensor->irq_enabled = true;
475 enable_irq(sensor->irq);
476 }
477 }
478
479 return 0;
480}
481
482/* Registers DTS irq to be visible by GIC */
483static int stm_register_irq(struct stm_thermal_sensor *sensor)
484{
485 struct device *dev = sensor->dev;
486 struct platform_device *pdev = to_platform_device(dev);
487 int ret;
488
489 sensor->irq = platform_get_irq(pdev, 0);
490 if (sensor->irq < 0) {
491 dev_err(dev, "%s: Unable to find IRQ\n", __func__);
492 return sensor->irq;
493 }
494
495 ret = devm_request_threaded_irq(dev, sensor->irq,
496 stm_thermal_alarm_irq,
497 stm_thermal_alarm_irq_thread,
498 IRQF_ONESHOT,
499 dev->driver->name, sensor);
500 if (ret) {
501 dev_err(dev, "%s: Failed to register IRQ %d\n", __func__,
502 sensor->irq);
503 return ret;
504 }
505
506 sensor->irq_enabled = true;
507
508 dev_dbg(dev, "%s: thermal IRQ registered", __func__);
509
510 return 0;
511}
512
513static int stm_thermal_sensor_off(struct stm_thermal_sensor *sensor)
514{
515 int ret;
516
517 ret = stm_sensor_power_off(sensor);
518 if (ret)
519 return ret;
520
521 clk_disable_unprepare(sensor->clk);
522
523 return 0;
524}
525
526static int stm_thermal_prepare(struct stm_thermal_sensor *sensor)
527{
528 int ret;
529 struct device *dev = sensor->dev;
530
531 ret = clk_prepare_enable(sensor->clk);
532 if (ret)
533 return ret;
534
535 ret = stm_thermal_calibration(sensor);
536 if (ret)
537 goto thermal_unprepare;
538
539 /* Set threshold(s) for IRQ */
540 ret = stm_thermal_set_threshold(sensor);
541 if (ret)
542 goto thermal_unprepare;
543
544 ret = stm_enable_irq(sensor);
545 if (ret)
546 goto thermal_unprepare;
547
548 ret = stm_sensor_power_on(sensor);
549 if (ret) {
550 dev_err(dev, "%s: failed to power on sensor\n", __func__);
551 goto irq_disable;
552 }
553
554 return 0;
555
556irq_disable:
557 stm_disable_irq(sensor);
558
559thermal_unprepare:
560 clk_disable_unprepare(sensor->clk);
561
562 return ret;
563}
564
565#ifdef CONFIG_PM_SLEEP
566static int stm_thermal_suspend(struct device *dev)
567{
568 int ret;
569 struct platform_device *pdev = to_platform_device(dev);
570 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
571
572 ret = stm_thermal_sensor_off(sensor);
573 if (ret)
574 return ret;
575
576 sensor->mode = THERMAL_DEVICE_DISABLED;
577
578 return 0;
579}
580
581static int stm_thermal_resume(struct device *dev)
582{
583 int ret;
584 struct platform_device *pdev = to_platform_device(dev);
585 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
586
587 ret = stm_thermal_prepare(sensor);
588 if (ret)
589 return ret;
590
591 sensor->mode = THERMAL_DEVICE_ENABLED;
592
593 return 0;
594}
595#endif /* CONFIG_PM_SLEEP */
596
597SIMPLE_DEV_PM_OPS(stm_thermal_pm_ops, stm_thermal_suspend, stm_thermal_resume);
598
599static const struct thermal_zone_of_device_ops stm_tz_ops = {
600 .get_temp = stm_thermal_get_temp,
601};
602
603static const struct of_device_id stm_thermal_of_match[] = {
604 { .compatible = "st,stm32-thermal"},
605 { /* sentinel */ }
606};
607MODULE_DEVICE_TABLE(of, stm_thermal_of_match);
608
609static int stm_thermal_probe(struct platform_device *pdev)
610{
611 struct stm_thermal_sensor *sensor;
612 struct resource *res;
613 const struct thermal_trip *trip;
614 void __iomem *base;
615 int ret, i;
616
617 if (!pdev->dev.of_node) {
618 dev_err(&pdev->dev, "%s: device tree node not found\n",
619 __func__);
620 return -EINVAL;
621 }
622
623 sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
624 if (!sensor)
625 return -ENOMEM;
626
627 platform_set_drvdata(pdev, sensor);
628
629 sensor->dev = &pdev->dev;
630
631 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
632 base = devm_ioremap_resource(&pdev->dev, res);
633 if (IS_ERR(base))
634 return PTR_ERR(base);
635
636 /* Populate sensor */
637 sensor->base = base;
638
639 ret = stm_thermal_read_factory_settings(sensor);
640 if (ret)
641 return ret;
642
643 sensor->clk = devm_clk_get(&pdev->dev, "pclk");
644 if (IS_ERR(sensor->clk)) {
645 dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n",
646 __func__);
647 return PTR_ERR(sensor->clk);
648 }
649
650 /* Register IRQ into GIC */
651 ret = stm_register_irq(sensor);
652 if (ret)
653 return ret;
654
655 sensor->th_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0,
656 sensor,
657 &stm_tz_ops);
658
659 if (IS_ERR(sensor->th_dev)) {
660 dev_err(&pdev->dev, "%s: thermal zone sensor registering KO\n",
661 __func__);
662 ret = PTR_ERR(sensor->th_dev);
663 return ret;
664 }
665
666 if (!sensor->th_dev->ops->get_crit_temp) {
667 /* Critical point must be provided */
668 ret = -EINVAL;
669 goto err_tz;
670 }
671
672 ret = sensor->th_dev->ops->get_crit_temp(sensor->th_dev,
673 &sensor->temp_critical);
674 if (ret) {
675 dev_err(&pdev->dev,
676 "Not able to read critical_temp: %d\n", ret);
677 goto err_tz;
678 }
679
680 sensor->temp_critical = celsius(sensor->temp_critical);
681
682 /* Set thresholds for IRQ */
683 sensor->high_temp = sensor->temp_critical;
684
685 trip = of_thermal_get_trip_points(sensor->th_dev);
686 sensor->num_trips = of_thermal_get_ntrips(sensor->th_dev);
687
688 /* Find out passive temperature if it exists */
689 for (i = (sensor->num_trips - 1); i >= 0; i--) {
690 if (trip[i].type == THERMAL_TRIP_PASSIVE) {
691 sensor->temp_passive = celsius(trip[i].temperature);
692 /* Update high temperature threshold */
693 sensor->high_temp = sensor->temp_passive;
694 }
695 }
696
697 /*
698 * Ensure low_temp_enabled flag is disabled.
699 * By disabling low_temp_enabled, low threshold IT will not be
700 * configured neither enabled because it is not needed as high
701 * threshold is set on the lowest temperature trip point after
702 * probe.
703 */
704 sensor->low_temp_enabled = false;
705
706 /* Configure and enable HW sensor */
707 ret = stm_thermal_prepare(sensor);
708 if (ret) {
709 dev_err(&pdev->dev,
710 "Not able to enable sensor: %d\n", ret);
711 goto err_tz;
712 }
713
714 /*
715 * Thermal_zone doesn't enable hwmon as default,
716 * enable it here
717 */
718 sensor->th_dev->tzp->no_hwmon = false;
719 ret = thermal_add_hwmon_sysfs(sensor->th_dev);
720 if (ret)
721 goto err_tz;
722
723 sensor->mode = THERMAL_DEVICE_ENABLED;
724
725 dev_info(&pdev->dev, "%s: Driver initialized successfully\n",
726 __func__);
727
728 return 0;
729
730err_tz:
731 thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev);
732 return ret;
733}
734
735static int stm_thermal_remove(struct platform_device *pdev)
736{
737 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
738
739 stm_thermal_sensor_off(sensor);
740 thermal_remove_hwmon_sysfs(sensor->th_dev);
741 thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev);
742
743 return 0;
744}
745
746static struct platform_driver stm_thermal_driver = {
747 .driver = {
748 .name = "stm_thermal",
749 .pm = &stm_thermal_pm_ops,
750 .of_match_table = stm_thermal_of_match,
751 },
752 .probe = stm_thermal_probe,
753 .remove = stm_thermal_remove,
754};
755module_platform_driver(stm_thermal_driver);
756
757MODULE_DESCRIPTION("STMicroelectronics STM32 Thermal Sensor Driver");
758MODULE_AUTHOR("David Hernandez Sanchez <david.hernandezsanchez@st.com>");
759MODULE_LICENSE("GPL v2");
760MODULE_ALIAS("platform:stm_thermal");