aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/thermal/qoriq-thermal.txt7
-rw-r--r--Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt56
-rw-r--r--Documentation/devicetree/bindings/thermal/zx2967-thermal.txt116
-rw-r--r--arch/powerpc/boot/dts/fsl/t1023si-post.dtsi4
-rw-r--r--arch/powerpc/boot/dts/fsl/t1040si-post.dtsi4
-rw-r--r--drivers/thermal/Kconfig17
-rw-r--r--drivers/thermal/Makefile2
-rw-r--r--drivers/thermal/clock_cooling.c50
-rw-r--r--drivers/thermal/cpu_cooling.c102
-rw-r--r--drivers/thermal/devfreq_cooling.c53
-rw-r--r--drivers/thermal/imx_thermal.c4
-rw-r--r--drivers/thermal/intel_powerclamp.c4
-rw-r--r--drivers/thermal/mtk_thermal.c16
-rw-r--r--drivers/thermal/rcar_gen3_thermal.c335
-rw-r--r--drivers/thermal/samsung/exynos_tmu.c1
-rw-r--r--drivers/thermal/samsung/exynos_tmu.h1
-rw-r--r--drivers/thermal/thermal_core.c75
-rw-r--r--drivers/thermal/ti-soc-thermal/Kconfig1
-rw-r--r--drivers/thermal/ti-soc-thermal/dra752-bandgap.h19
-rw-r--r--drivers/thermal/ti-soc-thermal/dra752-thermal-data.c28
-rw-r--r--drivers/thermal/zx2967_thermal.c258
-rw-r--r--include/linux/thermal.h4
22 files changed, 890 insertions, 267 deletions
diff --git a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
index 66223d561972..20ca4ef9d776 100644
--- a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
@@ -17,6 +17,12 @@ Required properties:
17 calibration data, as specified by the SoC reference manual. 17 calibration data, as specified by the SoC reference manual.
18 The first cell of each pair is the value to be written to TTCFGR, 18 The first cell of each pair is the value to be written to TTCFGR,
19 and the second is the value to be written to TSCFGR. 19 and the second is the value to be written to TSCFGR.
20- #thermal-sensor-cells : Must be 1. The sensor specifier is the monitoring
21 site ID, and represents the "n" in TRITSRn and TRATSRn.
22
23Optional property:
24- little-endian : If present, the TMU registers are little endian. If absent,
25 the default is big endian.
20 26
21Example: 27Example:
22 28
@@ -60,4 +66,5 @@ tmu@f0000 {
60 66
61 0x00030000 0x00000012 67 0x00030000 0x00000012
62 0x00030001 0x0000001d>; 68 0x00030001 0x0000001d>;
69 #thermal-sensor-cells = <1>;
63}; 70};
diff --git a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
new file mode 100644
index 000000000000..07a9713ae6a7
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
@@ -0,0 +1,56 @@
1* DT bindings for Renesas R-Car Gen3 Thermal Sensor driver
2
3On R-Car Gen3 SoCs, the thermal sensor controllers (TSC) control the thermal
4sensors (THS) which are the analog circuits for measuring temperature (Tj)
5inside the LSI.
6
7Required properties:
8- compatible : "renesas,<soctype>-thermal",
9 Examples with soctypes are:
10 - "renesas,r8a7795-thermal" (R-Car H3)
11 - "renesas,r8a7796-thermal" (R-Car M3-W)
12- reg : Address ranges of the thermal registers. Each sensor
13 needs one address range. Sorting must be done in
14 increasing order according to datasheet, i.e.
15 TSC1, TSC2, ...
16- clocks : Must contain a reference to the functional clock.
17- #thermal-sensor-cells : must be <1>.
18
19Optional properties:
20
21- interrupts : interrupts routed to the TSC (3 for H3 and M3-W)
22- power-domain : Must contain a reference to the power domain. This
23 property is mandatory if the thermal sensor instance
24 is part of a controllable power domain.
25
26Example:
27
28 tsc: thermal@e6198000 {
29 compatible = "renesas,r8a7795-thermal";
30 reg = <0 0xe6198000 0 0x68>,
31 <0 0xe61a0000 0 0x5c>,
32 <0 0xe61a8000 0 0x5c>;
33 interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
34 <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
35 <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
36 clocks = <&cpg CPG_MOD 522>;
37 power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
38 #thermal-sensor-cells = <1>;
39 status = "okay";
40 };
41
42 thermal-zones {
43 sensor_thermal1: sensor-thermal1 {
44 polling-delay-passive = <250>;
45 polling-delay = <1000>;
46 thermal-sensors = <&tsc 0>;
47
48 trips {
49 sensor1_crit: sensor1-crit {
50 temperature = <90000>;
51 hysteresis = <2000>;
52 type = "critical";
53 };
54 };
55 };
56 };
diff --git a/Documentation/devicetree/bindings/thermal/zx2967-thermal.txt b/Documentation/devicetree/bindings/thermal/zx2967-thermal.txt
new file mode 100644
index 000000000000..3dc1c6bf0478
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/zx2967-thermal.txt
@@ -0,0 +1,116 @@
1* ZTE zx2967 family Thermal
2
3Required Properties:
4- compatible: should be one of the following.
5 * zte,zx296718-thermal
6- reg: physical base address of the controller and length of memory mapped
7 region.
8- clocks : Pairs of phandle and specifier referencing the controller's clocks.
9- clock-names: "topcrm" for the topcrm clock.
10 "apb" for the apb clock.
11- #thermal-sensor-cells: must be 0.
12
13Please note: slope coefficient defined in thermal-zones section need to be
14multiplied by 1000.
15
16Example for tempsensor:
17
18 tempsensor: tempsensor@148a000 {
19 compatible = "zte,zx296718-thermal";
20 reg = <0x0148a000 0x20>;
21 clocks = <&topcrm TEMPSENSOR_GATE>, <&audiocrm AUDIO_TS_PCLK>;
22 clock-names = "topcrm", "apb";
23 #thermal-sensor-cells = <0>;
24 };
25
26Example for cooling device:
27
28 cooling_dev: cooling_dev {
29 cluster0_cooling_dev: cluster0-cooling-dev {
30 #cooling-cells = <2>;
31 cpumask = <0xf>;
32 capacitance = <1500>;
33 };
34
35 cluster1_cooling_dev: cluster1-cooling-dev {
36 #cooling-cells = <2>;
37 cpumask = <0x30>;
38 capacitance = <2000>;
39 };
40 };
41
42Example for thermal zones:
43
44 thermal-zones {
45 zx296718_thermal: zx296718_thermal {
46 polling-delay-passive = <500>;
47 polling-delay = <1000>;
48 sustainable-power = <6500>;
49
50 thermal-sensors = <&tempsensor 0>;
51 /*
52 * slope need to be multiplied by 1000.
53 */
54 coefficients = <1951 (-922)>;
55
56 trips {
57 trip0: switch_on_temperature {
58 temperature = <90000>;
59 hysteresis = <2000>;
60 type = "passive";
61 };
62
63 trip1: desired_temperature {
64 temperature = <100000>;
65 hysteresis = <2000>;
66 type = "passive";
67 };
68
69 crit: critical_temperature {
70 temperature = <110000>;
71 hysteresis = <2000>;
72 type = "critical";
73 };
74 };
75
76 cooling-maps {
77 map0 {
78 trip = <&trip0>;
79 cooling-device = <&gpu 2 5>;
80 };
81
82 map1 {
83 trip = <&trip0>;
84 cooling-device = <&cluster0_cooling_dev 1 2>;
85 };
86
87 map2 {
88 trip = <&trip1>;
89 cooling-device = <&cluster0_cooling_dev 1 2>;
90 };
91
92 map3 {
93 trip = <&crit>;
94 cooling-device = <&cluster0_cooling_dev 1 2>;
95 };
96
97 map4 {
98 trip = <&trip0>;
99 cooling-device = <&cluster1_cooling_dev 1 2>;
100 contribution = <9000>;
101 };
102
103 map5 {
104 trip = <&trip1>;
105 cooling-device = <&cluster1_cooling_dev 1 2>;
106 contribution = <4096>;
107 };
108
109 map6 {
110 trip = <&crit>;
111 cooling-device = <&cluster1_cooling_dev 1 2>;
112 contribution = <4096>;
113 };
114 };
115 };
116 };
diff --git a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
index da2894c59479..4908af501098 100644
--- a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
@@ -422,7 +422,7 @@
422 0x00030001 0x0000000d 422 0x00030001 0x0000000d
423 0x00030002 0x00000019 423 0x00030002 0x00000019
424 0x00030003 0x00000024>; 424 0x00030003 0x00000024>;
425 #thermal-sensor-cells = <0>; 425 #thermal-sensor-cells = <1>;
426 }; 426 };
427 427
428 thermal-zones { 428 thermal-zones {
@@ -430,7 +430,7 @@
430 polling-delay-passive = <1000>; 430 polling-delay-passive = <1000>;
431 polling-delay = <5000>; 431 polling-delay = <5000>;
432 432
433 thermal-sensors = <&tmu>; 433 thermal-sensors = <&tmu 0>;
434 434
435 trips { 435 trips {
436 cpu_alert: cpu-alert { 436 cpu_alert: cpu-alert {
diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
index 44e399b17f6f..145c7f43b5b6 100644
--- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
@@ -526,7 +526,7 @@
526 526
527 0x00030000 0x00000012 527 0x00030000 0x00000012
528 0x00030001 0x0000001d>; 528 0x00030001 0x0000001d>;
529 #thermal-sensor-cells = <0>; 529 #thermal-sensor-cells = <1>;
530 }; 530 };
531 531
532 thermal-zones { 532 thermal-zones {
@@ -534,7 +534,7 @@
534 polling-delay-passive = <1000>; 534 polling-delay-passive = <1000>;
535 polling-delay = <5000>; 535 polling-delay = <5000>;
536 536
537 thermal-sensors = <&tmu>; 537 thermal-sensors = <&tmu 2>;
538 538
539 trips { 539 trips {
540 cpu_alert: cpu-alert { 540 cpu_alert: cpu-alert {
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index c2c056cc7ea5..776b34396144 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -245,6 +245,15 @@ config RCAR_THERMAL
245 Enable this to plug the R-Car thermal sensor driver into the Linux 245 Enable this to plug the R-Car thermal sensor driver into the Linux
246 thermal framework. 246 thermal framework.
247 247
248config RCAR_GEN3_THERMAL
249 tristate "Renesas R-Car Gen3 thermal driver"
250 depends on ARCH_RENESAS || COMPILE_TEST
251 depends on HAS_IOMEM
252 depends on OF
253 help
254 Enable this to plug the R-Car Gen3 thermal sensor driver into the Linux
255 thermal framework.
256
248config KIRKWOOD_THERMAL 257config KIRKWOOD_THERMAL
249 tristate "Temperature sensor on Marvell Kirkwood SoCs" 258 tristate "Temperature sensor on Marvell Kirkwood SoCs"
250 depends on MACH_KIRKWOOD || COMPILE_TEST 259 depends on MACH_KIRKWOOD || COMPILE_TEST
@@ -436,4 +445,12 @@ depends on (ARCH_QCOM && OF) || COMPILE_TEST
436source "drivers/thermal/qcom/Kconfig" 445source "drivers/thermal/qcom/Kconfig"
437endmenu 446endmenu
438 447
448config ZX2967_THERMAL
449 tristate "Thermal sensors on zx2967 SoC"
450 depends on ARCH_ZX || COMPILE_TEST
451 help
452 Enable the zx2967 thermal sensors driver, which supports
453 the primitive temperature sensor embedded in zx2967 SoCs.
454 This sensor generates the real time die temperature.
455
439endif 456endif
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 6a3d7b573036..7adae2029355 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
31obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o 31obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o
32obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o 32obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o
33obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o 33obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o
34obj-$(CONFIG_RCAR_GEN3_THERMAL) += rcar_gen3_thermal.o
34obj-$(CONFIG_KIRKWOOD_THERMAL) += kirkwood_thermal.o 35obj-$(CONFIG_KIRKWOOD_THERMAL) += kirkwood_thermal.o
35obj-y += samsung/ 36obj-y += samsung/
36obj-$(CONFIG_DOVE_THERMAL) += dove_thermal.o 37obj-$(CONFIG_DOVE_THERMAL) += dove_thermal.o
@@ -56,3 +57,4 @@ obj-$(CONFIG_TEGRA_SOCTHERM) += tegra/
56obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o 57obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
57obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o 58obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
58obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o 59obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
60obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o
diff --git a/drivers/thermal/clock_cooling.c b/drivers/thermal/clock_cooling.c
index ed5dd0e88657..56711c25584d 100644
--- a/drivers/thermal/clock_cooling.c
+++ b/drivers/thermal/clock_cooling.c
@@ -65,42 +65,7 @@ struct clock_cooling_device {
65}; 65};
66#define to_clock_cooling_device(x) \ 66#define to_clock_cooling_device(x) \
67 container_of(x, struct clock_cooling_device, clk_rate_change_nb) 67 container_of(x, struct clock_cooling_device, clk_rate_change_nb)
68static DEFINE_IDR(clock_idr); 68static DEFINE_IDA(clock_ida);
69static DEFINE_MUTEX(cooling_clock_lock);
70
71/**
72 * clock_cooling_get_idr - function to get an unique id.
73 * @id: int * value generated by this function.
74 *
75 * This function will populate @id with an unique
76 * id, using the idr API.
77 *
78 * Return: 0 on success, an error code on failure.
79 */
80static int clock_cooling_get_idr(int *id)
81{
82 int ret;
83
84 mutex_lock(&cooling_clock_lock);
85 ret = idr_alloc(&clock_idr, NULL, 0, 0, GFP_KERNEL);
86 mutex_unlock(&cooling_clock_lock);
87 if (unlikely(ret < 0))
88 return ret;
89 *id = ret;
90
91 return 0;
92}
93
94/**
95 * release_idr - function to free the unique id.
96 * @id: int value representing the unique id.
97 */
98static void release_idr(int id)
99{
100 mutex_lock(&cooling_clock_lock);
101 idr_remove(&clock_idr, id);
102 mutex_unlock(&cooling_clock_lock);
103}
104 69
105/* Below code defines functions to be used for clock as cooling device */ 70/* Below code defines functions to be used for clock as cooling device */
106 71
@@ -432,16 +397,17 @@ clock_cooling_register(struct device *dev, const char *clock_name)
432 if (IS_ERR(ccdev->clk)) 397 if (IS_ERR(ccdev->clk))
433 return ERR_CAST(ccdev->clk); 398 return ERR_CAST(ccdev->clk);
434 399
435 ret = clock_cooling_get_idr(&ccdev->id); 400 ret = ida_simple_get(&clock_ida, 0, 0, GFP_KERNEL);
436 if (ret) 401 if (ret < 0)
437 return ERR_PTR(-EINVAL); 402 return ERR_PTR(ret);
403 ccdev->id = ret;
438 404
439 snprintf(dev_name, sizeof(dev_name), "thermal-clock-%d", ccdev->id); 405 snprintf(dev_name, sizeof(dev_name), "thermal-clock-%d", ccdev->id);
440 406
441 cdev = thermal_cooling_device_register(dev_name, ccdev, 407 cdev = thermal_cooling_device_register(dev_name, ccdev,
442 &clock_cooling_ops); 408 &clock_cooling_ops);
443 if (IS_ERR(cdev)) { 409 if (IS_ERR(cdev)) {
444 release_idr(ccdev->id); 410 ida_simple_remove(&clock_ida, ccdev->id);
445 return ERR_PTR(-EINVAL); 411 return ERR_PTR(-EINVAL);
446 } 412 }
447 ccdev->cdev = cdev; 413 ccdev->cdev = cdev;
@@ -450,7 +416,7 @@ clock_cooling_register(struct device *dev, const char *clock_name)
450 /* Assuming someone has already filled the opp table for this device */ 416 /* Assuming someone has already filled the opp table for this device */
451 ret = dev_pm_opp_init_cpufreq_table(dev, &ccdev->freq_table); 417 ret = dev_pm_opp_init_cpufreq_table(dev, &ccdev->freq_table);
452 if (ret) { 418 if (ret) {
453 release_idr(ccdev->id); 419 ida_simple_remove(&clock_ida, ccdev->id);
454 return ERR_PTR(ret); 420 return ERR_PTR(ret);
455 } 421 }
456 ccdev->clock_state = 0; 422 ccdev->clock_state = 0;
@@ -481,6 +447,6 @@ void clock_cooling_unregister(struct thermal_cooling_device *cdev)
481 dev_pm_opp_free_cpufreq_table(ccdev->dev, &ccdev->freq_table); 447 dev_pm_opp_free_cpufreq_table(ccdev->dev, &ccdev->freq_table);
482 448
483 thermal_cooling_device_unregister(ccdev->cdev); 449 thermal_cooling_device_unregister(ccdev->cdev);
484 release_idr(ccdev->id); 450 ida_simple_remove(&clock_ida, ccdev->id);
485} 451}
486EXPORT_SYMBOL_GPL(clock_cooling_unregister); 452EXPORT_SYMBOL_GPL(clock_cooling_unregister);
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 85fdbf762fa0..91048eeca28b 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -26,6 +26,7 @@
26#include <linux/thermal.h> 26#include <linux/thermal.h>
27#include <linux/cpufreq.h> 27#include <linux/cpufreq.h>
28#include <linux/err.h> 28#include <linux/err.h>
29#include <linux/idr.h>
29#include <linux/pm_opp.h> 30#include <linux/pm_opp.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <linux/cpu.h> 32#include <linux/cpu.h>
@@ -104,50 +105,13 @@ struct cpufreq_cooling_device {
104 struct device *cpu_dev; 105 struct device *cpu_dev;
105 get_static_t plat_get_static_power; 106 get_static_t plat_get_static_power;
106}; 107};
107static DEFINE_IDR(cpufreq_idr); 108static DEFINE_IDA(cpufreq_ida);
108static DEFINE_MUTEX(cooling_cpufreq_lock);
109 109
110static unsigned int cpufreq_dev_count; 110static unsigned int cpufreq_dev_count;
111 111
112static DEFINE_MUTEX(cooling_list_lock); 112static DEFINE_MUTEX(cooling_list_lock);
113static LIST_HEAD(cpufreq_dev_list); 113static LIST_HEAD(cpufreq_dev_list);
114 114
115/**
116 * get_idr - function to get a unique id.
117 * @idr: struct idr * handle used to create a id.
118 * @id: int * value generated by this function.
119 *
120 * This function will populate @id with an unique
121 * id, using the idr API.
122 *
123 * Return: 0 on success, an error code on failure.
124 */
125static int get_idr(struct idr *idr, int *id)
126{
127 int ret;
128
129 mutex_lock(&cooling_cpufreq_lock);
130 ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
131 mutex_unlock(&cooling_cpufreq_lock);
132 if (unlikely(ret < 0))
133 return ret;
134 *id = ret;
135
136 return 0;
137}
138
139/**
140 * release_idr - function to free the unique id.
141 * @idr: struct idr * handle used for creating the id.
142 * @id: int value representing the unique id.
143 */
144static void release_idr(struct idr *idr, int id)
145{
146 mutex_lock(&cooling_cpufreq_lock);
147 idr_remove(idr, id);
148 mutex_unlock(&cooling_cpufreq_lock);
149}
150
151/* Below code defines functions to be used for cpufreq as cooling device */ 115/* Below code defines functions to be used for cpufreq as cooling device */
152 116
153/** 117/**
@@ -645,31 +609,39 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev,
645 unsigned long state, u32 *power) 609 unsigned long state, u32 *power)
646{ 610{
647 unsigned int freq, num_cpus; 611 unsigned int freq, num_cpus;
648 cpumask_t cpumask; 612 cpumask_var_t cpumask;
649 u32 static_power, dynamic_power; 613 u32 static_power, dynamic_power;
650 int ret; 614 int ret;
651 struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; 615 struct cpufreq_cooling_device *cpufreq_device = cdev->devdata;
652 616
653 cpumask_and(&cpumask, &cpufreq_device->allowed_cpus, cpu_online_mask); 617 if (!alloc_cpumask_var(&cpumask, GFP_KERNEL))
654 num_cpus = cpumask_weight(&cpumask); 618 return -ENOMEM;
619
620 cpumask_and(cpumask, &cpufreq_device->allowed_cpus, cpu_online_mask);
621 num_cpus = cpumask_weight(cpumask);
655 622
656 /* None of our cpus are online, so no power */ 623 /* None of our cpus are online, so no power */
657 if (num_cpus == 0) { 624 if (num_cpus == 0) {
658 *power = 0; 625 *power = 0;
659 return 0; 626 ret = 0;
627 goto out;
660 } 628 }
661 629
662 freq = cpufreq_device->freq_table[state]; 630 freq = cpufreq_device->freq_table[state];
663 if (!freq) 631 if (!freq) {
664 return -EINVAL; 632 ret = -EINVAL;
633 goto out;
634 }
665 635
666 dynamic_power = cpu_freq_to_power(cpufreq_device, freq) * num_cpus; 636 dynamic_power = cpu_freq_to_power(cpufreq_device, freq) * num_cpus;
667 ret = get_static_power(cpufreq_device, tz, freq, &static_power); 637 ret = get_static_power(cpufreq_device, tz, freq, &static_power);
668 if (ret) 638 if (ret)
669 return ret; 639 goto out;
670 640
671 *power = static_power + dynamic_power; 641 *power = static_power + dynamic_power;
672 return 0; 642out:
643 free_cpumask_var(cpumask);
644 return ret;
673} 645}
674 646
675/** 647/**
@@ -795,16 +767,20 @@ __cpufreq_cooling_register(struct device_node *np,
795 struct cpufreq_cooling_device *cpufreq_dev; 767 struct cpufreq_cooling_device *cpufreq_dev;
796 char dev_name[THERMAL_NAME_LENGTH]; 768 char dev_name[THERMAL_NAME_LENGTH];
797 struct cpufreq_frequency_table *pos, *table; 769 struct cpufreq_frequency_table *pos, *table;
798 struct cpumask temp_mask; 770 cpumask_var_t temp_mask;
799 unsigned int freq, i, num_cpus; 771 unsigned int freq, i, num_cpus;
800 int ret; 772 int ret;
801 struct thermal_cooling_device_ops *cooling_ops; 773 struct thermal_cooling_device_ops *cooling_ops;
802 774
803 cpumask_and(&temp_mask, clip_cpus, cpu_online_mask); 775 if (!alloc_cpumask_var(&temp_mask, GFP_KERNEL))
804 policy = cpufreq_cpu_get(cpumask_first(&temp_mask)); 776 return ERR_PTR(-ENOMEM);
777
778 cpumask_and(temp_mask, clip_cpus, cpu_online_mask);
779 policy = cpufreq_cpu_get(cpumask_first(temp_mask));
805 if (!policy) { 780 if (!policy) {
806 pr_debug("%s: CPUFreq policy not found\n", __func__); 781 pr_debug("%s: CPUFreq policy not found\n", __func__);
807 return ERR_PTR(-EPROBE_DEFER); 782 cool_dev = ERR_PTR(-EPROBE_DEFER);
783 goto free_cpumask;
808 } 784 }
809 785
810 table = policy->freq_table; 786 table = policy->freq_table;
@@ -867,11 +843,12 @@ __cpufreq_cooling_register(struct device_node *np,
867 cooling_ops = &cpufreq_cooling_ops; 843 cooling_ops = &cpufreq_cooling_ops;
868 } 844 }
869 845
870 ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); 846 ret = ida_simple_get(&cpufreq_ida, 0, 0, GFP_KERNEL);
871 if (ret) { 847 if (ret < 0) {
872 cool_dev = ERR_PTR(ret); 848 cool_dev = ERR_PTR(ret);
873 goto free_power_table; 849 goto free_power_table;
874 } 850 }
851 cpufreq_dev->id = ret;
875 852
876 /* Fill freq-table in descending order of frequencies */ 853 /* Fill freq-table in descending order of frequencies */
877 for (i = 0, freq = -1; i <= cpufreq_dev->max_level; i++) { 854 for (i = 0, freq = -1; i <= cpufreq_dev->max_level; i++) {
@@ -891,27 +868,24 @@ __cpufreq_cooling_register(struct device_node *np,
891 cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, 868 cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev,
892 cooling_ops); 869 cooling_ops);
893 if (IS_ERR(cool_dev)) 870 if (IS_ERR(cool_dev))
894 goto remove_idr; 871 goto remove_ida;
895 872
896 cpufreq_dev->clipped_freq = cpufreq_dev->freq_table[0]; 873 cpufreq_dev->clipped_freq = cpufreq_dev->freq_table[0];
897 cpufreq_dev->cool_dev = cool_dev; 874 cpufreq_dev->cool_dev = cool_dev;
898 875
899 mutex_lock(&cooling_cpufreq_lock);
900
901 mutex_lock(&cooling_list_lock); 876 mutex_lock(&cooling_list_lock);
902 list_add(&cpufreq_dev->node, &cpufreq_dev_list); 877 list_add(&cpufreq_dev->node, &cpufreq_dev_list);
903 mutex_unlock(&cooling_list_lock);
904 878
905 /* Register the notifier for first cpufreq cooling device */ 879 /* Register the notifier for first cpufreq cooling device */
906 if (!cpufreq_dev_count++) 880 if (!cpufreq_dev_count++)
907 cpufreq_register_notifier(&thermal_cpufreq_notifier_block, 881 cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
908 CPUFREQ_POLICY_NOTIFIER); 882 CPUFREQ_POLICY_NOTIFIER);
909 mutex_unlock(&cooling_cpufreq_lock); 883 mutex_unlock(&cooling_list_lock);
910 884
911 goto put_policy; 885 goto put_policy;
912 886
913remove_idr: 887remove_ida:
914 release_idr(&cpufreq_idr, cpufreq_dev->id); 888 ida_simple_remove(&cpufreq_ida, cpufreq_dev->id);
915free_power_table: 889free_power_table:
916 kfree(cpufreq_dev->dyn_power_table); 890 kfree(cpufreq_dev->dyn_power_table);
917free_table: 891free_table:
@@ -924,7 +898,8 @@ free_cdev:
924 kfree(cpufreq_dev); 898 kfree(cpufreq_dev);
925put_policy: 899put_policy:
926 cpufreq_cpu_put(policy); 900 cpufreq_cpu_put(policy);
927 901free_cpumask:
902 free_cpumask_var(temp_mask);
928 return cool_dev; 903 return cool_dev;
929} 904}
930 905
@@ -1052,20 +1027,17 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
1052 1027
1053 cpufreq_dev = cdev->devdata; 1028 cpufreq_dev = cdev->devdata;
1054 1029
1030 mutex_lock(&cooling_list_lock);
1055 /* Unregister the notifier for the last cpufreq cooling device */ 1031 /* Unregister the notifier for the last cpufreq cooling device */
1056 mutex_lock(&cooling_cpufreq_lock);
1057 if (!--cpufreq_dev_count) 1032 if (!--cpufreq_dev_count)
1058 cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, 1033 cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
1059 CPUFREQ_POLICY_NOTIFIER); 1034 CPUFREQ_POLICY_NOTIFIER);
1060 1035
1061 mutex_lock(&cooling_list_lock);
1062 list_del(&cpufreq_dev->node); 1036 list_del(&cpufreq_dev->node);
1063 mutex_unlock(&cooling_list_lock); 1037 mutex_unlock(&cooling_list_lock);
1064 1038
1065 mutex_unlock(&cooling_cpufreq_lock);
1066
1067 thermal_cooling_device_unregister(cpufreq_dev->cool_dev); 1039 thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
1068 release_idr(&cpufreq_idr, cpufreq_dev->id); 1040 ida_simple_remove(&cpufreq_ida, cpufreq_dev->id);
1069 kfree(cpufreq_dev->dyn_power_table); 1041 kfree(cpufreq_dev->dyn_power_table);
1070 kfree(cpufreq_dev->time_in_idle_timestamp); 1042 kfree(cpufreq_dev->time_in_idle_timestamp);
1071 kfree(cpufreq_dev->time_in_idle); 1043 kfree(cpufreq_dev->time_in_idle);
diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c
index ba7a5cd994dc..7743a78d4723 100644
--- a/drivers/thermal/devfreq_cooling.c
+++ b/drivers/thermal/devfreq_cooling.c
@@ -21,14 +21,14 @@
21#include <linux/devfreq.h> 21#include <linux/devfreq.h>
22#include <linux/devfreq_cooling.h> 22#include <linux/devfreq_cooling.h>
23#include <linux/export.h> 23#include <linux/export.h>
24#include <linux/idr.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
25#include <linux/pm_opp.h> 26#include <linux/pm_opp.h>
26#include <linux/thermal.h> 27#include <linux/thermal.h>
27 28
28#include <trace/events/thermal.h> 29#include <trace/events/thermal.h>
29 30
30static DEFINE_MUTEX(devfreq_lock); 31static DEFINE_IDA(devfreq_ida);
31static DEFINE_IDR(devfreq_idr);
32 32
33/** 33/**
34 * struct devfreq_cooling_device - Devfreq cooling device 34 * struct devfreq_cooling_device - Devfreq cooling device
@@ -58,42 +58,6 @@ struct devfreq_cooling_device {
58}; 58};
59 59
60/** 60/**
61 * get_idr - function to get a unique id.
62 * @idr: struct idr * handle used to create a id.
63 * @id: int * value generated by this function.
64 *
65 * This function will populate @id with an unique
66 * id, using the idr API.
67 *
68 * Return: 0 on success, an error code on failure.
69 */
70static int get_idr(struct idr *idr, int *id)
71{
72 int ret;
73
74 mutex_lock(&devfreq_lock);
75 ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
76 mutex_unlock(&devfreq_lock);
77 if (unlikely(ret < 0))
78 return ret;
79 *id = ret;
80
81 return 0;
82}
83
84/**
85 * release_idr - function to free the unique id.
86 * @idr: struct idr * handle used for creating the id.
87 * @id: int value representing the unique id.
88 */
89static void release_idr(struct idr *idr, int id)
90{
91 mutex_lock(&devfreq_lock);
92 idr_remove(idr, id);
93 mutex_unlock(&devfreq_lock);
94}
95
96/**
97 * partition_enable_opps() - disable all opps above a given state 61 * partition_enable_opps() - disable all opps above a given state
98 * @dfc: Pointer to devfreq we are operating on 62 * @dfc: Pointer to devfreq we are operating on
99 * @cdev_state: cooling device state we're setting 63 * @cdev_state: cooling device state we're setting
@@ -489,9 +453,10 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
489 if (err) 453 if (err)
490 goto free_dfc; 454 goto free_dfc;
491 455
492 err = get_idr(&devfreq_idr, &dfc->id); 456 err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL);
493 if (err) 457 if (err < 0)
494 goto free_tables; 458 goto free_tables;
459 dfc->id = err;
495 460
496 snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d", dfc->id); 461 snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d", dfc->id);
497 462
@@ -502,15 +467,15 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
502 dev_err(df->dev.parent, 467 dev_err(df->dev.parent,
503 "Failed to register devfreq cooling device (%d)\n", 468 "Failed to register devfreq cooling device (%d)\n",
504 err); 469 err);
505 goto release_idr; 470 goto release_ida;
506 } 471 }
507 472
508 dfc->cdev = cdev; 473 dfc->cdev = cdev;
509 474
510 return cdev; 475 return cdev;
511 476
512release_idr: 477release_ida:
513 release_idr(&devfreq_idr, dfc->id); 478 ida_simple_remove(&devfreq_ida, dfc->id);
514free_tables: 479free_tables:
515 kfree(dfc->power_table); 480 kfree(dfc->power_table);
516 kfree(dfc->freq_table); 481 kfree(dfc->freq_table);
@@ -558,7 +523,7 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
558 dfc = cdev->devdata; 523 dfc = cdev->devdata;
559 524
560 thermal_cooling_device_unregister(dfc->cdev); 525 thermal_cooling_device_unregister(dfc->cdev);
561 release_idr(&devfreq_idr, dfc->id); 526 ida_simple_remove(&devfreq_ida, dfc->id);
562 kfree(dfc->power_table); 527 kfree(dfc->power_table);
563 kfree(dfc->freq_table); 528 kfree(dfc->freq_table);
564 529
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 06912f0602b7..fb648a45754e 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -489,6 +489,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
489 data->tempmon = map; 489 data->tempmon = map;
490 490
491 data->socdata = of_device_get_match_data(&pdev->dev); 491 data->socdata = of_device_get_match_data(&pdev->dev);
492 if (!data->socdata) {
493 dev_err(&pdev->dev, "no device match found\n");
494 return -ENODEV;
495 }
492 496
493 /* make sure the IRQ flag is clear before enabling irq on i.MX6SX */ 497 /* make sure the IRQ flag is clear before enabling irq on i.MX6SX */
494 if (data->socdata->version == TEMPMON_IMX6SX) { 498 if (data->socdata->version == TEMPMON_IMX6SX) {
diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c
index df64692e9e64..a47103a659fa 100644
--- a/drivers/thermal/intel_powerclamp.c
+++ b/drivers/thermal/intel_powerclamp.c
@@ -461,16 +461,13 @@ static void poll_pkg_cstate(struct work_struct *dummy)
461{ 461{
462 static u64 msr_last; 462 static u64 msr_last;
463 static u64 tsc_last; 463 static u64 tsc_last;
464 static unsigned long jiffies_last;
465 464
466 u64 msr_now; 465 u64 msr_now;
467 unsigned long jiffies_now;
468 u64 tsc_now; 466 u64 tsc_now;
469 u64 val64; 467 u64 val64;
470 468
471 msr_now = pkg_state_counter(); 469 msr_now = pkg_state_counter();
472 tsc_now = rdtsc(); 470 tsc_now = rdtsc();
473 jiffies_now = jiffies;
474 471
475 /* calculate pkg cstate vs tsc ratio */ 472 /* calculate pkg cstate vs tsc ratio */
476 if (!msr_last || !tsc_last) 473 if (!msr_last || !tsc_last)
@@ -485,7 +482,6 @@ static void poll_pkg_cstate(struct work_struct *dummy)
485 482
486 /* update record */ 483 /* update record */
487 msr_last = msr_now; 484 msr_last = msr_now;
488 jiffies_last = jiffies_now;
489 tsc_last = tsc_now; 485 tsc_last = tsc_now;
490 486
491 if (true == clamping) 487 if (true == clamping)
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
index 34169c32d495..1aff7fde54b1 100644
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mtk_thermal.c
@@ -183,37 +183,37 @@ struct mtk_thermal {
183}; 183};
184 184
185/* MT8173 thermal sensor data */ 185/* MT8173 thermal sensor data */
186const int mt8173_bank_data[MT8173_NUM_ZONES][3] = { 186static const int mt8173_bank_data[MT8173_NUM_ZONES][3] = {
187 { MT8173_TS2, MT8173_TS3 }, 187 { MT8173_TS2, MT8173_TS3 },
188 { MT8173_TS2, MT8173_TS4 }, 188 { MT8173_TS2, MT8173_TS4 },
189 { MT8173_TS1, MT8173_TS2, MT8173_TSABB }, 189 { MT8173_TS1, MT8173_TS2, MT8173_TSABB },
190 { MT8173_TS2 }, 190 { MT8173_TS2 },
191}; 191};
192 192
193const 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_MSR2
195}; 195};
196 196
197const int mt8173_adcpnp[MT8173_NUM_SENSORS_PER_ZONE] = { 197static const int mt8173_adcpnp[MT8173_NUM_SENSORS_PER_ZONE] = {
198 TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3 198 TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
199}; 199};
200 200
201const int mt8173_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 }; 201static const int mt8173_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 };
202 202
203/* MT2701 thermal sensor data */ 203/* MT2701 thermal sensor data */
204const int mt2701_bank_data[MT2701_NUM_SENSORS] = { 204static const int mt2701_bank_data[MT2701_NUM_SENSORS] = {
205 MT2701_TS1, MT2701_TS2, MT2701_TSABB 205 MT2701_TS1, MT2701_TS2, MT2701_TSABB
206}; 206};
207 207
208const int mt2701_msr[MT2701_NUM_SENSORS_PER_ZONE] = { 208static const int mt2701_msr[MT2701_NUM_SENSORS_PER_ZONE] = {
209 TEMP_MSR0, TEMP_MSR1, TEMP_MSR2 209 TEMP_MSR0, TEMP_MSR1, TEMP_MSR2
210}; 210};
211 211
212const int mt2701_adcpnp[MT2701_NUM_SENSORS_PER_ZONE] = { 212static const int mt2701_adcpnp[MT2701_NUM_SENSORS_PER_ZONE] = {
213 TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2 213 TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2
214}; 214};
215 215
216const int mt2701_mux_values[MT2701_NUM_SENSORS] = { 0, 1, 16 }; 216static const int mt2701_mux_values[MT2701_NUM_SENSORS] = { 0, 1, 16 };
217 217
218/** 218/**
219 * The MT8173 thermal controller has four banks. Each bank can read up to 219 * The MT8173 thermal controller has four banks. Each bank can read up to
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
new file mode 100644
index 000000000000..d33c845244b1
--- /dev/null
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -0,0 +1,335 @@
1/*
2 * R-Car Gen3 THS thermal sensor driver
3 * Based on rcar_thermal.c and work from Hien Dang and Khiem Nguyen.
4 *
5 * Copyright (C) 2016 Renesas Electronics Corporation.
6 * Copyright (C) 2016 Sang Engineering
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 */
18#include <linux/delay.h>
19#include <linux/err.h>
20#include <linux/interrupt.h>
21#include <linux/io.h>
22#include <linux/module.h>
23#include <linux/mutex.h>
24#include <linux/of_device.h>
25#include <linux/platform_device.h>
26#include <linux/pm_runtime.h>
27#include <linux/thermal.h>
28
29/* Register offsets */
30#define REG_GEN3_IRQSTR 0x04
31#define REG_GEN3_IRQMSK 0x08
32#define REG_GEN3_IRQCTL 0x0C
33#define REG_GEN3_IRQEN 0x10
34#define REG_GEN3_IRQTEMP1 0x14
35#define REG_GEN3_IRQTEMP2 0x18
36#define REG_GEN3_IRQTEMP3 0x1C
37#define REG_GEN3_CTSR 0x20
38#define REG_GEN3_THCTR 0x20
39#define REG_GEN3_TEMP 0x28
40#define REG_GEN3_THCODE1 0x50
41#define REG_GEN3_THCODE2 0x54
42#define REG_GEN3_THCODE3 0x58
43
44/* CTSR bits */
45#define CTSR_PONM BIT(8)
46#define CTSR_AOUT BIT(7)
47#define CTSR_THBGR BIT(5)
48#define CTSR_VMEN BIT(4)
49#define CTSR_VMST BIT(1)
50#define CTSR_THSST BIT(0)
51
52/* THCTR bits */
53#define THCTR_PONM BIT(6)
54#define THCTR_THSST BIT(0)
55
56#define CTEMP_MASK 0xFFF
57
58#define MCELSIUS(temp) ((temp) * 1000)
59#define GEN3_FUSE_MASK 0xFFF
60
61#define TSC_MAX_NUM 3
62
63/* Structure for thermal temperature calculation */
64struct equation_coefs {
65 int a1;
66 int b1;
67 int a2;
68 int b2;
69};
70
71struct rcar_gen3_thermal_tsc {
72 void __iomem *base;
73 struct thermal_zone_device *zone;
74 struct equation_coefs coef;
75 struct mutex lock;
76};
77
78struct rcar_gen3_thermal_priv {
79 struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM];
80};
81
82struct rcar_gen3_thermal_data {
83 void (*thermal_init)(struct rcar_gen3_thermal_tsc *tsc);
84};
85
86static inline u32 rcar_gen3_thermal_read(struct rcar_gen3_thermal_tsc *tsc,
87 u32 reg)
88{
89 return ioread32(tsc->base + reg);
90}
91
92static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc,
93 u32 reg, u32 data)
94{
95 iowrite32(data, tsc->base + reg);
96}
97
98/*
99 * Linear approximation for temperature
100 *
101 * [reg] = [temp] * a + b => [temp] = ([reg] - b) / a
102 *
103 * The constants a and b are calculated using two triplets of int values PTAT
104 * and THCODE. PTAT and THCODE can either be read from hardware or use hard
105 * coded values from driver. The formula to calculate a and b are taken from
106 * BSP and sparsely documented and understood.
107 *
108 * Examining the linear formula and the formula used to calculate constants a
109 * and b while knowing that the span for PTAT and THCODE values are between
110 * 0x000 and 0xfff the largest integer possible is 0xfff * 0xfff == 0xffe001.
111 * Integer also needs to be signed so that leaves 7 bits for binary
112 * fixed point scaling.
113 */
114
115#define FIXPT_SHIFT 7
116#define FIXPT_INT(_x) ((_x) << FIXPT_SHIFT)
117#define FIXPT_DIV(_a, _b) DIV_ROUND_CLOSEST(((_a) << FIXPT_SHIFT), (_b))
118#define FIXPT_TO_MCELSIUS(_x) ((_x) * 1000 >> FIXPT_SHIFT)
119
120#define RCAR3_THERMAL_GRAN 500 /* mili Celsius */
121
122/* no idea where these constants come from */
123#define TJ_1 96
124#define TJ_3 -41
125
126static void rcar_gen3_thermal_calc_coefs(struct equation_coefs *coef,
127 int *ptat, int *thcode)
128{
129 int tj_2;
130
131 /* TODO: Find documentation and document constant calculation formula */
132
133 /*
134 * Division is not scaled in BSP and if scaled it might overflow
135 * the dividend (4095 * 4095 << 14 > INT_MAX) so keep it unscaled
136 */
137 tj_2 = (FIXPT_INT((ptat[1] - ptat[2]) * 137)
138 / (ptat[0] - ptat[2])) - FIXPT_INT(41);
139
140 coef->a1 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[2]),
141 tj_2 - FIXPT_INT(TJ_3));
142 coef->b1 = FIXPT_INT(thcode[2]) - coef->a1 * TJ_3;
143
144 coef->a2 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[0]),
145 tj_2 - FIXPT_INT(TJ_1));
146 coef->b2 = FIXPT_INT(thcode[0]) - coef->a2 * TJ_1;
147}
148
149static int rcar_gen3_thermal_round(int temp)
150{
151 int result, round_offs;
152
153 round_offs = temp >= 0 ? RCAR3_THERMAL_GRAN / 2 :
154 -RCAR3_THERMAL_GRAN / 2;
155 result = (temp + round_offs) / RCAR3_THERMAL_GRAN;
156 return result * RCAR3_THERMAL_GRAN;
157}
158
159static int rcar_gen3_thermal_get_temp(void *devdata, int *temp)
160{
161 struct rcar_gen3_thermal_tsc *tsc = devdata;
162 int mcelsius, val1, val2;
163 u32 reg;
164
165 /* 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;
169
170 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);
172 mcelsius = FIXPT_TO_MCELSIUS((val1 + val2) / 2);
173
174 mutex_unlock(&tsc->lock);
175
176 /* Make sure we are inside specifications */
177 if ((mcelsius < MCELSIUS(-40)) || (mcelsius > MCELSIUS(125)))
178 return -EIO;
179
180 /* Round value to device granularity setting */
181 *temp = rcar_gen3_thermal_round(mcelsius);
182
183 return 0;
184}
185
186static struct thermal_zone_of_device_ops rcar_gen3_tz_of_ops = {
187 .get_temp = rcar_gen3_thermal_get_temp,
188};
189
190static void r8a7795_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
191{
192 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_THBGR);
193 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, 0x0);
194
195 usleep_range(1000, 2000);
196
197 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_PONM);
198 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F);
199 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR,
200 CTSR_PONM | CTSR_AOUT | CTSR_THBGR | CTSR_VMEN);
201
202 usleep_range(100, 200);
203
204 rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR,
205 CTSR_PONM | CTSR_AOUT | CTSR_THBGR | CTSR_VMEN |
206 CTSR_VMST | CTSR_THSST);
207
208 usleep_range(1000, 2000);
209}
210
211static void r8a7796_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
212{
213 u32 reg_val;
214
215 reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR);
216 reg_val &= ~THCTR_PONM;
217 rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val);
218
219 usleep_range(1000, 2000);
220
221 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F);
222 reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR);
223 reg_val |= THCTR_THSST;
224 rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val);
225}
226
227static const struct rcar_gen3_thermal_data r8a7795_data = {
228 .thermal_init = r8a7795_thermal_init,
229};
230
231static const struct rcar_gen3_thermal_data r8a7796_data = {
232 .thermal_init = r8a7796_thermal_init,
233};
234
235static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
236 { .compatible = "renesas,r8a7795-thermal", .data = &r8a7795_data},
237 { .compatible = "renesas,r8a7796-thermal", .data = &r8a7796_data},
238 {},
239};
240MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids);
241
242static int rcar_gen3_thermal_remove(struct platform_device *pdev)
243{
244 struct device *dev = &pdev->dev;
245
246 pm_runtime_put(dev);
247 pm_runtime_disable(dev);
248
249 return 0;
250}
251
252static int rcar_gen3_thermal_probe(struct platform_device *pdev)
253{
254 struct rcar_gen3_thermal_priv *priv;
255 struct device *dev = &pdev->dev;
256 struct resource *res;
257 struct thermal_zone_device *zone;
258 int ret, i;
259 const struct rcar_gen3_thermal_data *match_data =
260 of_device_get_match_data(dev);
261
262 /* default values if FUSEs are missing */
263 /* TODO: Read values from hardware on supported platforms */
264 int ptat[3] = { 2351, 1509, 435 };
265 int thcode[TSC_MAX_NUM][3] = {
266 { 3248, 2800, 2221 },
267 { 3245, 2795, 2216 },
268 { 3250, 2805, 2237 },
269 };
270
271 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
272 if (!priv)
273 return -ENOMEM;
274
275 platform_set_drvdata(pdev, priv);
276
277 pm_runtime_enable(dev);
278 pm_runtime_get_sync(dev);
279
280 for (i = 0; i < TSC_MAX_NUM; i++) {
281 struct rcar_gen3_thermal_tsc *tsc;
282
283 tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL);
284 if (!tsc) {
285 ret = -ENOMEM;
286 goto error_unregister;
287 }
288
289 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
290 if (!res)
291 break;
292
293 tsc->base = devm_ioremap_resource(dev, res);
294 if (IS_ERR(tsc->base)) {
295 ret = PTR_ERR(tsc->base);
296 goto error_unregister;
297 }
298
299 priv->tscs[i] = tsc;
300 mutex_init(&tsc->lock);
301
302 match_data->thermal_init(tsc);
303 rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]);
304
305 zone = devm_thermal_zone_of_sensor_register(dev, i, tsc,
306 &rcar_gen3_tz_of_ops);
307 if (IS_ERR(zone)) {
308 dev_err(dev, "Can't register thermal zone\n");
309 ret = PTR_ERR(zone);
310 goto error_unregister;
311 }
312 tsc->zone = zone;
313 }
314
315 return 0;
316
317error_unregister:
318 rcar_gen3_thermal_remove(pdev);
319
320 return ret;
321}
322
323static struct platform_driver rcar_gen3_thermal_driver = {
324 .driver = {
325 .name = "rcar_gen3_thermal",
326 .of_match_table = rcar_gen3_thermal_dt_ids,
327 },
328 .probe = rcar_gen3_thermal_probe,
329 .remove = rcar_gen3_thermal_remove,
330};
331module_platform_driver(rcar_gen3_thermal_driver);
332
333MODULE_LICENSE("GPL v2");
334MODULE_DESCRIPTION("R-Car Gen3 THS thermal sensor driver");
335MODULE_AUTHOR("Wolfram Sang <wsa+renesas@sang-engineering.com>");
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index ad1186dd6132..7b8ef09d2b3c 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -1168,7 +1168,6 @@ static int exynos_of_sensor_conf(struct device_node *np,
1168 pdata->default_temp_offset = (u8)value; 1168 pdata->default_temp_offset = (u8)value;
1169 1169
1170 of_property_read_u32(np, "samsung,tmu_cal_type", &pdata->cal_type); 1170 of_property_read_u32(np, "samsung,tmu_cal_type", &pdata->cal_type);
1171 of_property_read_u32(np, "samsung,tmu_cal_mode", &pdata->cal_mode);
1172 1171
1173 of_node_put(np); 1172 of_node_put(np);
1174 return 0; 1173 return 0;
diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
index 440c7140b660..5149c2a3030c 100644
--- a/drivers/thermal/samsung/exynos_tmu.h
+++ b/drivers/thermal/samsung/exynos_tmu.h
@@ -70,7 +70,6 @@ struct exynos_tmu_platform_data {
70 70
71 enum soc_type type; 71 enum soc_type type;
72 u32 cal_type; 72 u32 cal_type;
73 u32 cal_mode;
74}; 73};
75 74
76#endif /* _EXYNOS_TMU_H */ 75#endif /* _EXYNOS_TMU_H */
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 655591316a88..11f0675cb7e5 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -36,9 +36,8 @@ MODULE_AUTHOR("Zhang Rui");
36MODULE_DESCRIPTION("Generic thermal management sysfs support"); 36MODULE_DESCRIPTION("Generic thermal management sysfs support");
37MODULE_LICENSE("GPL v2"); 37MODULE_LICENSE("GPL v2");
38 38
39static DEFINE_IDR(thermal_tz_idr); 39static DEFINE_IDA(thermal_tz_ida);
40static DEFINE_IDR(thermal_cdev_idr); 40static DEFINE_IDA(thermal_cdev_ida);
41static DEFINE_MUTEX(thermal_idr_lock);
42 41
43static LIST_HEAD(thermal_tz_list); 42static LIST_HEAD(thermal_tz_list);
44static LIST_HEAD(thermal_cdev_list); 43static LIST_HEAD(thermal_cdev_list);
@@ -589,29 +588,6 @@ void thermal_zone_device_unbind_exception(struct thermal_zone_device *tz,
589 * - thermal zone devices lifecycle: registration, unregistration, 588 * - thermal zone devices lifecycle: registration, unregistration,
590 * binding, and unbinding. 589 * binding, and unbinding.
591 */ 590 */
592static int get_idr(struct idr *idr, struct mutex *lock, int *id)
593{
594 int ret;
595
596 if (lock)
597 mutex_lock(lock);
598 ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
599 if (lock)
600 mutex_unlock(lock);
601 if (unlikely(ret < 0))
602 return ret;
603 *id = ret;
604 return 0;
605}
606
607static void release_idr(struct idr *idr, struct mutex *lock, int id)
608{
609 if (lock)
610 mutex_lock(lock);
611 idr_remove(idr, id);
612 if (lock)
613 mutex_unlock(lock);
614}
615 591
616/** 592/**
617 * thermal_zone_bind_cooling_device() - bind a cooling device to a thermal zone 593 * thermal_zone_bind_cooling_device() - bind a cooling device to a thermal zone
@@ -685,15 +661,16 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
685 dev->target = THERMAL_NO_TARGET; 661 dev->target = THERMAL_NO_TARGET;
686 dev->weight = weight; 662 dev->weight = weight;
687 663
688 result = get_idr(&tz->idr, &tz->lock, &dev->id); 664 result = ida_simple_get(&tz->ida, 0, 0, GFP_KERNEL);
689 if (result) 665 if (result < 0)
690 goto free_mem; 666 goto free_mem;
691 667
668 dev->id = result;
692 sprintf(dev->name, "cdev%d", dev->id); 669 sprintf(dev->name, "cdev%d", dev->id);
693 result = 670 result =
694 sysfs_create_link(&tz->device.kobj, &cdev->device.kobj, dev->name); 671 sysfs_create_link(&tz->device.kobj, &cdev->device.kobj, dev->name);
695 if (result) 672 if (result)
696 goto release_idr; 673 goto release_ida;
697 674
698 sprintf(dev->attr_name, "cdev%d_trip_point", dev->id); 675 sprintf(dev->attr_name, "cdev%d_trip_point", dev->id);
699 sysfs_attr_init(&dev->attr.attr); 676 sysfs_attr_init(&dev->attr.attr);
@@ -737,8 +714,8 @@ remove_trip_file:
737 device_remove_file(&tz->device, &dev->attr); 714 device_remove_file(&tz->device, &dev->attr);
738remove_symbol_link: 715remove_symbol_link:
739 sysfs_remove_link(&tz->device.kobj, dev->name); 716 sysfs_remove_link(&tz->device.kobj, dev->name);
740release_idr: 717release_ida:
741 release_idr(&tz->idr, &tz->lock, dev->id); 718 ida_simple_remove(&tz->ida, dev->id);
742free_mem: 719free_mem:
743 kfree(dev); 720 kfree(dev);
744 return result; 721 return result;
@@ -785,7 +762,7 @@ unbind:
785 device_remove_file(&tz->device, &pos->weight_attr); 762 device_remove_file(&tz->device, &pos->weight_attr);
786 device_remove_file(&tz->device, &pos->attr); 763 device_remove_file(&tz->device, &pos->attr);
787 sysfs_remove_link(&tz->device.kobj, pos->name); 764 sysfs_remove_link(&tz->device.kobj, pos->name);
788 release_idr(&tz->idr, &tz->lock, pos->id); 765 ida_simple_remove(&tz->ida, pos->id);
789 kfree(pos); 766 kfree(pos);
790 return 0; 767 return 0;
791} 768}
@@ -925,12 +902,13 @@ __thermal_cooling_device_register(struct device_node *np,
925 if (!cdev) 902 if (!cdev)
926 return ERR_PTR(-ENOMEM); 903 return ERR_PTR(-ENOMEM);
927 904
928 result = get_idr(&thermal_cdev_idr, &thermal_idr_lock, &cdev->id); 905 result = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
929 if (result) { 906 if (result < 0) {
930 kfree(cdev); 907 kfree(cdev);
931 return ERR_PTR(result); 908 return ERR_PTR(result);
932 } 909 }
933 910
911 cdev->id = result;
934 strlcpy(cdev->type, type ? : "", sizeof(cdev->type)); 912 strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
935 mutex_init(&cdev->lock); 913 mutex_init(&cdev->lock);
936 INIT_LIST_HEAD(&cdev->thermal_instances); 914 INIT_LIST_HEAD(&cdev->thermal_instances);
@@ -943,7 +921,7 @@ __thermal_cooling_device_register(struct device_node *np,
943 dev_set_name(&cdev->device, "cooling_device%d", cdev->id); 921 dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
944 result = device_register(&cdev->device); 922 result = device_register(&cdev->device);
945 if (result) { 923 if (result) {
946 release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); 924 ida_simple_remove(&thermal_cdev_ida, cdev->id);
947 kfree(cdev); 925 kfree(cdev);
948 return ERR_PTR(result); 926 return ERR_PTR(result);
949 } 927 }
@@ -1070,7 +1048,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
1070 1048
1071 mutex_unlock(&thermal_list_lock); 1049 mutex_unlock(&thermal_list_lock);
1072 1050
1073 release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); 1051 ida_simple_remove(&thermal_cdev_ida, cdev->id);
1074 device_unregister(&cdev->device); 1052 device_unregister(&cdev->device);
1075} 1053}
1076EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister); 1054EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister);
@@ -1172,14 +1150,15 @@ thermal_zone_device_register(const char *type, int trips, int mask,
1172 return ERR_PTR(-ENOMEM); 1150 return ERR_PTR(-ENOMEM);
1173 1151
1174 INIT_LIST_HEAD(&tz->thermal_instances); 1152 INIT_LIST_HEAD(&tz->thermal_instances);
1175 idr_init(&tz->idr); 1153 ida_init(&tz->ida);
1176 mutex_init(&tz->lock); 1154 mutex_init(&tz->lock);
1177 result = get_idr(&thermal_tz_idr, &thermal_idr_lock, &tz->id); 1155 result = ida_simple_get(&thermal_tz_ida, 0, 0, GFP_KERNEL);
1178 if (result) { 1156 if (result < 0) {
1179 kfree(tz); 1157 kfree(tz);
1180 return ERR_PTR(result); 1158 return ERR_PTR(result);
1181 } 1159 }
1182 1160
1161 tz->id = result;
1183 strlcpy(tz->type, type, sizeof(tz->type)); 1162 strlcpy(tz->type, type, sizeof(tz->type));
1184 tz->ops = ops; 1163 tz->ops = ops;
1185 tz->tzp = tzp; 1164 tz->tzp = tzp;
@@ -1201,7 +1180,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
1201 dev_set_name(&tz->device, "thermal_zone%d", tz->id); 1180 dev_set_name(&tz->device, "thermal_zone%d", tz->id);
1202 result = device_register(&tz->device); 1181 result = device_register(&tz->device);
1203 if (result) { 1182 if (result) {
1204 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); 1183 ida_simple_remove(&thermal_tz_ida, tz->id);
1205 kfree(tz); 1184 kfree(tz);
1206 return ERR_PTR(result); 1185 return ERR_PTR(result);
1207 } 1186 }
@@ -1255,7 +1234,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
1255 return tz; 1234 return tz;
1256 1235
1257unregister: 1236unregister:
1258 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); 1237 ida_simple_remove(&thermal_tz_ida, tz->id);
1259 device_unregister(&tz->device); 1238 device_unregister(&tz->device);
1260 return ERR_PTR(result); 1239 return ERR_PTR(result);
1261} 1240}
@@ -1313,8 +1292,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
1313 thermal_set_governor(tz, NULL); 1292 thermal_set_governor(tz, NULL);
1314 1293
1315 thermal_remove_hwmon_sysfs(tz); 1294 thermal_remove_hwmon_sysfs(tz);
1316 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); 1295 ida_simple_remove(&thermal_tz_ida, tz->id);
1317 idr_destroy(&tz->idr); 1296 ida_destroy(&tz->ida);
1318 mutex_destroy(&tz->lock); 1297 mutex_destroy(&tz->lock);
1319 device_unregister(&tz->device); 1298 device_unregister(&tz->device);
1320} 1299}
@@ -1514,9 +1493,8 @@ unregister_class:
1514unregister_governors: 1493unregister_governors:
1515 thermal_unregister_governors(); 1494 thermal_unregister_governors();
1516error: 1495error:
1517 idr_destroy(&thermal_tz_idr); 1496 ida_destroy(&thermal_tz_ida);
1518 idr_destroy(&thermal_cdev_idr); 1497 ida_destroy(&thermal_cdev_ida);
1519 mutex_destroy(&thermal_idr_lock);
1520 mutex_destroy(&thermal_list_lock); 1498 mutex_destroy(&thermal_list_lock);
1521 mutex_destroy(&thermal_governor_lock); 1499 mutex_destroy(&thermal_governor_lock);
1522 return result; 1500 return result;
@@ -1529,9 +1507,8 @@ static void __exit thermal_exit(void)
1529 genetlink_exit(); 1507 genetlink_exit();
1530 class_unregister(&thermal_class); 1508 class_unregister(&thermal_class);
1531 thermal_unregister_governors(); 1509 thermal_unregister_governors();
1532 idr_destroy(&thermal_tz_idr); 1510 ida_destroy(&thermal_tz_ida);
1533 idr_destroy(&thermal_cdev_idr); 1511 ida_destroy(&thermal_cdev_ida);
1534 mutex_destroy(&thermal_idr_lock);
1535 mutex_destroy(&thermal_list_lock); 1512 mutex_destroy(&thermal_list_lock);
1536 mutex_destroy(&thermal_governor_lock); 1513 mutex_destroy(&thermal_governor_lock);
1537} 1514}
diff --git a/drivers/thermal/ti-soc-thermal/Kconfig b/drivers/thermal/ti-soc-thermal/Kconfig
index ea8283f08aa6..fe0e877f84d0 100644
--- a/drivers/thermal/ti-soc-thermal/Kconfig
+++ b/drivers/thermal/ti-soc-thermal/Kconfig
@@ -11,7 +11,6 @@ config TI_SOC_THERMAL
11config TI_THERMAL 11config TI_THERMAL
12 bool "Texas Instruments SoCs thermal framework support" 12 bool "Texas Instruments SoCs thermal framework support"
13 depends on TI_SOC_THERMAL 13 depends on TI_SOC_THERMAL
14 depends on CPU_THERMAL
15 help 14 help
16 If you say yes here you want to get support for generic thermal 15 If you say yes here you want to get support for generic thermal
17 framework for the Texas Instruments on die bandgap temperature sensor. 16 framework for the Texas Instruments on die bandgap temperature sensor.
diff --git a/drivers/thermal/ti-soc-thermal/dra752-bandgap.h b/drivers/thermal/ti-soc-thermal/dra752-bandgap.h
index 6b0f2b1160f7..a31e4b5e82cd 100644
--- a/drivers/thermal/ti-soc-thermal/dra752-bandgap.h
+++ b/drivers/thermal/ti-soc-thermal/dra752-bandgap.h
@@ -54,7 +54,6 @@
54#define DRA752_STD_FUSE_OPP_BGAP_CORE_OFFSET 0x8 54#define DRA752_STD_FUSE_OPP_BGAP_CORE_OFFSET 0x8
55#define DRA752_TEMP_SENSOR_CORE_OFFSET 0x154 55#define DRA752_TEMP_SENSOR_CORE_OFFSET 0x154
56#define DRA752_BANDGAP_THRESHOLD_CORE_OFFSET 0x1ac 56#define DRA752_BANDGAP_THRESHOLD_CORE_OFFSET 0x1ac
57#define DRA752_BANDGAP_TSHUT_CORE_OFFSET 0x1b8
58#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_OFFSET 0x1c4 57#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_OFFSET 0x1c4
59#define DRA752_DTEMP_CORE_0_OFFSET 0x208 58#define DRA752_DTEMP_CORE_0_OFFSET 0x208
60#define DRA752_DTEMP_CORE_1_OFFSET 0x20c 59#define DRA752_DTEMP_CORE_1_OFFSET 0x20c
@@ -66,7 +65,6 @@
66#define DRA752_STD_FUSE_OPP_BGAP_IVA_OFFSET 0x388 65#define DRA752_STD_FUSE_OPP_BGAP_IVA_OFFSET 0x388
67#define DRA752_TEMP_SENSOR_IVA_OFFSET 0x398 66#define DRA752_TEMP_SENSOR_IVA_OFFSET 0x398
68#define DRA752_BANDGAP_THRESHOLD_IVA_OFFSET 0x3a4 67#define DRA752_BANDGAP_THRESHOLD_IVA_OFFSET 0x3a4
69#define DRA752_BANDGAP_TSHUT_IVA_OFFSET 0x3ac
70#define DRA752_BANDGAP_CUMUL_DTEMP_IVA_OFFSET 0x3b4 68#define DRA752_BANDGAP_CUMUL_DTEMP_IVA_OFFSET 0x3b4
71#define DRA752_DTEMP_IVA_0_OFFSET 0x3d0 69#define DRA752_DTEMP_IVA_0_OFFSET 0x3d0
72#define DRA752_DTEMP_IVA_1_OFFSET 0x3d4 70#define DRA752_DTEMP_IVA_1_OFFSET 0x3d4
@@ -78,7 +76,6 @@
78#define DRA752_STD_FUSE_OPP_BGAP_MPU_OFFSET 0x4 76#define DRA752_STD_FUSE_OPP_BGAP_MPU_OFFSET 0x4
79#define DRA752_TEMP_SENSOR_MPU_OFFSET 0x14c 77#define DRA752_TEMP_SENSOR_MPU_OFFSET 0x14c
80#define DRA752_BANDGAP_THRESHOLD_MPU_OFFSET 0x1a4 78#define DRA752_BANDGAP_THRESHOLD_MPU_OFFSET 0x1a4
81#define DRA752_BANDGAP_TSHUT_MPU_OFFSET 0x1b0
82#define DRA752_BANDGAP_CUMUL_DTEMP_MPU_OFFSET 0x1bc 79#define DRA752_BANDGAP_CUMUL_DTEMP_MPU_OFFSET 0x1bc
83#define DRA752_DTEMP_MPU_0_OFFSET 0x1e0 80#define DRA752_DTEMP_MPU_0_OFFSET 0x1e0
84#define DRA752_DTEMP_MPU_1_OFFSET 0x1e4 81#define DRA752_DTEMP_MPU_1_OFFSET 0x1e4
@@ -90,7 +87,6 @@
90#define DRA752_STD_FUSE_OPP_BGAP_DSPEVE_OFFSET 0x384 87#define DRA752_STD_FUSE_OPP_BGAP_DSPEVE_OFFSET 0x384
91#define DRA752_TEMP_SENSOR_DSPEVE_OFFSET 0x394 88#define DRA752_TEMP_SENSOR_DSPEVE_OFFSET 0x394
92#define DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET 0x3a0 89#define DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET 0x3a0
93#define DRA752_BANDGAP_TSHUT_DSPEVE_OFFSET 0x3a8
94#define DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_OFFSET 0x3b0 90#define DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_OFFSET 0x3b0
95#define DRA752_DTEMP_DSPEVE_0_OFFSET 0x3bc 91#define DRA752_DTEMP_DSPEVE_0_OFFSET 0x3bc
96#define DRA752_DTEMP_DSPEVE_1_OFFSET 0x3c0 92#define DRA752_DTEMP_DSPEVE_1_OFFSET 0x3c0
@@ -102,7 +98,6 @@
102#define DRA752_STD_FUSE_OPP_BGAP_GPU_OFFSET 0x0 98#define DRA752_STD_FUSE_OPP_BGAP_GPU_OFFSET 0x0
103#define DRA752_TEMP_SENSOR_GPU_OFFSET 0x150 99#define DRA752_TEMP_SENSOR_GPU_OFFSET 0x150
104#define DRA752_BANDGAP_THRESHOLD_GPU_OFFSET 0x1a8 100#define DRA752_BANDGAP_THRESHOLD_GPU_OFFSET 0x1a8
105#define DRA752_BANDGAP_TSHUT_GPU_OFFSET 0x1b4
106#define DRA752_BANDGAP_CUMUL_DTEMP_GPU_OFFSET 0x1c0 101#define DRA752_BANDGAP_CUMUL_DTEMP_GPU_OFFSET 0x1c0
107#define DRA752_DTEMP_GPU_0_OFFSET 0x1f4 102#define DRA752_DTEMP_GPU_0_OFFSET 0x1f4
108#define DRA752_DTEMP_GPU_1_OFFSET 0x1f8 103#define DRA752_DTEMP_GPU_1_OFFSET 0x1f8
@@ -173,10 +168,6 @@
173#define DRA752_BANDGAP_THRESHOLD_HOT_MASK (0x3ff << 16) 168#define DRA752_BANDGAP_THRESHOLD_HOT_MASK (0x3ff << 16)
174#define DRA752_BANDGAP_THRESHOLD_COLD_MASK (0x3ff << 0) 169#define DRA752_BANDGAP_THRESHOLD_COLD_MASK (0x3ff << 0)
175 170
176/* DRA752.TSHUT_THRESHOLD */
177#define DRA752_TSHUT_THRESHOLD_MUXCTRL_MASK BIT(31)
178#define DRA752_TSHUT_THRESHOLD_HOT_MASK (0x3ff << 16)
179#define DRA752_TSHUT_THRESHOLD_COLD_MASK (0x3ff << 0)
180 171
181/* DRA752.BANDGAP_CUMUL_DTEMP_CORE */ 172/* DRA752.BANDGAP_CUMUL_DTEMP_CORE */
182#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_MASK (0xffffffff << 0) 173#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_MASK (0xffffffff << 0)
@@ -216,8 +207,6 @@
216#define DRA752_GPU_MAX_TEMP 125000 207#define DRA752_GPU_MAX_TEMP 125000
217#define DRA752_GPU_HYST_VAL 5000 208#define DRA752_GPU_HYST_VAL 5000
218/* interrupts thresholds */ 209/* interrupts thresholds */
219#define DRA752_GPU_TSHUT_HOT 915
220#define DRA752_GPU_TSHUT_COLD 900
221#define DRA752_GPU_T_HOT 800 210#define DRA752_GPU_T_HOT 800
222#define DRA752_GPU_T_COLD 795 211#define DRA752_GPU_T_COLD 795
223 212
@@ -230,8 +219,6 @@
230#define DRA752_MPU_MAX_TEMP 125000 219#define DRA752_MPU_MAX_TEMP 125000
231#define DRA752_MPU_HYST_VAL 5000 220#define DRA752_MPU_HYST_VAL 5000
232/* interrupts thresholds */ 221/* interrupts thresholds */
233#define DRA752_MPU_TSHUT_HOT 915
234#define DRA752_MPU_TSHUT_COLD 900
235#define DRA752_MPU_T_HOT 800 222#define DRA752_MPU_T_HOT 800
236#define DRA752_MPU_T_COLD 795 223#define DRA752_MPU_T_COLD 795
237 224
@@ -244,8 +231,6 @@
244#define DRA752_CORE_MAX_TEMP 125000 231#define DRA752_CORE_MAX_TEMP 125000
245#define DRA752_CORE_HYST_VAL 5000 232#define DRA752_CORE_HYST_VAL 5000
246/* interrupts thresholds */ 233/* interrupts thresholds */
247#define DRA752_CORE_TSHUT_HOT 915
248#define DRA752_CORE_TSHUT_COLD 900
249#define DRA752_CORE_T_HOT 800 234#define DRA752_CORE_T_HOT 800
250#define DRA752_CORE_T_COLD 795 235#define DRA752_CORE_T_COLD 795
251 236
@@ -258,8 +243,6 @@
258#define DRA752_DSPEVE_MAX_TEMP 125000 243#define DRA752_DSPEVE_MAX_TEMP 125000
259#define DRA752_DSPEVE_HYST_VAL 5000 244#define DRA752_DSPEVE_HYST_VAL 5000
260/* interrupts thresholds */ 245/* interrupts thresholds */
261#define DRA752_DSPEVE_TSHUT_HOT 915
262#define DRA752_DSPEVE_TSHUT_COLD 900
263#define DRA752_DSPEVE_T_HOT 800 246#define DRA752_DSPEVE_T_HOT 800
264#define DRA752_DSPEVE_T_COLD 795 247#define DRA752_DSPEVE_T_COLD 795
265 248
@@ -272,8 +255,6 @@
272#define DRA752_IVA_MAX_TEMP 125000 255#define DRA752_IVA_MAX_TEMP 125000
273#define DRA752_IVA_HYST_VAL 5000 256#define DRA752_IVA_HYST_VAL 5000
274/* interrupts thresholds */ 257/* interrupts thresholds */
275#define DRA752_IVA_TSHUT_HOT 915
276#define DRA752_IVA_TSHUT_COLD 900
277#define DRA752_IVA_T_HOT 800 258#define DRA752_IVA_T_HOT 800
278#define DRA752_IVA_T_COLD 795 259#define DRA752_IVA_T_COLD 795
279 260
diff --git a/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c b/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
index 58b5c6694cd4..118d7d847715 100644
--- a/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
+++ b/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
@@ -49,9 +49,6 @@ dra752_core_temp_sensor_registers = {
49 .bgap_threshold = DRA752_BANDGAP_THRESHOLD_CORE_OFFSET, 49 .bgap_threshold = DRA752_BANDGAP_THRESHOLD_CORE_OFFSET,
50 .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK, 50 .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
51 .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK, 51 .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
52 .tshut_threshold = DRA752_BANDGAP_TSHUT_CORE_OFFSET,
53 .tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
54 .tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
55 .bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET, 52 .bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
56 .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK, 53 .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
57 .status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_CORE_MASK, 54 .status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_CORE_MASK,
@@ -85,9 +82,6 @@ dra752_iva_temp_sensor_registers = {
85 .bgap_threshold = DRA752_BANDGAP_THRESHOLD_IVA_OFFSET, 82 .bgap_threshold = DRA752_BANDGAP_THRESHOLD_IVA_OFFSET,
86 .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK, 83 .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
87 .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK, 84 .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
88 .tshut_threshold = DRA752_BANDGAP_TSHUT_IVA_OFFSET,
89 .tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
90 .tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
91 .bgap_status = DRA752_BANDGAP_STATUS_2_OFFSET, 85 .bgap_status = DRA752_BANDGAP_STATUS_2_OFFSET,
92 .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK, 86 .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
93 .status_hot_mask = DRA752_BANDGAP_STATUS_2_HOT_IVA_MASK, 87 .status_hot_mask = DRA752_BANDGAP_STATUS_2_HOT_IVA_MASK,
@@ -121,9 +115,6 @@ dra752_mpu_temp_sensor_registers = {
121 .bgap_threshold = DRA752_BANDGAP_THRESHOLD_MPU_OFFSET, 115 .bgap_threshold = DRA752_BANDGAP_THRESHOLD_MPU_OFFSET,
122 .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK, 116 .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
123 .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK, 117 .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
124 .tshut_threshold = DRA752_BANDGAP_TSHUT_MPU_OFFSET,
125 .tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
126 .tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
127 .bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET, 118 .bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
128 .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK, 119 .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
129 .status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_MPU_MASK, 120 .status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_MPU_MASK,
@@ -157,9 +148,6 @@ dra752_dspeve_temp_sensor_registers = {
157 .bgap_threshold = DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET, 148 .bgap_threshold = DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET,
158 .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK, 149 .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
159 .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK, 150 .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
160 .tshut_threshold = DRA752_BANDGAP_TSHUT_DSPEVE_OFFSET,
161 .tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
162 .tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
163 .bgap_status = DRA752_BANDGAP_STATUS_2_OFFSET, 151 .bgap_status = DRA752_BANDGAP_STATUS_2_OFFSET,
164 .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK, 152 .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
165 .status_hot_mask = DRA752_BANDGAP_STATUS_2_HOT_DSPEVE_MASK, 153 .status_hot_mask = DRA752_BANDGAP_STATUS_2_HOT_DSPEVE_MASK,
@@ -193,9 +181,6 @@ dra752_gpu_temp_sensor_registers = {
193 .bgap_threshold = DRA752_BANDGAP_THRESHOLD_GPU_OFFSET, 181 .bgap_threshold = DRA752_BANDGAP_THRESHOLD_GPU_OFFSET,
194 .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK, 182 .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
195 .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK, 183 .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
196 .tshut_threshold = DRA752_BANDGAP_TSHUT_GPU_OFFSET,
197 .tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
198 .tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
199 .bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET, 184 .bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
200 .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK, 185 .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
201 .status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_GPU_MASK, 186 .status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_GPU_MASK,
@@ -211,8 +196,6 @@ dra752_gpu_temp_sensor_registers = {
211 196
212/* Thresholds and limits for DRA752 MPU temperature sensor */ 197/* Thresholds and limits for DRA752 MPU temperature sensor */
213static struct temp_sensor_data dra752_mpu_temp_sensor_data = { 198static struct temp_sensor_data dra752_mpu_temp_sensor_data = {
214 .tshut_hot = DRA752_MPU_TSHUT_HOT,
215 .tshut_cold = DRA752_MPU_TSHUT_COLD,
216 .t_hot = DRA752_MPU_T_HOT, 199 .t_hot = DRA752_MPU_T_HOT,
217 .t_cold = DRA752_MPU_T_COLD, 200 .t_cold = DRA752_MPU_T_COLD,
218 .min_freq = DRA752_MPU_MIN_FREQ, 201 .min_freq = DRA752_MPU_MIN_FREQ,
@@ -226,8 +209,6 @@ static struct temp_sensor_data dra752_mpu_temp_sensor_data = {
226 209
227/* Thresholds and limits for DRA752 GPU temperature sensor */ 210/* Thresholds and limits for DRA752 GPU temperature sensor */
228static struct temp_sensor_data dra752_gpu_temp_sensor_data = { 211static struct temp_sensor_data dra752_gpu_temp_sensor_data = {
229 .tshut_hot = DRA752_GPU_TSHUT_HOT,
230 .tshut_cold = DRA752_GPU_TSHUT_COLD,
231 .t_hot = DRA752_GPU_T_HOT, 212 .t_hot = DRA752_GPU_T_HOT,
232 .t_cold = DRA752_GPU_T_COLD, 213 .t_cold = DRA752_GPU_T_COLD,
233 .min_freq = DRA752_GPU_MIN_FREQ, 214 .min_freq = DRA752_GPU_MIN_FREQ,
@@ -241,8 +222,6 @@ static struct temp_sensor_data dra752_gpu_temp_sensor_data = {
241 222
242/* Thresholds and limits for DRA752 CORE temperature sensor */ 223/* Thresholds and limits for DRA752 CORE temperature sensor */
243static struct temp_sensor_data dra752_core_temp_sensor_data = { 224static struct temp_sensor_data dra752_core_temp_sensor_data = {
244 .tshut_hot = DRA752_CORE_TSHUT_HOT,
245 .tshut_cold = DRA752_CORE_TSHUT_COLD,
246 .t_hot = DRA752_CORE_T_HOT, 225 .t_hot = DRA752_CORE_T_HOT,
247 .t_cold = DRA752_CORE_T_COLD, 226 .t_cold = DRA752_CORE_T_COLD,
248 .min_freq = DRA752_CORE_MIN_FREQ, 227 .min_freq = DRA752_CORE_MIN_FREQ,
@@ -256,8 +235,6 @@ static struct temp_sensor_data dra752_core_temp_sensor_data = {
256 235
257/* Thresholds and limits for DRA752 DSPEVE temperature sensor */ 236/* Thresholds and limits for DRA752 DSPEVE temperature sensor */
258static struct temp_sensor_data dra752_dspeve_temp_sensor_data = { 237static struct temp_sensor_data dra752_dspeve_temp_sensor_data = {
259 .tshut_hot = DRA752_DSPEVE_TSHUT_HOT,
260 .tshut_cold = DRA752_DSPEVE_TSHUT_COLD,
261 .t_hot = DRA752_DSPEVE_T_HOT, 238 .t_hot = DRA752_DSPEVE_T_HOT,
262 .t_cold = DRA752_DSPEVE_T_COLD, 239 .t_cold = DRA752_DSPEVE_T_COLD,
263 .min_freq = DRA752_DSPEVE_MIN_FREQ, 240 .min_freq = DRA752_DSPEVE_MIN_FREQ,
@@ -271,8 +248,6 @@ static struct temp_sensor_data dra752_dspeve_temp_sensor_data = {
271 248
272/* Thresholds and limits for DRA752 IVA temperature sensor */ 249/* Thresholds and limits for DRA752 IVA temperature sensor */
273static struct temp_sensor_data dra752_iva_temp_sensor_data = { 250static struct temp_sensor_data dra752_iva_temp_sensor_data = {
274 .tshut_hot = DRA752_IVA_TSHUT_HOT,
275 .tshut_cold = DRA752_IVA_TSHUT_COLD,
276 .t_hot = DRA752_IVA_T_HOT, 251 .t_hot = DRA752_IVA_T_HOT,
277 .t_cold = DRA752_IVA_T_COLD, 252 .t_cold = DRA752_IVA_T_COLD,
278 .min_freq = DRA752_IVA_MIN_FREQ, 253 .min_freq = DRA752_IVA_MIN_FREQ,
@@ -416,8 +391,7 @@ int dra752_adc_to_temp[DRA752_ADC_END_VALUE - DRA752_ADC_START_VALUE + 1] = {
416 391
417/* DRA752 data */ 392/* DRA752 data */
418const struct ti_bandgap_data dra752_data = { 393const struct ti_bandgap_data dra752_data = {
419 .features = TI_BANDGAP_FEATURE_TSHUT_CONFIG | 394 .features = TI_BANDGAP_FEATURE_FREEZE_BIT |
420 TI_BANDGAP_FEATURE_FREEZE_BIT |
421 TI_BANDGAP_FEATURE_TALERT | 395 TI_BANDGAP_FEATURE_TALERT |
422 TI_BANDGAP_FEATURE_COUNTER_DELAY | 396 TI_BANDGAP_FEATURE_COUNTER_DELAY |
423 TI_BANDGAP_FEATURE_HISTORY_BUFFER | 397 TI_BANDGAP_FEATURE_HISTORY_BUFFER |
diff --git a/drivers/thermal/zx2967_thermal.c b/drivers/thermal/zx2967_thermal.c
new file mode 100644
index 000000000000..a5670ad2cfc8
--- /dev/null
+++ b/drivers/thermal/zx2967_thermal.c
@@ -0,0 +1,258 @@
1/*
2 * ZTE's zx2967 family thermal sensor driver
3 *
4 * Copyright (C) 2017 ZTE Ltd.
5 *
6 * Author: Baoyou Xie <baoyou.xie@linaro.org>
7 *
8 * License terms: GNU General Public License (GPL) version 2
9 */
10
11#include <linux/clk.h>
12#include <linux/device.h>
13#include <linux/err.h>
14#include <linux/iopoll.h>
15#include <linux/module.h>
16#include <linux/platform_device.h>
17#include <linux/thermal.h>
18
19/* Power Mode: 0->low 1->high */
20#define ZX2967_THERMAL_POWER_MODE 0
21#define ZX2967_POWER_MODE_LOW 0
22#define ZX2967_POWER_MODE_HIGH 1
23
24/* DCF Control Register */
25#define ZX2967_THERMAL_DCF 0x4
26#define ZX2967_DCF_EN BIT(1)
27#define ZX2967_DCF_FREEZE BIT(0)
28
29/* Selection Register */
30#define ZX2967_THERMAL_SEL 0x8
31
32/* Control Register */
33#define ZX2967_THERMAL_CTRL 0x10
34
35#define ZX2967_THERMAL_READY BIT(12)
36#define ZX2967_THERMAL_TEMP_MASK GENMASK(11, 0)
37#define ZX2967_THERMAL_ID_MASK 0x18
38#define ZX2967_THERMAL_ID 0x10
39
40#define ZX2967_GET_TEMP_TIMEOUT_US (100 * 1024)
41
42/**
43 * struct zx2967_thermal_priv - zx2967 thermal sensor private structure
44 * @tzd: struct thermal_zone_device where the sensor is registered
45 * @lock: prevents read sensor in parallel
46 * @clk_topcrm: topcrm clk structure
47 * @clk_apb: apb clk structure
48 * @regs: pointer to base address of the thermal sensor
49 */
50
51struct zx2967_thermal_priv {
52 struct thermal_zone_device *tzd;
53 struct mutex lock;
54 struct clk *clk_topcrm;
55 struct clk *clk_apb;
56 void __iomem *regs;
57 struct device *dev;
58};
59
60static int zx2967_thermal_get_temp(void *data, int *temp)
61{
62 void __iomem *regs;
63 struct zx2967_thermal_priv *priv = data;
64 u32 val;
65 int ret;
66
67 if (!priv->tzd)
68 return -EAGAIN;
69
70 regs = priv->regs;
71 mutex_lock(&priv->lock);
72 writel_relaxed(ZX2967_POWER_MODE_LOW,
73 regs + ZX2967_THERMAL_POWER_MODE);
74 writel_relaxed(ZX2967_DCF_EN, regs + ZX2967_THERMAL_DCF);
75
76 val = readl_relaxed(regs + ZX2967_THERMAL_SEL);
77 val &= ~ZX2967_THERMAL_ID_MASK;
78 val |= ZX2967_THERMAL_ID;
79 writel_relaxed(val, regs + ZX2967_THERMAL_SEL);
80
81 /*
82 * Must wait for a while, surely it's a bit odd.
83 * otherwise temperature value we got has a few deviation, even if
84 * the THERMAL_READY bit is set.
85 */
86 usleep_range(100, 300);
87 ret = readx_poll_timeout(readl, regs + ZX2967_THERMAL_CTRL,
88 val, val & ZX2967_THERMAL_READY, 300,
89 ZX2967_GET_TEMP_TIMEOUT_US);
90 if (ret) {
91 dev_err(priv->dev, "Thermal sensor data timeout\n");
92 goto unlock;
93 }
94
95 writel_relaxed(ZX2967_DCF_FREEZE | ZX2967_DCF_EN,
96 regs + ZX2967_THERMAL_DCF);
97 val = readl_relaxed(regs + ZX2967_THERMAL_CTRL)
98 & ZX2967_THERMAL_TEMP_MASK;
99 writel_relaxed(ZX2967_POWER_MODE_HIGH,
100 regs + ZX2967_THERMAL_POWER_MODE);
101
102 /*
103 * Calculate temperature
104 * In dts, slope is multiplied by 1000.
105 */
106 *temp = DIV_ROUND_CLOSEST(((s32)val + priv->tzd->tzp->offset) * 1000,
107 priv->tzd->tzp->slope);
108
109unlock:
110 mutex_unlock(&priv->lock);
111 return ret;
112}
113
114static struct thermal_zone_of_device_ops zx2967_of_thermal_ops = {
115 .get_temp = zx2967_thermal_get_temp,
116};
117
118static int zx2967_thermal_probe(struct platform_device *pdev)
119{
120 struct zx2967_thermal_priv *priv;
121 struct resource *res;
122 int ret;
123
124 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
125 if (!priv)
126 return -ENOMEM;
127
128 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
129 priv->regs = devm_ioremap_resource(&pdev->dev, res);
130 if (IS_ERR(priv->regs))
131 return PTR_ERR(priv->regs);
132
133 priv->clk_topcrm = devm_clk_get(&pdev->dev, "topcrm");
134 if (IS_ERR(priv->clk_topcrm)) {
135 ret = PTR_ERR(priv->clk_topcrm);
136 dev_err(&pdev->dev, "failed to get topcrm clock: %d\n", ret);
137 return ret;
138 }
139
140 ret = clk_prepare_enable(priv->clk_topcrm);
141 if (ret) {
142 dev_err(&pdev->dev, "failed to enable topcrm clock: %d\n",
143 ret);
144 return ret;
145 }
146
147 priv->clk_apb = devm_clk_get(&pdev->dev, "apb");
148 if (IS_ERR(priv->clk_apb)) {
149 ret = PTR_ERR(priv->clk_apb);
150 dev_err(&pdev->dev, "failed to get apb clock: %d\n", ret);
151 goto disable_clk_topcrm;
152 }
153
154 ret = clk_prepare_enable(priv->clk_apb);
155 if (ret) {
156 dev_err(&pdev->dev, "failed to enable apb clock: %d\n",
157 ret);
158 goto disable_clk_topcrm;
159 }
160
161 mutex_init(&priv->lock);
162 priv->tzd = thermal_zone_of_sensor_register(&pdev->dev,
163 0, priv, &zx2967_of_thermal_ops);
164
165 if (IS_ERR(priv->tzd)) {
166 ret = PTR_ERR(priv->tzd);
167 dev_err(&pdev->dev, "failed to register sensor: %d\n", ret);
168 goto disable_clk_all;
169 }
170
171 if (priv->tzd->tzp->slope == 0) {
172 thermal_zone_of_sensor_unregister(&pdev->dev, priv->tzd);
173 dev_err(&pdev->dev, "coefficients of sensor is invalid\n");
174 ret = -EINVAL;
175 goto disable_clk_all;
176 }
177
178 priv->dev = &pdev->dev;
179 platform_set_drvdata(pdev, priv);
180
181 return 0;
182
183disable_clk_all:
184 clk_disable_unprepare(priv->clk_apb);
185disable_clk_topcrm:
186 clk_disable_unprepare(priv->clk_topcrm);
187 return ret;
188}
189
190static int zx2967_thermal_exit(struct platform_device *pdev)
191{
192 struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev);
193
194 thermal_zone_of_sensor_unregister(&pdev->dev, priv->tzd);
195 clk_disable_unprepare(priv->clk_topcrm);
196 clk_disable_unprepare(priv->clk_apb);
197
198 return 0;
199}
200
201static const struct of_device_id zx2967_thermal_id_table[] = {
202 { .compatible = "zte,zx296718-thermal" },
203 {}
204};
205MODULE_DEVICE_TABLE(of, zx2967_thermal_id_table);
206
207#ifdef CONFIG_PM_SLEEP
208static int zx2967_thermal_suspend(struct device *dev)
209{
210 struct platform_device *pdev = to_platform_device(dev);
211 struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev);
212
213 if (priv && priv->clk_topcrm)
214 clk_disable_unprepare(priv->clk_topcrm);
215
216 if (priv && priv->clk_apb)
217 clk_disable_unprepare(priv->clk_apb);
218
219 return 0;
220}
221
222static int zx2967_thermal_resume(struct device *dev)
223{
224 struct platform_device *pdev = to_platform_device(dev);
225 struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev);
226 int error;
227
228 error = clk_prepare_enable(priv->clk_topcrm);
229 if (error)
230 return error;
231
232 error = clk_prepare_enable(priv->clk_apb);
233 if (error) {
234 clk_disable_unprepare(priv->clk_topcrm);
235 return error;
236 }
237
238 return 0;
239}
240#endif
241
242static SIMPLE_DEV_PM_OPS(zx2967_thermal_pm_ops,
243 zx2967_thermal_suspend, zx2967_thermal_resume);
244
245static struct platform_driver zx2967_thermal_driver = {
246 .probe = zx2967_thermal_probe,
247 .remove = zx2967_thermal_exit,
248 .driver = {
249 .name = "zx2967_thermal",
250 .of_match_table = zx2967_thermal_id_table,
251 .pm = &zx2967_thermal_pm_ops,
252 },
253};
254module_platform_driver(zx2967_thermal_driver);
255
256MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
257MODULE_DESCRIPTION("ZTE zx2967 thermal driver");
258MODULE_LICENSE("GPL v2");
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index e275e98bdceb..dab11f97e1c6 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -194,7 +194,7 @@ struct thermal_attr {
194 * @governor: pointer to the governor for this thermal zone 194 * @governor: pointer to the governor for this thermal zone
195 * @governor_data: private pointer for governor data 195 * @governor_data: private pointer for governor data
196 * @thermal_instances: list of &struct thermal_instance of this thermal zone 196 * @thermal_instances: list of &struct thermal_instance of this thermal zone
197 * @idr: &struct idr to generate unique id for this zone's cooling 197 * @ida: &struct ida to generate unique id for this zone's cooling
198 * devices 198 * devices
199 * @lock: lock to protect thermal_instances list 199 * @lock: lock to protect thermal_instances list
200 * @node: node in thermal_tz_list (in thermal_core.c) 200 * @node: node in thermal_tz_list (in thermal_core.c)
@@ -227,7 +227,7 @@ struct thermal_zone_device {
227 struct thermal_governor *governor; 227 struct thermal_governor *governor;
228 void *governor_data; 228 void *governor_data;
229 struct list_head thermal_instances; 229 struct list_head thermal_instances;
230 struct idr idr; 230 struct ida ida;
231 struct mutex lock; 231 struct mutex lock;
232 struct list_head node; 232 struct list_head node;
233 struct delayed_work poll_queue; 233 struct delayed_work poll_queue;