aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt32
-rw-r--r--Documentation/devicetree/bindings/thermal/brcm,ns-thermal37
-rw-r--r--Documentation/devicetree/bindings/thermal/da9062-thermal.txt36
-rw-r--r--drivers/thermal/Kconfig15
-rw-r--r--drivers/thermal/Makefile2
-rw-r--r--drivers/thermal/broadcom/Kconfig16
-rw-r--r--drivers/thermal/broadcom/Makefile2
-rw-r--r--drivers/thermal/broadcom/bcm2835_thermal.c314
-rw-r--r--drivers/thermal/broadcom/ns-thermal.c106
-rw-r--r--drivers/thermal/da9062-thermal.c315
-rw-r--r--drivers/thermal/mtk_thermal.c2
-rw-r--r--drivers/thermal/rcar_gen3_thermal.c199
-rw-r--r--drivers/thermal/ti-soc-thermal/dra752-thermal-data.c10
-rw-r--r--drivers/thermal/ti-soc-thermal/omap3-thermal-data.c4
-rw-r--r--drivers/thermal/ti-soc-thermal/omap4-thermal-data.c6
-rw-r--r--drivers/thermal/ti-soc-thermal/omap5-thermal-data.c4
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-bandgap.h4
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-thermal-common.c158
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-thermal.h16
19 files changed, 1061 insertions, 217 deletions
diff --git a/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt b/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
index 474531d2b2c5..da8c5b73ad10 100644
--- a/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.txt
@@ -3,15 +3,39 @@ Binding for Thermal Sensor driver for BCM2835 SoCs.
3Required parameters: 3Required parameters:
4------------------- 4-------------------
5 5
6compatible: should be one of: "brcm,bcm2835-thermal", 6compatible: should be one of: "brcm,bcm2835-thermal",
7 "brcm,bcm2836-thermal" or "brcm,bcm2837-thermal" 7 "brcm,bcm2836-thermal" or "brcm,bcm2837-thermal"
8reg: Address range of the thermal registers. 8reg: Address range of the thermal registers.
9clocks: Phandle of the clock used by the thermal sensor. 9clocks: Phandle of the clock used by the thermal sensor.
10#thermal-sensor-cells: should be 0 (see thermal.txt)
10 11
11Example: 12Example:
12 13
14thermal-zones {
15 cpu_thermal: cpu-thermal {
16 polling-delay-passive = <0>;
17 polling-delay = <1000>;
18
19 thermal-sensors = <&thermal>;
20
21 trips {
22 cpu-crit {
23 temperature = <80000>;
24 hysteresis = <0>;
25 type = "critical";
26 };
27 };
28
29 coefficients = <(-538) 407000>;
30
31 cooling-maps {
32 };
33 };
34};
35
13thermal: thermal@7e212000 { 36thermal: thermal@7e212000 {
14 compatible = "brcm,bcm2835-thermal"; 37 compatible = "brcm,bcm2835-thermal";
15 reg = <0x7e212000 0x8>; 38 reg = <0x7e212000 0x8>;
16 clocks = <&clocks BCM2835_CLOCK_TSENS>; 39 clocks = <&clocks BCM2835_CLOCK_TSENS>;
40 #thermal-sensor-cells = <0>;
17}; 41};
diff --git a/Documentation/devicetree/bindings/thermal/brcm,ns-thermal b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal
new file mode 100644
index 000000000000..68e047170039
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal
@@ -0,0 +1,37 @@
1* Broadcom Northstar Thermal
2
3This binding describes thermal sensor that is part of Northstar's DMU (Device
4Management Unit).
5
6Required properties:
7- compatible : Must be "brcm,ns-thermal"
8- reg : iomem address range of PVTMON registers
9- #thermal-sensor-cells : Should be <0>
10
11Example:
12
13thermal: thermal@1800c2c0 {
14 compatible = "brcm,ns-thermal";
15 reg = <0x1800c2c0 0x10>;
16 #thermal-sensor-cells = <0>;
17};
18
19thermal-zones {
20 cpu_thermal: cpu-thermal {
21 polling-delay-passive = <0>;
22 polling-delay = <1000>;
23 coefficients = <(-556) 418000>;
24 thermal-sensors = <&thermal>;
25
26 trips {
27 cpu-crit {
28 temperature = <125000>;
29 hysteresis = <0>;
30 type = "critical";
31 };
32 };
33
34 cooling-maps {
35 };
36 };
37};
diff --git a/Documentation/devicetree/bindings/thermal/da9062-thermal.txt b/Documentation/devicetree/bindings/thermal/da9062-thermal.txt
new file mode 100644
index 000000000000..e241bb5a5584
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/da9062-thermal.txt
@@ -0,0 +1,36 @@
1* Dialog DA9062/61 TJUNC Thermal Module
2
3This module is part of the DA9061/DA9062. For more details about entire
4DA9062 and DA9061 chips see Documentation/devicetree/bindings/mfd/da9062.txt
5
6Junction temperature thermal module uses an interrupt signal to identify
7high THERMAL_TRIP_HOT temperatures for the PMIC device.
8
9Required properties:
10
11- compatible: should be one of the following valid compatible string lines:
12 "dlg,da9061-thermal", "dlg,da9062-thermal"
13 "dlg,da9062-thermal"
14
15Optional properties:
16
17- polling-delay-passive : Specify the polling period, measured in
18 milliseconds, between thermal zone device update checks.
19
20Example: DA9062
21
22 pmic0: da9062@58 {
23 thermal {
24 compatible = "dlg,da9062-thermal";
25 polling-delay-passive = <3000>;
26 };
27 };
28
29Example: DA9061 using a fall-back compatible for the DA9062 onkey driver
30
31 pmic0: da9061@58 {
32 thermal {
33 compatible = "dlg,da9061-thermal", "dlg,da9062-thermal";
34 polling-delay-passive = <3000>;
35 };
36 };
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 74ef51dfb816..4edc011fe4a5 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -320,6 +320,16 @@ config DB8500_CPUFREQ_COOLING
320 bound cpufreq cooling device turns active to set CPU frequency low to 320 bound cpufreq cooling device turns active to set CPU frequency low to
321 cool down the CPU. 321 cool down the CPU.
322 322
323config DA9062_THERMAL
324 tristate "DA9062/DA9061 Dialog Semiconductor thermal driver"
325 depends on MFD_DA9062 || COMPILE_TEST
326 depends on OF
327 help
328 Enable this for the Dialog Semiconductor thermal sensor driver.
329 This will report PMIC junction over-temperature for one thermal trip
330 zone.
331 Compatible with the DA9062 and DA9061 PMICs.
332
323config INTEL_POWERCLAMP 333config INTEL_POWERCLAMP
324 tristate "Intel PowerClamp idle injection driver" 334 tristate "Intel PowerClamp idle injection driver"
325 depends on THERMAL 335 depends on THERMAL
@@ -409,6 +419,11 @@ config MTK_THERMAL
409 Enable this option if you want to have support for thermal management 419 Enable this option if you want to have support for thermal management
410 controller present in Mediatek SoCs 420 controller present in Mediatek SoCs
411 421
422menu "Broadcom thermal drivers"
423depends on ARCH_BCM || COMPILE_TEST
424source "drivers/thermal/broadcom/Kconfig"
425endmenu
426
412menu "Texas Instruments thermal drivers" 427menu "Texas Instruments thermal drivers"
413depends on ARCH_HAS_BANDGAP || COMPILE_TEST 428depends on ARCH_HAS_BANDGAP || COMPILE_TEST
414depends on HAS_IOMEM 429depends on HAS_IOMEM
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 7adae2029355..e6834061da28 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -27,6 +27,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o
27thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o 27thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
28 28
29# platform thermal drivers 29# platform thermal drivers
30obj-y += broadcom/
30obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o 31obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
31obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o 32obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o
32obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o 33obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o
@@ -42,6 +43,7 @@ obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
42obj-$(CONFIG_MAX77620_THERMAL) += max77620_thermal.o 43obj-$(CONFIG_MAX77620_THERMAL) += max77620_thermal.o
43obj-$(CONFIG_QORIQ_THERMAL) += qoriq_thermal.o 44obj-$(CONFIG_QORIQ_THERMAL) += qoriq_thermal.o
44obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o 45obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
46obj-$(CONFIG_DA9062_THERMAL) += da9062-thermal.o
45obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o 47obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
46obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o 48obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o
47obj-$(CONFIG_INTEL_SOC_DTS_IOSF_CORE) += intel_soc_dts_iosf.o 49obj-$(CONFIG_INTEL_SOC_DTS_IOSF_CORE) += intel_soc_dts_iosf.o
diff --git a/drivers/thermal/broadcom/Kconfig b/drivers/thermal/broadcom/Kconfig
new file mode 100644
index 000000000000..ab08af4654ef
--- /dev/null
+++ b/drivers/thermal/broadcom/Kconfig
@@ -0,0 +1,16 @@
1config BCM2835_THERMAL
2 tristate "Thermal sensors on bcm2835 SoC"
3 depends on ARCH_BCM2835 || COMPILE_TEST
4 depends on HAS_IOMEM
5 depends on THERMAL_OF
6 help
7 Support for thermal sensors on Broadcom bcm2835 SoCs.
8
9config BCM_NS_THERMAL
10 tristate "Northstar thermal driver"
11 depends on ARCH_BCM_IPROC || COMPILE_TEST
12 help
13 Northstar is a family of SoCs that includes e.g. BCM4708, BCM47081,
14 BCM4709 and BCM47094. It contains DMU (Device Management Unit) block
15 with a thermal sensor that allows checking CPU temperature. This
16 driver provides support for it.
diff --git a/drivers/thermal/broadcom/Makefile b/drivers/thermal/broadcom/Makefile
new file mode 100644
index 000000000000..c6f62e4fd0ee
--- /dev/null
+++ b/drivers/thermal/broadcom/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_BCM2835_THERMAL) += bcm2835_thermal.o
2obj-$(CONFIG_BCM_NS_THERMAL) += ns-thermal.o
diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c
new file mode 100644
index 000000000000..0ecf80890c84
--- /dev/null
+++ b/drivers/thermal/broadcom/bcm2835_thermal.c
@@ -0,0 +1,314 @@
1/*
2 * Driver for Broadcom BCM2835 SoC temperature sensor
3 *
4 * Copyright (C) 2016 Martin Sperl
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/clk.h>
18#include <linux/debugfs.h>
19#include <linux/device.h>
20#include <linux/err.h>
21#include <linux/io.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/of.h>
25#include <linux/of_address.h>
26#include <linux/of_device.h>
27#include <linux/platform_device.h>
28#include <linux/thermal.h>
29
30#define BCM2835_TS_TSENSCTL 0x00
31#define BCM2835_TS_TSENSSTAT 0x04
32
33#define BCM2835_TS_TSENSCTL_PRWDW BIT(0)
34#define BCM2835_TS_TSENSCTL_RSTB BIT(1)
35
36/*
37 * bandgap reference voltage in 6 mV increments
38 * 000b = 1178 mV, 001b = 1184 mV, ... 111b = 1220 mV
39 */
40#define BCM2835_TS_TSENSCTL_CTRL_BITS 3
41#define BCM2835_TS_TSENSCTL_CTRL_SHIFT 2
42#define BCM2835_TS_TSENSCTL_CTRL_MASK \
43 GENMASK(BCM2835_TS_TSENSCTL_CTRL_BITS + \
44 BCM2835_TS_TSENSCTL_CTRL_SHIFT - 1, \
45 BCM2835_TS_TSENSCTL_CTRL_SHIFT)
46#define BCM2835_TS_TSENSCTL_CTRL_DEFAULT 1
47#define BCM2835_TS_TSENSCTL_EN_INT BIT(5)
48#define BCM2835_TS_TSENSCTL_DIRECT BIT(6)
49#define BCM2835_TS_TSENSCTL_CLR_INT BIT(7)
50#define BCM2835_TS_TSENSCTL_THOLD_SHIFT 8
51#define BCM2835_TS_TSENSCTL_THOLD_BITS 10
52#define BCM2835_TS_TSENSCTL_THOLD_MASK \
53 GENMASK(BCM2835_TS_TSENSCTL_THOLD_BITS + \
54 BCM2835_TS_TSENSCTL_THOLD_SHIFT - 1, \
55 BCM2835_TS_TSENSCTL_THOLD_SHIFT)
56/*
57 * time how long the block to be asserted in reset
58 * which based on a clock counter (TSENS clock assumed)
59 */
60#define BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT 18
61#define BCM2835_TS_TSENSCTL_RSTDELAY_BITS 8
62#define BCM2835_TS_TSENSCTL_REGULEN BIT(26)
63
64#define BCM2835_TS_TSENSSTAT_DATA_BITS 10
65#define BCM2835_TS_TSENSSTAT_DATA_SHIFT 0
66#define BCM2835_TS_TSENSSTAT_DATA_MASK \
67 GENMASK(BCM2835_TS_TSENSSTAT_DATA_BITS + \
68 BCM2835_TS_TSENSSTAT_DATA_SHIFT - 1, \
69 BCM2835_TS_TSENSSTAT_DATA_SHIFT)
70#define BCM2835_TS_TSENSSTAT_VALID BIT(10)
71#define BCM2835_TS_TSENSSTAT_INTERRUPT BIT(11)
72
73struct bcm2835_thermal_data {
74 struct thermal_zone_device *tz;
75 void __iomem *regs;
76 struct clk *clk;
77 struct dentry *debugfsdir;
78};
79
80static int bcm2835_thermal_adc2temp(u32 adc, int offset, int slope)
81{
82 return offset + slope * adc;
83}
84
85static int bcm2835_thermal_temp2adc(int temp, int offset, int slope)
86{
87 temp -= offset;
88 temp /= slope;
89
90 if (temp < 0)
91 temp = 0;
92 if (temp >= BIT(BCM2835_TS_TSENSSTAT_DATA_BITS))
93 temp = BIT(BCM2835_TS_TSENSSTAT_DATA_BITS) - 1;
94
95 return temp;
96}
97
98static int bcm2835_thermal_get_temp(void *d, int *temp)
99{
100 struct bcm2835_thermal_data *data = d;
101 u32 val = readl(data->regs + BCM2835_TS_TSENSSTAT);
102
103 if (!(val & BCM2835_TS_TSENSSTAT_VALID))
104 return -EIO;
105
106 val &= BCM2835_TS_TSENSSTAT_DATA_MASK;
107
108 *temp = bcm2835_thermal_adc2temp(
109 val,
110 thermal_zone_get_offset(data->tz),
111 thermal_zone_get_slope(data->tz));
112
113 return 0;
114}
115
116static const struct debugfs_reg32 bcm2835_thermal_regs[] = {
117 {
118 .name = "ctl",
119 .offset = 0
120 },
121 {
122 .name = "stat",
123 .offset = 4
124 }
125};
126
127static void bcm2835_thermal_debugfs(struct platform_device *pdev)
128{
129 struct thermal_zone_device *tz = platform_get_drvdata(pdev);
130 struct bcm2835_thermal_data *data = tz->devdata;
131 struct debugfs_regset32 *regset;
132
133 data->debugfsdir = debugfs_create_dir("bcm2835_thermal", NULL);
134 if (!data->debugfsdir)
135 return;
136
137 regset = devm_kzalloc(&pdev->dev, sizeof(*regset), GFP_KERNEL);
138 if (!regset)
139 return;
140
141 regset->regs = bcm2835_thermal_regs;
142 regset->nregs = ARRAY_SIZE(bcm2835_thermal_regs);
143 regset->base = data->regs;
144
145 debugfs_create_regset32("regset", 0444, data->debugfsdir, regset);
146}
147
148static struct thermal_zone_of_device_ops bcm2835_thermal_ops = {
149 .get_temp = bcm2835_thermal_get_temp,
150};
151
152/*
153 * Note: as per Raspberry Foundation FAQ
154 * (https://www.raspberrypi.org/help/faqs/#performanceOperatingTemperature)
155 * the recommended temperature range for the SoC -40C to +85C
156 * so the trip limit is set to 80C.
157 * this applies to all the BCM283X SoC
158 */
159
160static const struct of_device_id bcm2835_thermal_of_match_table[] = {
161 {
162 .compatible = "brcm,bcm2835-thermal",
163 },
164 {
165 .compatible = "brcm,bcm2836-thermal",
166 },
167 {
168 .compatible = "brcm,bcm2837-thermal",
169 },
170 {},
171};
172MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table);
173
174static int bcm2835_thermal_probe(struct platform_device *pdev)
175{
176 const struct of_device_id *match;
177 struct thermal_zone_device *tz;
178 struct bcm2835_thermal_data *data;
179 struct resource *res;
180 int err = 0;
181 u32 val;
182 unsigned long rate;
183
184 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
185 if (!data)
186 return -ENOMEM;
187
188 match = of_match_device(bcm2835_thermal_of_match_table,
189 &pdev->dev);
190 if (!match)
191 return -EINVAL;
192
193 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
194 data->regs = devm_ioremap_resource(&pdev->dev, res);
195 if (IS_ERR(data->regs)) {
196 err = PTR_ERR(data->regs);
197 dev_err(&pdev->dev, "Could not get registers: %d\n", err);
198 return err;
199 }
200
201 data->clk = devm_clk_get(&pdev->dev, NULL);
202 if (IS_ERR(data->clk)) {
203 err = PTR_ERR(data->clk);
204 if (err != -EPROBE_DEFER)
205 dev_err(&pdev->dev, "Could not get clk: %d\n", err);
206 return err;
207 }
208
209 err = clk_prepare_enable(data->clk);
210 if (err)
211 return err;
212
213 rate = clk_get_rate(data->clk);
214 if ((rate < 1920000) || (rate > 5000000))
215 dev_warn(&pdev->dev,
216 "Clock %pCn running at %pCr Hz is outside of the recommended range: 1.92 to 5MHz\n",
217 data->clk, data->clk);
218
219 /* register of thermal sensor and get info from DT */
220 tz = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
221 &bcm2835_thermal_ops);
222 if (IS_ERR(tz)) {
223 err = PTR_ERR(tz);
224 dev_err(&pdev->dev,
225 "Failed to register the thermal device: %d\n",
226 err);
227 goto err_clk;
228 }
229
230 /*
231 * right now the FW does set up the HW-block, so we are not
232 * touching the configuration registers.
233 * But if the HW is not enabled, then set it up
234 * using "sane" values used by the firmware right now.
235 */
236 val = readl(data->regs + BCM2835_TS_TSENSCTL);
237 if (!(val & BCM2835_TS_TSENSCTL_RSTB)) {
238 int trip_temp, offset, slope;
239
240 slope = thermal_zone_get_slope(tz);
241 offset = thermal_zone_get_offset(tz);
242 /*
243 * For now we deal only with critical, otherwise
244 * would need to iterate
245 */
246 err = tz->ops->get_trip_temp(tz, 0, &trip_temp);
247 if (err < 0) {
248 err = PTR_ERR(tz);
249 dev_err(&pdev->dev,
250 "Not able to read trip_temp: %d\n",
251 err);
252 goto err_tz;
253 }
254
255 /* set bandgap reference voltage and enable voltage regulator */
256 val = (BCM2835_TS_TSENSCTL_CTRL_DEFAULT <<
257 BCM2835_TS_TSENSCTL_CTRL_SHIFT) |
258 BCM2835_TS_TSENSCTL_REGULEN;
259
260 /* use the recommended reset duration */
261 val |= (0xFE << BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT);
262
263 /* trip_adc value from info */
264 val |= bcm2835_thermal_temp2adc(trip_temp,
265 offset,
266 slope)
267 << BCM2835_TS_TSENSCTL_THOLD_SHIFT;
268
269 /* write the value back to the register as 2 steps */
270 writel(val, data->regs + BCM2835_TS_TSENSCTL);
271 val |= BCM2835_TS_TSENSCTL_RSTB;
272 writel(val, data->regs + BCM2835_TS_TSENSCTL);
273 }
274
275 data->tz = tz;
276
277 platform_set_drvdata(pdev, tz);
278
279 bcm2835_thermal_debugfs(pdev);
280
281 return 0;
282err_tz:
283 thermal_zone_of_sensor_unregister(&pdev->dev, tz);
284err_clk:
285 clk_disable_unprepare(data->clk);
286
287 return err;
288}
289
290static int bcm2835_thermal_remove(struct platform_device *pdev)
291{
292 struct thermal_zone_device *tz = platform_get_drvdata(pdev);
293 struct bcm2835_thermal_data *data = tz->devdata;
294
295 debugfs_remove_recursive(data->debugfsdir);
296 thermal_zone_of_sensor_unregister(&pdev->dev, tz);
297 clk_disable_unprepare(data->clk);
298
299 return 0;
300}
301
302static struct platform_driver bcm2835_thermal_driver = {
303 .probe = bcm2835_thermal_probe,
304 .remove = bcm2835_thermal_remove,
305 .driver = {
306 .name = "bcm2835_thermal",
307 .of_match_table = bcm2835_thermal_of_match_table,
308 },
309};
310module_platform_driver(bcm2835_thermal_driver);
311
312MODULE_AUTHOR("Martin Sperl");
313MODULE_DESCRIPTION("Thermal driver for bcm2835 chip");
314MODULE_LICENSE("GPL");
diff --git a/drivers/thermal/broadcom/ns-thermal.c b/drivers/thermal/broadcom/ns-thermal.c
new file mode 100644
index 000000000000..322e741a2463
--- /dev/null
+++ b/drivers/thermal/broadcom/ns-thermal.c
@@ -0,0 +1,106 @@
1/*
2 * Copyright (C) 2017 Rafał Miłecki <rafal@milecki.pl>
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 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/of_address.h>
11#include <linux/platform_device.h>
12#include <linux/thermal.h>
13
14#define PVTMON_CONTROL0 0x00
15#define PVTMON_CONTROL0_SEL_MASK 0x0000000e
16#define PVTMON_CONTROL0_SEL_TEMP_MONITOR 0x00000000
17#define PVTMON_CONTROL0_SEL_TEST_MODE 0x0000000e
18#define PVTMON_STATUS 0x08
19
20struct ns_thermal {
21 struct thermal_zone_device *tz;
22 void __iomem *pvtmon;
23};
24
25static int ns_thermal_get_temp(void *data, int *temp)
26{
27 struct ns_thermal *ns_thermal = data;
28 int offset = thermal_zone_get_offset(ns_thermal->tz);
29 int slope = thermal_zone_get_slope(ns_thermal->tz);
30 u32 val;
31
32 val = readl(ns_thermal->pvtmon + PVTMON_CONTROL0);
33 if ((val & PVTMON_CONTROL0_SEL_MASK) != PVTMON_CONTROL0_SEL_TEMP_MONITOR) {
34 /* Clear current mode selection */
35 val &= ~PVTMON_CONTROL0_SEL_MASK;
36
37 /* Set temp monitor mode (it's the default actually) */
38 val |= PVTMON_CONTROL0_SEL_TEMP_MONITOR;
39
40 writel(val, ns_thermal->pvtmon + PVTMON_CONTROL0);
41 }
42
43 val = readl(ns_thermal->pvtmon + PVTMON_STATUS);
44 *temp = slope * val + offset;
45
46 return 0;
47}
48
49static const struct thermal_zone_of_device_ops ns_thermal_ops = {
50 .get_temp = ns_thermal_get_temp,
51};
52
53static int ns_thermal_probe(struct platform_device *pdev)
54{
55 struct device *dev = &pdev->dev;
56 struct ns_thermal *ns_thermal;
57
58 ns_thermal = devm_kzalloc(dev, sizeof(*ns_thermal), GFP_KERNEL);
59 if (!ns_thermal)
60 return -ENOMEM;
61
62 ns_thermal->pvtmon = of_iomap(dev_of_node(dev), 0);
63 if (WARN_ON(!ns_thermal->pvtmon))
64 return -ENOENT;
65
66 ns_thermal->tz = devm_thermal_zone_of_sensor_register(dev, 0,
67 ns_thermal,
68 &ns_thermal_ops);
69 if (IS_ERR(ns_thermal->tz)) {
70 iounmap(ns_thermal->pvtmon);
71 return PTR_ERR(ns_thermal->tz);
72 }
73
74 platform_set_drvdata(pdev, ns_thermal);
75
76 return 0;
77}
78
79static int ns_thermal_remove(struct platform_device *pdev)
80{
81 struct ns_thermal *ns_thermal = platform_get_drvdata(pdev);
82
83 iounmap(ns_thermal->pvtmon);
84
85 return 0;
86}
87
88static const struct of_device_id ns_thermal_of_match[] = {
89 { .compatible = "brcm,ns-thermal", },
90 {},
91};
92MODULE_DEVICE_TABLE(of, ns_thermal_of_match);
93
94static struct platform_driver ns_thermal_driver = {
95 .probe = ns_thermal_probe,
96 .remove = ns_thermal_remove,
97 .driver = {
98 .name = "ns-thermal",
99 .of_match_table = ns_thermal_of_match,
100 },
101};
102module_platform_driver(ns_thermal_driver);
103
104MODULE_AUTHOR("Rafał Miłecki <rafal@milecki.pl>");
105MODULE_DESCRIPTION("Northstar thermal driver");
106MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/da9062-thermal.c b/drivers/thermal/da9062-thermal.c
new file mode 100644
index 000000000000..dd8dd947b7f0
--- /dev/null
+++ b/drivers/thermal/da9062-thermal.c
@@ -0,0 +1,315 @@
1/*
2 * Thermal device driver for DA9062 and DA9061
3 * Copyright (C) 2017 Dialog Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16/* When over-temperature is reached, an interrupt from the device will be
17 * triggered. Following this event the interrupt will be disabled and
18 * periodic transmission of uevents (HOT trip point) should define the
19 * first level of temperature supervision. It is expected that any final
20 * implementation of the thermal driver will include a .notify() function
21 * to implement these uevents to userspace.
22 *
23 * These uevents are intended to indicate non-invasive temperature control
24 * of the system, where the necessary measures for cooling are the
25 * responsibility of the host software. Once the temperature falls again,
26 * the IRQ is re-enabled so the start of a new over-temperature event can
27 * be detected without constant software monitoring.
28 */
29
30#include <linux/errno.h>
31#include <linux/interrupt.h>
32#include <linux/module.h>
33#include <linux/of.h>
34#include <linux/platform_device.h>
35#include <linux/regmap.h>
36#include <linux/thermal.h>
37#include <linux/workqueue.h>
38
39#include <linux/mfd/da9062/core.h>
40#include <linux/mfd/da9062/registers.h>
41
42/* Minimum, maximum and default polling millisecond periods are provided
43 * here as an example. It is expected that any final implementation to also
44 * include a modification of these settings to match the required
45 * application.
46 */
47#define DA9062_DEFAULT_POLLING_MS_PERIOD 3000
48#define DA9062_MAX_POLLING_MS_PERIOD 10000
49#define DA9062_MIN_POLLING_MS_PERIOD 1000
50
51#define DA9062_MILLI_CELSIUS(t) ((t) * 1000)
52
53struct da9062_thermal_config {
54 const char *name;
55};
56
57struct da9062_thermal {
58 struct da9062 *hw;
59 struct delayed_work work;
60 struct thermal_zone_device *zone;
61 enum thermal_device_mode mode;
62 struct mutex lock; /* protection for da9062_thermal temperature */
63 int temperature;
64 int irq;
65 const struct da9062_thermal_config *config;
66 struct device *dev;
67};
68
69static void da9062_thermal_poll_on(struct work_struct *work)
70{
71 struct da9062_thermal *thermal = container_of(work,
72 struct da9062_thermal,
73 work.work);
74 unsigned long delay;
75 unsigned int val;
76 int ret;
77
78 /* clear E_TEMP */
79 ret = regmap_write(thermal->hw->regmap,
80 DA9062AA_EVENT_B,
81 DA9062AA_E_TEMP_MASK);
82 if (ret < 0) {
83 dev_err(thermal->dev,
84 "Cannot clear the TJUNC temperature status\n");
85 goto err_enable_irq;
86 }
87
88 /* Now read E_TEMP again: it is acting like a status bit.
89 * If over-temperature, then this status will be true.
90 * If not over-temperature, this status will be false.
91 */
92 ret = regmap_read(thermal->hw->regmap,
93 DA9062AA_EVENT_B,
94 &val);
95 if (ret < 0) {
96 dev_err(thermal->dev,
97 "Cannot check the TJUNC temperature status\n");
98 goto err_enable_irq;
99 }
100
101 if (val & DA9062AA_E_TEMP_MASK) {
102 mutex_lock(&thermal->lock);
103 thermal->temperature = DA9062_MILLI_CELSIUS(125);
104 mutex_unlock(&thermal->lock);
105 thermal_zone_device_update(thermal->zone,
106 THERMAL_EVENT_UNSPECIFIED);
107
108 delay = msecs_to_jiffies(thermal->zone->passive_delay);
109 schedule_delayed_work(&thermal->work, delay);
110 return;
111 }
112
113 mutex_lock(&thermal->lock);
114 thermal->temperature = DA9062_MILLI_CELSIUS(0);
115 mutex_unlock(&thermal->lock);
116 thermal_zone_device_update(thermal->zone,
117 THERMAL_EVENT_UNSPECIFIED);
118
119err_enable_irq:
120 enable_irq(thermal->irq);
121}
122
123static irqreturn_t da9062_thermal_irq_handler(int irq, void *data)
124{
125 struct da9062_thermal *thermal = data;
126
127 disable_irq_nosync(thermal->irq);
128 schedule_delayed_work(&thermal->work, 0);
129
130 return IRQ_HANDLED;
131}
132
133static int da9062_thermal_get_mode(struct thermal_zone_device *z,
134 enum thermal_device_mode *mode)
135{
136 struct da9062_thermal *thermal = z->devdata;
137 *mode = thermal->mode;
138 return 0;
139}
140
141static int da9062_thermal_get_trip_type(struct thermal_zone_device *z,
142 int trip,
143 enum thermal_trip_type *type)
144{
145 struct da9062_thermal *thermal = z->devdata;
146
147 switch (trip) {
148 case 0:
149 *type = THERMAL_TRIP_HOT;
150 break;
151 default:
152 dev_err(thermal->dev,
153 "Driver does not support more than 1 trip-wire\n");
154 return -EINVAL;
155 }
156
157 return 0;
158}
159
160static int da9062_thermal_get_trip_temp(struct thermal_zone_device *z,
161 int trip,
162 int *temp)
163{
164 struct da9062_thermal *thermal = z->devdata;
165
166 switch (trip) {
167 case 0:
168 *temp = DA9062_MILLI_CELSIUS(125);
169 break;
170 default:
171 dev_err(thermal->dev,
172 "Driver does not support more than 1 trip-wire\n");
173 return -EINVAL;
174 }
175
176 return 0;
177}
178
179static int da9062_thermal_get_temp(struct thermal_zone_device *z,
180 int *temp)
181{
182 struct da9062_thermal *thermal = z->devdata;
183
184 mutex_lock(&thermal->lock);
185 *temp = thermal->temperature;
186 mutex_unlock(&thermal->lock);
187
188 return 0;
189}
190
191static struct thermal_zone_device_ops da9062_thermal_ops = {
192 .get_temp = da9062_thermal_get_temp,
193 .get_mode = da9062_thermal_get_mode,
194 .get_trip_type = da9062_thermal_get_trip_type,
195 .get_trip_temp = da9062_thermal_get_trip_temp,
196};
197
198static const struct da9062_thermal_config da9062_config = {
199 .name = "da9062-thermal",
200};
201
202static const struct of_device_id da9062_compatible_reg_id_table[] = {
203 { .compatible = "dlg,da9062-thermal", .data = &da9062_config },
204 { },
205};
206
207MODULE_DEVICE_TABLE(of, da9062_compatible_reg_id_table);
208
209static int da9062_thermal_probe(struct platform_device *pdev)
210{
211 struct da9062 *chip = dev_get_drvdata(pdev->dev.parent);
212 struct da9062_thermal *thermal;
213 unsigned int pp_tmp = DA9062_DEFAULT_POLLING_MS_PERIOD;
214 const struct of_device_id *match;
215 int ret = 0;
216
217 match = of_match_node(da9062_compatible_reg_id_table,
218 pdev->dev.of_node);
219 if (!match)
220 return -ENXIO;
221
222 if (pdev->dev.of_node) {
223 if (!of_property_read_u32(pdev->dev.of_node,
224 "polling-delay-passive",
225 &pp_tmp)) {
226 if (pp_tmp < DA9062_MIN_POLLING_MS_PERIOD ||
227 pp_tmp > DA9062_MAX_POLLING_MS_PERIOD) {
228 dev_warn(&pdev->dev,
229 "Out-of-range polling period %d ms\n",
230 pp_tmp);
231 pp_tmp = DA9062_DEFAULT_POLLING_MS_PERIOD;
232 }
233 }
234 }
235
236 thermal = devm_kzalloc(&pdev->dev, sizeof(struct da9062_thermal),
237 GFP_KERNEL);
238 if (!thermal) {
239 ret = -ENOMEM;
240 goto err;
241 }
242
243 thermal->config = match->data;
244 thermal->hw = chip;
245 thermal->mode = THERMAL_DEVICE_ENABLED;
246 thermal->dev = &pdev->dev;
247
248 INIT_DELAYED_WORK(&thermal->work, da9062_thermal_poll_on);
249 mutex_init(&thermal->lock);
250
251 thermal->zone = thermal_zone_device_register(thermal->config->name,
252 1, 0, thermal,
253 &da9062_thermal_ops, NULL, pp_tmp,
254 0);
255 if (IS_ERR(thermal->zone)) {
256 dev_err(&pdev->dev, "Cannot register thermal zone device\n");
257 ret = PTR_ERR(thermal->zone);
258 goto err;
259 }
260
261 dev_dbg(&pdev->dev,
262 "TJUNC temperature polling period set at %d ms\n",
263 thermal->zone->passive_delay);
264
265 ret = platform_get_irq_byname(pdev, "THERMAL");
266 if (ret < 0) {
267 dev_err(&pdev->dev, "Failed to get platform IRQ.\n");
268 goto err_zone;
269 }
270 thermal->irq = ret;
271
272 ret = request_threaded_irq(thermal->irq, NULL,
273 da9062_thermal_irq_handler,
274 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
275 "THERMAL", thermal);
276 if (ret) {
277 dev_err(&pdev->dev,
278 "Failed to request thermal device IRQ.\n");
279 goto err_zone;
280 }
281
282 platform_set_drvdata(pdev, thermal);
283 return 0;
284
285err_zone:
286 thermal_zone_device_unregister(thermal->zone);
287err:
288 return ret;
289}
290
291static int da9062_thermal_remove(struct platform_device *pdev)
292{
293 struct da9062_thermal *thermal = platform_get_drvdata(pdev);
294
295 free_irq(thermal->irq, thermal);
296 cancel_delayed_work_sync(&thermal->work);
297 thermal_zone_device_unregister(thermal->zone);
298 return 0;
299}
300
301static struct platform_driver da9062_thermal_driver = {
302 .probe = da9062_thermal_probe,
303 .remove = da9062_thermal_remove,
304 .driver = {
305 .name = "da9062-thermal",
306 .of_match_table = da9062_compatible_reg_id_table,
307 },
308};
309
310module_platform_driver(da9062_thermal_driver);
311
312MODULE_AUTHOR("Steve Twiss");
313MODULE_DESCRIPTION("Thermal TJUNC device driver for Dialog DA9062 and DA9061");
314MODULE_LICENSE("GPL");
315MODULE_ALIAS("platform:da9062-thermal");
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
index 1aff7fde54b1..7737f14846f9 100644
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mtk_thermal.c
@@ -191,7 +191,7 @@ static const int mt8173_bank_data[MT8173_NUM_ZONES][3] = {
191}; 191};
192 192
193static const int mt8173_msr[MT8173_NUM_SENSORS_PER_ZONE] = { 193static const int mt8173_msr[MT8173_NUM_SENSORS_PER_ZONE] = {
194 TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR2 194 TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
195}; 195};
196 196
197static const int mt8173_adcpnp[MT8173_NUM_SENSORS_PER_ZONE] = { 197static const int mt8173_adcpnp[MT8173_NUM_SENSORS_PER_ZONE] = {
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index d33c845244b1..37fcefd06d9f 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -20,12 +20,14 @@
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/mutex.h>
24#include <linux/of_device.h> 23#include <linux/of_device.h>
25#include <linux/platform_device.h> 24#include <linux/platform_device.h>
26#include <linux/pm_runtime.h> 25#include <linux/pm_runtime.h>
26#include <linux/spinlock.h>
27#include <linux/thermal.h> 27#include <linux/thermal.h>
28 28
29#include "thermal_core.h"
30
29/* Register offsets */ 31/* Register offsets */
30#define REG_GEN3_IRQSTR 0x04 32#define REG_GEN3_IRQSTR 0x04
31#define REG_GEN3_IRQMSK 0x08 33#define REG_GEN3_IRQMSK 0x08
@@ -41,6 +43,14 @@
41#define REG_GEN3_THCODE2 0x54 43#define REG_GEN3_THCODE2 0x54
42#define REG_GEN3_THCODE3 0x58 44#define REG_GEN3_THCODE3 0x58
43 45
46/* IRQ{STR,MSK,EN} bits */
47#define IRQ_TEMP1 BIT(0)
48#define IRQ_TEMP2 BIT(1)
49#define IRQ_TEMP3 BIT(2)
50#define IRQ_TEMPD1 BIT(3)
51#define IRQ_TEMPD2 BIT(4)
52#define IRQ_TEMPD3 BIT(5)
53
44/* CTSR bits */ 54/* CTSR bits */
45#define CTSR_PONM BIT(8) 55#define CTSR_PONM BIT(8)
46#define CTSR_AOUT BIT(7) 56#define CTSR_AOUT BIT(7)
@@ -72,11 +82,15 @@ struct rcar_gen3_thermal_tsc {
72 void __iomem *base; 82 void __iomem *base;
73 struct thermal_zone_device *zone; 83 struct thermal_zone_device *zone;
74 struct equation_coefs coef; 84 struct equation_coefs coef;
75 struct mutex lock; 85 int low;
86 int high;
76}; 87};
77 88
78struct rcar_gen3_thermal_priv { 89struct rcar_gen3_thermal_priv {
79 struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM]; 90 struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM];
91 unsigned int num_tscs;
92 spinlock_t lock; /* Protect interrupts on and off */
93 const struct rcar_gen3_thermal_data *data;
80}; 94};
81 95
82struct rcar_gen3_thermal_data { 96struct rcar_gen3_thermal_data {
@@ -114,6 +128,7 @@ static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc,
114 128
115#define FIXPT_SHIFT 7 129#define FIXPT_SHIFT 7
116#define FIXPT_INT(_x) ((_x) << FIXPT_SHIFT) 130#define FIXPT_INT(_x) ((_x) << FIXPT_SHIFT)
131#define INT_FIXPT(_x) ((_x) >> FIXPT_SHIFT)
117#define FIXPT_DIV(_a, _b) DIV_ROUND_CLOSEST(((_a) << FIXPT_SHIFT), (_b)) 132#define FIXPT_DIV(_a, _b) DIV_ROUND_CLOSEST(((_a) << FIXPT_SHIFT), (_b))
118#define FIXPT_TO_MCELSIUS(_x) ((_x) * 1000 >> FIXPT_SHIFT) 133#define FIXPT_TO_MCELSIUS(_x) ((_x) * 1000 >> FIXPT_SHIFT)
119 134
@@ -163,16 +178,12 @@ static int rcar_gen3_thermal_get_temp(void *devdata, int *temp)
163 u32 reg; 178 u32 reg;
164 179
165 /* Read register and convert to mili Celsius */ 180 /* Read register and convert to mili Celsius */
166 mutex_lock(&tsc->lock);
167
168 reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK; 181 reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK;
169 182
170 val1 = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b1, tsc->coef.a1); 183 val1 = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b1, tsc->coef.a1);
171 val2 = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b2, tsc->coef.a2); 184 val2 = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b2, tsc->coef.a2);
172 mcelsius = FIXPT_TO_MCELSIUS((val1 + val2) / 2); 185 mcelsius = FIXPT_TO_MCELSIUS((val1 + val2) / 2);
173 186
174 mutex_unlock(&tsc->lock);
175
176 /* Make sure we are inside specifications */ 187 /* Make sure we are inside specifications */
177 if ((mcelsius < MCELSIUS(-40)) || (mcelsius > MCELSIUS(125))) 188 if ((mcelsius < MCELSIUS(-40)) || (mcelsius > MCELSIUS(125)))
178 return -EIO; 189 return -EIO;
@@ -183,10 +194,90 @@ static int rcar_gen3_thermal_get_temp(void *devdata, int *temp)
183 return 0; 194 return 0;
184} 195}
185 196
197static int rcar_gen3_thermal_mcelsius_to_temp(struct rcar_gen3_thermal_tsc *tsc,
198 int mcelsius)
199{
200 int celsius, val1, val2;
201
202 celsius = DIV_ROUND_CLOSEST(mcelsius, 1000);
203 val1 = celsius * tsc->coef.a1 + tsc->coef.b1;
204 val2 = celsius * tsc->coef.a2 + tsc->coef.b2;
205
206 return INT_FIXPT((val1 + val2) / 2);
207}
208
209static int rcar_gen3_thermal_set_trips(void *devdata, int low, int high)
210{
211 struct rcar_gen3_thermal_tsc *tsc = devdata;
212
213 low = clamp_val(low, -40000, 125000);
214 high = clamp_val(high, -40000, 125000);
215
216 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP1,
217 rcar_gen3_thermal_mcelsius_to_temp(tsc, low));
218
219 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP2,
220 rcar_gen3_thermal_mcelsius_to_temp(tsc, high));
221
222 tsc->low = low;
223 tsc->high = high;
224
225 return 0;
226}
227
186static struct thermal_zone_of_device_ops rcar_gen3_tz_of_ops = { 228static struct thermal_zone_of_device_ops rcar_gen3_tz_of_ops = {
187 .get_temp = rcar_gen3_thermal_get_temp, 229 .get_temp = rcar_gen3_thermal_get_temp,
230 .set_trips = rcar_gen3_thermal_set_trips,
188}; 231};
189 232
233static void rcar_thermal_irq_set(struct rcar_gen3_thermal_priv *priv, bool on)
234{
235 unsigned int i;
236 u32 val = on ? IRQ_TEMPD1 | IRQ_TEMP2 : 0;
237
238 for (i = 0; i < priv->num_tscs; i++)
239 rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQMSK, val);
240}
241
242static irqreturn_t rcar_gen3_thermal_irq(int irq, void *data)
243{
244 struct rcar_gen3_thermal_priv *priv = data;
245 u32 status;
246 int i, ret = IRQ_HANDLED;
247
248 spin_lock(&priv->lock);
249 for (i = 0; i < priv->num_tscs; i++) {
250 status = rcar_gen3_thermal_read(priv->tscs[i], REG_GEN3_IRQSTR);
251 rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQSTR, 0);
252 if (status)
253 ret = IRQ_WAKE_THREAD;
254 }
255
256 if (ret == IRQ_WAKE_THREAD)
257 rcar_thermal_irq_set(priv, false);
258
259 spin_unlock(&priv->lock);
260
261 return ret;
262}
263
264static irqreturn_t rcar_gen3_thermal_irq_thread(int irq, void *data)
265{
266 struct rcar_gen3_thermal_priv *priv = data;
267 unsigned long flags;
268 int i;
269
270 for (i = 0; i < priv->num_tscs; i++)
271 thermal_zone_device_update(priv->tscs[i]->zone,
272 THERMAL_EVENT_UNSPECIFIED);
273
274 spin_lock_irqsave(&priv->lock, flags);
275 rcar_thermal_irq_set(priv, true);
276 spin_unlock_irqrestore(&priv->lock, flags);
277
278 return IRQ_HANDLED;
279}
280
190static void r8a7795_thermal_init(struct rcar_gen3_thermal_tsc *tsc) 281static void r8a7795_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
191{ 282{
192 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_THBGR); 283 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_THBGR);
@@ -195,7 +286,11 @@ static void r8a7795_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
195 usleep_range(1000, 2000); 286 usleep_range(1000, 2000);
196 287
197 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_PONM); 288 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_PONM);
289
198 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F); 290 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F);
291 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0);
292 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN, IRQ_TEMPD1 | IRQ_TEMP2);
293
199 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, 294 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR,
200 CTSR_PONM | CTSR_AOUT | CTSR_THBGR | CTSR_VMEN); 295 CTSR_PONM | CTSR_AOUT | CTSR_THBGR | CTSR_VMEN);
201 296
@@ -219,9 +314,14 @@ static void r8a7796_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
219 usleep_range(1000, 2000); 314 usleep_range(1000, 2000);
220 315
221 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F); 316 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F);
317 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0);
318 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN, IRQ_TEMPD1 | IRQ_TEMP2);
319
222 reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR); 320 reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR);
223 reg_val |= THCTR_THSST; 321 reg_val |= THCTR_THSST;
224 rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val); 322 rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val);
323
324 usleep_range(1000, 2000);
225} 325}
226 326
227static const struct rcar_gen3_thermal_data r8a7795_data = { 327static const struct rcar_gen3_thermal_data r8a7795_data = {
@@ -255,9 +355,8 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
255 struct device *dev = &pdev->dev; 355 struct device *dev = &pdev->dev;
256 struct resource *res; 356 struct resource *res;
257 struct thermal_zone_device *zone; 357 struct thermal_zone_device *zone;
258 int ret, i; 358 int ret, irq, i;
259 const struct rcar_gen3_thermal_data *match_data = 359 char *irqname;
260 of_device_get_match_data(dev);
261 360
262 /* default values if FUSEs are missing */ 361 /* default values if FUSEs are missing */
263 /* TODO: Read values from hardware on supported platforms */ 362 /* TODO: Read values from hardware on supported platforms */
@@ -272,24 +371,50 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
272 if (!priv) 371 if (!priv)
273 return -ENOMEM; 372 return -ENOMEM;
274 373
374 priv->data = of_device_get_match_data(dev);
375
376 spin_lock_init(&priv->lock);
377
275 platform_set_drvdata(pdev, priv); 378 platform_set_drvdata(pdev, priv);
276 379
380 /*
381 * Request 2 (of the 3 possible) IRQs, the driver only needs to
382 * to trigger on the low and high trip points of the current
383 * temp window at this point.
384 */
385 for (i = 0; i < 2; i++) {
386 irq = platform_get_irq(pdev, i);
387 if (irq < 0)
388 return irq;
389
390 irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:ch%d",
391 dev_name(dev), i);
392 if (!irqname)
393 return -ENOMEM;
394
395 ret = devm_request_threaded_irq(dev, irq, rcar_gen3_thermal_irq,
396 rcar_gen3_thermal_irq_thread,
397 IRQF_SHARED, irqname, priv);
398 if (ret)
399 return ret;
400 }
401
277 pm_runtime_enable(dev); 402 pm_runtime_enable(dev);
278 pm_runtime_get_sync(dev); 403 pm_runtime_get_sync(dev);
279 404
280 for (i = 0; i < TSC_MAX_NUM; i++) { 405 for (i = 0; i < TSC_MAX_NUM; i++) {
281 struct rcar_gen3_thermal_tsc *tsc; 406 struct rcar_gen3_thermal_tsc *tsc;
282 407
408 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
409 if (!res)
410 break;
411
283 tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL); 412 tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL);
284 if (!tsc) { 413 if (!tsc) {
285 ret = -ENOMEM; 414 ret = -ENOMEM;
286 goto error_unregister; 415 goto error_unregister;
287 } 416 }
288 417
289 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
290 if (!res)
291 break;
292
293 tsc->base = devm_ioremap_resource(dev, res); 418 tsc->base = devm_ioremap_resource(dev, res);
294 if (IS_ERR(tsc->base)) { 419 if (IS_ERR(tsc->base)) {
295 ret = PTR_ERR(tsc->base); 420 ret = PTR_ERR(tsc->base);
@@ -297,9 +422,8 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
297 } 422 }
298 423
299 priv->tscs[i] = tsc; 424 priv->tscs[i] = tsc;
300 mutex_init(&tsc->lock);
301 425
302 match_data->thermal_init(tsc); 426 priv->data->thermal_init(tsc);
303 rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]); 427 rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]);
304 428
305 zone = devm_thermal_zone_of_sensor_register(dev, i, tsc, 429 zone = devm_thermal_zone_of_sensor_register(dev, i, tsc,
@@ -310,8 +434,23 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
310 goto error_unregister; 434 goto error_unregister;
311 } 435 }
312 tsc->zone = zone; 436 tsc->zone = zone;
437
438 ret = of_thermal_get_ntrips(tsc->zone);
439 if (ret < 0)
440 goto error_unregister;
441
442 dev_info(dev, "TSC%d: Loaded %d trip points\n", i, ret);
313 } 443 }
314 444
445 priv->num_tscs = i;
446
447 if (!priv->num_tscs) {
448 ret = -ENODEV;
449 goto error_unregister;
450 }
451
452 rcar_thermal_irq_set(priv, true);
453
315 return 0; 454 return 0;
316 455
317error_unregister: 456error_unregister:
@@ -320,9 +459,39 @@ error_unregister:
320 return ret; 459 return ret;
321} 460}
322 461
462static int __maybe_unused rcar_gen3_thermal_suspend(struct device *dev)
463{
464 struct rcar_gen3_thermal_priv *priv = dev_get_drvdata(dev);
465
466 rcar_thermal_irq_set(priv, false);
467
468 return 0;
469}
470
471static int __maybe_unused rcar_gen3_thermal_resume(struct device *dev)
472{
473 struct rcar_gen3_thermal_priv *priv = dev_get_drvdata(dev);
474 unsigned int i;
475
476 for (i = 0; i < priv->num_tscs; i++) {
477 struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
478
479 priv->data->thermal_init(tsc);
480 rcar_gen3_thermal_set_trips(tsc, tsc->low, tsc->high);
481 }
482
483 rcar_thermal_irq_set(priv, true);
484
485 return 0;
486}
487
488static SIMPLE_DEV_PM_OPS(rcar_gen3_thermal_pm_ops, rcar_gen3_thermal_suspend,
489 rcar_gen3_thermal_resume);
490
323static struct platform_driver rcar_gen3_thermal_driver = { 491static struct platform_driver rcar_gen3_thermal_driver = {
324 .driver = { 492 .driver = {
325 .name = "rcar_gen3_thermal", 493 .name = "rcar_gen3_thermal",
494 .pm = &rcar_gen3_thermal_pm_ops,
326 .of_match_table = rcar_gen3_thermal_dt_ids, 495 .of_match_table = rcar_gen3_thermal_dt_ids,
327 }, 496 },
328 .probe = rcar_gen3_thermal_probe, 497 .probe = rcar_gen3_thermal_probe,
diff --git a/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c b/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
index 118d7d847715..4167373327d9 100644
--- a/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
+++ b/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
@@ -410,8 +410,6 @@ const struct ti_bandgap_data dra752_data = {
410 .domain = "cpu", 410 .domain = "cpu",
411 .register_cooling = ti_thermal_register_cpu_cooling, 411 .register_cooling = ti_thermal_register_cpu_cooling,
412 .unregister_cooling = ti_thermal_unregister_cpu_cooling, 412 .unregister_cooling = ti_thermal_unregister_cpu_cooling,
413 .slope = DRA752_GRADIENT_SLOPE,
414 .constant = DRA752_GRADIENT_CONST,
415 .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB, 413 .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
416 .constant_pcb = DRA752_GRADIENT_CONST_W_PCB, 414 .constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
417 }, 415 },
@@ -419,8 +417,6 @@ const struct ti_bandgap_data dra752_data = {
419 .registers = &dra752_gpu_temp_sensor_registers, 417 .registers = &dra752_gpu_temp_sensor_registers,
420 .ts_data = &dra752_gpu_temp_sensor_data, 418 .ts_data = &dra752_gpu_temp_sensor_data,
421 .domain = "gpu", 419 .domain = "gpu",
422 .slope = DRA752_GRADIENT_SLOPE,
423 .constant = DRA752_GRADIENT_CONST,
424 .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB, 420 .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
425 .constant_pcb = DRA752_GRADIENT_CONST_W_PCB, 421 .constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
426 }, 422 },
@@ -428,8 +424,6 @@ const struct ti_bandgap_data dra752_data = {
428 .registers = &dra752_core_temp_sensor_registers, 424 .registers = &dra752_core_temp_sensor_registers,
429 .ts_data = &dra752_core_temp_sensor_data, 425 .ts_data = &dra752_core_temp_sensor_data,
430 .domain = "core", 426 .domain = "core",
431 .slope = DRA752_GRADIENT_SLOPE,
432 .constant = DRA752_GRADIENT_CONST,
433 .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB, 427 .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
434 .constant_pcb = DRA752_GRADIENT_CONST_W_PCB, 428 .constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
435 }, 429 },
@@ -437,8 +431,6 @@ const struct ti_bandgap_data dra752_data = {
437 .registers = &dra752_dspeve_temp_sensor_registers, 431 .registers = &dra752_dspeve_temp_sensor_registers,
438 .ts_data = &dra752_dspeve_temp_sensor_data, 432 .ts_data = &dra752_dspeve_temp_sensor_data,
439 .domain = "dspeve", 433 .domain = "dspeve",
440 .slope = DRA752_GRADIENT_SLOPE,
441 .constant = DRA752_GRADIENT_CONST,
442 .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB, 434 .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
443 .constant_pcb = DRA752_GRADIENT_CONST_W_PCB, 435 .constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
444 }, 436 },
@@ -446,8 +438,6 @@ const struct ti_bandgap_data dra752_data = {
446 .registers = &dra752_iva_temp_sensor_registers, 438 .registers = &dra752_iva_temp_sensor_registers,
447 .ts_data = &dra752_iva_temp_sensor_data, 439 .ts_data = &dra752_iva_temp_sensor_data,
448 .domain = "iva", 440 .domain = "iva",
449 .slope = DRA752_GRADIENT_SLOPE,
450 .constant = DRA752_GRADIENT_CONST,
451 .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB, 441 .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
452 .constant_pcb = DRA752_GRADIENT_CONST_W_PCB, 442 .constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
453 }, 443 },
diff --git a/drivers/thermal/ti-soc-thermal/omap3-thermal-data.c b/drivers/thermal/ti-soc-thermal/omap3-thermal-data.c
index 3ee34340edab..c6d217913dd1 100644
--- a/drivers/thermal/ti-soc-thermal/omap3-thermal-data.c
+++ b/drivers/thermal/ti-soc-thermal/omap3-thermal-data.c
@@ -91,8 +91,6 @@ const struct ti_bandgap_data omap34xx_data = {
91 .registers = &omap34xx_mpu_temp_sensor_registers, 91 .registers = &omap34xx_mpu_temp_sensor_registers,
92 .ts_data = &omap34xx_mpu_temp_sensor_data, 92 .ts_data = &omap34xx_mpu_temp_sensor_data,
93 .domain = "cpu", 93 .domain = "cpu",
94 .slope = 0,
95 .constant = 20000,
96 .slope_pcb = 0, 94 .slope_pcb = 0,
97 .constant_pcb = 20000, 95 .constant_pcb = 20000,
98 .register_cooling = NULL, 96 .register_cooling = NULL,
@@ -164,8 +162,6 @@ const struct ti_bandgap_data omap36xx_data = {
164 .registers = &omap36xx_mpu_temp_sensor_registers, 162 .registers = &omap36xx_mpu_temp_sensor_registers,
165 .ts_data = &omap36xx_mpu_temp_sensor_data, 163 .ts_data = &omap36xx_mpu_temp_sensor_data,
166 .domain = "cpu", 164 .domain = "cpu",
167 .slope = 0,
168 .constant = 20000,
169 .slope_pcb = 0, 165 .slope_pcb = 0,
170 .constant_pcb = 20000, 166 .constant_pcb = 20000,
171 .register_cooling = NULL, 167 .register_cooling = NULL,
diff --git a/drivers/thermal/ti-soc-thermal/omap4-thermal-data.c b/drivers/thermal/ti-soc-thermal/omap4-thermal-data.c
index d255d33da9eb..fd1113360603 100644
--- a/drivers/thermal/ti-soc-thermal/omap4-thermal-data.c
+++ b/drivers/thermal/ti-soc-thermal/omap4-thermal-data.c
@@ -82,8 +82,6 @@ const struct ti_bandgap_data omap4430_data = {
82 .registers = &omap4430_mpu_temp_sensor_registers, 82 .registers = &omap4430_mpu_temp_sensor_registers,
83 .ts_data = &omap4430_mpu_temp_sensor_data, 83 .ts_data = &omap4430_mpu_temp_sensor_data,
84 .domain = "cpu", 84 .domain = "cpu",
85 .slope = OMAP_GRADIENT_SLOPE_4430,
86 .constant = OMAP_GRADIENT_CONST_4430,
87 .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4430, 85 .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4430,
88 .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4430, 86 .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4430,
89 .register_cooling = ti_thermal_register_cpu_cooling, 87 .register_cooling = ti_thermal_register_cpu_cooling,
@@ -222,8 +220,6 @@ const struct ti_bandgap_data omap4460_data = {
222 .registers = &omap4460_mpu_temp_sensor_registers, 220 .registers = &omap4460_mpu_temp_sensor_registers,
223 .ts_data = &omap4460_mpu_temp_sensor_data, 221 .ts_data = &omap4460_mpu_temp_sensor_data,
224 .domain = "cpu", 222 .domain = "cpu",
225 .slope = OMAP_GRADIENT_SLOPE_4460,
226 .constant = OMAP_GRADIENT_CONST_4460,
227 .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4460, 223 .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4460,
228 .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4460, 224 .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4460,
229 .register_cooling = ti_thermal_register_cpu_cooling, 225 .register_cooling = ti_thermal_register_cpu_cooling,
@@ -255,8 +251,6 @@ const struct ti_bandgap_data omap4470_data = {
255 .registers = &omap4460_mpu_temp_sensor_registers, 251 .registers = &omap4460_mpu_temp_sensor_registers,
256 .ts_data = &omap4460_mpu_temp_sensor_data, 252 .ts_data = &omap4460_mpu_temp_sensor_data,
257 .domain = "cpu", 253 .domain = "cpu",
258 .slope = OMAP_GRADIENT_SLOPE_4470,
259 .constant = OMAP_GRADIENT_CONST_4470,
260 .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4470, 254 .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4470,
261 .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4470, 255 .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4470,
262 .register_cooling = ti_thermal_register_cpu_cooling, 256 .register_cooling = ti_thermal_register_cpu_cooling,
diff --git a/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c b/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
index 79ff70c446ba..cd9a304fb571 100644
--- a/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
+++ b/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
@@ -336,8 +336,6 @@ const struct ti_bandgap_data omap5430_data = {
336 .domain = "cpu", 336 .domain = "cpu",
337 .register_cooling = ti_thermal_register_cpu_cooling, 337 .register_cooling = ti_thermal_register_cpu_cooling,
338 .unregister_cooling = ti_thermal_unregister_cpu_cooling, 338 .unregister_cooling = ti_thermal_unregister_cpu_cooling,
339 .slope = OMAP_GRADIENT_SLOPE_5430_CPU,
340 .constant = OMAP_GRADIENT_CONST_5430_CPU,
341 .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_CPU, 339 .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_CPU,
342 .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_CPU, 340 .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_CPU,
343 }, 341 },
@@ -345,8 +343,6 @@ const struct ti_bandgap_data omap5430_data = {
345 .registers = &omap5430_gpu_temp_sensor_registers, 343 .registers = &omap5430_gpu_temp_sensor_registers,
346 .ts_data = &omap5430_gpu_temp_sensor_data, 344 .ts_data = &omap5430_gpu_temp_sensor_data,
347 .domain = "gpu", 345 .domain = "gpu",
348 .slope = OMAP_GRADIENT_SLOPE_5430_GPU,
349 .constant = OMAP_GRADIENT_CONST_5430_GPU,
350 .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU, 346 .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU,
351 .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_GPU, 347 .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_GPU,
352 }, 348 },
diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.h b/drivers/thermal/ti-soc-thermal/ti-bandgap.h
index fe0adb898764..209c664c2823 100644
--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.h
+++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.h
@@ -254,8 +254,6 @@ struct ti_bandgap {
254 * @ts_data: pointer to struct with thresholds, limits of temperature sensor 254 * @ts_data: pointer to struct with thresholds, limits of temperature sensor
255 * @registers: pointer to the list of register offsets and bitfields 255 * @registers: pointer to the list of register offsets and bitfields
256 * @domain: the name of the domain where the sensor is located 256 * @domain: the name of the domain where the sensor is located
257 * @slope: sensor gradient slope info for hotspot extrapolation equation
258 * @constant: sensor gradient const info for hotspot extrapolation equation
259 * @slope_pcb: sensor gradient slope info for hotspot extrapolation equation 257 * @slope_pcb: sensor gradient slope info for hotspot extrapolation equation
260 * with no external influence 258 * with no external influence
261 * @constant_pcb: sensor gradient const info for hotspot extrapolation equation 259 * @constant_pcb: sensor gradient const info for hotspot extrapolation equation
@@ -274,8 +272,6 @@ struct ti_temp_sensor {
274 struct temp_sensor_registers *registers; 272 struct temp_sensor_registers *registers;
275 char *domain; 273 char *domain;
276 /* for hotspot extrapolation */ 274 /* for hotspot extrapolation */
277 const int slope;
278 const int constant;
279 const int slope_pcb; 275 const int slope_pcb;
280 const int constant_pcb; 276 const int constant_pcb;
281 int (*register_cooling)(struct ti_bandgap *bgp, int id); 277 int (*register_cooling)(struct ti_bandgap *bgp, int id);
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
index 0586bd0f2bab..02790f69e26c 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
@@ -96,8 +96,8 @@ static inline int __ti_thermal_get_temp(void *devdata, int *temp)
96 return ret; 96 return ret;
97 97
98 /* Default constants */ 98 /* Default constants */
99 slope = s->slope; 99 slope = thermal_zone_get_slope(data->ti_thermal);
100 constant = s->constant; 100 constant = thermal_zone_get_offset(data->ti_thermal);
101 101
102 pcb_tz = data->pcb_tz; 102 pcb_tz = data->pcb_tz;
103 /* In case pcb zone is available, use the extrapolation rule with it */ 103 /* In case pcb zone is available, use the extrapolation rule with it */
@@ -126,119 +126,6 @@ static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
126 return __ti_thermal_get_temp(data, temp); 126 return __ti_thermal_get_temp(data, temp);
127} 127}
128 128
129/* Bind callback functions for thermal zone */
130static int ti_thermal_bind(struct thermal_zone_device *thermal,
131 struct thermal_cooling_device *cdev)
132{
133 struct ti_thermal_data *data = thermal->devdata;
134 int id;
135
136 if (!data || IS_ERR(data))
137 return -ENODEV;
138
139 /* check if this is the cooling device we registered */
140 if (data->cool_dev != cdev)
141 return 0;
142
143 id = data->sensor_id;
144
145 /* Simple thing, two trips, one passive another critical */
146 return thermal_zone_bind_cooling_device(thermal, 0, cdev,
147 /* bind with min and max states defined by cpu_cooling */
148 THERMAL_NO_LIMIT,
149 THERMAL_NO_LIMIT,
150 THERMAL_WEIGHT_DEFAULT);
151}
152
153/* Unbind callback functions for thermal zone */
154static int ti_thermal_unbind(struct thermal_zone_device *thermal,
155 struct thermal_cooling_device *cdev)
156{
157 struct ti_thermal_data *data = thermal->devdata;
158
159 if (!data || IS_ERR(data))
160 return -ENODEV;
161
162 /* check if this is the cooling device we registered */
163 if (data->cool_dev != cdev)
164 return 0;
165
166 /* Simple thing, two trips, one passive another critical */
167 return thermal_zone_unbind_cooling_device(thermal, 0, cdev);
168}
169
170/* Get mode callback functions for thermal zone */
171static int ti_thermal_get_mode(struct thermal_zone_device *thermal,
172 enum thermal_device_mode *mode)
173{
174 struct ti_thermal_data *data = thermal->devdata;
175
176 if (data)
177 *mode = data->mode;
178
179 return 0;
180}
181
182/* Set mode callback functions for thermal zone */
183static int ti_thermal_set_mode(struct thermal_zone_device *thermal,
184 enum thermal_device_mode mode)
185{
186 struct ti_thermal_data *data = thermal->devdata;
187 struct ti_bandgap *bgp;
188
189 bgp = data->bgp;
190
191 if (!data->ti_thermal) {
192 dev_notice(&thermal->device, "thermal zone not registered\n");
193 return 0;
194 }
195
196 mutex_lock(&data->ti_thermal->lock);
197
198 if (mode == THERMAL_DEVICE_ENABLED)
199 data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
200 else
201 data->ti_thermal->polling_delay = 0;
202
203 mutex_unlock(&data->ti_thermal->lock);
204
205 data->mode = mode;
206 ti_bandgap_write_update_interval(bgp, data->sensor_id,
207 data->ti_thermal->polling_delay);
208 thermal_zone_device_update(data->ti_thermal, THERMAL_EVENT_UNSPECIFIED);
209 dev_dbg(&thermal->device, "thermal polling set for duration=%d msec\n",
210 data->ti_thermal->polling_delay);
211
212 return 0;
213}
214
215/* Get trip type callback functions for thermal zone */
216static int ti_thermal_get_trip_type(struct thermal_zone_device *thermal,
217 int trip, enum thermal_trip_type *type)
218{
219 if (!ti_thermal_is_valid_trip(trip))
220 return -EINVAL;
221
222 if (trip + 1 == OMAP_TRIP_NUMBER)
223 *type = THERMAL_TRIP_CRITICAL;
224 else
225 *type = THERMAL_TRIP_PASSIVE;
226
227 return 0;
228}
229
230/* Get trip temperature callback functions for thermal zone */
231static int ti_thermal_get_trip_temp(struct thermal_zone_device *thermal,
232 int trip, int *temp)
233{
234 if (!ti_thermal_is_valid_trip(trip))
235 return -EINVAL;
236
237 *temp = ti_thermal_get_trip_value(trip);
238
239 return 0;
240}
241
242static int __ti_thermal_get_trend(void *p, int trip, enum thermal_trend *trend) 129static int __ti_thermal_get_trend(void *p, int trip, enum thermal_trend *trend)
243{ 130{
244 struct ti_thermal_data *data = p; 131 struct ti_thermal_data *data = p;
@@ -262,38 +149,11 @@ static int __ti_thermal_get_trend(void *p, int trip, enum thermal_trend *trend)
262 return 0; 149 return 0;
263} 150}
264 151
265/* Get the temperature trend callback functions for thermal zone */
266static int ti_thermal_get_trend(struct thermal_zone_device *thermal,
267 int trip, enum thermal_trend *trend)
268{
269 return __ti_thermal_get_trend(thermal->devdata, trip, trend);
270}
271
272/* Get critical temperature callback functions for thermal zone */
273static int ti_thermal_get_crit_temp(struct thermal_zone_device *thermal,
274 int *temp)
275{
276 /* shutdown zone */
277 return ti_thermal_get_trip_temp(thermal, OMAP_TRIP_NUMBER - 1, temp);
278}
279
280static const struct thermal_zone_of_device_ops ti_of_thermal_ops = { 152static const struct thermal_zone_of_device_ops ti_of_thermal_ops = {
281 .get_temp = __ti_thermal_get_temp, 153 .get_temp = __ti_thermal_get_temp,
282 .get_trend = __ti_thermal_get_trend, 154 .get_trend = __ti_thermal_get_trend,
283}; 155};
284 156
285static struct thermal_zone_device_ops ti_thermal_ops = {
286 .get_temp = ti_thermal_get_temp,
287 .get_trend = ti_thermal_get_trend,
288 .bind = ti_thermal_bind,
289 .unbind = ti_thermal_unbind,
290 .get_mode = ti_thermal_get_mode,
291 .set_mode = ti_thermal_set_mode,
292 .get_trip_type = ti_thermal_get_trip_type,
293 .get_trip_temp = ti_thermal_get_trip_temp,
294 .get_crit_temp = ti_thermal_get_crit_temp,
295};
296
297static struct ti_thermal_data 157static struct ti_thermal_data
298*ti_thermal_build_data(struct ti_bandgap *bgp, int id) 158*ti_thermal_build_data(struct ti_bandgap *bgp, int id)
299{ 159{
@@ -331,18 +191,10 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
331 data->ti_thermal = devm_thermal_zone_of_sensor_register(bgp->dev, id, 191 data->ti_thermal = devm_thermal_zone_of_sensor_register(bgp->dev, id,
332 data, &ti_of_thermal_ops); 192 data, &ti_of_thermal_ops);
333 if (IS_ERR(data->ti_thermal)) { 193 if (IS_ERR(data->ti_thermal)) {
334 /* Create thermal zone */ 194 dev_err(bgp->dev, "thermal zone device is NULL\n");
335 data->ti_thermal = thermal_zone_device_register(domain, 195 return PTR_ERR(data->ti_thermal);
336 OMAP_TRIP_NUMBER, 0, data, &ti_thermal_ops,
337 NULL, FAST_TEMP_MONITORING_RATE,
338 FAST_TEMP_MONITORING_RATE);
339 if (IS_ERR(data->ti_thermal)) {
340 dev_err(bgp->dev, "thermal zone device is NULL\n");
341 return PTR_ERR(data->ti_thermal);
342 }
343 data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
344 data->our_zone = true;
345 } 196 }
197
346 ti_bandgap_set_sensor_data(bgp, id, data); 198 ti_bandgap_set_sensor_data(bgp, id, data);
347 ti_bandgap_write_update_interval(bgp, data->sensor_id, 199 ti_bandgap_write_update_interval(bgp, data->sensor_id,
348 data->ti_thermal->polling_delay); 200 data->ti_thermal->polling_delay);
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal.h b/drivers/thermal/ti-soc-thermal/ti-thermal.h
index f8b7ffea6194..8e85ca973967 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal.h
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal.h
@@ -25,22 +25,6 @@
25 25
26#include "ti-bandgap.h" 26#include "ti-bandgap.h"
27 27
28/* sensors gradient and offsets */
29#define OMAP_GRADIENT_SLOPE_4430 0
30#define OMAP_GRADIENT_CONST_4430 20000
31#define OMAP_GRADIENT_SLOPE_4460 348
32#define OMAP_GRADIENT_CONST_4460 -9301
33#define OMAP_GRADIENT_SLOPE_4470 308
34#define OMAP_GRADIENT_CONST_4470 -7896
35
36#define OMAP_GRADIENT_SLOPE_5430_CPU 65
37#define OMAP_GRADIENT_CONST_5430_CPU -1791
38#define OMAP_GRADIENT_SLOPE_5430_GPU 117
39#define OMAP_GRADIENT_CONST_5430_GPU -2992
40
41#define DRA752_GRADIENT_SLOPE 0
42#define DRA752_GRADIENT_CONST 2000
43
44/* PCB sensor calculation constants */ 28/* PCB sensor calculation constants */
45#define OMAP_GRADIENT_SLOPE_W_PCB_4430 0 29#define OMAP_GRADIENT_SLOPE_W_PCB_4430 0
46#define OMAP_GRADIENT_CONST_W_PCB_4430 20000 30#define OMAP_GRADIENT_CONST_W_PCB_4430 20000