aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-16 10:56:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-16 10:56:57 -0400
commita455eda33faafcaac1effb31d682765b14ef868c (patch)
tree9a4ca7da47300ca9081445539ff337efcead4b6b
parentcc7ce90153e74f8266eefee9fba466faa1a2d5df (diff)
parent37bcec5d9f71bd13142a97d2196b293c9ac23823 (diff)
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal
Pull thermal soc updates from Eduardo Valentin: - thermal core has a new devm_* API for registering cooling devices. I took the entire series, that is why you see changes on drivers/hwmon in this pull (Guenter Roeck) - rockchip thermal driver gains support to PX30 SoC (Elaine Zhang) - the generic-adc thermal driver now considers the lookup table DT property as optional (Jean-Francois Dagenais) - Refactoring of tsens thermal driver (Amit Kucheria) - Cleanups on cpu cooling driver (Daniel Lezcano) - broadcom thermal driver dropped support to ACPI (Srinath Mannam) - tegra thermal driver gains support to OC hw throttle and GPU throtle (Wei Ni) - Fixes in several thermal drivers. * 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal: (59 commits) hwmon: (pwm-fan) Use devm_thermal_of_cooling_device_register hwmon: (npcm750-pwm-fan) Use devm_thermal_of_cooling_device_register hwmon: (mlxreg-fan) Use devm_thermal_of_cooling_device_register hwmon: (gpio-fan) Use devm_thermal_of_cooling_device_register hwmon: (aspeed-pwm-tacho) Use devm_thermal_of_cooling_device_register thermal: rcar_gen3_thermal: Fix to show correct trip points number thermal: rcar_thermal: update calculation formula for R-Car Gen3 SoCs thermal: cpu_cooling: Actually trace CPU load in thermal_power_cpu_get_power thermal: rockchip: Support the PX30 SoC in thermal driver dt-bindings: rockchip-thermal: Support the PX30 SoC compatible thermal: rockchip: fix up the tsadc pinctrl setting error thermal: broadcom: Remove ACPI support thermal: Fix build error of missing devm_ioremap_resource on UM thermal/drivers/cpu_cooling: Remove pointless field thermal/drivers/cpu_cooling: Add Software Package Data Exchange (SPDX) thermal/drivers/cpu_cooling: Fixup the header and copyright thermal/drivers/cpu_cooling: Remove pointless test in power2state() thermal: rcar_gen3_thermal: disable interrupt in .remove thermal: rcar_gen3_thermal: fix interrupt type thermal: Introduce devm_thermal_of_cooling_device_register ...
-rw-r--r--Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt33
-rw-r--r--Documentation/devicetree/bindings/thermal/nvidia,tegra124-soctherm.txt62
-rw-r--r--Documentation/devicetree/bindings/thermal/qcom-tsens.txt14
-rw-r--r--Documentation/devicetree/bindings/thermal/rockchip-thermal.txt1
-rw-r--r--Documentation/devicetree/bindings/thermal/thermal-generic-adc.txt10
-rw-r--r--MAINTAINERS6
-rw-r--r--drivers/hwmon/aspeed-pwm-tacho.c6
-rw-r--r--drivers/hwmon/gpio-fan.c25
-rw-r--r--drivers/hwmon/mlxreg-fan.c31
-rw-r--r--drivers/hwmon/npcm750-pwm-fan.c6
-rw-r--r--drivers/hwmon/pwm-fan.c97
-rw-r--r--drivers/thermal/Kconfig11
-rw-r--r--drivers/thermal/Makefile1
-rw-r--r--drivers/thermal/broadcom/sr-thermal.c8
-rw-r--r--drivers/thermal/cpu_cooling.c30
-rw-r--r--drivers/thermal/of-thermal.c3
-rw-r--r--drivers/thermal/qcom/Makefile4
-rw-r--r--drivers/thermal/qcom/tsens-8916.c105
-rw-r--r--drivers/thermal/qcom/tsens-8960.c84
-rw-r--r--drivers/thermal/qcom/tsens-common.c159
-rw-r--r--drivers/thermal/qcom/tsens-v0_1.c (renamed from drivers/thermal/qcom/tsens-8974.c)166
-rw-r--r--drivers/thermal/qcom/tsens-v1.c193
-rw-r--r--drivers/thermal/qcom/tsens-v2.c111
-rw-r--r--drivers/thermal/qcom/tsens.c100
-rw-r--r--drivers/thermal/qcom/tsens.h291
-rw-r--r--drivers/thermal/qoriq_thermal.c5
-rw-r--r--drivers/thermal/rcar_gen3_thermal.c51
-rw-r--r--drivers/thermal/rcar_thermal.c11
-rw-r--r--drivers/thermal/rockchip_thermal.c74
-rw-r--r--drivers/thermal/st/Kconfig22
-rw-r--r--drivers/thermal/st/stm_thermal.c6
-rw-r--r--drivers/thermal/tegra/Kconfig4
-rw-r--r--drivers/thermal/tegra/soctherm.c961
-rw-r--r--drivers/thermal/tegra/soctherm.h16
-rw-r--r--drivers/thermal/tegra/tegra124-soctherm.c7
-rw-r--r--drivers/thermal/tegra/tegra132-soctherm.c7
-rw-r--r--drivers/thermal/tegra/tegra210-soctherm.c15
-rw-r--r--drivers/thermal/thermal-generic-adc.c9
-rw-r--r--drivers/thermal/thermal_core.c49
-rw-r--r--drivers/thermal/thermal_mmio.c129
-rw-r--r--include/dt-bindings/thermal/tegra124-soctherm.h8
-rw-r--r--include/linux/thermal.h13
42 files changed, 2339 insertions, 605 deletions
diff --git a/Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt b/Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt
new file mode 100644
index 000000000000..703979dbd577
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt
@@ -0,0 +1,33 @@
1Amazon's Annapurna Labs Thermal Sensor
2
3Simple thermal device that allows temperature reading by a single MMIO
4transaction.
5
6Required properties:
7- compatible: "amazon,al-thermal".
8- reg: The physical base address and length of the sensor's registers.
9- #thermal-sensor-cells: Must be 1. See ./thermal.txt for a description.
10
11Example:
12 thermal: thermal {
13 compatible = "amazon,al-thermal";
14 reg = <0x0 0x05002860 0x0 0x1>;
15 #thermal-sensor-cells = <0x1>;
16 };
17
18 thermal-zones {
19 thermal-z0 {
20 polling-delay-passive = <250>;
21 polling-delay = <1000>;
22 thermal-sensors = <&thermal 0>;
23 trips {
24 critical {
25 temperature = <105000>;
26 hysteresis = <2000>;
27 type = "critical";
28 };
29 };
30
31 };
32 };
33
diff --git a/Documentation/devicetree/bindings/thermal/nvidia,tegra124-soctherm.txt b/Documentation/devicetree/bindings/thermal/nvidia,tegra124-soctherm.txt
index b6c0ae53d4dc..f02f38527a6b 100644
--- a/Documentation/devicetree/bindings/thermal/nvidia,tegra124-soctherm.txt
+++ b/Documentation/devicetree/bindings/thermal/nvidia,tegra124-soctherm.txt
@@ -52,13 +52,47 @@ Required properties :
52 Must set as following values: 52 Must set as following values:
53 TEGRA_SOCTHERM_THROT_LEVEL_LOW, TEGRA_SOCTHERM_THROT_LEVEL_MED 53 TEGRA_SOCTHERM_THROT_LEVEL_LOW, TEGRA_SOCTHERM_THROT_LEVEL_MED
54 TEGRA_SOCTHERM_THROT_LEVEL_HIGH, TEGRA_SOCTHERM_THROT_LEVEL_NONE 54 TEGRA_SOCTHERM_THROT_LEVEL_HIGH, TEGRA_SOCTHERM_THROT_LEVEL_NONE
55 - nvidia,gpu-throt-level: This property is for Tegra124 and Tegra210.
56 It is the level of pulse skippers, which used to throttle clock
57 frequencies. It indicates gpu clock throttling depth and can be
58 programmed to any of the following values which represent a throttling
59 percentage:
60 TEGRA_SOCTHERM_THROT_LEVEL_NONE (0%)
61 TEGRA_SOCTHERM_THROT_LEVEL_LOW (50%),
62 TEGRA_SOCTHERM_THROT_LEVEL_MED (75%),
63 TEGRA_SOCTHERM_THROT_LEVEL_HIGH (85%).
55 - #cooling-cells: Should be 1. This cooling device only support on/off state. 64 - #cooling-cells: Should be 1. This cooling device only support on/off state.
56 See ./thermal.txt for a description of this property. 65 See ./thermal.txt for a description of this property.
57 66
67 Optional properties: The following properties are T210 specific and
68 valid only for OCx throttle events.
69 - nvidia,count-threshold: Specifies the number of OC events that are
70 required for triggering an interrupt. Interrupts are not triggered if
71 the property is missing. A value of 0 will interrupt on every OC alarm.
72 - nvidia,polarity-active-low: Configures the polarity of the OC alaram
73 signal. If present, this means assert low, otherwise assert high.
74 - nvidia,alarm-filter: Number of clocks to filter event. When the filter
75 expires (which means the OC event has not occurred for a long time),
76 the counter is cleared and filter is rearmed. Default value is 0.
77 - nvidia,throttle-period-us: Specifies the number of uSec for which
78 throttling is engaged after the OC event is deasserted. Default value
79 is 0.
80
81Optional properties:
82- nvidia,thermtrips : When present, this property specifies the temperature at
83 which the soctherm hardware will assert the thermal trigger signal to the
84 Power Management IC, which can be configured to reset or shutdown the device.
85 It is an array of pairs where each pair represents a tsensor id followed by a
86 temperature in milli Celcius. In the absence of this property the critical
87 trip point will be used for thermtrip temperature.
88
58Note: 89Note:
59- the "critical" type trip points will be set to SOC_THERM hardware as the 90- the "critical" type trip points will be used to set the temperature at which
60shut down temperature. Once the temperature of this thermal zone is higher 91the SOC_THERM hardware will assert a thermal trigger if the "nvidia,thermtrips"
61than it, the system will be shutdown or reset by hardware. 92property is missing. When the thermtrips property is present, the breach of a
93critical trip point is reported back to the thermal framework to implement
94software shutdown.
95
62- the "hot" type trip points will be set to SOC_THERM hardware as the throttle 96- the "hot" type trip points will be set to SOC_THERM hardware as the throttle
63temperature. Once the the temperature of this thermal zone is higher 97temperature. Once the the temperature of this thermal zone is higher
64than it, it will trigger the HW throttle event. 98than it, it will trigger the HW throttle event.
@@ -79,25 +113,32 @@ Example :
79 113
80 #thermal-sensor-cells = <1>; 114 #thermal-sensor-cells = <1>;
81 115
116 nvidia,thermtrips = <TEGRA124_SOCTHERM_SENSOR_CPU 102500
117 TEGRA124_SOCTHERM_SENSOR_GPU 103000>;
118
82 throttle-cfgs { 119 throttle-cfgs {
83 /* 120 /*
84 * When the "heavy" cooling device triggered, 121 * When the "heavy" cooling device triggered,
85 * the HW will skip cpu clock's pulse in 85% depth 122 * the HW will skip cpu clock's pulse in 85% depth,
123 * skip gpu clock's pulse in 85% level
86 */ 124 */
87 throttle_heavy: heavy { 125 throttle_heavy: heavy {
88 nvidia,priority = <100>; 126 nvidia,priority = <100>;
89 nvidia,cpu-throt-percent = <85>; 127 nvidia,cpu-throt-percent = <85>;
128 nvidia,gpu-throt-level = <TEGRA_SOCTHERM_THROT_LEVEL_HIGH>;
90 129
91 #cooling-cells = <1>; 130 #cooling-cells = <1>;
92 }; 131 };
93 132
94 /* 133 /*
95 * When the "light" cooling device triggered, 134 * When the "light" cooling device triggered,
96 * the HW will skip cpu clock's pulse in 50% depth 135 * the HW will skip cpu clock's pulse in 50% depth,
136 * skip gpu clock's pulse in 50% level
97 */ 137 */
98 throttle_light: light { 138 throttle_light: light {
99 nvidia,priority = <80>; 139 nvidia,priority = <80>;
100 nvidia,cpu-throt-percent = <50>; 140 nvidia,cpu-throt-percent = <50>;
141 nvidia,gpu-throt-level = <TEGRA_SOCTHERM_THROT_LEVEL_LOW>;
101 142
102 #cooling-cells = <1>; 143 #cooling-cells = <1>;
103 }; 144 };
@@ -107,6 +148,17 @@ Example :
107 * arbiter will select the highest priority as the final throttle 148 * arbiter will select the highest priority as the final throttle
108 * settings to skip cpu pulse. 149 * settings to skip cpu pulse.
109 */ 150 */
151
152 throttle_oc1: oc1 {
153 nvidia,priority = <50>;
154 nvidia,polarity-active-low;
155 nvidia,count-threshold = <100>;
156 nvidia,alarm-filter = <5100000>;
157 nvidia,throttle-period-us = <0>;
158 nvidia,cpu-throt-percent = <75>;
159 nvidia,gpu-throt-level =
160 <TEGRA_SOCTHERM_THROT_LEVEL_MED>;
161 };
110 }; 162 };
111 }; 163 };
112 164
diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
index 1d9e8cf61018..673cc1831ee9 100644
--- a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
@@ -6,11 +6,14 @@ Required properties:
6 - "qcom,msm8916-tsens" (MSM8916) 6 - "qcom,msm8916-tsens" (MSM8916)
7 - "qcom,msm8974-tsens" (MSM8974) 7 - "qcom,msm8974-tsens" (MSM8974)
8 - "qcom,msm8996-tsens" (MSM8996) 8 - "qcom,msm8996-tsens" (MSM8996)
9 - "qcom,qcs404-tsens", "qcom,tsens-v1" (QCS404)
9 - "qcom,msm8998-tsens", "qcom,tsens-v2" (MSM8998) 10 - "qcom,msm8998-tsens", "qcom,tsens-v2" (MSM8998)
10 - "qcom,sdm845-tsens", "qcom,tsens-v2" (SDM845) 11 - "qcom,sdm845-tsens", "qcom,tsens-v2" (SDM845)
11 The generic "qcom,tsens-v2" property must be used as a fallback for any SoC 12 The generic "qcom,tsens-v2" property must be used as a fallback for any SoC
12 with version 2 of the TSENS IP. MSM8996 is the only exception because the 13 with version 2 of the TSENS IP. MSM8996 is the only exception because the
13 generic property did not exist when support was added. 14 generic property did not exist when support was added.
15 Similarly, the generic "qcom,tsens-v1" property must be used as a fallback for
16 any SoC with version 1 of the TSENS IP.
14 17
15- reg: Address range of the thermal registers. 18- reg: Address range of the thermal registers.
16 New platforms containing v2.x.y of the TSENS IP must specify the SROT and TM 19 New platforms containing v2.x.y of the TSENS IP must specify the SROT and TM
@@ -39,3 +42,14 @@ tsens0: thermal-sensor@c263000 {
39 #qcom,sensors = <13>; 42 #qcom,sensors = <13>;
40 #thermal-sensor-cells = <1>; 43 #thermal-sensor-cells = <1>;
41 }; 44 };
45
46Example 3 (for any platform containing v1 of the TSENS IP):
47tsens: thermal-sensor@4a9000 {
48 compatible = "qcom,qcs404-tsens", "qcom,tsens-v1";
49 reg = <0x004a9000 0x1000>, /* TM */
50 <0x004a8000 0x1000>; /* SROT */
51 nvmem-cells = <&tsens_caldata>;
52 nvmem-cell-names = "calib";
53 #qcom,sensors = <10>;
54 #thermal-sensor-cells = <1>;
55 };
diff --git a/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt b/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
index 43d744e5305e..c6aac9bcacf1 100644
--- a/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
@@ -2,6 +2,7 @@
2 2
3Required properties: 3Required properties:
4- compatible : should be "rockchip,<name>-tsadc" 4- compatible : should be "rockchip,<name>-tsadc"
5 "rockchip,px30-tsadc": found on PX30 SoCs
5 "rockchip,rv1108-tsadc": found on RV1108 SoCs 6 "rockchip,rv1108-tsadc": found on RV1108 SoCs
6 "rockchip,rk3228-tsadc": found on RK3228 SoCs 7 "rockchip,rk3228-tsadc": found on RK3228 SoCs
7 "rockchip,rk3288-tsadc": found on RK3288 SoCs 8 "rockchip,rk3288-tsadc": found on RK3288 SoCs
diff --git a/Documentation/devicetree/bindings/thermal/thermal-generic-adc.txt b/Documentation/devicetree/bindings/thermal/thermal-generic-adc.txt
index d72355502b78..691a09db2fef 100644
--- a/Documentation/devicetree/bindings/thermal/thermal-generic-adc.txt
+++ b/Documentation/devicetree/bindings/thermal/thermal-generic-adc.txt
@@ -8,16 +8,22 @@ temperature using voltage-temperature lookup table.
8Required properties: 8Required properties:
9=================== 9===================
10- compatible: Must be "generic-adc-thermal". 10- compatible: Must be "generic-adc-thermal".
11- #thermal-sensor-cells: Should be 1. See ./thermal.txt for a description
12 of this property.
13Optional properties:
14===================
11- temperature-lookup-table: Two dimensional array of Integer; lookup table 15- temperature-lookup-table: Two dimensional array of Integer; lookup table
12 to map the relation between ADC value and 16 to map the relation between ADC value and
13 temperature. When ADC is read, the value is 17 temperature. When ADC is read, the value is
14 looked up on the table to get the equivalent 18 looked up on the table to get the equivalent
15 temperature. 19 temperature.
20
16 The first value of the each row of array is the 21 The first value of the each row of array is the
17 temperature in milliCelsius and second value of 22 temperature in milliCelsius and second value of
18 the each row of array is the ADC read value. 23 the each row of array is the ADC read value.
19- #thermal-sensor-cells: Should be 1. See ./thermal.txt for a description 24
20 of this property. 25 If not specified, driver assumes the ADC channel
26 gives milliCelsius directly.
21 27
22Example : 28Example :
23#include <dt-bindings/thermal/thermal.h> 29#include <dt-bindings/thermal/thermal.h>
diff --git a/MAINTAINERS b/MAINTAINERS
index ee6cf4d1010c..59efb8bd33e0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -742,6 +742,12 @@ F: drivers/tty/serial/altera_jtaguart.c
742F: include/linux/altera_uart.h 742F: include/linux/altera_uart.h
743F: include/linux/altera_jtaguart.h 743F: include/linux/altera_jtaguart.h
744 744
745AMAZON ANNAPURNA LABS THERMAL MMIO DRIVER
746M: Talel Shenhar <talel@amazon.com>
747S: Maintained
748F: Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt
749F: drivers/thermal/thermal_mmio.c
750
745AMAZON ETHERNET DRIVERS 751AMAZON ETHERNET DRIVERS
746M: Netanel Belgazal <netanel@amazon.com> 752M: Netanel Belgazal <netanel@amazon.com>
747R: Saeed Bishara <saeedb@amazon.com> 753R: Saeed Bishara <saeedb@amazon.com>
diff --git a/drivers/hwmon/aspeed-pwm-tacho.c b/drivers/hwmon/aspeed-pwm-tacho.c
index c4dd6301e7c8..0daf0b32aa4a 100644
--- a/drivers/hwmon/aspeed-pwm-tacho.c
+++ b/drivers/hwmon/aspeed-pwm-tacho.c
@@ -830,10 +830,8 @@ static int aspeed_create_pwm_cooling(struct device *dev,
830 } 830 }
831 snprintf(cdev->name, MAX_CDEV_NAME_LEN, "%pOFn%d", child, pwm_port); 831 snprintf(cdev->name, MAX_CDEV_NAME_LEN, "%pOFn%d", child, pwm_port);
832 832
833 cdev->tcdev = thermal_of_cooling_device_register(child, 833 cdev->tcdev = devm_thermal_of_cooling_device_register(dev, child,
834 cdev->name, 834 cdev->name, cdev, &aspeed_pwm_cool_ops);
835 cdev,
836 &aspeed_pwm_cool_ops);
837 if (IS_ERR(cdev->tcdev)) 835 if (IS_ERR(cdev->tcdev))
838 return PTR_ERR(cdev->tcdev); 836 return PTR_ERR(cdev->tcdev);
839 837
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index f1bf67aca9e8..3f6e5b4e3997 100644
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -498,6 +498,11 @@ static const struct of_device_id of_gpio_fan_match[] = {
498}; 498};
499MODULE_DEVICE_TABLE(of, of_gpio_fan_match); 499MODULE_DEVICE_TABLE(of, of_gpio_fan_match);
500 500
501static void gpio_fan_stop(void *data)
502{
503 set_fan_speed(data, 0);
504}
505
501static int gpio_fan_probe(struct platform_device *pdev) 506static int gpio_fan_probe(struct platform_device *pdev)
502{ 507{
503 int err; 508 int err;
@@ -532,6 +537,7 @@ static int gpio_fan_probe(struct platform_device *pdev)
532 err = fan_ctrl_init(fan_data); 537 err = fan_ctrl_init(fan_data);
533 if (err) 538 if (err)
534 return err; 539 return err;
540 devm_add_action_or_reset(dev, gpio_fan_stop, fan_data);
535 } 541 }
536 542
537 /* Make this driver part of hwmon class. */ 543 /* Make this driver part of hwmon class. */
@@ -543,32 +549,20 @@ static int gpio_fan_probe(struct platform_device *pdev)
543 return PTR_ERR(fan_data->hwmon_dev); 549 return PTR_ERR(fan_data->hwmon_dev);
544 550
545 /* Optional cooling device register for Device tree platforms */ 551 /* Optional cooling device register for Device tree platforms */
546 fan_data->cdev = thermal_of_cooling_device_register(np, 552 fan_data->cdev = devm_thermal_of_cooling_device_register(dev, np,
547 "gpio-fan", 553 "gpio-fan", fan_data, &gpio_fan_cool_ops);
548 fan_data,
549 &gpio_fan_cool_ops);
550 554
551 dev_info(dev, "GPIO fan initialized\n"); 555 dev_info(dev, "GPIO fan initialized\n");
552 556
553 return 0; 557 return 0;
554} 558}
555 559
556static int gpio_fan_remove(struct platform_device *pdev) 560static void gpio_fan_shutdown(struct platform_device *pdev)
557{ 561{
558 struct gpio_fan_data *fan_data = platform_get_drvdata(pdev); 562 struct gpio_fan_data *fan_data = platform_get_drvdata(pdev);
559 563
560 if (!IS_ERR(fan_data->cdev))
561 thermal_cooling_device_unregister(fan_data->cdev);
562
563 if (fan_data->gpios) 564 if (fan_data->gpios)
564 set_fan_speed(fan_data, 0); 565 set_fan_speed(fan_data, 0);
565
566 return 0;
567}
568
569static void gpio_fan_shutdown(struct platform_device *pdev)
570{
571 gpio_fan_remove(pdev);
572} 566}
573 567
574#ifdef CONFIG_PM_SLEEP 568#ifdef CONFIG_PM_SLEEP
@@ -602,7 +596,6 @@ static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume);
602 596
603static struct platform_driver gpio_fan_driver = { 597static struct platform_driver gpio_fan_driver = {
604 .probe = gpio_fan_probe, 598 .probe = gpio_fan_probe,
605 .remove = gpio_fan_remove,
606 .shutdown = gpio_fan_shutdown, 599 .shutdown = gpio_fan_shutdown,
607 .driver = { 600 .driver = {
608 .name = "gpio-fan", 601 .name = "gpio-fan",
diff --git a/drivers/hwmon/mlxreg-fan.c b/drivers/hwmon/mlxreg-fan.c
index f816d2ae1e58..ed8d59d4eecb 100644
--- a/drivers/hwmon/mlxreg-fan.c
+++ b/drivers/hwmon/mlxreg-fan.c
@@ -465,42 +465,42 @@ static int mlxreg_fan_config(struct mlxreg_fan *fan,
465static int mlxreg_fan_probe(struct platform_device *pdev) 465static int mlxreg_fan_probe(struct platform_device *pdev)
466{ 466{
467 struct mlxreg_core_platform_data *pdata; 467 struct mlxreg_core_platform_data *pdata;
468 struct device *dev = &pdev->dev;
468 struct mlxreg_fan *fan; 469 struct mlxreg_fan *fan;
469 struct device *hwm; 470 struct device *hwm;
470 int err; 471 int err;
471 472
472 pdata = dev_get_platdata(&pdev->dev); 473 pdata = dev_get_platdata(dev);
473 if (!pdata) { 474 if (!pdata) {
474 dev_err(&pdev->dev, "Failed to get platform data.\n"); 475 dev_err(dev, "Failed to get platform data.\n");
475 return -EINVAL; 476 return -EINVAL;
476 } 477 }
477 478
478 fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL); 479 fan = devm_kzalloc(dev, sizeof(*fan), GFP_KERNEL);
479 if (!fan) 480 if (!fan)
480 return -ENOMEM; 481 return -ENOMEM;
481 482
482 fan->dev = &pdev->dev; 483 fan->dev = dev;
483 fan->regmap = pdata->regmap; 484 fan->regmap = pdata->regmap;
484 platform_set_drvdata(pdev, fan);
485 485
486 err = mlxreg_fan_config(fan, pdata); 486 err = mlxreg_fan_config(fan, pdata);
487 if (err) 487 if (err)
488 return err; 488 return err;
489 489
490 hwm = devm_hwmon_device_register_with_info(&pdev->dev, "mlxreg_fan", 490 hwm = devm_hwmon_device_register_with_info(dev, "mlxreg_fan",
491 fan, 491 fan,
492 &mlxreg_fan_hwmon_chip_info, 492 &mlxreg_fan_hwmon_chip_info,
493 NULL); 493 NULL);
494 if (IS_ERR(hwm)) { 494 if (IS_ERR(hwm)) {
495 dev_err(&pdev->dev, "Failed to register hwmon device\n"); 495 dev_err(dev, "Failed to register hwmon device\n");
496 return PTR_ERR(hwm); 496 return PTR_ERR(hwm);
497 } 497 }
498 498
499 if (IS_REACHABLE(CONFIG_THERMAL)) { 499 if (IS_REACHABLE(CONFIG_THERMAL)) {
500 fan->cdev = thermal_cooling_device_register("mlxreg_fan", fan, 500 fan->cdev = devm_thermal_of_cooling_device_register(dev,
501 &mlxreg_fan_cooling_ops); 501 NULL, "mlxreg_fan", fan, &mlxreg_fan_cooling_ops);
502 if (IS_ERR(fan->cdev)) { 502 if (IS_ERR(fan->cdev)) {
503 dev_err(&pdev->dev, "Failed to register cooling device\n"); 503 dev_err(dev, "Failed to register cooling device\n");
504 return PTR_ERR(fan->cdev); 504 return PTR_ERR(fan->cdev);
505 } 505 }
506 } 506 }
@@ -508,22 +508,11 @@ static int mlxreg_fan_probe(struct platform_device *pdev)
508 return 0; 508 return 0;
509} 509}
510 510
511static int mlxreg_fan_remove(struct platform_device *pdev)
512{
513 struct mlxreg_fan *fan = platform_get_drvdata(pdev);
514
515 if (IS_REACHABLE(CONFIG_THERMAL))
516 thermal_cooling_device_unregister(fan->cdev);
517
518 return 0;
519}
520
521static struct platform_driver mlxreg_fan_driver = { 511static struct platform_driver mlxreg_fan_driver = {
522 .driver = { 512 .driver = {
523 .name = "mlxreg-fan", 513 .name = "mlxreg-fan",
524 }, 514 },
525 .probe = mlxreg_fan_probe, 515 .probe = mlxreg_fan_probe,
526 .remove = mlxreg_fan_remove,
527}; 516};
528 517
529module_platform_driver(mlxreg_fan_driver); 518module_platform_driver(mlxreg_fan_driver);
diff --git a/drivers/hwmon/npcm750-pwm-fan.c b/drivers/hwmon/npcm750-pwm-fan.c
index 1dc0cd452498..09aaefa6fdb8 100644
--- a/drivers/hwmon/npcm750-pwm-fan.c
+++ b/drivers/hwmon/npcm750-pwm-fan.c
@@ -846,10 +846,8 @@ static int npcm7xx_create_pwm_cooling(struct device *dev,
846 snprintf(cdev->name, THERMAL_NAME_LENGTH, "%pOFn%d", child, 846 snprintf(cdev->name, THERMAL_NAME_LENGTH, "%pOFn%d", child,
847 pwm_port); 847 pwm_port);
848 848
849 cdev->tcdev = thermal_of_cooling_device_register(child, 849 cdev->tcdev = devm_thermal_of_cooling_device_register(dev, child,
850 cdev->name, 850 cdev->name, cdev, &npcm7xx_pwm_cool_ops);
851 cdev,
852 &npcm7xx_pwm_cool_ops);
853 if (IS_ERR(cdev->tcdev)) 851 if (IS_ERR(cdev->tcdev))
854 return PTR_ERR(cdev->tcdev); 852 return PTR_ERR(cdev->tcdev);
855 853
diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
index eead8afe6447..5fb2745f0226 100644
--- a/drivers/hwmon/pwm-fan.c
+++ b/drivers/hwmon/pwm-fan.c
@@ -273,27 +273,40 @@ static int pwm_fan_of_get_cooling_data(struct device *dev,
273 return 0; 273 return 0;
274} 274}
275 275
276static void pwm_fan_regulator_disable(void *data)
277{
278 regulator_disable(data);
279}
280
281static void pwm_fan_pwm_disable(void *__ctx)
282{
283 struct pwm_fan_ctx *ctx = __ctx;
284 pwm_disable(ctx->pwm);
285 del_timer_sync(&ctx->rpm_timer);
286}
287
276static int pwm_fan_probe(struct platform_device *pdev) 288static int pwm_fan_probe(struct platform_device *pdev)
277{ 289{
278 struct thermal_cooling_device *cdev; 290 struct thermal_cooling_device *cdev;
291 struct device *dev = &pdev->dev;
279 struct pwm_fan_ctx *ctx; 292 struct pwm_fan_ctx *ctx;
280 struct device *hwmon; 293 struct device *hwmon;
281 int ret; 294 int ret;
282 struct pwm_state state = { }; 295 struct pwm_state state = { };
283 u32 ppr = 2; 296 u32 ppr = 2;
284 297
285 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 298 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
286 if (!ctx) 299 if (!ctx)
287 return -ENOMEM; 300 return -ENOMEM;
288 301
289 mutex_init(&ctx->lock); 302 mutex_init(&ctx->lock);
290 303
291 ctx->pwm = devm_of_pwm_get(&pdev->dev, pdev->dev.of_node, NULL); 304 ctx->pwm = devm_of_pwm_get(dev, dev->of_node, NULL);
292 if (IS_ERR(ctx->pwm)) { 305 if (IS_ERR(ctx->pwm)) {
293 ret = PTR_ERR(ctx->pwm); 306 ret = PTR_ERR(ctx->pwm);
294 307
295 if (ret != -EPROBE_DEFER) 308 if (ret != -EPROBE_DEFER)
296 dev_err(&pdev->dev, "Could not get PWM: %d\n", ret); 309 dev_err(dev, "Could not get PWM: %d\n", ret);
297 310
298 return ret; 311 return ret;
299 } 312 }
@@ -304,7 +317,7 @@ static int pwm_fan_probe(struct platform_device *pdev)
304 if (ctx->irq == -EPROBE_DEFER) 317 if (ctx->irq == -EPROBE_DEFER)
305 return ctx->irq; 318 return ctx->irq;
306 319
307 ctx->reg_en = devm_regulator_get_optional(&pdev->dev, "fan"); 320 ctx->reg_en = devm_regulator_get_optional(dev, "fan");
308 if (IS_ERR(ctx->reg_en)) { 321 if (IS_ERR(ctx->reg_en)) {
309 if (PTR_ERR(ctx->reg_en) != -ENODEV) 322 if (PTR_ERR(ctx->reg_en) != -ENODEV)
310 return PTR_ERR(ctx->reg_en); 323 return PTR_ERR(ctx->reg_en);
@@ -313,10 +326,11 @@ static int pwm_fan_probe(struct platform_device *pdev)
313 } else { 326 } else {
314 ret = regulator_enable(ctx->reg_en); 327 ret = regulator_enable(ctx->reg_en);
315 if (ret) { 328 if (ret) {
316 dev_err(&pdev->dev, 329 dev_err(dev, "Failed to enable fan supply: %d\n", ret);
317 "Failed to enable fan supply: %d\n", ret);
318 return ret; 330 return ret;
319 } 331 }
332 devm_add_action_or_reset(dev, pwm_fan_regulator_disable,
333 ctx->reg_en);
320 } 334 }
321 335
322 ctx->pwm_value = MAX_PWM; 336 ctx->pwm_value = MAX_PWM;
@@ -328,91 +342,57 @@ static int pwm_fan_probe(struct platform_device *pdev)
328 342
329 ret = pwm_apply_state(ctx->pwm, &state); 343 ret = pwm_apply_state(ctx->pwm, &state);
330 if (ret) { 344 if (ret) {
331 dev_err(&pdev->dev, "Failed to configure PWM: %d\n", ret); 345 dev_err(dev, "Failed to configure PWM: %d\n", ret);
332 goto err_reg_disable; 346 return ret;
333 } 347 }
334
335 timer_setup(&ctx->rpm_timer, sample_timer, 0); 348 timer_setup(&ctx->rpm_timer, sample_timer, 0);
349 devm_add_action_or_reset(dev, pwm_fan_pwm_disable, ctx);
336 350
337 of_property_read_u32(pdev->dev.of_node, "pulses-per-revolution", &ppr); 351 of_property_read_u32(dev->of_node, "pulses-per-revolution", &ppr);
338 ctx->pulses_per_revolution = ppr; 352 ctx->pulses_per_revolution = ppr;
339 if (!ctx->pulses_per_revolution) { 353 if (!ctx->pulses_per_revolution) {
340 dev_err(&pdev->dev, "pulses-per-revolution can't be zero.\n"); 354 dev_err(dev, "pulses-per-revolution can't be zero.\n");
341 ret = -EINVAL; 355 return -EINVAL;
342 goto err_pwm_disable;
343 } 356 }
344 357
345 if (ctx->irq > 0) { 358 if (ctx->irq > 0) {
346 ret = devm_request_irq(&pdev->dev, ctx->irq, pulse_handler, 0, 359 ret = devm_request_irq(dev, ctx->irq, pulse_handler, 0,
347 pdev->name, ctx); 360 pdev->name, ctx);
348 if (ret) { 361 if (ret) {
349 dev_err(&pdev->dev, 362 dev_err(dev, "Failed to request interrupt: %d\n", ret);
350 "Failed to request interrupt: %d\n", ret); 363 return ret;
351 goto err_pwm_disable;
352 } 364 }
353 ctx->sample_start = ktime_get(); 365 ctx->sample_start = ktime_get();
354 mod_timer(&ctx->rpm_timer, jiffies + HZ); 366 mod_timer(&ctx->rpm_timer, jiffies + HZ);
355 } 367 }
356 368
357 hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, "pwmfan", 369 hwmon = devm_hwmon_device_register_with_groups(dev, "pwmfan",
358 ctx, pwm_fan_groups); 370 ctx, pwm_fan_groups);
359 if (IS_ERR(hwmon)) { 371 if (IS_ERR(hwmon)) {
360 ret = PTR_ERR(hwmon); 372 dev_err(dev, "Failed to register hwmon device\n");
361 dev_err(&pdev->dev, 373 return PTR_ERR(hwmon);
362 "Failed to register hwmon device: %d\n", ret);
363 goto err_del_timer;
364 } 374 }
365 375
366 ret = pwm_fan_of_get_cooling_data(&pdev->dev, ctx); 376 ret = pwm_fan_of_get_cooling_data(dev, ctx);
367 if (ret) 377 if (ret)
368 goto err_del_timer; 378 return ret;
369 379
370 ctx->pwm_fan_state = ctx->pwm_fan_max_state; 380 ctx->pwm_fan_state = ctx->pwm_fan_max_state;
371 if (IS_ENABLED(CONFIG_THERMAL)) { 381 if (IS_ENABLED(CONFIG_THERMAL)) {
372 cdev = thermal_of_cooling_device_register(pdev->dev.of_node, 382 cdev = devm_thermal_of_cooling_device_register(dev,
373 "pwm-fan", ctx, 383 dev->of_node, "pwm-fan", ctx, &pwm_fan_cooling_ops);
374 &pwm_fan_cooling_ops);
375 if (IS_ERR(cdev)) { 384 if (IS_ERR(cdev)) {
376 ret = PTR_ERR(cdev); 385 ret = PTR_ERR(cdev);
377 dev_err(&pdev->dev, 386 dev_err(dev,
378 "Failed to register pwm-fan as cooling device: %d\n", 387 "Failed to register pwm-fan as cooling device: %d\n",
379 ret); 388 ret);
380 goto err_del_timer; 389 return ret;
381 } 390 }
382 ctx->cdev = cdev; 391 ctx->cdev = cdev;
383 thermal_cdev_update(cdev); 392 thermal_cdev_update(cdev);
384 } 393 }
385 394
386 return 0; 395 return 0;
387
388err_del_timer:
389 del_timer_sync(&ctx->rpm_timer);
390
391err_pwm_disable:
392 state.enabled = false;
393 pwm_apply_state(ctx->pwm, &state);
394
395err_reg_disable:
396 if (ctx->reg_en)
397 regulator_disable(ctx->reg_en);
398
399 return ret;
400}
401
402static int pwm_fan_remove(struct platform_device *pdev)
403{
404 struct pwm_fan_ctx *ctx = platform_get_drvdata(pdev);
405
406 thermal_cooling_device_unregister(ctx->cdev);
407 del_timer_sync(&ctx->rpm_timer);
408
409 if (ctx->pwm_value)
410 pwm_disable(ctx->pwm);
411
412 if (ctx->reg_en)
413 regulator_disable(ctx->reg_en);
414
415 return 0;
416} 396}
417 397
418#ifdef CONFIG_PM_SLEEP 398#ifdef CONFIG_PM_SLEEP
@@ -480,7 +460,6 @@ MODULE_DEVICE_TABLE(of, of_pwm_fan_match);
480 460
481static struct platform_driver pwm_fan_driver = { 461static struct platform_driver pwm_fan_driver = {
482 .probe = pwm_fan_probe, 462 .probe = pwm_fan_probe,
483 .remove = pwm_fan_remove,
484 .driver = { 463 .driver = {
485 .name = "pwm-fan", 464 .name = "pwm-fan",
486 .pm = &pwm_fan_pm, 465 .pm = &pwm_fan_pm,
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 653aa27a25a4..66a709d5d6b9 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -200,6 +200,17 @@ config THERMAL_EMULATION
200 because userland can easily disable the thermal policy by simply 200 because userland can easily disable the thermal policy by simply
201 flooding this sysfs node with low temperature values. 201 flooding this sysfs node with low temperature values.
202 202
203config THERMAL_MMIO
204 tristate "Generic Thermal MMIO driver"
205 depends on OF || COMPILE_TEST
206 depends on HAS_IOMEM
207 help
208 This option enables the generic thermal MMIO driver that will use
209 memory-mapped reads to get the temperature. Any HW/System that
210 allows temperature reading by a single memory-mapped reading, be it
211 register or shared memory, is a potential candidate to work with this
212 driver.
213
203config HISI_THERMAL 214config HISI_THERMAL
204 tristate "Hisilicon thermal driver" 215 tristate "Hisilicon thermal driver"
205 depends on ARCH_HISI || COMPILE_TEST 216 depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 486d682be047..74a37c7f847a 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -29,6 +29,7 @@ thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
29 29
30# platform thermal drivers 30# platform thermal drivers
31obj-y += broadcom/ 31obj-y += broadcom/
32obj-$(CONFIG_THERMAL_MMIO) += thermal_mmio.o
32obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o 33obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o
33obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o 34obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o
34obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o 35obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o
diff --git a/drivers/thermal/broadcom/sr-thermal.c b/drivers/thermal/broadcom/sr-thermal.c
index 2284cbecedf3..475ce2900771 100644
--- a/drivers/thermal/broadcom/sr-thermal.c
+++ b/drivers/thermal/broadcom/sr-thermal.c
@@ -3,7 +3,6 @@
3 * Copyright (C) 2018 Broadcom 3 * Copyright (C) 2018 Broadcom
4 */ 4 */
5 5
6#include <linux/acpi.h>
7#include <linux/module.h> 6#include <linux/module.h>
8#include <linux/of_address.h> 7#include <linux/of_address.h>
9#include <linux/platform_device.h> 8#include <linux/platform_device.h>
@@ -100,18 +99,11 @@ static const struct of_device_id sr_thermal_of_match[] = {
100}; 99};
101MODULE_DEVICE_TABLE(of, sr_thermal_of_match); 100MODULE_DEVICE_TABLE(of, sr_thermal_of_match);
102 101
103static const struct acpi_device_id sr_thermal_acpi_ids[] = {
104 { .id = "BRCM0500" },
105 { /* sentinel */ }
106};
107MODULE_DEVICE_TABLE(acpi, sr_thermal_acpi_ids);
108
109static struct platform_driver sr_thermal_driver = { 102static struct platform_driver sr_thermal_driver = {
110 .probe = sr_thermal_probe, 103 .probe = sr_thermal_probe,
111 .driver = { 104 .driver = {
112 .name = "sr-thermal", 105 .name = "sr-thermal",
113 .of_match_table = sr_thermal_of_match, 106 .of_match_table = sr_thermal_of_match,
114 .acpi_match_table = ACPI_PTR(sr_thermal_acpi_ids),
115 }, 107 },
116}; 108};
117module_platform_driver(sr_thermal_driver); 109module_platform_driver(sr_thermal_driver);
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index f7c1f49ec87f..4c5db59a619b 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -1,26 +1,14 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * linux/drivers/thermal/cpu_cooling.c 3 * linux/drivers/thermal/cpu_cooling.c
3 * 4 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) 5 * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
5 * Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
6 * 6 *
7 * Copyright (C) 2014 Viresh Kumar <viresh.kumar@linaro.org> 7 * Copyright (C) 2012-2018 Linaro Limited.
8 * 8 *
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 * Authors: Amit Daniel <amit.kachhap@linaro.org>
10 * This program is free software; you can redistribute it and/or modify 10 * Viresh Kumar <viresh.kumar@linaro.org>
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 * 11 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */ 12 */
25#include <linux/module.h> 13#include <linux/module.h>
26#include <linux/thermal.h> 14#include <linux/thermal.h>
@@ -99,7 +87,6 @@ struct cpufreq_cooling_device {
99 unsigned int clipped_freq; 87 unsigned int clipped_freq;
100 unsigned int max_level; 88 unsigned int max_level;
101 struct freq_table *freq_table; /* In descending order */ 89 struct freq_table *freq_table; /* In descending order */
102 struct thermal_cooling_device *cdev;
103 struct cpufreq_policy *policy; 90 struct cpufreq_policy *policy;
104 struct list_head node; 91 struct list_head node;
105 struct time_in_idle *idle_time; 92 struct time_in_idle *idle_time;
@@ -207,8 +194,7 @@ static int update_freq_table(struct cpufreq_cooling_device *cpufreq_cdev,
207 194
208 dev = get_cpu_device(cpu); 195 dev = get_cpu_device(cpu);
209 if (unlikely(!dev)) { 196 if (unlikely(!dev)) {
210 dev_warn(&cpufreq_cdev->cdev->device, 197 pr_warn("No cpu device for cpu %d\n", cpu);
211 "No cpu device for cpu %d\n", cpu);
212 return -ENODEV; 198 return -ENODEV;
213 } 199 }
214 200
@@ -458,7 +444,7 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
458 load = 0; 444 load = 0;
459 445
460 total_load += load; 446 total_load += load;
461 if (trace_thermal_power_cpu_limit_enabled() && load_cpu) 447 if (load_cpu)
462 load_cpu[i] = load; 448 load_cpu[i] = load;
463 449
464 i++; 450 i++;
@@ -541,7 +527,6 @@ static int cpufreq_power2state(struct thermal_cooling_device *cdev,
541 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; 527 struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
542 struct cpufreq_policy *policy = cpufreq_cdev->policy; 528 struct cpufreq_policy *policy = cpufreq_cdev->policy;
543 529
544 power = power > 0 ? power : 0;
545 last_load = cpufreq_cdev->last_load ?: 1; 530 last_load = cpufreq_cdev->last_load ?: 1;
546 normalised_power = (power * 100) / last_load; 531 normalised_power = (power * 100) / last_load;
547 target_freq = cpu_power_to_freq(cpufreq_cdev, normalised_power); 532 target_freq = cpu_power_to_freq(cpufreq_cdev, normalised_power);
@@ -692,7 +677,6 @@ __cpufreq_cooling_register(struct device_node *np,
692 goto remove_ida; 677 goto remove_ida;
693 678
694 cpufreq_cdev->clipped_freq = cpufreq_cdev->freq_table[0].frequency; 679 cpufreq_cdev->clipped_freq = cpufreq_cdev->freq_table[0].frequency;
695 cpufreq_cdev->cdev = cdev;
696 680
697 mutex_lock(&cooling_list_lock); 681 mutex_lock(&cooling_list_lock);
698 /* Register the notifier for first cpufreq cooling device */ 682 /* Register the notifier for first cpufreq cooling device */
@@ -810,7 +794,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
810 cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, 794 cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
811 CPUFREQ_POLICY_NOTIFIER); 795 CPUFREQ_POLICY_NOTIFIER);
812 796
813 thermal_cooling_device_unregister(cpufreq_cdev->cdev); 797 thermal_cooling_device_unregister(cdev);
814 ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id); 798 ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
815 kfree(cpufreq_cdev->idle_time); 799 kfree(cpufreq_cdev->idle_time);
816 kfree(cpufreq_cdev->freq_table); 800 kfree(cpufreq_cdev->freq_table);
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index 2df059cc07e2..dc5093be553e 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -5,6 +5,9 @@
5 * Copyright (C) 2013 Texas Instruments 5 * Copyright (C) 2013 Texas Instruments
6 * Copyright (C) 2013 Eduardo Valentin <eduardo.valentin@ti.com> 6 * Copyright (C) 2013 Eduardo Valentin <eduardo.valentin@ti.com>
7 */ 7 */
8
9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
8#include <linux/thermal.h> 11#include <linux/thermal.h>
9#include <linux/slab.h> 12#include <linux/slab.h>
10#include <linux/types.h> 13#include <linux/types.h>
diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
index 717a08600bb5..fc6fe50cdde4 100644
--- a/drivers/thermal/qcom/Makefile
+++ b/drivers/thermal/qcom/Makefile
@@ -1,3 +1,5 @@
1obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o 1obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o
2qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o tsens-v2.o 2
3qcom_tsens-y += tsens.o tsens-common.o tsens-v0_1.o \
4 tsens-8960.o tsens-v2.o tsens-v1.o
3obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o 5obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
diff --git a/drivers/thermal/qcom/tsens-8916.c b/drivers/thermal/qcom/tsens-8916.c
deleted file mode 100644
index c6dd620ac029..000000000000
--- a/drivers/thermal/qcom/tsens-8916.c
+++ /dev/null
@@ -1,105 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4 */
5
6#include <linux/platform_device.h>
7#include "tsens.h"
8
9/* eeprom layout data for 8916 */
10#define BASE0_MASK 0x0000007f
11#define BASE1_MASK 0xfe000000
12#define BASE0_SHIFT 0
13#define BASE1_SHIFT 25
14
15#define S0_P1_MASK 0x00000f80
16#define S1_P1_MASK 0x003e0000
17#define S2_P1_MASK 0xf8000000
18#define S3_P1_MASK 0x000003e0
19#define S4_P1_MASK 0x000f8000
20
21#define S0_P2_MASK 0x0001f000
22#define S1_P2_MASK 0x07c00000
23#define S2_P2_MASK 0x0000001f
24#define S3_P2_MASK 0x00007c00
25#define S4_P2_MASK 0x01f00000
26
27#define S0_P1_SHIFT 7
28#define S1_P1_SHIFT 17
29#define S2_P1_SHIFT 27
30#define S3_P1_SHIFT 5
31#define S4_P1_SHIFT 15
32
33#define S0_P2_SHIFT 12
34#define S1_P2_SHIFT 22
35#define S2_P2_SHIFT 0
36#define S3_P2_SHIFT 10
37#define S4_P2_SHIFT 20
38
39#define CAL_SEL_MASK 0xe0000000
40#define CAL_SEL_SHIFT 29
41
42static int calibrate_8916(struct tsens_device *tmdev)
43{
44 int base0 = 0, base1 = 0, i;
45 u32 p1[5], p2[5];
46 int mode = 0;
47 u32 *qfprom_cdata, *qfprom_csel;
48
49 qfprom_cdata = (u32 *)qfprom_read(tmdev->dev, "calib");
50 if (IS_ERR(qfprom_cdata))
51 return PTR_ERR(qfprom_cdata);
52
53 qfprom_csel = (u32 *)qfprom_read(tmdev->dev, "calib_sel");
54 if (IS_ERR(qfprom_csel))
55 return PTR_ERR(qfprom_csel);
56
57 mode = (qfprom_csel[0] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
58 dev_dbg(tmdev->dev, "calibration mode is %d\n", mode);
59
60 switch (mode) {
61 case TWO_PT_CALIB:
62 base1 = (qfprom_cdata[1] & BASE1_MASK) >> BASE1_SHIFT;
63 p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT;
64 p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT;
65 p2[2] = (qfprom_cdata[1] & S2_P2_MASK) >> S2_P2_SHIFT;
66 p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
67 p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
68 for (i = 0; i < tmdev->num_sensors; i++)
69 p2[i] = ((base1 + p2[i]) << 3);
70 /* Fall through */
71 case ONE_PT_CALIB2:
72 base0 = (qfprom_cdata[0] & BASE0_MASK);
73 p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT;
74 p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT;
75 p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
76 p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
77 p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
78 for (i = 0; i < tmdev->num_sensors; i++)
79 p1[i] = (((base0) + p1[i]) << 3);
80 break;
81 default:
82 for (i = 0; i < tmdev->num_sensors; i++) {
83 p1[i] = 500;
84 p2[i] = 780;
85 }
86 break;
87 }
88
89 compute_intercept_slope(tmdev, p1, p2, mode);
90
91 return 0;
92}
93
94static const struct tsens_ops ops_8916 = {
95 .init = init_common,
96 .calibrate = calibrate_8916,
97 .get_temp = get_temp_common,
98};
99
100const struct tsens_data data_8916 = {
101 .num_sensors = 5,
102 .ops = &ops_8916,
103 .reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 },
104 .hw_ids = (unsigned int []){0, 1, 2, 4, 5 },
105};
diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
index 0f0adb302a7b..8d9b721dadb6 100644
--- a/drivers/thermal/qcom/tsens-8960.c
+++ b/drivers/thermal/qcom/tsens-8960.c
@@ -56,21 +56,21 @@
56#define TRDY_MASK BIT(7) 56#define TRDY_MASK BIT(7)
57#define TIMEOUT_US 100 57#define TIMEOUT_US 100
58 58
59static int suspend_8960(struct tsens_device *tmdev) 59static int suspend_8960(struct tsens_priv *priv)
60{ 60{
61 int ret; 61 int ret;
62 unsigned int mask; 62 unsigned int mask;
63 struct regmap *map = tmdev->tm_map; 63 struct regmap *map = priv->tm_map;
64 64
65 ret = regmap_read(map, THRESHOLD_ADDR, &tmdev->ctx.threshold); 65 ret = regmap_read(map, THRESHOLD_ADDR, &priv->ctx.threshold);
66 if (ret) 66 if (ret)
67 return ret; 67 return ret;
68 68
69 ret = regmap_read(map, CNTL_ADDR, &tmdev->ctx.control); 69 ret = regmap_read(map, CNTL_ADDR, &priv->ctx.control);
70 if (ret) 70 if (ret)
71 return ret; 71 return ret;
72 72
73 if (tmdev->num_sensors > 1) 73 if (priv->num_sensors > 1)
74 mask = SLP_CLK_ENA | EN; 74 mask = SLP_CLK_ENA | EN;
75 else 75 else
76 mask = SLP_CLK_ENA_8660 | EN; 76 mask = SLP_CLK_ENA_8660 | EN;
@@ -82,10 +82,10 @@ static int suspend_8960(struct tsens_device *tmdev)
82 return 0; 82 return 0;
83} 83}
84 84
85static int resume_8960(struct tsens_device *tmdev) 85static int resume_8960(struct tsens_priv *priv)
86{ 86{
87 int ret; 87 int ret;
88 struct regmap *map = tmdev->tm_map; 88 struct regmap *map = priv->tm_map;
89 89
90 ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST); 90 ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
91 if (ret) 91 if (ret)
@@ -95,80 +95,80 @@ static int resume_8960(struct tsens_device *tmdev)
95 * Separate CONFIG restore is not needed only for 8660 as 95 * Separate CONFIG restore is not needed only for 8660 as
96 * config is part of CTRL Addr and its restored as such 96 * config is part of CTRL Addr and its restored as such
97 */ 97 */
98 if (tmdev->num_sensors > 1) { 98 if (priv->num_sensors > 1) {
99 ret = regmap_update_bits(map, CONFIG_ADDR, CONFIG_MASK, CONFIG); 99 ret = regmap_update_bits(map, CONFIG_ADDR, CONFIG_MASK, CONFIG);
100 if (ret) 100 if (ret)
101 return ret; 101 return ret;
102 } 102 }
103 103
104 ret = regmap_write(map, THRESHOLD_ADDR, tmdev->ctx.threshold); 104 ret = regmap_write(map, THRESHOLD_ADDR, priv->ctx.threshold);
105 if (ret) 105 if (ret)
106 return ret; 106 return ret;
107 107
108 ret = regmap_write(map, CNTL_ADDR, tmdev->ctx.control); 108 ret = regmap_write(map, CNTL_ADDR, priv->ctx.control);
109 if (ret) 109 if (ret)
110 return ret; 110 return ret;
111 111
112 return 0; 112 return 0;
113} 113}
114 114
115static int enable_8960(struct tsens_device *tmdev, int id) 115static int enable_8960(struct tsens_priv *priv, int id)
116{ 116{
117 int ret; 117 int ret;
118 u32 reg, mask; 118 u32 reg, mask;
119 119
120 ret = regmap_read(tmdev->tm_map, CNTL_ADDR, &reg); 120 ret = regmap_read(priv->tm_map, CNTL_ADDR, &reg);
121 if (ret) 121 if (ret)
122 return ret; 122 return ret;
123 123
124 mask = BIT(id + SENSOR0_SHIFT); 124 mask = BIT(id + SENSOR0_SHIFT);
125 ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg | SW_RST); 125 ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST);
126 if (ret) 126 if (ret)
127 return ret; 127 return ret;
128 128
129 if (tmdev->num_sensors > 1) 129 if (priv->num_sensors > 1)
130 reg |= mask | SLP_CLK_ENA | EN; 130 reg |= mask | SLP_CLK_ENA | EN;
131 else 131 else
132 reg |= mask | SLP_CLK_ENA_8660 | EN; 132 reg |= mask | SLP_CLK_ENA_8660 | EN;
133 133
134 ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg); 134 ret = regmap_write(priv->tm_map, CNTL_ADDR, reg);
135 if (ret) 135 if (ret)
136 return ret; 136 return ret;
137 137
138 return 0; 138 return 0;
139} 139}
140 140
141static void disable_8960(struct tsens_device *tmdev) 141static void disable_8960(struct tsens_priv *priv)
142{ 142{
143 int ret; 143 int ret;
144 u32 reg_cntl; 144 u32 reg_cntl;
145 u32 mask; 145 u32 mask;
146 146
147 mask = GENMASK(tmdev->num_sensors - 1, 0); 147 mask = GENMASK(priv->num_sensors - 1, 0);
148 mask <<= SENSOR0_SHIFT; 148 mask <<= SENSOR0_SHIFT;
149 mask |= EN; 149 mask |= EN;
150 150
151 ret = regmap_read(tmdev->tm_map, CNTL_ADDR, &reg_cntl); 151 ret = regmap_read(priv->tm_map, CNTL_ADDR, &reg_cntl);
152 if (ret) 152 if (ret)
153 return; 153 return;
154 154
155 reg_cntl &= ~mask; 155 reg_cntl &= ~mask;
156 156
157 if (tmdev->num_sensors > 1) 157 if (priv->num_sensors > 1)
158 reg_cntl &= ~SLP_CLK_ENA; 158 reg_cntl &= ~SLP_CLK_ENA;
159 else 159 else
160 reg_cntl &= ~SLP_CLK_ENA_8660; 160 reg_cntl &= ~SLP_CLK_ENA_8660;
161 161
162 regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl); 162 regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
163} 163}
164 164
165static int init_8960(struct tsens_device *tmdev) 165static int init_8960(struct tsens_priv *priv)
166{ 166{
167 int ret, i; 167 int ret, i;
168 u32 reg_cntl; 168 u32 reg_cntl;
169 169
170 tmdev->tm_map = dev_get_regmap(tmdev->dev, NULL); 170 priv->tm_map = dev_get_regmap(priv->dev, NULL);
171 if (!tmdev->tm_map) 171 if (!priv->tm_map)
172 return -ENODEV; 172 return -ENODEV;
173 173
174 /* 174 /*
@@ -177,21 +177,21 @@ static int init_8960(struct tsens_device *tmdev)
177 * but the control registers stay in the same place, i.e 177 * but the control registers stay in the same place, i.e
178 * directly after the first 5 status registers. 178 * directly after the first 5 status registers.
179 */ 179 */
180 for (i = 0; i < tmdev->num_sensors; i++) { 180 for (i = 0; i < priv->num_sensors; i++) {
181 if (i >= 5) 181 if (i >= 5)
182 tmdev->sensor[i].status = S0_STATUS_ADDR + 40; 182 priv->sensor[i].status = S0_STATUS_ADDR + 40;
183 tmdev->sensor[i].status += i * 4; 183 priv->sensor[i].status += i * 4;
184 } 184 }
185 185
186 reg_cntl = SW_RST; 186 reg_cntl = SW_RST;
187 ret = regmap_update_bits(tmdev->tm_map, CNTL_ADDR, SW_RST, reg_cntl); 187 ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl);
188 if (ret) 188 if (ret)
189 return ret; 189 return ret;
190 190
191 if (tmdev->num_sensors > 1) { 191 if (priv->num_sensors > 1) {
192 reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18); 192 reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
193 reg_cntl &= ~SW_RST; 193 reg_cntl &= ~SW_RST;
194 ret = regmap_update_bits(tmdev->tm_map, CONFIG_ADDR, 194 ret = regmap_update_bits(priv->tm_map, CONFIG_ADDR,
195 CONFIG_MASK, CONFIG); 195 CONFIG_MASK, CONFIG);
196 } else { 196 } else {
197 reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16); 197 reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16);
@@ -199,30 +199,30 @@ static int init_8960(struct tsens_device *tmdev)
199 reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660; 199 reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660;
200 } 200 }
201 201
202 reg_cntl |= GENMASK(tmdev->num_sensors - 1, 0) << SENSOR0_SHIFT; 202 reg_cntl |= GENMASK(priv->num_sensors - 1, 0) << SENSOR0_SHIFT;
203 ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl); 203 ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
204 if (ret) 204 if (ret)
205 return ret; 205 return ret;
206 206
207 reg_cntl |= EN; 207 reg_cntl |= EN;
208 ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl); 208 ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
209 if (ret) 209 if (ret)
210 return ret; 210 return ret;
211 211
212 return 0; 212 return 0;
213} 213}
214 214
215static int calibrate_8960(struct tsens_device *tmdev) 215static int calibrate_8960(struct tsens_priv *priv)
216{ 216{
217 int i; 217 int i;
218 char *data; 218 char *data;
219 219
220 ssize_t num_read = tmdev->num_sensors; 220 ssize_t num_read = priv->num_sensors;
221 struct tsens_sensor *s = tmdev->sensor; 221 struct tsens_sensor *s = priv->sensor;
222 222
223 data = qfprom_read(tmdev->dev, "calib"); 223 data = qfprom_read(priv->dev, "calib");
224 if (IS_ERR(data)) 224 if (IS_ERR(data))
225 data = qfprom_read(tmdev->dev, "calib_backup"); 225 data = qfprom_read(priv->dev, "calib_backup");
226 if (IS_ERR(data)) 226 if (IS_ERR(data))
227 return PTR_ERR(data); 227 return PTR_ERR(data);
228 228
@@ -243,21 +243,21 @@ static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)
243 return adc_code * slope + offset; 243 return adc_code * slope + offset;
244} 244}
245 245
246static int get_temp_8960(struct tsens_device *tmdev, int id, int *temp) 246static int get_temp_8960(struct tsens_priv *priv, int id, int *temp)
247{ 247{
248 int ret; 248 int ret;
249 u32 code, trdy; 249 u32 code, trdy;
250 const struct tsens_sensor *s = &tmdev->sensor[id]; 250 const struct tsens_sensor *s = &priv->sensor[id];
251 unsigned long timeout; 251 unsigned long timeout;
252 252
253 timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); 253 timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
254 do { 254 do {
255 ret = regmap_read(tmdev->tm_map, INT_STATUS_ADDR, &trdy); 255 ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy);
256 if (ret) 256 if (ret)
257 return ret; 257 return ret;
258 if (!(trdy & TRDY_MASK)) 258 if (!(trdy & TRDY_MASK))
259 continue; 259 continue;
260 ret = regmap_read(tmdev->tm_map, s->status, &code); 260 ret = regmap_read(priv->tm_map, s->status, &code);
261 if (ret) 261 if (ret)
262 return ret; 262 return ret;
263 *temp = code_to_mdegC(code, s); 263 *temp = code_to_mdegC(code, s);
@@ -277,7 +277,7 @@ static const struct tsens_ops ops_8960 = {
277 .resume = resume_8960, 277 .resume = resume_8960,
278}; 278};
279 279
280const struct tsens_data data_8960 = { 280const struct tsens_plat_data data_8960 = {
281 .num_sensors = 11, 281 .num_sensors = 11,
282 .ops = &ops_8960, 282 .ops = &ops_8960,
283}; 283};
diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index f80c73f11740..928e8e81ba69 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -12,18 +12,6 @@
12#include <linux/regmap.h> 12#include <linux/regmap.h>
13#include "tsens.h" 13#include "tsens.h"
14 14
15/* SROT */
16#define TSENS_EN BIT(0)
17
18/* TM */
19#define STATUS_OFFSET 0x30
20#define SN_ADDR_OFFSET 0x4
21#define SN_ST_TEMP_MASK 0x3ff
22#define CAL_DEGC_PT1 30
23#define CAL_DEGC_PT2 120
24#define SLOPE_FACTOR 1000
25#define SLOPE_DEFAULT 3200
26
27char *qfprom_read(struct device *dev, const char *cname) 15char *qfprom_read(struct device *dev, const char *cname)
28{ 16{
29 struct nvmem_cell *cell; 17 struct nvmem_cell *cell;
@@ -46,18 +34,18 @@ char *qfprom_read(struct device *dev, const char *cname)
46 * and offset values are derived from tz->tzp->slope and tz->tzp->offset 34 * and offset values are derived from tz->tzp->slope and tz->tzp->offset
47 * resp. 35 * resp.
48 */ 36 */
49void compute_intercept_slope(struct tsens_device *tmdev, u32 *p1, 37void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
50 u32 *p2, u32 mode) 38 u32 *p2, u32 mode)
51{ 39{
52 int i; 40 int i;
53 int num, den; 41 int num, den;
54 42
55 for (i = 0; i < tmdev->num_sensors; i++) { 43 for (i = 0; i < priv->num_sensors; i++) {
56 dev_dbg(tmdev->dev, 44 dev_dbg(priv->dev,
57 "sensor%d - data_point1:%#x data_point2:%#x\n", 45 "sensor%d - data_point1:%#x data_point2:%#x\n",
58 i, p1[i], p2[i]); 46 i, p1[i], p2[i]);
59 47
60 tmdev->sensor[i].slope = SLOPE_DEFAULT; 48 priv->sensor[i].slope = SLOPE_DEFAULT;
61 if (mode == TWO_PT_CALIB) { 49 if (mode == TWO_PT_CALIB) {
62 /* 50 /*
63 * slope (m) = adc_code2 - adc_code1 (y2 - y1)/ 51 * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
@@ -66,16 +54,30 @@ void compute_intercept_slope(struct tsens_device *tmdev, u32 *p1,
66 num = p2[i] - p1[i]; 54 num = p2[i] - p1[i];
67 num *= SLOPE_FACTOR; 55 num *= SLOPE_FACTOR;
68 den = CAL_DEGC_PT2 - CAL_DEGC_PT1; 56 den = CAL_DEGC_PT2 - CAL_DEGC_PT1;
69 tmdev->sensor[i].slope = num / den; 57 priv->sensor[i].slope = num / den;
70 } 58 }
71 59
72 tmdev->sensor[i].offset = (p1[i] * SLOPE_FACTOR) - 60 priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
73 (CAL_DEGC_PT1 * 61 (CAL_DEGC_PT1 *
74 tmdev->sensor[i].slope); 62 priv->sensor[i].slope);
75 dev_dbg(tmdev->dev, "offset:%d\n", tmdev->sensor[i].offset); 63 dev_dbg(priv->dev, "offset:%d\n", priv->sensor[i].offset);
76 } 64 }
77} 65}
78 66
67bool is_sensor_enabled(struct tsens_priv *priv, u32 hw_id)
68{
69 u32 val;
70 int ret;
71
72 if ((hw_id > (priv->num_sensors - 1)) || (hw_id < 0))
73 return -EINVAL;
74 ret = regmap_field_read(priv->rf[SENSOR_EN], &val);
75 if (ret)
76 return ret;
77
78 return val & (1 << hw_id);
79}
80
79static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s) 81static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
80{ 82{
81 int degc, num, den; 83 int degc, num, den;
@@ -95,18 +97,54 @@ static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
95 return degc; 97 return degc;
96} 98}
97 99
98int get_temp_common(struct tsens_device *tmdev, int id, int *temp) 100int get_temp_tsens_valid(struct tsens_priv *priv, int i, int *temp)
99{ 101{
100 struct tsens_sensor *s = &tmdev->sensor[id]; 102 struct tsens_sensor *s = &priv->sensor[i];
101 u32 code; 103 u32 temp_idx = LAST_TEMP_0 + s->hw_id;
102 unsigned int status_reg; 104 u32 valid_idx = VALID_0 + s->hw_id;
105 u32 last_temp = 0, valid, mask;
106 int ret;
107
108 ret = regmap_field_read(priv->rf[valid_idx], &valid);
109 if (ret)
110 return ret;
111 while (!valid) {
112 /* Valid bit is 0 for 6 AHB clock cycles.
113 * At 19.2MHz, 1 AHB clock is ~60ns.
114 * We should enter this loop very, very rarely.
115 */
116 ndelay(400);
117 ret = regmap_field_read(priv->rf[valid_idx], &valid);
118 if (ret)
119 return ret;
120 }
121
122 /* Valid bit is set, OK to read the temperature */
123 ret = regmap_field_read(priv->rf[temp_idx], &last_temp);
124 if (ret)
125 return ret;
126
127 if (priv->feat->adc) {
128 /* Convert temperature from ADC code to milliCelsius */
129 *temp = code_to_degc(last_temp, s) * 1000;
130 } else {
131 mask = GENMASK(priv->fields[LAST_TEMP_0].msb,
132 priv->fields[LAST_TEMP_0].lsb);
133 /* Convert temperature from deciCelsius to milliCelsius */
134 *temp = sign_extend32(last_temp, fls(mask) - 1) * 100;
135 }
136
137 return 0;
138}
139
140int get_temp_common(struct tsens_priv *priv, int i, int *temp)
141{
142 struct tsens_sensor *s = &priv->sensor[i];
103 int last_temp = 0, ret; 143 int last_temp = 0, ret;
104 144
105 status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * SN_ADDR_OFFSET; 145 ret = regmap_field_read(priv->rf[LAST_TEMP_0 + s->hw_id], &last_temp);
106 ret = regmap_read(tmdev->tm_map, status_reg, &code);
107 if (ret) 146 if (ret)
108 return ret; 147 return ret;
109 last_temp = code & SN_ST_TEMP_MASK;
110 148
111 *temp = code_to_degc(last_temp, s) * 1000; 149 *temp = code_to_degc(last_temp, s) * 1000;
112 150
@@ -127,21 +165,21 @@ static const struct regmap_config tsens_srot_config = {
127 .reg_stride = 4, 165 .reg_stride = 4,
128}; 166};
129 167
130int __init init_common(struct tsens_device *tmdev) 168int __init init_common(struct tsens_priv *priv)
131{ 169{
132 void __iomem *tm_base, *srot_base; 170 void __iomem *tm_base, *srot_base;
171 struct device *dev = priv->dev;
133 struct resource *res; 172 struct resource *res;
134 u32 code; 173 u32 enabled;
135 int ret; 174 int ret, i, j;
136 struct platform_device *op = of_find_device_by_node(tmdev->dev->of_node); 175 struct platform_device *op = of_find_device_by_node(priv->dev->of_node);
137 u16 ctrl_offset = tmdev->reg_offsets[SROT_CTRL_OFFSET];
138 176
139 if (!op) 177 if (!op)
140 return -EINVAL; 178 return -EINVAL;
141 179
142 if (op->num_resources > 1) { 180 if (op->num_resources > 1) {
143 /* DT with separate SROT and TM address space */ 181 /* DT with separate SROT and TM address space */
144 tmdev->tm_offset = 0; 182 priv->tm_offset = 0;
145 res = platform_get_resource(op, IORESOURCE_MEM, 1); 183 res = platform_get_resource(op, IORESOURCE_MEM, 1);
146 srot_base = devm_ioremap_resource(&op->dev, res); 184 srot_base = devm_ioremap_resource(&op->dev, res);
147 if (IS_ERR(srot_base)) { 185 if (IS_ERR(srot_base)) {
@@ -149,16 +187,15 @@ int __init init_common(struct tsens_device *tmdev)
149 goto err_put_device; 187 goto err_put_device;
150 } 188 }
151 189
152 tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, srot_base, 190 priv->srot_map = devm_regmap_init_mmio(dev, srot_base,
153 &tsens_srot_config); 191 &tsens_srot_config);
154 if (IS_ERR(tmdev->srot_map)) { 192 if (IS_ERR(priv->srot_map)) {
155 ret = PTR_ERR(tmdev->srot_map); 193 ret = PTR_ERR(priv->srot_map);
156 goto err_put_device; 194 goto err_put_device;
157 } 195 }
158
159 } else { 196 } else {
160 /* old DTs where SROT and TM were in a contiguous 2K block */ 197 /* old DTs where SROT and TM were in a contiguous 2K block */
161 tmdev->tm_offset = 0x1000; 198 priv->tm_offset = 0x1000;
162 } 199 }
163 200
164 res = platform_get_resource(op, IORESOURCE_MEM, 0); 201 res = platform_get_resource(op, IORESOURCE_MEM, 0);
@@ -168,19 +205,47 @@ int __init init_common(struct tsens_device *tmdev)
168 goto err_put_device; 205 goto err_put_device;
169 } 206 }
170 207
171 tmdev->tm_map = devm_regmap_init_mmio(tmdev->dev, tm_base, &tsens_config); 208 priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);
172 if (IS_ERR(tmdev->tm_map)) { 209 if (IS_ERR(priv->tm_map)) {
173 ret = PTR_ERR(tmdev->tm_map); 210 ret = PTR_ERR(priv->tm_map);
174 goto err_put_device; 211 goto err_put_device;
175 } 212 }
176 213
177 if (tmdev->srot_map) { 214 priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
178 ret = regmap_read(tmdev->srot_map, ctrl_offset, &code); 215 priv->fields[TSENS_EN]);
179 if (ret) 216 if (IS_ERR(priv->rf[TSENS_EN])) {
217 ret = PTR_ERR(priv->rf[TSENS_EN]);
218 goto err_put_device;
219 }
220 ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
221 if (ret)
222 goto err_put_device;
223 if (!enabled) {
224 dev_err(dev, "tsens device is not enabled\n");
225 ret = -ENODEV;
226 goto err_put_device;
227 }
228
229 priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
230 priv->fields[SENSOR_EN]);
231 if (IS_ERR(priv->rf[SENSOR_EN])) {
232 ret = PTR_ERR(priv->rf[SENSOR_EN]);
233 goto err_put_device;
234 }
235 /* now alloc regmap_fields in tm_map */
236 for (i = 0, j = LAST_TEMP_0; i < priv->feat->max_sensors; i++, j++) {
237 priv->rf[j] = devm_regmap_field_alloc(dev, priv->tm_map,
238 priv->fields[j]);
239 if (IS_ERR(priv->rf[j])) {
240 ret = PTR_ERR(priv->rf[j]);
180 goto err_put_device; 241 goto err_put_device;
181 if (!(code & TSENS_EN)) { 242 }
182 dev_err(tmdev->dev, "tsens device is not enabled\n"); 243 }
183 ret = -ENODEV; 244 for (i = 0, j = VALID_0; i < priv->feat->max_sensors; i++, j++) {
245 priv->rf[j] = devm_regmap_field_alloc(dev, priv->tm_map,
246 priv->fields[j]);
247 if (IS_ERR(priv->rf[j])) {
248 ret = PTR_ERR(priv->rf[j]);
184 goto err_put_device; 249 goto err_put_device;
185 } 250 }
186 } 251 }
diff --git a/drivers/thermal/qcom/tsens-8974.c b/drivers/thermal/qcom/tsens-v0_1.c
index 3d3fda3d731b..a319283c223f 100644
--- a/drivers/thermal/qcom/tsens-8974.c
+++ b/drivers/thermal/qcom/tsens-v0_1.c
@@ -6,6 +6,48 @@
6#include <linux/platform_device.h> 6#include <linux/platform_device.h>
7#include "tsens.h" 7#include "tsens.h"
8 8
9/* ----- SROT ------ */
10#define SROT_CTRL_OFF 0x0000
11
12/* ----- TM ------ */
13#define TM_INT_EN_OFF 0x0000
14#define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF 0x0004
15#define TM_Sn_STATUS_OFF 0x0030
16#define TM_TRDY_OFF 0x005c
17
18/* eeprom layout data for 8916 */
19#define MSM8916_BASE0_MASK 0x0000007f
20#define MSM8916_BASE1_MASK 0xfe000000
21#define MSM8916_BASE0_SHIFT 0
22#define MSM8916_BASE1_SHIFT 25
23
24#define MSM8916_S0_P1_MASK 0x00000f80
25#define MSM8916_S1_P1_MASK 0x003e0000
26#define MSM8916_S2_P1_MASK 0xf8000000
27#define MSM8916_S3_P1_MASK 0x000003e0
28#define MSM8916_S4_P1_MASK 0x000f8000
29
30#define MSM8916_S0_P2_MASK 0x0001f000
31#define MSM8916_S1_P2_MASK 0x07c00000
32#define MSM8916_S2_P2_MASK 0x0000001f
33#define MSM8916_S3_P2_MASK 0x00007c00
34#define MSM8916_S4_P2_MASK 0x01f00000
35
36#define MSM8916_S0_P1_SHIFT 7
37#define MSM8916_S1_P1_SHIFT 17
38#define MSM8916_S2_P1_SHIFT 27
39#define MSM8916_S3_P1_SHIFT 5
40#define MSM8916_S4_P1_SHIFT 15
41
42#define MSM8916_S0_P2_SHIFT 12
43#define MSM8916_S1_P2_SHIFT 22
44#define MSM8916_S2_P2_SHIFT 0
45#define MSM8916_S3_P2_SHIFT 10
46#define MSM8916_S4_P2_SHIFT 20
47
48#define MSM8916_CAL_SEL_MASK 0xe0000000
49#define MSM8916_CAL_SEL_SHIFT 29
50
9/* eeprom layout data for 8974 */ 51/* eeprom layout data for 8974 */
10#define BASE1_MASK 0xff 52#define BASE1_MASK 0xff
11#define S0_P1_MASK 0x3f00 53#define S0_P1_MASK 0x3f00
@@ -91,7 +133,59 @@
91 133
92#define BIT_APPEND 0x3 134#define BIT_APPEND 0x3
93 135
94static int calibrate_8974(struct tsens_device *tmdev) 136static int calibrate_8916(struct tsens_priv *priv)
137{
138 int base0 = 0, base1 = 0, i;
139 u32 p1[5], p2[5];
140 int mode = 0;
141 u32 *qfprom_cdata, *qfprom_csel;
142
143 qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
144 if (IS_ERR(qfprom_cdata))
145 return PTR_ERR(qfprom_cdata);
146
147 qfprom_csel = (u32 *)qfprom_read(priv->dev, "calib_sel");
148 if (IS_ERR(qfprom_csel))
149 return PTR_ERR(qfprom_csel);
150
151 mode = (qfprom_csel[0] & MSM8916_CAL_SEL_MASK) >> MSM8916_CAL_SEL_SHIFT;
152 dev_dbg(priv->dev, "calibration mode is %d\n", mode);
153
154 switch (mode) {
155 case TWO_PT_CALIB:
156 base1 = (qfprom_cdata[1] & MSM8916_BASE1_MASK) >> MSM8916_BASE1_SHIFT;
157 p2[0] = (qfprom_cdata[0] & MSM8916_S0_P2_MASK) >> MSM8916_S0_P2_SHIFT;
158 p2[1] = (qfprom_cdata[0] & MSM8916_S1_P2_MASK) >> MSM8916_S1_P2_SHIFT;
159 p2[2] = (qfprom_cdata[1] & MSM8916_S2_P2_MASK) >> MSM8916_S2_P2_SHIFT;
160 p2[3] = (qfprom_cdata[1] & MSM8916_S3_P2_MASK) >> MSM8916_S3_P2_SHIFT;
161 p2[4] = (qfprom_cdata[1] & MSM8916_S4_P2_MASK) >> MSM8916_S4_P2_SHIFT;
162 for (i = 0; i < priv->num_sensors; i++)
163 p2[i] = ((base1 + p2[i]) << 3);
164 /* Fall through */
165 case ONE_PT_CALIB2:
166 base0 = (qfprom_cdata[0] & MSM8916_BASE0_MASK);
167 p1[0] = (qfprom_cdata[0] & MSM8916_S0_P1_MASK) >> MSM8916_S0_P1_SHIFT;
168 p1[1] = (qfprom_cdata[0] & MSM8916_S1_P1_MASK) >> MSM8916_S1_P1_SHIFT;
169 p1[2] = (qfprom_cdata[0] & MSM8916_S2_P1_MASK) >> MSM8916_S2_P1_SHIFT;
170 p1[3] = (qfprom_cdata[1] & MSM8916_S3_P1_MASK) >> MSM8916_S3_P1_SHIFT;
171 p1[4] = (qfprom_cdata[1] & MSM8916_S4_P1_MASK) >> MSM8916_S4_P1_SHIFT;
172 for (i = 0; i < priv->num_sensors; i++)
173 p1[i] = (((base0) + p1[i]) << 3);
174 break;
175 default:
176 for (i = 0; i < priv->num_sensors; i++) {
177 p1[i] = 500;
178 p2[i] = 780;
179 }
180 break;
181 }
182
183 compute_intercept_slope(priv, p1, p2, mode);
184
185 return 0;
186}
187
188static int calibrate_8974(struct tsens_priv *priv)
95{ 189{
96 int base1 = 0, base2 = 0, i; 190 int base1 = 0, base2 = 0, i;
97 u32 p1[11], p2[11]; 191 u32 p1[11], p2[11];
@@ -99,11 +193,11 @@ static int calibrate_8974(struct tsens_device *tmdev)
99 u32 *calib, *bkp; 193 u32 *calib, *bkp;
100 u32 calib_redun_sel; 194 u32 calib_redun_sel;
101 195
102 calib = (u32 *)qfprom_read(tmdev->dev, "calib"); 196 calib = (u32 *)qfprom_read(priv->dev, "calib");
103 if (IS_ERR(calib)) 197 if (IS_ERR(calib))
104 return PTR_ERR(calib); 198 return PTR_ERR(calib);
105 199
106 bkp = (u32 *)qfprom_read(tmdev->dev, "calib_backup"); 200 bkp = (u32 *)qfprom_read(priv->dev, "calib_backup");
107 if (IS_ERR(bkp)) 201 if (IS_ERR(bkp))
108 return PTR_ERR(bkp); 202 return PTR_ERR(bkp);
109 203
@@ -184,25 +278,25 @@ static int calibrate_8974(struct tsens_device *tmdev)
184 278
185 switch (mode) { 279 switch (mode) {
186 case ONE_PT_CALIB: 280 case ONE_PT_CALIB:
187 for (i = 0; i < tmdev->num_sensors; i++) 281 for (i = 0; i < priv->num_sensors; i++)
188 p1[i] += (base1 << 2) | BIT_APPEND; 282 p1[i] += (base1 << 2) | BIT_APPEND;
189 break; 283 break;
190 case TWO_PT_CALIB: 284 case TWO_PT_CALIB:
191 for (i = 0; i < tmdev->num_sensors; i++) { 285 for (i = 0; i < priv->num_sensors; i++) {
192 p2[i] += base2; 286 p2[i] += base2;
193 p2[i] <<= 2; 287 p2[i] <<= 2;
194 p2[i] |= BIT_APPEND; 288 p2[i] |= BIT_APPEND;
195 } 289 }
196 /* Fall through */ 290 /* Fall through */
197 case ONE_PT_CALIB2: 291 case ONE_PT_CALIB2:
198 for (i = 0; i < tmdev->num_sensors; i++) { 292 for (i = 0; i < priv->num_sensors; i++) {
199 p1[i] += base1; 293 p1[i] += base1;
200 p1[i] <<= 2; 294 p1[i] <<= 2;
201 p1[i] |= BIT_APPEND; 295 p1[i] |= BIT_APPEND;
202 } 296 }
203 break; 297 break;
204 default: 298 default:
205 for (i = 0; i < tmdev->num_sensors; i++) 299 for (i = 0; i < priv->num_sensors; i++)
206 p2[i] = 780; 300 p2[i] = 780;
207 p1[0] = 502; 301 p1[0] = 502;
208 p1[1] = 509; 302 p1[1] = 509;
@@ -218,19 +312,71 @@ static int calibrate_8974(struct tsens_device *tmdev)
218 break; 312 break;
219 } 313 }
220 314
221 compute_intercept_slope(tmdev, p1, p2, mode); 315 compute_intercept_slope(priv, p1, p2, mode);
222 316
223 return 0; 317 return 0;
224} 318}
225 319
320/* v0.1: 8916, 8974 */
321
322static const struct tsens_features tsens_v0_1_feat = {
323 .ver_major = VER_0_1,
324 .crit_int = 0,
325 .adc = 1,
326 .srot_split = 1,
327 .max_sensors = 11,
328};
329
330static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = {
331 /* ----- SROT ------ */
332 /* No VERSION information */
333
334 /* CTRL_OFFSET */
335 [TSENS_EN] = REG_FIELD(SROT_CTRL_OFF, 0, 0),
336 [TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1, 1),
337 [SENSOR_EN] = REG_FIELD(SROT_CTRL_OFF, 3, 13),
338
339 /* ----- TM ------ */
340 /* INTERRUPT ENABLE */
341 [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0),
342
343 /* Sn_STATUS */
344 REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 9),
345 /* No VALID field on v0.1 */
346 REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS, TM_Sn_STATUS_OFF, 10, 10),
347 REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),
348 REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),
349 /* No CRITICAL field on v0.1 */
350 REG_FIELD_FOR_EACH_SENSOR11(MAX_STATUS, TM_Sn_STATUS_OFF, 13, 13),
351
352 /* TRDY: 1=ready, 0=in progress */
353 [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
354};
355
356static const struct tsens_ops ops_8916 = {
357 .init = init_common,
358 .calibrate = calibrate_8916,
359 .get_temp = get_temp_common,
360};
361
362const struct tsens_plat_data data_8916 = {
363 .num_sensors = 5,
364 .ops = &ops_8916,
365 .hw_ids = (unsigned int []){0, 1, 2, 4, 5 },
366
367 .feat = &tsens_v0_1_feat,
368 .fields = tsens_v0_1_regfields,
369};
370
226static const struct tsens_ops ops_8974 = { 371static const struct tsens_ops ops_8974 = {
227 .init = init_common, 372 .init = init_common,
228 .calibrate = calibrate_8974, 373 .calibrate = calibrate_8974,
229 .get_temp = get_temp_common, 374 .get_temp = get_temp_common,
230}; 375};
231 376
232const struct tsens_data data_8974 = { 377const struct tsens_plat_data data_8974 = {
233 .num_sensors = 11, 378 .num_sensors = 11,
234 .ops = &ops_8974, 379 .ops = &ops_8974,
235 .reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 }, 380 .feat = &tsens_v0_1_feat,
381 .fields = tsens_v0_1_regfields,
236}; 382};
diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
new file mode 100644
index 000000000000..10b595d4f619
--- /dev/null
+++ b/drivers/thermal/qcom/tsens-v1.c
@@ -0,0 +1,193 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019, Linaro Limited
4 */
5
6#include <linux/bitops.h>
7#include <linux/regmap.h>
8#include <linux/delay.h>
9#include "tsens.h"
10
11/* ----- SROT ------ */
12#define SROT_HW_VER_OFF 0x0000
13#define SROT_CTRL_OFF 0x0004
14
15/* ----- TM ------ */
16#define TM_INT_EN_OFF 0x0000
17#define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF 0x0004
18#define TM_Sn_STATUS_OFF 0x0044
19#define TM_TRDY_OFF 0x0084
20
21/* eeprom layout data for qcs404/405 (v1) */
22#define BASE0_MASK 0x000007f8
23#define BASE1_MASK 0x0007f800
24#define BASE0_SHIFT 3
25#define BASE1_SHIFT 11
26
27#define S0_P1_MASK 0x0000003f
28#define S1_P1_MASK 0x0003f000
29#define S2_P1_MASK 0x3f000000
30#define S3_P1_MASK 0x000003f0
31#define S4_P1_MASK 0x003f0000
32#define S5_P1_MASK 0x0000003f
33#define S6_P1_MASK 0x0003f000
34#define S7_P1_MASK 0x3f000000
35#define S8_P1_MASK 0x000003f0
36#define S9_P1_MASK 0x003f0000
37
38#define S0_P2_MASK 0x00000fc0
39#define S1_P2_MASK 0x00fc0000
40#define S2_P2_MASK_1_0 0xc0000000
41#define S2_P2_MASK_5_2 0x0000000f
42#define S3_P2_MASK 0x0000fc00
43#define S4_P2_MASK 0x0fc00000
44#define S5_P2_MASK 0x00000fc0
45#define S6_P2_MASK 0x00fc0000
46#define S7_P2_MASK_1_0 0xc0000000
47#define S7_P2_MASK_5_2 0x0000000f
48#define S8_P2_MASK 0x0000fc00
49#define S9_P2_MASK 0x0fc00000
50
51#define S0_P1_SHIFT 0
52#define S0_P2_SHIFT 6
53#define S1_P1_SHIFT 12
54#define S1_P2_SHIFT 18
55#define S2_P1_SHIFT 24
56#define S2_P2_SHIFT_1_0 30
57
58#define S2_P2_SHIFT_5_2 0
59#define S3_P1_SHIFT 4
60#define S3_P2_SHIFT 10
61#define S4_P1_SHIFT 16
62#define S4_P2_SHIFT 22
63
64#define S5_P1_SHIFT 0
65#define S5_P2_SHIFT 6
66#define S6_P1_SHIFT 12
67#define S6_P2_SHIFT 18
68#define S7_P1_SHIFT 24
69#define S7_P2_SHIFT_1_0 30
70
71#define S7_P2_SHIFT_5_2 0
72#define S8_P1_SHIFT 4
73#define S8_P2_SHIFT 10
74#define S9_P1_SHIFT 16
75#define S9_P2_SHIFT 22
76
77#define CAL_SEL_MASK 7
78#define CAL_SEL_SHIFT 0
79
80static int calibrate_v1(struct tsens_priv *priv)
81{
82 u32 base0 = 0, base1 = 0;
83 u32 p1[10], p2[10];
84 u32 mode = 0, lsb = 0, msb = 0;
85 u32 *qfprom_cdata;
86 int i;
87
88 qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
89 if (IS_ERR(qfprom_cdata))
90 return PTR_ERR(qfprom_cdata);
91
92 mode = (qfprom_cdata[4] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
93 dev_dbg(priv->dev, "calibration mode is %d\n", mode);
94
95 switch (mode) {
96 case TWO_PT_CALIB:
97 base1 = (qfprom_cdata[4] & BASE1_MASK) >> BASE1_SHIFT;
98 p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT;
99 p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT;
100 /* This value is split over two registers, 2 bits and 4 bits */
101 lsb = (qfprom_cdata[0] & S2_P2_MASK_1_0) >> S2_P2_SHIFT_1_0;
102 msb = (qfprom_cdata[1] & S2_P2_MASK_5_2) >> S2_P2_SHIFT_5_2;
103 p2[2] = msb << 2 | lsb;
104 p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
105 p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
106 p2[5] = (qfprom_cdata[2] & S5_P2_MASK) >> S5_P2_SHIFT;
107 p2[6] = (qfprom_cdata[2] & S6_P2_MASK) >> S6_P2_SHIFT;
108 /* This value is split over two registers, 2 bits and 4 bits */
109 lsb = (qfprom_cdata[2] & S7_P2_MASK_1_0) >> S7_P2_SHIFT_1_0;
110 msb = (qfprom_cdata[3] & S7_P2_MASK_5_2) >> S7_P2_SHIFT_5_2;
111 p2[7] = msb << 2 | lsb;
112 p2[8] = (qfprom_cdata[3] & S8_P2_MASK) >> S8_P2_SHIFT;
113 p2[9] = (qfprom_cdata[3] & S9_P2_MASK) >> S9_P2_SHIFT;
114 for (i = 0; i < priv->num_sensors; i++)
115 p2[i] = ((base1 + p2[i]) << 2);
116 /* Fall through */
117 case ONE_PT_CALIB2:
118 base0 = (qfprom_cdata[4] & BASE0_MASK) >> BASE0_SHIFT;
119 p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT;
120 p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT;
121 p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
122 p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
123 p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
124 p1[5] = (qfprom_cdata[2] & S5_P1_MASK) >> S5_P1_SHIFT;
125 p1[6] = (qfprom_cdata[2] & S6_P1_MASK) >> S6_P1_SHIFT;
126 p1[7] = (qfprom_cdata[2] & S7_P1_MASK) >> S7_P1_SHIFT;
127 p1[8] = (qfprom_cdata[3] & S8_P1_MASK) >> S8_P1_SHIFT;
128 p1[9] = (qfprom_cdata[3] & S9_P1_MASK) >> S9_P1_SHIFT;
129 for (i = 0; i < priv->num_sensors; i++)
130 p1[i] = (((base0) + p1[i]) << 2);
131 break;
132 default:
133 for (i = 0; i < priv->num_sensors; i++) {
134 p1[i] = 500;
135 p2[i] = 780;
136 }
137 break;
138 }
139
140 compute_intercept_slope(priv, p1, p2, mode);
141
142 return 0;
143}
144
145/* v1.x: qcs404,405 */
146
147static const struct tsens_features tsens_v1_feat = {
148 .ver_major = VER_1_X,
149 .crit_int = 0,
150 .adc = 1,
151 .srot_split = 1,
152 .max_sensors = 11,
153};
154
155static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
156 /* ----- SROT ------ */
157 /* VERSION */
158 [VER_MAJOR] = REG_FIELD(SROT_HW_VER_OFF, 28, 31),
159 [VER_MINOR] = REG_FIELD(SROT_HW_VER_OFF, 16, 27),
160 [VER_STEP] = REG_FIELD(SROT_HW_VER_OFF, 0, 15),
161 /* CTRL_OFFSET */
162 [TSENS_EN] = REG_FIELD(SROT_CTRL_OFF, 0, 0),
163 [TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1, 1),
164 [SENSOR_EN] = REG_FIELD(SROT_CTRL_OFF, 3, 13),
165
166 /* ----- TM ------ */
167 /* INTERRUPT ENABLE */
168 [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0),
169
170 /* Sn_STATUS */
171 REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 9),
172 REG_FIELD_FOR_EACH_SENSOR11(VALID, TM_Sn_STATUS_OFF, 14, 14),
173 REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS, TM_Sn_STATUS_OFF, 10, 10),
174 REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),
175 REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),
176 /* No CRITICAL field on v1.x */
177 REG_FIELD_FOR_EACH_SENSOR11(MAX_STATUS, TM_Sn_STATUS_OFF, 13, 13),
178
179 /* TRDY: 1=ready, 0=in progress */
180 [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
181};
182
183static const struct tsens_ops ops_generic_v1 = {
184 .init = init_common,
185 .calibrate = calibrate_v1,
186 .get_temp = get_temp_tsens_valid,
187};
188
189const struct tsens_plat_data data_tsens_v1 = {
190 .ops = &ops_generic_v1,
191 .feat = &tsens_v1_feat,
192 .fields = tsens_v1_regfields,
193};
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index 381a212872bf..1099069f2aa3 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -4,76 +4,81 @@
4 * Copyright (c) 2018, Linaro Limited 4 * Copyright (c) 2018, Linaro Limited
5 */ 5 */
6 6
7#include <linux/regmap.h>
8#include <linux/bitops.h> 7#include <linux/bitops.h>
8#include <linux/regmap.h>
9#include "tsens.h" 9#include "tsens.h"
10 10
11#define STATUS_OFFSET 0xa0 11/* ----- SROT ------ */
12#define LAST_TEMP_MASK 0xfff 12#define SROT_HW_VER_OFF 0x0000
13#define STATUS_VALID_BIT BIT(21) 13#define SROT_CTRL_OFF 0x0004
14
15/* ----- TM ------ */
16#define TM_INT_EN_OFF 0x0004
17#define TM_UPPER_LOWER_INT_STATUS_OFF 0x0008
18#define TM_UPPER_LOWER_INT_CLEAR_OFF 0x000c
19#define TM_UPPER_LOWER_INT_MASK_OFF 0x0010
20#define TM_CRITICAL_INT_STATUS_OFF 0x0014
21#define TM_CRITICAL_INT_CLEAR_OFF 0x0018
22#define TM_CRITICAL_INT_MASK_OFF 0x001c
23#define TM_Sn_UPPER_LOWER_THRESHOLD_OFF 0x0020
24#define TM_Sn_CRITICAL_THRESHOLD_OFF 0x0060
25#define TM_Sn_STATUS_OFF 0x00a0
26#define TM_TRDY_OFF 0x00e4
14 27
15static int get_temp_tsens_v2(struct tsens_device *tmdev, int id, int *temp) 28/* v2.x: 8996, 8998, sdm845 */
16{
17 struct tsens_sensor *s = &tmdev->sensor[id];
18 u32 code;
19 unsigned int status_reg;
20 u32 last_temp = 0, last_temp2 = 0, last_temp3 = 0;
21 int ret;
22 29
23 status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * 4; 30static const struct tsens_features tsens_v2_feat = {
24 ret = regmap_read(tmdev->tm_map, status_reg, &code); 31 .ver_major = VER_2_X,
25 if (ret) 32 .crit_int = 1,
26 return ret; 33 .adc = 0,
27 last_temp = code & LAST_TEMP_MASK; 34 .srot_split = 1,
28 if (code & STATUS_VALID_BIT) 35 .max_sensors = 16,
29 goto done; 36};
30 37
31 /* Try a second time */ 38static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
32 ret = regmap_read(tmdev->tm_map, status_reg, &code); 39 /* ----- SROT ------ */
33 if (ret) 40 /* VERSION */
34 return ret; 41 [VER_MAJOR] = REG_FIELD(SROT_HW_VER_OFF, 28, 31),
35 if (code & STATUS_VALID_BIT) { 42 [VER_MINOR] = REG_FIELD(SROT_HW_VER_OFF, 16, 27),
36 last_temp = code & LAST_TEMP_MASK; 43 [VER_STEP] = REG_FIELD(SROT_HW_VER_OFF, 0, 15),
37 goto done; 44 /* CTRL_OFF */
38 } else { 45 [TSENS_EN] = REG_FIELD(SROT_CTRL_OFF, 0, 0),
39 last_temp2 = code & LAST_TEMP_MASK; 46 [TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1, 1),
40 } 47 [SENSOR_EN] = REG_FIELD(SROT_CTRL_OFF, 3, 18),
41 48
42 /* Try a third/last time */ 49 /* ----- TM ------ */
43 ret = regmap_read(tmdev->tm_map, status_reg, &code); 50 /* INTERRUPT ENABLE */
44 if (ret) 51 /* v2 has separate enables for UPPER/LOWER/CRITICAL interrupts */
45 return ret; 52 [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 2),
46 if (code & STATUS_VALID_BIT) {
47 last_temp = code & LAST_TEMP_MASK;
48 goto done;
49 } else {
50 last_temp3 = code & LAST_TEMP_MASK;
51 }
52 53
53 if (last_temp == last_temp2) 54 /* Sn_STATUS */
54 last_temp = last_temp2; 55 REG_FIELD_FOR_EACH_SENSOR16(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 11),
55 else if (last_temp2 == last_temp3) 56 REG_FIELD_FOR_EACH_SENSOR16(VALID, TM_Sn_STATUS_OFF, 21, 21),
56 last_temp = last_temp3; 57 REG_FIELD_FOR_EACH_SENSOR16(MIN_STATUS, TM_Sn_STATUS_OFF, 16, 16),
57done: 58 REG_FIELD_FOR_EACH_SENSOR16(LOWER_STATUS, TM_Sn_STATUS_OFF, 17, 17),
58 /* Convert temperature from deciCelsius to milliCelsius */ 59 REG_FIELD_FOR_EACH_SENSOR16(UPPER_STATUS, TM_Sn_STATUS_OFF, 18, 18),
59 *temp = sign_extend32(last_temp, fls(LAST_TEMP_MASK) - 1) * 100; 60 REG_FIELD_FOR_EACH_SENSOR16(CRITICAL_STATUS, TM_Sn_STATUS_OFF, 19, 19),
61 REG_FIELD_FOR_EACH_SENSOR16(MAX_STATUS, TM_Sn_STATUS_OFF, 20, 20),
60 62
61 return 0; 63 /* TRDY: 1=ready, 0=in progress */
62} 64 [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
65};
63 66
64static const struct tsens_ops ops_generic_v2 = { 67static const struct tsens_ops ops_generic_v2 = {
65 .init = init_common, 68 .init = init_common,
66 .get_temp = get_temp_tsens_v2, 69 .get_temp = get_temp_tsens_valid,
67}; 70};
68 71
69const struct tsens_data data_tsens_v2 = { 72const struct tsens_plat_data data_tsens_v2 = {
70 .ops = &ops_generic_v2, 73 .ops = &ops_generic_v2,
71 .reg_offsets = { [SROT_CTRL_OFFSET] = 0x4 }, 74 .feat = &tsens_v2_feat,
75 .fields = tsens_v2_regfields,
72}; 76};
73 77
74/* Kept around for backward compatibility with old msm8996.dtsi */ 78/* Kept around for backward compatibility with old msm8996.dtsi */
75const struct tsens_data data_8996 = { 79const struct tsens_plat_data data_8996 = {
76 .num_sensors = 13, 80 .num_sensors = 13,
77 .ops = &ops_generic_v2, 81 .ops = &ops_generic_v2,
78 .reg_offsets = { [SROT_CTRL_OFFSET] = 0x4 }, 82 .feat = &tsens_v2_feat,
83 .fields = tsens_v2_regfields,
79}; 84};
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index f1ec9bbe4717..36b0b52db524 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -15,38 +15,38 @@
15static int tsens_get_temp(void *data, int *temp) 15static int tsens_get_temp(void *data, int *temp)
16{ 16{
17 const struct tsens_sensor *s = data; 17 const struct tsens_sensor *s = data;
18 struct tsens_device *tmdev = s->tmdev; 18 struct tsens_priv *priv = s->priv;
19 19
20 return tmdev->ops->get_temp(tmdev, s->id, temp); 20 return priv->ops->get_temp(priv, s->id, temp);
21} 21}
22 22
23static int tsens_get_trend(void *p, int trip, enum thermal_trend *trend) 23static int tsens_get_trend(void *data, int trip, enum thermal_trend *trend)
24{ 24{
25 const struct tsens_sensor *s = p; 25 const struct tsens_sensor *s = data;
26 struct tsens_device *tmdev = s->tmdev; 26 struct tsens_priv *priv = s->priv;
27 27
28 if (tmdev->ops->get_trend) 28 if (priv->ops->get_trend)
29 return tmdev->ops->get_trend(tmdev, s->id, trend); 29 return priv->ops->get_trend(priv, s->id, trend);
30 30
31 return -ENOTSUPP; 31 return -ENOTSUPP;
32} 32}
33 33
34static int __maybe_unused tsens_suspend(struct device *dev) 34static int __maybe_unused tsens_suspend(struct device *dev)
35{ 35{
36 struct tsens_device *tmdev = dev_get_drvdata(dev); 36 struct tsens_priv *priv = dev_get_drvdata(dev);
37 37
38 if (tmdev->ops && tmdev->ops->suspend) 38 if (priv->ops && priv->ops->suspend)
39 return tmdev->ops->suspend(tmdev); 39 return priv->ops->suspend(priv);
40 40
41 return 0; 41 return 0;
42} 42}
43 43
44static int __maybe_unused tsens_resume(struct device *dev) 44static int __maybe_unused tsens_resume(struct device *dev)
45{ 45{
46 struct tsens_device *tmdev = dev_get_drvdata(dev); 46 struct tsens_priv *priv = dev_get_drvdata(dev);
47 47
48 if (tmdev->ops && tmdev->ops->resume) 48 if (priv->ops && priv->ops->resume)
49 return tmdev->ops->resume(tmdev); 49 return priv->ops->resume(priv);
50 50
51 return 0; 51 return 0;
52} 52}
@@ -64,6 +64,9 @@ static const struct of_device_id tsens_table[] = {
64 .compatible = "qcom,msm8996-tsens", 64 .compatible = "qcom,msm8996-tsens",
65 .data = &data_8996, 65 .data = &data_8996,
66 }, { 66 }, {
67 .compatible = "qcom,tsens-v1",
68 .data = &data_tsens_v1,
69 }, {
67 .compatible = "qcom,tsens-v2", 70 .compatible = "qcom,tsens-v2",
68 .data = &data_tsens_v2, 71 .data = &data_tsens_v2,
69 }, 72 },
@@ -76,22 +79,27 @@ static const struct thermal_zone_of_device_ops tsens_of_ops = {
76 .get_trend = tsens_get_trend, 79 .get_trend = tsens_get_trend,
77}; 80};
78 81
79static int tsens_register(struct tsens_device *tmdev) 82static int tsens_register(struct tsens_priv *priv)
80{ 83{
81 int i; 84 int i;
82 struct thermal_zone_device *tzd; 85 struct thermal_zone_device *tzd;
83 86
84 for (i = 0; i < tmdev->num_sensors; i++) { 87 for (i = 0; i < priv->num_sensors; i++) {
85 tmdev->sensor[i].tmdev = tmdev; 88 if (!is_sensor_enabled(priv, priv->sensor[i].hw_id)) {
86 tmdev->sensor[i].id = i; 89 dev_err(priv->dev, "sensor %d: disabled\n",
87 tzd = devm_thermal_zone_of_sensor_register(tmdev->dev, i, 90 priv->sensor[i].hw_id);
88 &tmdev->sensor[i], 91 continue;
92 }
93 priv->sensor[i].priv = priv;
94 priv->sensor[i].id = i;
95 tzd = devm_thermal_zone_of_sensor_register(priv->dev, i,
96 &priv->sensor[i],
89 &tsens_of_ops); 97 &tsens_of_ops);
90 if (IS_ERR(tzd)) 98 if (IS_ERR(tzd))
91 continue; 99 continue;
92 tmdev->sensor[i].tzd = tzd; 100 priv->sensor[i].tzd = tzd;
93 if (tmdev->ops->enable) 101 if (priv->ops->enable)
94 tmdev->ops->enable(tmdev, i); 102 priv->ops->enable(priv, i);
95 } 103 }
96 return 0; 104 return 0;
97} 105}
@@ -101,8 +109,8 @@ static int tsens_probe(struct platform_device *pdev)
101 int ret, i; 109 int ret, i;
102 struct device *dev; 110 struct device *dev;
103 struct device_node *np; 111 struct device_node *np;
104 struct tsens_device *tmdev; 112 struct tsens_priv *priv;
105 const struct tsens_data *data; 113 const struct tsens_plat_data *data;
106 const struct of_device_id *id; 114 const struct of_device_id *id;
107 u32 num_sensors; 115 u32 num_sensors;
108 116
@@ -129,55 +137,55 @@ static int tsens_probe(struct platform_device *pdev)
129 return -EINVAL; 137 return -EINVAL;
130 } 138 }
131 139
132 tmdev = devm_kzalloc(dev, 140 priv = devm_kzalloc(dev,
133 struct_size(tmdev, sensor, num_sensors), 141 struct_size(priv, sensor, num_sensors),
134 GFP_KERNEL); 142 GFP_KERNEL);
135 if (!tmdev) 143 if (!priv)
136 return -ENOMEM; 144 return -ENOMEM;
137 145
138 tmdev->dev = dev; 146 priv->dev = dev;
139 tmdev->num_sensors = num_sensors; 147 priv->num_sensors = num_sensors;
140 tmdev->ops = data->ops; 148 priv->ops = data->ops;
141 for (i = 0; i < tmdev->num_sensors; i++) { 149 for (i = 0; i < priv->num_sensors; i++) {
142 if (data->hw_ids) 150 if (data->hw_ids)
143 tmdev->sensor[i].hw_id = data->hw_ids[i]; 151 priv->sensor[i].hw_id = data->hw_ids[i];
144 else 152 else
145 tmdev->sensor[i].hw_id = i; 153 priv->sensor[i].hw_id = i;
146 }
147 for (i = 0; i < REG_ARRAY_SIZE; i++) {
148 tmdev->reg_offsets[i] = data->reg_offsets[i];
149 } 154 }
155 priv->feat = data->feat;
156 priv->fields = data->fields;
150 157
151 if (!tmdev->ops || !tmdev->ops->init || !tmdev->ops->get_temp) 158 if (!priv->ops || !priv->ops->init || !priv->ops->get_temp)
152 return -EINVAL; 159 return -EINVAL;
153 160
154 ret = tmdev->ops->init(tmdev); 161 ret = priv->ops->init(priv);
155 if (ret < 0) { 162 if (ret < 0) {
156 dev_err(dev, "tsens init failed\n"); 163 dev_err(dev, "tsens init failed\n");
157 return ret; 164 return ret;
158 } 165 }
159 166
160 if (tmdev->ops->calibrate) { 167 if (priv->ops->calibrate) {
161 ret = tmdev->ops->calibrate(tmdev); 168 ret = priv->ops->calibrate(priv);
162 if (ret < 0) { 169 if (ret < 0) {
163 dev_err(dev, "tsens calibration failed\n"); 170 if (ret != -EPROBE_DEFER)
171 dev_err(dev, "tsens calibration failed\n");
164 return ret; 172 return ret;
165 } 173 }
166 } 174 }
167 175
168 ret = tsens_register(tmdev); 176 ret = tsens_register(priv);
169 177
170 platform_set_drvdata(pdev, tmdev); 178 platform_set_drvdata(pdev, priv);
171 179
172 return ret; 180 return ret;
173} 181}
174 182
175static int tsens_remove(struct platform_device *pdev) 183static int tsens_remove(struct platform_device *pdev)
176{ 184{
177 struct tsens_device *tmdev = platform_get_drvdata(pdev); 185 struct tsens_priv *priv = platform_get_drvdata(pdev);
178 186
179 if (tmdev->ops->disable) 187 if (priv->ops->disable)
180 tmdev->ops->disable(tmdev); 188 priv->ops->disable(priv);
181 189
182 return 0; 190 return 0;
183} 191}
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 7b7feee5dc46..eefe3844fb4e 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -9,17 +9,39 @@
9#define ONE_PT_CALIB 0x1 9#define ONE_PT_CALIB 0x1
10#define ONE_PT_CALIB2 0x2 10#define ONE_PT_CALIB2 0x2
11#define TWO_PT_CALIB 0x3 11#define TWO_PT_CALIB 0x3
12#define CAL_DEGC_PT1 30
13#define CAL_DEGC_PT2 120
14#define SLOPE_FACTOR 1000
15#define SLOPE_DEFAULT 3200
16
12 17
13#include <linux/thermal.h> 18#include <linux/thermal.h>
19#include <linux/regmap.h>
20
21struct tsens_priv;
14 22
15struct tsens_device; 23enum tsens_ver {
24 VER_0_1 = 0,
25 VER_1_X,
26 VER_2_X,
27};
16 28
29/**
30 * struct tsens_sensor - data for each sensor connected to the tsens device
31 * @priv: tsens device instance that this sensor is connected to
32 * @tzd: pointer to the thermal zone that this sensor is in
33 * @offset: offset of temperature adjustment curve
34 * @id: Sensor ID
35 * @hw_id: HW ID can be used in case of platform-specific IDs
36 * @slope: slope of temperature adjustment curve
37 * @status: 8960-specific variable to track 8960 and 8660 status register offset
38 */
17struct tsens_sensor { 39struct tsens_sensor {
18 struct tsens_device *tmdev; 40 struct tsens_priv *priv;
19 struct thermal_zone_device *tzd; 41 struct thermal_zone_device *tzd;
20 int offset; 42 int offset;
21 int id; 43 unsigned int id;
22 int hw_id; 44 unsigned int hw_id;
23 int slope; 45 int slope;
24 u32 status; 46 u32 status;
25}; 47};
@@ -37,63 +59,274 @@ struct tsens_sensor {
37 */ 59 */
38struct tsens_ops { 60struct tsens_ops {
39 /* mandatory callbacks */ 61 /* mandatory callbacks */
40 int (*init)(struct tsens_device *); 62 int (*init)(struct tsens_priv *priv);
41 int (*calibrate)(struct tsens_device *); 63 int (*calibrate)(struct tsens_priv *priv);
42 int (*get_temp)(struct tsens_device *, int, int *); 64 int (*get_temp)(struct tsens_priv *priv, int i, int *temp);
43 /* optional callbacks */ 65 /* optional callbacks */
44 int (*enable)(struct tsens_device *, int); 66 int (*enable)(struct tsens_priv *priv, int i);
45 void (*disable)(struct tsens_device *); 67 void (*disable)(struct tsens_priv *priv);
46 int (*suspend)(struct tsens_device *); 68 int (*suspend)(struct tsens_priv *priv);
47 int (*resume)(struct tsens_device *); 69 int (*resume)(struct tsens_priv *priv);
48 int (*get_trend)(struct tsens_device *, int, enum thermal_trend *); 70 int (*get_trend)(struct tsens_priv *priv, int i, enum thermal_trend *trend);
49}; 71};
50 72
51enum reg_list { 73#define REG_FIELD_FOR_EACH_SENSOR11(_name, _offset, _startbit, _stopbit) \
52 SROT_CTRL_OFFSET, 74 [_name##_##0] = REG_FIELD(_offset, _startbit, _stopbit), \
75 [_name##_##1] = REG_FIELD(_offset + 4, _startbit, _stopbit), \
76 [_name##_##2] = REG_FIELD(_offset + 8, _startbit, _stopbit), \
77 [_name##_##3] = REG_FIELD(_offset + 12, _startbit, _stopbit), \
78 [_name##_##4] = REG_FIELD(_offset + 16, _startbit, _stopbit), \
79 [_name##_##5] = REG_FIELD(_offset + 20, _startbit, _stopbit), \
80 [_name##_##6] = REG_FIELD(_offset + 24, _startbit, _stopbit), \
81 [_name##_##7] = REG_FIELD(_offset + 28, _startbit, _stopbit), \
82 [_name##_##8] = REG_FIELD(_offset + 32, _startbit, _stopbit), \
83 [_name##_##9] = REG_FIELD(_offset + 36, _startbit, _stopbit), \
84 [_name##_##10] = REG_FIELD(_offset + 40, _startbit, _stopbit)
53 85
54 REG_ARRAY_SIZE, 86#define REG_FIELD_FOR_EACH_SENSOR16(_name, _offset, _startbit, _stopbit) \
87 [_name##_##0] = REG_FIELD(_offset, _startbit, _stopbit), \
88 [_name##_##1] = REG_FIELD(_offset + 4, _startbit, _stopbit), \
89 [_name##_##2] = REG_FIELD(_offset + 8, _startbit, _stopbit), \
90 [_name##_##3] = REG_FIELD(_offset + 12, _startbit, _stopbit), \
91 [_name##_##4] = REG_FIELD(_offset + 16, _startbit, _stopbit), \
92 [_name##_##5] = REG_FIELD(_offset + 20, _startbit, _stopbit), \
93 [_name##_##6] = REG_FIELD(_offset + 24, _startbit, _stopbit), \
94 [_name##_##7] = REG_FIELD(_offset + 28, _startbit, _stopbit), \
95 [_name##_##8] = REG_FIELD(_offset + 32, _startbit, _stopbit), \
96 [_name##_##9] = REG_FIELD(_offset + 36, _startbit, _stopbit), \
97 [_name##_##10] = REG_FIELD(_offset + 40, _startbit, _stopbit), \
98 [_name##_##11] = REG_FIELD(_offset + 44, _startbit, _stopbit), \
99 [_name##_##12] = REG_FIELD(_offset + 48, _startbit, _stopbit), \
100 [_name##_##13] = REG_FIELD(_offset + 52, _startbit, _stopbit), \
101 [_name##_##14] = REG_FIELD(_offset + 56, _startbit, _stopbit), \
102 [_name##_##15] = REG_FIELD(_offset + 60, _startbit, _stopbit)
103
104/* reg_field IDs to use as an index into an array */
105enum regfield_ids {
106 /* ----- SROT ------ */
107 /* HW_VER */
108 VER_MAJOR = 0,
109 VER_MINOR,
110 VER_STEP,
111 /* CTRL_OFFSET */
112 TSENS_EN = 3,
113 TSENS_SW_RST,
114 SENSOR_EN,
115 CODE_OR_TEMP,
116
117 /* ----- TM ------ */
118 /* STATUS */
119 LAST_TEMP_0 = 7, /* Last temperature reading */
120 LAST_TEMP_1,
121 LAST_TEMP_2,
122 LAST_TEMP_3,
123 LAST_TEMP_4,
124 LAST_TEMP_5,
125 LAST_TEMP_6,
126 LAST_TEMP_7,
127 LAST_TEMP_8,
128 LAST_TEMP_9,
129 LAST_TEMP_10,
130 LAST_TEMP_11,
131 LAST_TEMP_12,
132 LAST_TEMP_13,
133 LAST_TEMP_14,
134 LAST_TEMP_15,
135 VALID_0 = 23, /* VALID reading or not */
136 VALID_1,
137 VALID_2,
138 VALID_3,
139 VALID_4,
140 VALID_5,
141 VALID_6,
142 VALID_7,
143 VALID_8,
144 VALID_9,
145 VALID_10,
146 VALID_11,
147 VALID_12,
148 VALID_13,
149 VALID_14,
150 VALID_15,
151 MIN_STATUS_0, /* MIN threshold violated */
152 MIN_STATUS_1,
153 MIN_STATUS_2,
154 MIN_STATUS_3,
155 MIN_STATUS_4,
156 MIN_STATUS_5,
157 MIN_STATUS_6,
158 MIN_STATUS_7,
159 MIN_STATUS_8,
160 MIN_STATUS_9,
161 MIN_STATUS_10,
162 MIN_STATUS_11,
163 MIN_STATUS_12,
164 MIN_STATUS_13,
165 MIN_STATUS_14,
166 MIN_STATUS_15,
167 MAX_STATUS_0, /* MAX threshold violated */
168 MAX_STATUS_1,
169 MAX_STATUS_2,
170 MAX_STATUS_3,
171 MAX_STATUS_4,
172 MAX_STATUS_5,
173 MAX_STATUS_6,
174 MAX_STATUS_7,
175 MAX_STATUS_8,
176 MAX_STATUS_9,
177 MAX_STATUS_10,
178 MAX_STATUS_11,
179 MAX_STATUS_12,
180 MAX_STATUS_13,
181 MAX_STATUS_14,
182 MAX_STATUS_15,
183 LOWER_STATUS_0, /* LOWER threshold violated */
184 LOWER_STATUS_1,
185 LOWER_STATUS_2,
186 LOWER_STATUS_3,
187 LOWER_STATUS_4,
188 LOWER_STATUS_5,
189 LOWER_STATUS_6,
190 LOWER_STATUS_7,
191 LOWER_STATUS_8,
192 LOWER_STATUS_9,
193 LOWER_STATUS_10,
194 LOWER_STATUS_11,
195 LOWER_STATUS_12,
196 LOWER_STATUS_13,
197 LOWER_STATUS_14,
198 LOWER_STATUS_15,
199 UPPER_STATUS_0, /* UPPER threshold violated */
200 UPPER_STATUS_1,
201 UPPER_STATUS_2,
202 UPPER_STATUS_3,
203 UPPER_STATUS_4,
204 UPPER_STATUS_5,
205 UPPER_STATUS_6,
206 UPPER_STATUS_7,
207 UPPER_STATUS_8,
208 UPPER_STATUS_9,
209 UPPER_STATUS_10,
210 UPPER_STATUS_11,
211 UPPER_STATUS_12,
212 UPPER_STATUS_13,
213 UPPER_STATUS_14,
214 UPPER_STATUS_15,
215 CRITICAL_STATUS_0, /* CRITICAL threshold violated */
216 CRITICAL_STATUS_1,
217 CRITICAL_STATUS_2,
218 CRITICAL_STATUS_3,
219 CRITICAL_STATUS_4,
220 CRITICAL_STATUS_5,
221 CRITICAL_STATUS_6,
222 CRITICAL_STATUS_7,
223 CRITICAL_STATUS_8,
224 CRITICAL_STATUS_9,
225 CRITICAL_STATUS_10,
226 CRITICAL_STATUS_11,
227 CRITICAL_STATUS_12,
228 CRITICAL_STATUS_13,
229 CRITICAL_STATUS_14,
230 CRITICAL_STATUS_15,
231 /* TRDY */
232 TRDY,
233 /* INTERRUPT ENABLE */
234 INT_EN, /* Pre-V1, V1.x */
235 LOW_INT_EN, /* V2.x */
236 UP_INT_EN, /* V2.x */
237 CRIT_INT_EN, /* V2.x */
238
239 /* Keep last */
240 MAX_REGFIELDS
55}; 241};
56 242
57/** 243/**
58 * struct tsens_data - tsens instance specific data 244 * struct tsens_features - Features supported by the IP
59 * @num_sensors: Max number of sensors supported by platform 245 * @ver_major: Major number of IP version
246 * @crit_int: does the IP support critical interrupts?
247 * @adc: do the sensors only output adc code (instead of temperature)?
248 * @srot_split: does the IP neatly splits the register space into SROT and TM,
249 * with SROT only being available to secure boot firmware?
250 * @max_sensors: maximum sensors supported by this version of the IP
251 */
252struct tsens_features {
253 unsigned int ver_major;
254 unsigned int crit_int:1;
255 unsigned int adc:1;
256 unsigned int srot_split:1;
257 unsigned int max_sensors;
258};
259
260/**
261 * struct tsens_plat_data - tsens compile-time platform data
262 * @num_sensors: Number of sensors supported by platform
60 * @ops: operations the tsens instance supports 263 * @ops: operations the tsens instance supports
61 * @hw_ids: Subset of sensors ids supported by platform, if not the first n 264 * @hw_ids: Subset of sensors ids supported by platform, if not the first n
62 * @reg_offsets: Register offsets for commonly used registers 265 * @feat: features of the IP
266 * @fields: bitfield locations
63 */ 267 */
64struct tsens_data { 268struct tsens_plat_data {
65 const u32 num_sensors; 269 const u32 num_sensors;
66 const struct tsens_ops *ops; 270 const struct tsens_ops *ops;
67 const u16 reg_offsets[REG_ARRAY_SIZE];
68 unsigned int *hw_ids; 271 unsigned int *hw_ids;
272 const struct tsens_features *feat;
273 const struct reg_field *fields;
69}; 274};
70 275
71/* Registers to be saved/restored across a context loss */ 276/**
277 * struct tsens_context - Registers to be saved/restored across a context loss
278 */
72struct tsens_context { 279struct tsens_context {
73 int threshold; 280 int threshold;
74 int control; 281 int control;
75}; 282};
76 283
77struct tsens_device { 284/**
285 * struct tsens_priv - private data for each instance of the tsens IP
286 * @dev: pointer to struct device
287 * @num_sensors: number of sensors enabled on this device
288 * @tm_map: pointer to TM register address space
289 * @srot_map: pointer to SROT register address space
290 * @tm_offset: deal with old device trees that don't address TM and SROT
291 * address space separately
292 * @rf: array of regmap_fields used to store value of the field
293 * @ctx: registers to be saved and restored during suspend/resume
294 * @feat: features of the IP
295 * @fields: bitfield locations
296 * @ops: pointer to list of callbacks supported by this device
297 * @sensor: list of sensors attached to this device
298 */
299struct tsens_priv {
78 struct device *dev; 300 struct device *dev;
79 u32 num_sensors; 301 u32 num_sensors;
80 struct regmap *tm_map; 302 struct regmap *tm_map;
81 struct regmap *srot_map; 303 struct regmap *srot_map;
82 u32 tm_offset; 304 u32 tm_offset;
83 u16 reg_offsets[REG_ARRAY_SIZE]; 305 struct regmap_field *rf[MAX_REGFIELDS];
84 struct tsens_context ctx; 306 struct tsens_context ctx;
307 const struct tsens_features *feat;
308 const struct reg_field *fields;
85 const struct tsens_ops *ops; 309 const struct tsens_ops *ops;
86 struct tsens_sensor sensor[0]; 310 struct tsens_sensor sensor[0];
87}; 311};
88 312
89char *qfprom_read(struct device *, const char *); 313char *qfprom_read(struct device *dev, const char *cname);
90void compute_intercept_slope(struct tsens_device *, u32 *, u32 *, u32); 314void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode);
91int init_common(struct tsens_device *); 315int init_common(struct tsens_priv *priv);
92int get_temp_common(struct tsens_device *, int, int *); 316int get_temp_tsens_valid(struct tsens_priv *priv, int i, int *temp);
317int get_temp_common(struct tsens_priv *priv, int i, int *temp);
318bool is_sensor_enabled(struct tsens_priv *priv, u32 hw_id);
319
320/* TSENS target */
321extern const struct tsens_plat_data data_8960;
322
323/* TSENS v0.1 targets */
324extern const struct tsens_plat_data data_8916, data_8974;
93 325
94/* TSENS v1 targets */ 326/* TSENS v1 targets */
95extern const struct tsens_data data_8916, data_8974, data_8960; 327extern const struct tsens_plat_data data_tsens_v1;
328
96/* TSENS v2 targets */ 329/* TSENS v2 targets */
97extern const struct tsens_data data_8996, data_tsens_v2; 330extern const struct tsens_plat_data data_8996, data_tsens_v2;
98 331
99#endif /* __QCOM_TSENS_H__ */ 332#endif /* __QCOM_TSENS_H__ */
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index 3b5f5b3fb1bc..7b364933bfb1 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -193,11 +193,6 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
193 struct qoriq_tmu_data *data; 193 struct qoriq_tmu_data *data;
194 struct device_node *np = pdev->dev.of_node; 194 struct device_node *np = pdev->dev.of_node;
195 195
196 if (!np) {
197 dev_err(&pdev->dev, "Device OF-Node is NULL");
198 return -ENODEV;
199 }
200
201 data = devm_kzalloc(&pdev->dev, sizeof(struct qoriq_tmu_data), 196 data = devm_kzalloc(&pdev->dev, sizeof(struct qoriq_tmu_data),
202 GFP_KERNEL); 197 GFP_KERNEL);
203 if (!data) 198 if (!data)
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index 88fa41cf16e8..83f306265ee1 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -14,7 +14,6 @@
14#include <linux/of_device.h> 14#include <linux/of_device.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/pm_runtime.h> 16#include <linux/pm_runtime.h>
17#include <linux/spinlock.h>
18#include <linux/sys_soc.h> 17#include <linux/sys_soc.h>
19#include <linux/thermal.h> 18#include <linux/thermal.h>
20 19
@@ -82,7 +81,6 @@ struct rcar_gen3_thermal_tsc {
82struct rcar_gen3_thermal_priv { 81struct rcar_gen3_thermal_priv {
83 struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM]; 82 struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM];
84 unsigned int num_tscs; 83 unsigned int num_tscs;
85 spinlock_t lock; /* Protect interrupts on and off */
86 void (*thermal_init)(struct rcar_gen3_thermal_tsc *tsc); 84 void (*thermal_init)(struct rcar_gen3_thermal_tsc *tsc);
87}; 85};
88 86
@@ -232,38 +230,16 @@ static irqreturn_t rcar_gen3_thermal_irq(int irq, void *data)
232{ 230{
233 struct rcar_gen3_thermal_priv *priv = data; 231 struct rcar_gen3_thermal_priv *priv = data;
234 u32 status; 232 u32 status;
235 int i, ret = IRQ_HANDLED; 233 int i;
236 234
237 spin_lock(&priv->lock);
238 for (i = 0; i < priv->num_tscs; i++) { 235 for (i = 0; i < priv->num_tscs; i++) {
239 status = rcar_gen3_thermal_read(priv->tscs[i], REG_GEN3_IRQSTR); 236 status = rcar_gen3_thermal_read(priv->tscs[i], REG_GEN3_IRQSTR);
240 rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQSTR, 0); 237 rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQSTR, 0);
241 if (status) 238 if (status)
242 ret = IRQ_WAKE_THREAD; 239 thermal_zone_device_update(priv->tscs[i]->zone,
240 THERMAL_EVENT_UNSPECIFIED);
243 } 241 }
244 242
245 if (ret == IRQ_WAKE_THREAD)
246 rcar_thermal_irq_set(priv, false);
247
248 spin_unlock(&priv->lock);
249
250 return ret;
251}
252
253static irqreturn_t rcar_gen3_thermal_irq_thread(int irq, void *data)
254{
255 struct rcar_gen3_thermal_priv *priv = data;
256 unsigned long flags;
257 int i;
258
259 for (i = 0; i < priv->num_tscs; i++)
260 thermal_zone_device_update(priv->tscs[i]->zone,
261 THERMAL_EVENT_UNSPECIFIED);
262
263 spin_lock_irqsave(&priv->lock, flags);
264 rcar_thermal_irq_set(priv, true);
265 spin_unlock_irqrestore(&priv->lock, flags);
266
267 return IRQ_HANDLED; 243 return IRQ_HANDLED;
268} 244}
269 245
@@ -307,7 +283,7 @@ static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
307 283
308 usleep_range(1000, 2000); 284 usleep_range(1000, 2000);
309 285
310 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F); 286 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0);
311 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0); 287 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0);
312 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN, IRQ_TEMPD1 | IRQ_TEMP2); 288 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN, IRQ_TEMPD1 | IRQ_TEMP2);
313 289
@@ -331,6 +307,9 @@ MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids);
331static int rcar_gen3_thermal_remove(struct platform_device *pdev) 307static int rcar_gen3_thermal_remove(struct platform_device *pdev)
332{ 308{
333 struct device *dev = &pdev->dev; 309 struct device *dev = &pdev->dev;
310 struct rcar_gen3_thermal_priv *priv = dev_get_drvdata(dev);
311
312 rcar_thermal_irq_set(priv, false);
334 313
335 pm_runtime_put(dev); 314 pm_runtime_put(dev);
336 pm_runtime_disable(dev); 315 pm_runtime_disable(dev);
@@ -371,8 +350,6 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
371 if (soc_device_match(r8a7795es1)) 350 if (soc_device_match(r8a7795es1))
372 priv->thermal_init = rcar_gen3_thermal_init_r8a7795es1; 351 priv->thermal_init = rcar_gen3_thermal_init_r8a7795es1;
373 352
374 spin_lock_init(&priv->lock);
375
376 platform_set_drvdata(pdev, priv); 353 platform_set_drvdata(pdev, priv);
377 354
378 /* 355 /*
@@ -390,9 +367,9 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
390 if (!irqname) 367 if (!irqname)
391 return -ENOMEM; 368 return -ENOMEM;
392 369
393 ret = devm_request_threaded_irq(dev, irq, rcar_gen3_thermal_irq, 370 ret = devm_request_threaded_irq(dev, irq, NULL,
394 rcar_gen3_thermal_irq_thread, 371 rcar_gen3_thermal_irq,
395 IRQF_SHARED, irqname, priv); 372 IRQF_ONESHOT, irqname, priv);
396 if (ret) 373 if (ret)
397 return ret; 374 return ret;
398 } 375 }
@@ -433,10 +410,6 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
433 } 410 }
434 tsc->zone = zone; 411 tsc->zone = zone;
435 412
436 ret = of_thermal_get_ntrips(tsc->zone);
437 if (ret < 0)
438 goto error_unregister;
439
440 tsc->zone->tzp->no_hwmon = false; 413 tsc->zone->tzp->no_hwmon = false;
441 ret = thermal_add_hwmon_sysfs(tsc->zone); 414 ret = thermal_add_hwmon_sysfs(tsc->zone);
442 if (ret) 415 if (ret)
@@ -448,6 +421,10 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
448 goto error_unregister; 421 goto error_unregister;
449 } 422 }
450 423
424 ret = of_thermal_get_ntrips(tsc->zone);
425 if (ret < 0)
426 goto error_unregister;
427
451 dev_info(dev, "TSC%d: Loaded %d trip points\n", i, ret); 428 dev_info(dev, "TSC%d: Loaded %d trip points\n", i, ret);
452 } 429 }
453 430
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 97462e9b40d8..d0873de718da 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -52,6 +52,7 @@ struct rcar_thermal_chip {
52 unsigned int irq_per_ch : 1; 52 unsigned int irq_per_ch : 1;
53 unsigned int needs_suspend_resume : 1; 53 unsigned int needs_suspend_resume : 1;
54 unsigned int nirqs; 54 unsigned int nirqs;
55 unsigned int ctemp_bands;
55}; 56};
56 57
57static const struct rcar_thermal_chip rcar_thermal = { 58static const struct rcar_thermal_chip rcar_thermal = {
@@ -60,6 +61,7 @@ static const struct rcar_thermal_chip rcar_thermal = {
60 .irq_per_ch = 0, 61 .irq_per_ch = 0,
61 .needs_suspend_resume = 0, 62 .needs_suspend_resume = 0,
62 .nirqs = 1, 63 .nirqs = 1,
64 .ctemp_bands = 1,
63}; 65};
64 66
65static const struct rcar_thermal_chip rcar_gen2_thermal = { 67static const struct rcar_thermal_chip rcar_gen2_thermal = {
@@ -68,6 +70,7 @@ static const struct rcar_thermal_chip rcar_gen2_thermal = {
68 .irq_per_ch = 0, 70 .irq_per_ch = 0,
69 .needs_suspend_resume = 0, 71 .needs_suspend_resume = 0,
70 .nirqs = 1, 72 .nirqs = 1,
73 .ctemp_bands = 1,
71}; 74};
72 75
73static const struct rcar_thermal_chip rcar_gen3_thermal = { 76static const struct rcar_thermal_chip rcar_gen3_thermal = {
@@ -80,6 +83,7 @@ static const struct rcar_thermal_chip rcar_gen3_thermal = {
80 * interrupts to detect a temperature change, rise or fall. 83 * interrupts to detect a temperature change, rise or fall.
81 */ 84 */
82 .nirqs = 2, 85 .nirqs = 2,
86 .ctemp_bands = 2,
83}; 87};
84 88
85struct rcar_thermal_priv { 89struct rcar_thermal_priv {
@@ -263,7 +267,12 @@ static int rcar_thermal_get_current_temp(struct rcar_thermal_priv *priv,
263 return ret; 267 return ret;
264 268
265 mutex_lock(&priv->lock); 269 mutex_lock(&priv->lock);
266 tmp = MCELSIUS((priv->ctemp * 5) - 65); 270 if (priv->chip->ctemp_bands == 1)
271 tmp = MCELSIUS((priv->ctemp * 5) - 65);
272 else if (priv->ctemp < 24)
273 tmp = MCELSIUS(((priv->ctemp * 55) - 720) / 10);
274 else
275 tmp = MCELSIUS((priv->ctemp * 5) - 60);
267 mutex_unlock(&priv->lock); 276 mutex_unlock(&priv->lock);
268 277
269 if ((tmp < MCELSIUS(-45)) || (tmp > MCELSIUS(125))) { 278 if ((tmp < MCELSIUS(-45)) || (tmp > MCELSIUS(125))) {
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 9c7643d62ed7..bda1ca199abd 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -172,6 +172,9 @@ struct rockchip_thermal_data {
172 int tshut_temp; 172 int tshut_temp;
173 enum tshut_mode tshut_mode; 173 enum tshut_mode tshut_mode;
174 enum tshut_polarity tshut_polarity; 174 enum tshut_polarity tshut_polarity;
175 struct pinctrl *pinctrl;
176 struct pinctrl_state *gpio_state;
177 struct pinctrl_state *otp_state;
175}; 178};
176 179
177/** 180/**
@@ -222,11 +225,15 @@ struct rockchip_thermal_data {
222#define GRF_TSADC_TESTBIT_L 0x0e648 225#define GRF_TSADC_TESTBIT_L 0x0e648
223#define GRF_TSADC_TESTBIT_H 0x0e64c 226#define GRF_TSADC_TESTBIT_H 0x0e64c
224 227
228#define PX30_GRF_SOC_CON2 0x0408
229
225#define GRF_SARADC_TESTBIT_ON (0x10001 << 2) 230#define GRF_SARADC_TESTBIT_ON (0x10001 << 2)
226#define GRF_TSADC_TESTBIT_H_ON (0x10001 << 2) 231#define GRF_TSADC_TESTBIT_H_ON (0x10001 << 2)
227#define GRF_TSADC_VCM_EN_L (0x10001 << 7) 232#define GRF_TSADC_VCM_EN_L (0x10001 << 7)
228#define GRF_TSADC_VCM_EN_H (0x10001 << 7) 233#define GRF_TSADC_VCM_EN_H (0x10001 << 7)
229 234
235#define GRF_CON_TSADC_CH_INV (0x10001 << 1)
236
230/** 237/**
231 * struct tsadc_table - code to temperature conversion table 238 * struct tsadc_table - code to temperature conversion table
232 * @code: the value of adc channel 239 * @code: the value of adc channel
@@ -689,6 +696,13 @@ static void rk_tsadcv3_initialize(struct regmap *grf, void __iomem *regs,
689 regs + TSADCV2_AUTO_CON); 696 regs + TSADCV2_AUTO_CON);
690} 697}
691 698
699static void rk_tsadcv4_initialize(struct regmap *grf, void __iomem *regs,
700 enum tshut_polarity tshut_polarity)
701{
702 rk_tsadcv2_initialize(grf, regs, tshut_polarity);
703 regmap_write(grf, PX30_GRF_SOC_CON2, GRF_CON_TSADC_CH_INV);
704}
705
692static void rk_tsadcv2_irq_ack(void __iomem *regs) 706static void rk_tsadcv2_irq_ack(void __iomem *regs)
693{ 707{
694 u32 val; 708 u32 val;
@@ -818,6 +832,30 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
818 writel_relaxed(val, regs + TSADCV2_INT_EN); 832 writel_relaxed(val, regs + TSADCV2_INT_EN);
819} 833}
820 834
835static const struct rockchip_tsadc_chip px30_tsadc_data = {
836 .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
837 .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */
838 .chn_num = 2, /* 2 channels for tsadc */
839
840 .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */
841 .tshut_temp = 95000,
842
843 .initialize = rk_tsadcv4_initialize,
844 .irq_ack = rk_tsadcv3_irq_ack,
845 .control = rk_tsadcv3_control,
846 .get_temp = rk_tsadcv2_get_temp,
847 .set_alarm_temp = rk_tsadcv2_alarm_temp,
848 .set_tshut_temp = rk_tsadcv2_tshut_temp,
849 .set_tshut_mode = rk_tsadcv2_tshut_mode,
850
851 .table = {
852 .id = rk3328_code_table,
853 .length = ARRAY_SIZE(rk3328_code_table),
854 .data_mask = TSADCV2_DATA_MASK,
855 .mode = ADC_INCREMENT,
856 },
857};
858
821static const struct rockchip_tsadc_chip rv1108_tsadc_data = { 859static const struct rockchip_tsadc_chip rv1108_tsadc_data = {
822 .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ 860 .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
823 .chn_num = 1, /* one channel for tsadc */ 861 .chn_num = 1, /* one channel for tsadc */
@@ -990,6 +1028,9 @@ static const struct rockchip_tsadc_chip rk3399_tsadc_data = {
990}; 1028};
991 1029
992static const struct of_device_id of_rockchip_thermal_match[] = { 1030static const struct of_device_id of_rockchip_thermal_match[] = {
1031 { .compatible = "rockchip,px30-tsadc",
1032 .data = (void *)&px30_tsadc_data,
1033 },
993 { 1034 {
994 .compatible = "rockchip,rv1108-tsadc", 1035 .compatible = "rockchip,rv1108-tsadc",
995 .data = (void *)&rv1108_tsadc_data, 1036 .data = (void *)&rv1108_tsadc_data,
@@ -1242,6 +1283,8 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
1242 return error; 1283 return error;
1243 } 1284 }
1244 1285
1286 thermal->chip->control(thermal->regs, false);
1287
1245 error = clk_prepare_enable(thermal->clk); 1288 error = clk_prepare_enable(thermal->clk);
1246 if (error) { 1289 if (error) {
1247 dev_err(&pdev->dev, "failed to enable converter clock: %d\n", 1290 dev_err(&pdev->dev, "failed to enable converter clock: %d\n",
@@ -1267,6 +1310,30 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
1267 thermal->chip->initialize(thermal->grf, thermal->regs, 1310 thermal->chip->initialize(thermal->grf, thermal->regs,
1268 thermal->tshut_polarity); 1311 thermal->tshut_polarity);
1269 1312
1313 if (thermal->tshut_mode == TSHUT_MODE_GPIO) {
1314 thermal->pinctrl = devm_pinctrl_get(&pdev->dev);
1315 if (IS_ERR(thermal->pinctrl)) {
1316 dev_err(&pdev->dev, "failed to find thermal pinctrl\n");
1317 return PTR_ERR(thermal->pinctrl);
1318 }
1319
1320 thermal->gpio_state = pinctrl_lookup_state(thermal->pinctrl,
1321 "gpio");
1322 if (IS_ERR_OR_NULL(thermal->gpio_state)) {
1323 dev_err(&pdev->dev, "failed to find thermal gpio state\n");
1324 return -EINVAL;
1325 }
1326
1327 thermal->otp_state = pinctrl_lookup_state(thermal->pinctrl,
1328 "otpout");
1329 if (IS_ERR_OR_NULL(thermal->otp_state)) {
1330 dev_err(&pdev->dev, "failed to find thermal otpout state\n");
1331 return -EINVAL;
1332 }
1333
1334 pinctrl_select_state(thermal->pinctrl, thermal->otp_state);
1335 }
1336
1270 for (i = 0; i < thermal->chip->chn_num; i++) { 1337 for (i = 0; i < thermal->chip->chn_num; i++) {
1271 error = rockchip_thermal_register_sensor(pdev, thermal, 1338 error = rockchip_thermal_register_sensor(pdev, thermal,
1272 &thermal->sensors[i], 1339 &thermal->sensors[i],
@@ -1337,8 +1404,8 @@ static int __maybe_unused rockchip_thermal_suspend(struct device *dev)
1337 1404
1338 clk_disable(thermal->pclk); 1405 clk_disable(thermal->pclk);
1339 clk_disable(thermal->clk); 1406 clk_disable(thermal->clk);
1340 1407 if (thermal->tshut_mode == TSHUT_MODE_GPIO)
1341 pinctrl_pm_select_sleep_state(dev); 1408 pinctrl_select_state(thermal->pinctrl, thermal->gpio_state);
1342 1409
1343 return 0; 1410 return 0;
1344} 1411}
@@ -1383,7 +1450,8 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
1383 for (i = 0; i < thermal->chip->chn_num; i++) 1450 for (i = 0; i < thermal->chip->chn_num; i++)
1384 rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); 1451 rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
1385 1452
1386 pinctrl_pm_select_default_state(dev); 1453 if (thermal->tshut_mode == TSHUT_MODE_GPIO)
1454 pinctrl_select_state(thermal->pinctrl, thermal->otp_state);
1387 1455
1388 return 0; 1456 return 0;
1389} 1457}
diff --git a/drivers/thermal/st/Kconfig b/drivers/thermal/st/Kconfig
index b80f9a9e4f8f..d8b1a4586d0b 100644
--- a/drivers/thermal/st/Kconfig
+++ b/drivers/thermal/st/Kconfig
@@ -3,9 +3,9 @@
3# 3#
4 4
5config ST_THERMAL 5config ST_THERMAL
6 tristate "Thermal sensors on STMicroelectronics STi series of SoCs" 6 tristate "Thermal sensors on STMicroelectronics STi series of SoCs"
7 help 7 help
8 Support for thermal sensors on STMicroelectronics STi series of SoCs. 8 Support for thermal sensors on STMicroelectronics STi series of SoCs.
9 9
10config ST_THERMAL_SYSCFG 10config ST_THERMAL_SYSCFG
11 select ST_THERMAL 11 select ST_THERMAL
@@ -16,11 +16,11 @@ config ST_THERMAL_MEMMAP
16 tristate "STi series memory mapped access based thermal sensors" 16 tristate "STi series memory mapped access based thermal sensors"
17 17
18config STM32_THERMAL 18config STM32_THERMAL
19 tristate "Thermal framework support on STMicroelectronics STM32 series of SoCs" 19 tristate "Thermal framework support on STMicroelectronics STM32 series of SoCs"
20 depends on MACH_STM32MP157 20 depends on MACH_STM32MP157
21 default y 21 default y
22 help 22 help
23 Support for thermal framework on STMicroelectronics STM32 series of 23 Support for thermal framework on STMicroelectronics STM32 series of
24 SoCs. This thermal driver allows to access to general thermal framework 24 SoCs. This thermal driver allows to access to general thermal framework
25 functionalities and to acces to SoC sensor functionalities. This 25 functionalities and to acces to SoC sensor functionalities. This
26 configuration is fully dependent of MACH_STM32MP157. 26 configuration is fully dependent of MACH_STM32MP157.
diff --git a/drivers/thermal/st/stm_thermal.c b/drivers/thermal/st/stm_thermal.c
index bbd73c5a4a4e..cf9ddc52f30e 100644
--- a/drivers/thermal/st/stm_thermal.c
+++ b/drivers/thermal/st/stm_thermal.c
@@ -570,8 +570,7 @@ thermal_unprepare:
570static int stm_thermal_suspend(struct device *dev) 570static int stm_thermal_suspend(struct device *dev)
571{ 571{
572 int ret; 572 int ret;
573 struct platform_device *pdev = to_platform_device(dev); 573 struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
574 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
575 574
576 ret = stm_thermal_sensor_off(sensor); 575 ret = stm_thermal_sensor_off(sensor);
577 if (ret) 576 if (ret)
@@ -585,8 +584,7 @@ static int stm_thermal_suspend(struct device *dev)
585static int stm_thermal_resume(struct device *dev) 584static int stm_thermal_resume(struct device *dev)
586{ 585{
587 int ret; 586 int ret;
588 struct platform_device *pdev = to_platform_device(dev); 587 struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
589 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
590 588
591 ret = stm_thermal_prepare(sensor); 589 ret = stm_thermal_prepare(sensor);
592 if (ret) 590 if (ret)
diff --git a/drivers/thermal/tegra/Kconfig b/drivers/thermal/tegra/Kconfig
index f8740f7852e3..fc0b33b3f26b 100644
--- a/drivers/thermal/tegra/Kconfig
+++ b/drivers/thermal/tegra/Kconfig
@@ -14,7 +14,7 @@ config TEGRA_BPMP_THERMAL
14 tristate "Tegra BPMP thermal sensing" 14 tristate "Tegra BPMP thermal sensing"
15 depends on TEGRA_BPMP || COMPILE_TEST 15 depends on TEGRA_BPMP || COMPILE_TEST
16 help 16 help
17 Enable this option for support for sensing system temperature of NVIDIA 17 Enable this option for support for sensing system temperature of NVIDIA
18 Tegra systems-on-chip with the BPMP coprocessor (Tegra186). 18 Tegra systems-on-chip with the BPMP coprocessor (Tegra186).
19 19
20endmenu 20endmenu
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index 70043a28eb7a..fcf70a3728b6 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -1,5 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. 3 * Copyright (c) 2014 - 2018, NVIDIA CORPORATION. All rights reserved.
3 * 4 *
4 * Author: 5 * Author:
5 * Mikko Perttunen <mperttunen@nvidia.com> 6 * Mikko Perttunen <mperttunen@nvidia.com>
@@ -22,6 +23,8 @@
22#include <linux/err.h> 23#include <linux/err.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
24#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/irq.h>
27#include <linux/irqdomain.h>
25#include <linux/module.h> 28#include <linux/module.h>
26#include <linux/of.h> 29#include <linux/of.h>
27#include <linux/platform_device.h> 30#include <linux/platform_device.h>
@@ -85,12 +88,51 @@
85#define THERMCTL_LVL0_UP_STATS 0x10 88#define THERMCTL_LVL0_UP_STATS 0x10
86#define THERMCTL_LVL0_DN_STATS 0x14 89#define THERMCTL_LVL0_DN_STATS 0x14
87 90
91#define THERMCTL_INTR_STATUS 0x84
92
93#define TH_INTR_MD0_MASK BIT(25)
94#define TH_INTR_MU0_MASK BIT(24)
95#define TH_INTR_GD0_MASK BIT(17)
96#define TH_INTR_GU0_MASK BIT(16)
97#define TH_INTR_CD0_MASK BIT(9)
98#define TH_INTR_CU0_MASK BIT(8)
99#define TH_INTR_PD0_MASK BIT(1)
100#define TH_INTR_PU0_MASK BIT(0)
101#define TH_INTR_IGNORE_MASK 0xFCFCFCFC
102
88#define THERMCTL_STATS_CTL 0x94 103#define THERMCTL_STATS_CTL 0x94
89#define STATS_CTL_CLR_DN 0x8 104#define STATS_CTL_CLR_DN 0x8
90#define STATS_CTL_EN_DN 0x4 105#define STATS_CTL_EN_DN 0x4
91#define STATS_CTL_CLR_UP 0x2 106#define STATS_CTL_CLR_UP 0x2
92#define STATS_CTL_EN_UP 0x1 107#define STATS_CTL_EN_UP 0x1
93 108
109#define OC1_CFG 0x310
110#define OC1_CFG_LONG_LATENCY_MASK BIT(6)
111#define OC1_CFG_HW_RESTORE_MASK BIT(5)
112#define OC1_CFG_PWR_GOOD_MASK_MASK BIT(4)
113#define OC1_CFG_THROTTLE_MODE_MASK (0x3 << 2)
114#define OC1_CFG_ALARM_POLARITY_MASK BIT(1)
115#define OC1_CFG_EN_THROTTLE_MASK BIT(0)
116
117#define OC1_CNT_THRESHOLD 0x314
118#define OC1_THROTTLE_PERIOD 0x318
119#define OC1_ALARM_COUNT 0x31c
120#define OC1_FILTER 0x320
121#define OC1_STATS 0x3a8
122
123#define OC_INTR_STATUS 0x39c
124#define OC_INTR_ENABLE 0x3a0
125#define OC_INTR_DISABLE 0x3a4
126#define OC_STATS_CTL 0x3c4
127#define OC_STATS_CTL_CLR_ALL 0x2
128#define OC_STATS_CTL_EN_ALL 0x1
129
130#define OC_INTR_OC1_MASK BIT(0)
131#define OC_INTR_OC2_MASK BIT(1)
132#define OC_INTR_OC3_MASK BIT(2)
133#define OC_INTR_OC4_MASK BIT(3)
134#define OC_INTR_OC5_MASK BIT(4)
135
94#define THROT_GLOBAL_CFG 0x400 136#define THROT_GLOBAL_CFG 0x400
95#define THROT_GLOBAL_ENB_MASK BIT(0) 137#define THROT_GLOBAL_ENB_MASK BIT(0)
96 138
@@ -160,6 +202,15 @@
160/* get dividend from the depth */ 202/* get dividend from the depth */
161#define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1) 203#define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1)
162 204
205/* gk20a nv_therm interface N:3 Mapping. Levels defined in tegra124-sochterm.h
206 * level vector
207 * NONE 3'b000
208 * LOW 3'b001
209 * MED 3'b011
210 * HIGH 3'b111
211 */
212#define THROT_LEVEL_TO_DEPTH(level) ((0x1 << (level)) - 1)
213
163/* get THROT_PSKIP_xxx offset per LIGHT/HEAVY throt and CPU/GPU dev */ 214/* get THROT_PSKIP_xxx offset per LIGHT/HEAVY throt and CPU/GPU dev */
164#define THROT_OFFSET 0x30 215#define THROT_OFFSET 0x30
165#define THROT_PSKIP_CTRL(throt, dev) (THROT_PSKIP_CTRL_LITE_CPU + \ 216#define THROT_PSKIP_CTRL(throt, dev) (THROT_PSKIP_CTRL_LITE_CPU + \
@@ -173,6 +224,25 @@
173#define THROT_DELAY_CTRL(throt) (THROT_DELAY_LITE + \ 224#define THROT_DELAY_CTRL(throt) (THROT_DELAY_LITE + \
174 (THROT_OFFSET * throt)) 225 (THROT_OFFSET * throt))
175 226
227#define ALARM_OFFSET 0x14
228#define ALARM_CFG(throt) (OC1_CFG + \
229 (ALARM_OFFSET * (throt - THROTTLE_OC1)))
230
231#define ALARM_CNT_THRESHOLD(throt) (OC1_CNT_THRESHOLD + \
232 (ALARM_OFFSET * (throt - THROTTLE_OC1)))
233
234#define ALARM_THROTTLE_PERIOD(throt) (OC1_THROTTLE_PERIOD + \
235 (ALARM_OFFSET * (throt - THROTTLE_OC1)))
236
237#define ALARM_ALARM_COUNT(throt) (OC1_ALARM_COUNT + \
238 (ALARM_OFFSET * (throt - THROTTLE_OC1)))
239
240#define ALARM_FILTER(throt) (OC1_FILTER + \
241 (ALARM_OFFSET * (throt - THROTTLE_OC1)))
242
243#define ALARM_STATS(throt) (OC1_STATS + \
244 (4 * (throt - THROTTLE_OC1)))
245
176/* get CCROC_THROT_PSKIP_xxx offset per HIGH/MED/LOW vect*/ 246/* get CCROC_THROT_PSKIP_xxx offset per HIGH/MED/LOW vect*/
177#define CCROC_THROT_OFFSET 0x0c 247#define CCROC_THROT_OFFSET 0x0c
178#define CCROC_THROT_PSKIP_CTRL_CPU_REG(vect) (CCROC_THROT_PSKIP_CTRL_CPU + \ 248#define CCROC_THROT_PSKIP_CTRL_CPU_REG(vect) (CCROC_THROT_PSKIP_CTRL_CPU + \
@@ -184,15 +254,32 @@
184#define THERMCTL_LVL_REGS_SIZE 0x20 254#define THERMCTL_LVL_REGS_SIZE 0x20
185#define THERMCTL_LVL_REG(rg, lv) ((rg) + ((lv) * THERMCTL_LVL_REGS_SIZE)) 255#define THERMCTL_LVL_REG(rg, lv) ((rg) + ((lv) * THERMCTL_LVL_REGS_SIZE))
186 256
257#define OC_THROTTLE_MODE_DISABLED 0
258#define OC_THROTTLE_MODE_BRIEF 2
259
187static const int min_low_temp = -127000; 260static const int min_low_temp = -127000;
188static const int max_high_temp = 127000; 261static const int max_high_temp = 127000;
189 262
190enum soctherm_throttle_id { 263enum soctherm_throttle_id {
191 THROTTLE_LIGHT = 0, 264 THROTTLE_LIGHT = 0,
192 THROTTLE_HEAVY, 265 THROTTLE_HEAVY,
266 THROTTLE_OC1,
267 THROTTLE_OC2,
268 THROTTLE_OC3,
269 THROTTLE_OC4,
270 THROTTLE_OC5, /* OC5 is reserved */
193 THROTTLE_SIZE, 271 THROTTLE_SIZE,
194}; 272};
195 273
274enum soctherm_oc_irq_id {
275 TEGRA_SOC_OC_IRQ_1,
276 TEGRA_SOC_OC_IRQ_2,
277 TEGRA_SOC_OC_IRQ_3,
278 TEGRA_SOC_OC_IRQ_4,
279 TEGRA_SOC_OC_IRQ_5,
280 TEGRA_SOC_OC_IRQ_MAX,
281};
282
196enum soctherm_throttle_dev_id { 283enum soctherm_throttle_dev_id {
197 THROTTLE_DEV_CPU = 0, 284 THROTTLE_DEV_CPU = 0,
198 THROTTLE_DEV_GPU, 285 THROTTLE_DEV_GPU,
@@ -202,6 +289,11 @@ enum soctherm_throttle_dev_id {
202static const char *const throt_names[] = { 289static const char *const throt_names[] = {
203 [THROTTLE_LIGHT] = "light", 290 [THROTTLE_LIGHT] = "light",
204 [THROTTLE_HEAVY] = "heavy", 291 [THROTTLE_HEAVY] = "heavy",
292 [THROTTLE_OC1] = "oc1",
293 [THROTTLE_OC2] = "oc2",
294 [THROTTLE_OC3] = "oc3",
295 [THROTTLE_OC4] = "oc4",
296 [THROTTLE_OC5] = "oc5",
205}; 297};
206 298
207struct tegra_soctherm; 299struct tegra_soctherm;
@@ -213,12 +305,23 @@ struct tegra_thermctl_zone {
213 const struct tegra_tsensor_group *sg; 305 const struct tegra_tsensor_group *sg;
214}; 306};
215 307
308struct soctherm_oc_cfg {
309 u32 active_low;
310 u32 throt_period;
311 u32 alarm_cnt_thresh;
312 u32 alarm_filter;
313 u32 mode;
314 bool intr_en;
315};
316
216struct soctherm_throt_cfg { 317struct soctherm_throt_cfg {
217 const char *name; 318 const char *name;
218 unsigned int id; 319 unsigned int id;
219 u8 priority; 320 u8 priority;
220 u8 cpu_throt_level; 321 u8 cpu_throt_level;
221 u32 cpu_throt_depth; 322 u32 cpu_throt_depth;
323 u32 gpu_throt_level;
324 struct soctherm_oc_cfg oc_cfg;
222 struct thermal_cooling_device *cdev; 325 struct thermal_cooling_device *cdev;
223 bool init; 326 bool init;
224}; 327};
@@ -231,6 +334,9 @@ struct tegra_soctherm {
231 void __iomem *clk_regs; 334 void __iomem *clk_regs;
232 void __iomem *ccroc_regs; 335 void __iomem *ccroc_regs;
233 336
337 int thermal_irq;
338 int edp_irq;
339
234 u32 *calib; 340 u32 *calib;
235 struct thermal_zone_device **thermctl_tzs; 341 struct thermal_zone_device **thermctl_tzs;
236 struct tegra_soctherm_soc *soc; 342 struct tegra_soctherm_soc *soc;
@@ -238,8 +344,19 @@ struct tegra_soctherm {
238 struct soctherm_throt_cfg throt_cfgs[THROTTLE_SIZE]; 344 struct soctherm_throt_cfg throt_cfgs[THROTTLE_SIZE];
239 345
240 struct dentry *debugfs_dir; 346 struct dentry *debugfs_dir;
347
348 struct mutex thermctl_lock;
241}; 349};
242 350
351struct soctherm_oc_irq_chip_data {
352 struct mutex irq_lock; /* serialize OC IRQs */
353 struct irq_chip irq_chip;
354 struct irq_domain *domain;
355 int irq_enable;
356};
357
358static struct soctherm_oc_irq_chip_data soc_irq_cdata;
359
243/** 360/**
244 * ccroc_writel() - writes a value to a CCROC register 361 * ccroc_writel() - writes a value to a CCROC register
245 * @ts: pointer to a struct tegra_soctherm 362 * @ts: pointer to a struct tegra_soctherm
@@ -446,6 +563,24 @@ find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name)
446 return NULL; 563 return NULL;
447} 564}
448 565
566static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id)
567{
568 int i, temp = min_low_temp;
569 struct tsensor_group_thermtrips *tt = ts->soc->thermtrips;
570
571 if (id >= TEGRA124_SOCTHERM_SENSOR_NUM)
572 return temp;
573
574 if (tt) {
575 for (i = 0; i < ts->soc->num_ttgs; i++) {
576 if (tt[i].id == id)
577 return tt[i].temp;
578 }
579 }
580
581 return temp;
582}
583
449static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp) 584static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
450{ 585{
451 struct tegra_thermctl_zone *zone = data; 586 struct tegra_thermctl_zone *zone = data;
@@ -464,7 +599,16 @@ static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
464 return ret; 599 return ret;
465 600
466 if (type == THERMAL_TRIP_CRITICAL) { 601 if (type == THERMAL_TRIP_CRITICAL) {
467 return thermtrip_program(dev, sg, temp); 602 /*
603 * If thermtrips property is set in DT,
604 * doesn't need to program critical type trip to HW,
605 * if not, program critical trip to HW.
606 */
607 if (min_low_temp == tsensor_group_thermtrip_get(ts, sg->id))
608 return thermtrip_program(dev, sg, temp);
609 else
610 return 0;
611
468 } else if (type == THERMAL_TRIP_HOT) { 612 } else if (type == THERMAL_TRIP_HOT) {
469 int i; 613 int i;
470 614
@@ -519,10 +663,60 @@ static int tegra_thermctl_get_trend(void *data, int trip,
519 return 0; 663 return 0;
520} 664}
521 665
666static void thermal_irq_enable(struct tegra_thermctl_zone *zn)
667{
668 u32 r;
669
670 /* multiple zones could be handling and setting trips at once */
671 mutex_lock(&zn->ts->thermctl_lock);
672 r = readl(zn->ts->regs + THERMCTL_INTR_ENABLE);
673 r = REG_SET_MASK(r, zn->sg->thermctl_isr_mask, TH_INTR_UP_DN_EN);
674 writel(r, zn->ts->regs + THERMCTL_INTR_ENABLE);
675 mutex_unlock(&zn->ts->thermctl_lock);
676}
677
678static void thermal_irq_disable(struct tegra_thermctl_zone *zn)
679{
680 u32 r;
681
682 /* multiple zones could be handling and setting trips at once */
683 mutex_lock(&zn->ts->thermctl_lock);
684 r = readl(zn->ts->regs + THERMCTL_INTR_DISABLE);
685 r = REG_SET_MASK(r, zn->sg->thermctl_isr_mask, 0);
686 writel(r, zn->ts->regs + THERMCTL_INTR_DISABLE);
687 mutex_unlock(&zn->ts->thermctl_lock);
688}
689
690static int tegra_thermctl_set_trips(void *data, int lo, int hi)
691{
692 struct tegra_thermctl_zone *zone = data;
693 u32 r;
694
695 thermal_irq_disable(zone);
696
697 r = readl(zone->ts->regs + zone->sg->thermctl_lvl0_offset);
698 r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 0);
699 writel(r, zone->ts->regs + zone->sg->thermctl_lvl0_offset);
700
701 lo = enforce_temp_range(zone->dev, lo) / zone->ts->soc->thresh_grain;
702 hi = enforce_temp_range(zone->dev, hi) / zone->ts->soc->thresh_grain;
703 dev_dbg(zone->dev, "%s hi:%d, lo:%d\n", __func__, hi, lo);
704
705 r = REG_SET_MASK(r, zone->sg->thermctl_lvl0_up_thresh_mask, hi);
706 r = REG_SET_MASK(r, zone->sg->thermctl_lvl0_dn_thresh_mask, lo);
707 r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 1);
708 writel(r, zone->ts->regs + zone->sg->thermctl_lvl0_offset);
709
710 thermal_irq_enable(zone);
711
712 return 0;
713}
714
522static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = { 715static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
523 .get_temp = tegra_thermctl_get_temp, 716 .get_temp = tegra_thermctl_get_temp,
524 .set_trip_temp = tegra_thermctl_set_trip_temp, 717 .set_trip_temp = tegra_thermctl_set_trip_temp,
525 .get_trend = tegra_thermctl_get_trend, 718 .get_trend = tegra_thermctl_get_trend,
719 .set_trips = tegra_thermctl_set_trips,
526}; 720};
527 721
528static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp) 722static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
@@ -555,7 +749,8 @@ static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
555 * @dev: struct device * of the SOC_THERM instance 749 * @dev: struct device * of the SOC_THERM instance
556 * 750 *
557 * Configure the SOC_THERM HW trip points, setting "THERMTRIP" 751 * Configure the SOC_THERM HW trip points, setting "THERMTRIP"
558 * "THROTTLE" trip points , using "critical" or "hot" type trip_temp 752 * "THROTTLE" trip points , using "thermtrips", "critical" or "hot"
753 * type trip_temp
559 * from thermal zone. 754 * from thermal zone.
560 * After they have been configured, THERMTRIP or THROTTLE will take 755 * After they have been configured, THERMTRIP or THROTTLE will take
561 * action when the configured SoC thermal sensor group reaches a 756 * action when the configured SoC thermal sensor group reaches a
@@ -577,28 +772,23 @@ static int tegra_soctherm_set_hwtrips(struct device *dev,
577{ 772{
578 struct tegra_soctherm *ts = dev_get_drvdata(dev); 773 struct tegra_soctherm *ts = dev_get_drvdata(dev);
579 struct soctherm_throt_cfg *stc; 774 struct soctherm_throt_cfg *stc;
580 int i, trip, temperature; 775 int i, trip, temperature, ret;
581 int ret;
582 776
583 ret = tz->ops->get_crit_temp(tz, &temperature); 777 /* Get thermtrips. If missing, try to get critical trips. */
584 if (ret) { 778 temperature = tsensor_group_thermtrip_get(ts, sg->id);
585 dev_warn(dev, "thermtrip: %s: missing critical temperature\n", 779 if (min_low_temp == temperature)
586 sg->name); 780 if (tz->ops->get_crit_temp(tz, &temperature))
587 goto set_throttle; 781 temperature = max_high_temp;
588 }
589 782
590 ret = thermtrip_program(dev, sg, temperature); 783 ret = thermtrip_program(dev, sg, temperature);
591 if (ret) { 784 if (ret) {
592 dev_err(dev, "thermtrip: %s: error during enable\n", 785 dev_err(dev, "thermtrip: %s: error during enable\n", sg->name);
593 sg->name);
594 return ret; 786 return ret;
595 } 787 }
596 788
597 dev_info(dev, 789 dev_info(dev, "thermtrip: will shut down when %s reaches %d mC\n",
598 "thermtrip: will shut down when %s reaches %d mC\n",
599 sg->name, temperature); 790 sg->name, temperature);
600 791
601set_throttle:
602 ret = get_hot_temp(tz, &trip, &temperature); 792 ret = get_hot_temp(tz, &trip, &temperature);
603 if (ret) { 793 if (ret) {
604 dev_info(dev, "throttrip: %s: missing hot temperature\n", 794 dev_info(dev, "throttrip: %s: missing hot temperature\n",
@@ -606,7 +796,7 @@ set_throttle:
606 return 0; 796 return 0;
607 } 797 }
608 798
609 for (i = 0; i < THROTTLE_SIZE; i++) { 799 for (i = 0; i < THROTTLE_OC1; i++) {
610 struct thermal_cooling_device *cdev; 800 struct thermal_cooling_device *cdev;
611 801
612 if (!ts->throt_cfgs[i].init) 802 if (!ts->throt_cfgs[i].init)
@@ -638,6 +828,461 @@ set_throttle:
638 return 0; 828 return 0;
639} 829}
640 830
831static irqreturn_t soctherm_thermal_isr(int irq, void *dev_id)
832{
833 struct tegra_soctherm *ts = dev_id;
834 u32 r;
835
836 /* Case for no lock:
837 * Although interrupts are enabled in set_trips, there is still no need
838 * to lock here because the interrupts are disabled before programming
839 * new trip points. Hence there cant be a interrupt on the same sensor.
840 * An interrupt can however occur on a sensor while trips are being
841 * programmed on a different one. This beign a LEVEL interrupt won't
842 * cause a new interrupt but this is taken care of by the re-reading of
843 * the STATUS register in the thread function.
844 */
845 r = readl(ts->regs + THERMCTL_INTR_STATUS);
846 writel(r, ts->regs + THERMCTL_INTR_DISABLE);
847
848 return IRQ_WAKE_THREAD;
849}
850
851/**
852 * soctherm_thermal_isr_thread() - Handles a thermal interrupt request
853 * @irq: The interrupt number being requested; not used
854 * @dev_id: Opaque pointer to tegra_soctherm;
855 *
856 * Clears the interrupt status register if there are expected
857 * interrupt bits set.
858 * The interrupt(s) are then handled by updating the corresponding
859 * thermal zones.
860 *
861 * An error is logged if any unexpected interrupt bits are set.
862 *
863 * Disabled interrupts are re-enabled.
864 *
865 * Return: %IRQ_HANDLED. Interrupt was handled and no further processing
866 * is needed.
867 */
868static irqreturn_t soctherm_thermal_isr_thread(int irq, void *dev_id)
869{
870 struct tegra_soctherm *ts = dev_id;
871 struct thermal_zone_device *tz;
872 u32 st, ex = 0, cp = 0, gp = 0, pl = 0, me = 0;
873
874 st = readl(ts->regs + THERMCTL_INTR_STATUS);
875
876 /* deliberately clear expected interrupts handled in SW */
877 cp |= st & TH_INTR_CD0_MASK;
878 cp |= st & TH_INTR_CU0_MASK;
879
880 gp |= st & TH_INTR_GD0_MASK;
881 gp |= st & TH_INTR_GU0_MASK;
882
883 pl |= st & TH_INTR_PD0_MASK;
884 pl |= st & TH_INTR_PU0_MASK;
885
886 me |= st & TH_INTR_MD0_MASK;
887 me |= st & TH_INTR_MU0_MASK;
888
889 ex |= cp | gp | pl | me;
890 if (ex) {
891 writel(ex, ts->regs + THERMCTL_INTR_STATUS);
892 st &= ~ex;
893
894 if (cp) {
895 tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_CPU];
896 thermal_zone_device_update(tz,
897 THERMAL_EVENT_UNSPECIFIED);
898 }
899
900 if (gp) {
901 tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_GPU];
902 thermal_zone_device_update(tz,
903 THERMAL_EVENT_UNSPECIFIED);
904 }
905
906 if (pl) {
907 tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_PLLX];
908 thermal_zone_device_update(tz,
909 THERMAL_EVENT_UNSPECIFIED);
910 }
911
912 if (me) {
913 tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_MEM];
914 thermal_zone_device_update(tz,
915 THERMAL_EVENT_UNSPECIFIED);
916 }
917 }
918
919 /* deliberately ignore expected interrupts NOT handled in SW */
920 ex |= TH_INTR_IGNORE_MASK;
921 st &= ~ex;
922
923 if (st) {
924 /* Whine about any other unexpected INTR bits still set */
925 pr_err("soctherm: Ignored unexpected INTRs 0x%08x\n", st);
926 writel(st, ts->regs + THERMCTL_INTR_STATUS);
927 }
928
929 return IRQ_HANDLED;
930}
931
932/**
933 * soctherm_oc_intr_enable() - Enables the soctherm over-current interrupt
934 * @alarm: The soctherm throttle id
935 * @enable: Flag indicating enable the soctherm over-current
936 * interrupt or disable it
937 *
938 * Enables a specific over-current pins @alarm to raise an interrupt if the flag
939 * is set and the alarm corresponds to OC1, OC2, OC3, or OC4.
940 */
941static void soctherm_oc_intr_enable(struct tegra_soctherm *ts,
942 enum soctherm_throttle_id alarm,
943 bool enable)
944{
945 u32 r;
946
947 if (!enable)
948 return;
949
950 r = readl(ts->regs + OC_INTR_ENABLE);
951 switch (alarm) {
952 case THROTTLE_OC1:
953 r = REG_SET_MASK(r, OC_INTR_OC1_MASK, 1);
954 break;
955 case THROTTLE_OC2:
956 r = REG_SET_MASK(r, OC_INTR_OC2_MASK, 1);
957 break;
958 case THROTTLE_OC3:
959 r = REG_SET_MASK(r, OC_INTR_OC3_MASK, 1);
960 break;
961 case THROTTLE_OC4:
962 r = REG_SET_MASK(r, OC_INTR_OC4_MASK, 1);
963 break;
964 default:
965 r = 0;
966 break;
967 }
968 writel(r, ts->regs + OC_INTR_ENABLE);
969}
970
971/**
972 * soctherm_handle_alarm() - Handles soctherm alarms
973 * @alarm: The soctherm throttle id
974 *
975 * "Handles" over-current alarms (OC1, OC2, OC3, and OC4) by printing
976 * a warning or informative message.
977 *
978 * Return: -EINVAL for @alarm = THROTTLE_OC3, otherwise 0 (success).
979 */
980static int soctherm_handle_alarm(enum soctherm_throttle_id alarm)
981{
982 int rv = -EINVAL;
983
984 switch (alarm) {
985 case THROTTLE_OC1:
986 pr_debug("soctherm: Successfully handled OC1 alarm\n");
987 rv = 0;
988 break;
989
990 case THROTTLE_OC2:
991 pr_debug("soctherm: Successfully handled OC2 alarm\n");
992 rv = 0;
993 break;
994
995 case THROTTLE_OC3:
996 pr_debug("soctherm: Successfully handled OC3 alarm\n");
997 rv = 0;
998 break;
999
1000 case THROTTLE_OC4:
1001 pr_debug("soctherm: Successfully handled OC4 alarm\n");
1002 rv = 0;
1003 break;
1004
1005 default:
1006 break;
1007 }
1008
1009 if (rv)
1010 pr_err("soctherm: ERROR in handling %s alarm\n",
1011 throt_names[alarm]);
1012
1013 return rv;
1014}
1015
1016/**
1017 * soctherm_edp_isr_thread() - log an over-current interrupt request
1018 * @irq: OC irq number. Currently not being used. See description
1019 * @arg: a void pointer for callback, currently not being used
1020 *
1021 * Over-current events are handled in hardware. This function is called to log
1022 * and handle any OC events that happened. Additionally, it checks every
1023 * over-current interrupt registers for registers are set but
1024 * was not expected (i.e. any discrepancy in interrupt status) by the function,
1025 * the discrepancy will logged.
1026 *
1027 * Return: %IRQ_HANDLED
1028 */
1029static irqreturn_t soctherm_edp_isr_thread(int irq, void *arg)
1030{
1031 struct tegra_soctherm *ts = arg;
1032 u32 st, ex, oc1, oc2, oc3, oc4;
1033
1034 st = readl(ts->regs + OC_INTR_STATUS);
1035
1036 /* deliberately clear expected interrupts handled in SW */
1037 oc1 = st & OC_INTR_OC1_MASK;
1038 oc2 = st & OC_INTR_OC2_MASK;
1039 oc3 = st & OC_INTR_OC3_MASK;
1040 oc4 = st & OC_INTR_OC4_MASK;
1041 ex = oc1 | oc2 | oc3 | oc4;
1042
1043 pr_err("soctherm: OC ALARM 0x%08x\n", ex);
1044 if (ex) {
1045 writel(st, ts->regs + OC_INTR_STATUS);
1046 st &= ~ex;
1047
1048 if (oc1 && !soctherm_handle_alarm(THROTTLE_OC1))
1049 soctherm_oc_intr_enable(ts, THROTTLE_OC1, true);
1050
1051 if (oc2 && !soctherm_handle_alarm(THROTTLE_OC2))
1052 soctherm_oc_intr_enable(ts, THROTTLE_OC2, true);
1053
1054 if (oc3 && !soctherm_handle_alarm(THROTTLE_OC3))
1055 soctherm_oc_intr_enable(ts, THROTTLE_OC3, true);
1056
1057 if (oc4 && !soctherm_handle_alarm(THROTTLE_OC4))
1058 soctherm_oc_intr_enable(ts, THROTTLE_OC4, true);
1059
1060 if (oc1 && soc_irq_cdata.irq_enable & BIT(0))
1061 handle_nested_irq(
1062 irq_find_mapping(soc_irq_cdata.domain, 0));
1063
1064 if (oc2 && soc_irq_cdata.irq_enable & BIT(1))
1065 handle_nested_irq(
1066 irq_find_mapping(soc_irq_cdata.domain, 1));
1067
1068 if (oc3 && soc_irq_cdata.irq_enable & BIT(2))
1069 handle_nested_irq(
1070 irq_find_mapping(soc_irq_cdata.domain, 2));
1071
1072 if (oc4 && soc_irq_cdata.irq_enable & BIT(3))
1073 handle_nested_irq(
1074 irq_find_mapping(soc_irq_cdata.domain, 3));
1075 }
1076
1077 if (st) {
1078 pr_err("soctherm: Ignored unexpected OC ALARM 0x%08x\n", st);
1079 writel(st, ts->regs + OC_INTR_STATUS);
1080 }
1081
1082 return IRQ_HANDLED;
1083}
1084
1085/**
1086 * soctherm_edp_isr() - Disables any active interrupts
1087 * @irq: The interrupt request number
1088 * @arg: Opaque pointer to an argument
1089 *
1090 * Writes to the OC_INTR_DISABLE register the over current interrupt status,
1091 * masking any asserted interrupts. Doing this prevents the same interrupts
1092 * from triggering this isr repeatedly. The thread woken by this isr will
1093 * handle asserted interrupts and subsequently unmask/re-enable them.
1094 *
1095 * The OC_INTR_DISABLE register indicates which OC interrupts
1096 * have been disabled.
1097 *
1098 * Return: %IRQ_WAKE_THREAD, handler requests to wake the handler thread
1099 */
1100static irqreturn_t soctherm_edp_isr(int irq, void *arg)
1101{
1102 struct tegra_soctherm *ts = arg;
1103 u32 r;
1104
1105 if (!ts)
1106 return IRQ_NONE;
1107
1108 r = readl(ts->regs + OC_INTR_STATUS);
1109 writel(r, ts->regs + OC_INTR_DISABLE);
1110
1111 return IRQ_WAKE_THREAD;
1112}
1113
1114/**
1115 * soctherm_oc_irq_lock() - locks the over-current interrupt request
1116 * @data: Interrupt request data
1117 *
1118 * Looks up the chip data from @data and locks the mutex associated with
1119 * a particular over-current interrupt request.
1120 */
1121static void soctherm_oc_irq_lock(struct irq_data *data)
1122{
1123 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
1124
1125 mutex_lock(&d->irq_lock);
1126}
1127
1128/**
1129 * soctherm_oc_irq_sync_unlock() - Unlocks the OC interrupt request
1130 * @data: Interrupt request data
1131 *
1132 * Looks up the interrupt request data @data and unlocks the mutex associated
1133 * with a particular over-current interrupt request.
1134 */
1135static void soctherm_oc_irq_sync_unlock(struct irq_data *data)
1136{
1137 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
1138
1139 mutex_unlock(&d->irq_lock);
1140}
1141
1142/**
1143 * soctherm_oc_irq_enable() - Enables the SOC_THERM over-current interrupt queue
1144 * @data: irq_data structure of the chip
1145 *
1146 * Sets the irq_enable bit of SOC_THERM allowing SOC_THERM
1147 * to respond to over-current interrupts.
1148 *
1149 */
1150static void soctherm_oc_irq_enable(struct irq_data *data)
1151{
1152 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
1153
1154 d->irq_enable |= BIT(data->hwirq);
1155}
1156
1157/**
1158 * soctherm_oc_irq_disable() - Disables overcurrent interrupt requests
1159 * @irq_data: The interrupt request information
1160 *
1161 * Clears the interrupt request enable bit of the overcurrent
1162 * interrupt request chip data.
1163 *
1164 * Return: Nothing is returned (void)
1165 */
1166static void soctherm_oc_irq_disable(struct irq_data *data)
1167{
1168 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
1169
1170 d->irq_enable &= ~BIT(data->hwirq);
1171}
1172
1173static int soctherm_oc_irq_set_type(struct irq_data *data, unsigned int type)
1174{
1175 return 0;
1176}
1177
1178/**
1179 * soctherm_oc_irq_map() - SOC_THERM interrupt request domain mapper
1180 * @h: Interrupt request domain
1181 * @virq: Virtual interrupt request number
1182 * @hw: Hardware interrupt request number
1183 *
1184 * Mapping callback function for SOC_THERM's irq_domain. When a SOC_THERM
1185 * interrupt request is called, the irq_domain takes the request's virtual
1186 * request number (much like a virtual memory address) and maps it to a
1187 * physical hardware request number.
1188 *
1189 * When a mapping doesn't already exist for a virtual request number, the
1190 * irq_domain calls this function to associate the virtual request number with
1191 * a hardware request number.
1192 *
1193 * Return: 0
1194 */
1195static int soctherm_oc_irq_map(struct irq_domain *h, unsigned int virq,
1196 irq_hw_number_t hw)
1197{
1198 struct soctherm_oc_irq_chip_data *data = h->host_data;
1199
1200 irq_set_chip_data(virq, data);
1201 irq_set_chip(virq, &data->irq_chip);
1202 irq_set_nested_thread(virq, 1);
1203 return 0;
1204}
1205
1206/**
1207 * soctherm_irq_domain_xlate_twocell() - xlate for soctherm interrupts
1208 * @d: Interrupt request domain
1209 * @intspec: Array of u32s from DTs "interrupt" property
1210 * @intsize: Number of values inside the intspec array
1211 * @out_hwirq: HW IRQ value associated with this interrupt
1212 * @out_type: The IRQ SENSE type for this interrupt.
1213 *
1214 * This Device Tree IRQ specifier translation function will translate a
1215 * specific "interrupt" as defined by 2 DT values where the cell values map
1216 * the hwirq number + 1 and linux irq flags. Since the output is the hwirq
1217 * number, this function will subtract 1 from the value listed in DT.
1218 *
1219 * Return: 0
1220 */
1221static int soctherm_irq_domain_xlate_twocell(struct irq_domain *d,
1222 struct device_node *ctrlr, const u32 *intspec, unsigned int intsize,
1223 irq_hw_number_t *out_hwirq, unsigned int *out_type)
1224{
1225 if (WARN_ON(intsize < 2))
1226 return -EINVAL;
1227
1228 /*
1229 * The HW value is 1 index less than the DT IRQ values.
1230 * i.e. OC4 goes to HW index 3.
1231 */
1232 *out_hwirq = intspec[0] - 1;
1233 *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
1234 return 0;
1235}
1236
1237static const struct irq_domain_ops soctherm_oc_domain_ops = {
1238 .map = soctherm_oc_irq_map,
1239 .xlate = soctherm_irq_domain_xlate_twocell,
1240};
1241
1242/**
1243 * soctherm_oc_int_init() - Initial enabling of the over
1244 * current interrupts
1245 * @np: The devicetree node for soctherm
1246 * @num_irqs: The number of new interrupt requests
1247 *
1248 * Sets the over current interrupt request chip data
1249 *
1250 * Return: 0 on success or if overcurrent interrupts are not enabled,
1251 * -ENOMEM (out of memory), or irq_base if the function failed to
1252 * allocate the irqs
1253 */
1254static int soctherm_oc_int_init(struct device_node *np, int num_irqs)
1255{
1256 if (!num_irqs) {
1257 pr_info("%s(): OC interrupts are not enabled\n", __func__);
1258 return 0;
1259 }
1260
1261 mutex_init(&soc_irq_cdata.irq_lock);
1262 soc_irq_cdata.irq_enable = 0;
1263
1264 soc_irq_cdata.irq_chip.name = "soc_therm_oc";
1265 soc_irq_cdata.irq_chip.irq_bus_lock = soctherm_oc_irq_lock;
1266 soc_irq_cdata.irq_chip.irq_bus_sync_unlock =
1267 soctherm_oc_irq_sync_unlock;
1268 soc_irq_cdata.irq_chip.irq_disable = soctherm_oc_irq_disable;
1269 soc_irq_cdata.irq_chip.irq_enable = soctherm_oc_irq_enable;
1270 soc_irq_cdata.irq_chip.irq_set_type = soctherm_oc_irq_set_type;
1271 soc_irq_cdata.irq_chip.irq_set_wake = NULL;
1272
1273 soc_irq_cdata.domain = irq_domain_add_linear(np, num_irqs,
1274 &soctherm_oc_domain_ops,
1275 &soc_irq_cdata);
1276
1277 if (!soc_irq_cdata.domain) {
1278 pr_err("%s: Failed to create IRQ domain\n", __func__);
1279 return -ENOMEM;
1280 }
1281
1282 pr_debug("%s(): OC interrupts enabled successful\n", __func__);
1283 return 0;
1284}
1285
641#ifdef CONFIG_DEBUG_FS 1286#ifdef CONFIG_DEBUG_FS
642static int regs_show(struct seq_file *s, void *data) 1287static int regs_show(struct seq_file *s, void *data)
643{ 1288{
@@ -929,6 +1574,120 @@ static const struct thermal_cooling_device_ops throt_cooling_ops = {
929 .set_cur_state = throt_set_cdev_state, 1574 .set_cur_state = throt_set_cdev_state,
930}; 1575};
931 1576
1577static int soctherm_thermtrips_parse(struct platform_device *pdev)
1578{
1579 struct device *dev = &pdev->dev;
1580 struct tegra_soctherm *ts = dev_get_drvdata(dev);
1581 struct tsensor_group_thermtrips *tt = ts->soc->thermtrips;
1582 const int max_num_prop = ts->soc->num_ttgs * 2;
1583 u32 *tlb;
1584 int i, j, n, ret;
1585
1586 if (!tt)
1587 return -ENOMEM;
1588
1589 n = of_property_count_u32_elems(dev->of_node, "nvidia,thermtrips");
1590 if (n <= 0) {
1591 dev_info(dev,
1592 "missing thermtrips, will use critical trips as shut down temp\n");
1593 return n;
1594 }
1595
1596 n = min(max_num_prop, n);
1597
1598 tlb = devm_kcalloc(&pdev->dev, max_num_prop, sizeof(u32), GFP_KERNEL);
1599 if (!tlb)
1600 return -ENOMEM;
1601 ret = of_property_read_u32_array(dev->of_node, "nvidia,thermtrips",
1602 tlb, n);
1603 if (ret) {
1604 dev_err(dev, "invalid num ele: thermtrips:%d\n", ret);
1605 return ret;
1606 }
1607
1608 i = 0;
1609 for (j = 0; j < n; j = j + 2) {
1610 if (tlb[j] >= TEGRA124_SOCTHERM_SENSOR_NUM)
1611 continue;
1612
1613 tt[i].id = tlb[j];
1614 tt[i].temp = tlb[j + 1];
1615 i++;
1616 }
1617
1618 return 0;
1619}
1620
1621static void soctherm_oc_cfg_parse(struct device *dev,
1622 struct device_node *np_oc,
1623 struct soctherm_throt_cfg *stc)
1624{
1625 u32 val;
1626
1627 if (of_property_read_bool(np_oc, "nvidia,polarity-active-low"))
1628 stc->oc_cfg.active_low = 1;
1629 else
1630 stc->oc_cfg.active_low = 0;
1631
1632 if (!of_property_read_u32(np_oc, "nvidia,count-threshold", &val)) {
1633 stc->oc_cfg.intr_en = 1;
1634 stc->oc_cfg.alarm_cnt_thresh = val;
1635 }
1636
1637 if (!of_property_read_u32(np_oc, "nvidia,throttle-period-us", &val))
1638 stc->oc_cfg.throt_period = val;
1639
1640 if (!of_property_read_u32(np_oc, "nvidia,alarm-filter", &val))
1641 stc->oc_cfg.alarm_filter = val;
1642
1643 /* BRIEF throttling by default, do not support STICKY */
1644 stc->oc_cfg.mode = OC_THROTTLE_MODE_BRIEF;
1645}
1646
1647static int soctherm_throt_cfg_parse(struct device *dev,
1648 struct device_node *np,
1649 struct soctherm_throt_cfg *stc)
1650{
1651 struct tegra_soctherm *ts = dev_get_drvdata(dev);
1652 int ret;
1653 u32 val;
1654
1655 ret = of_property_read_u32(np, "nvidia,priority", &val);
1656 if (ret) {
1657 dev_err(dev, "throttle-cfg: %s: invalid priority\n", stc->name);
1658 return -EINVAL;
1659 }
1660 stc->priority = val;
1661
1662 ret = of_property_read_u32(np, ts->soc->use_ccroc ?
1663 "nvidia,cpu-throt-level" :
1664 "nvidia,cpu-throt-percent", &val);
1665 if (!ret) {
1666 if (ts->soc->use_ccroc &&
1667 val <= TEGRA_SOCTHERM_THROT_LEVEL_HIGH)
1668 stc->cpu_throt_level = val;
1669 else if (!ts->soc->use_ccroc && val <= 100)
1670 stc->cpu_throt_depth = val;
1671 else
1672 goto err;
1673 } else {
1674 goto err;
1675 }
1676
1677 ret = of_property_read_u32(np, "nvidia,gpu-throt-level", &val);
1678 if (!ret && val <= TEGRA_SOCTHERM_THROT_LEVEL_HIGH)
1679 stc->gpu_throt_level = val;
1680 else
1681 goto err;
1682
1683 return 0;
1684
1685err:
1686 dev_err(dev, "throttle-cfg: %s: no throt prop or invalid prop\n",
1687 stc->name);
1688 return -EINVAL;
1689}
1690
932/** 1691/**
933 * soctherm_init_hw_throt_cdev() - Parse the HW throttle configurations 1692 * soctherm_init_hw_throt_cdev() - Parse the HW throttle configurations
934 * and register them as cooling devices. 1693 * and register them as cooling devices.
@@ -939,8 +1698,7 @@ static void soctherm_init_hw_throt_cdev(struct platform_device *pdev)
939 struct tegra_soctherm *ts = dev_get_drvdata(dev); 1698 struct tegra_soctherm *ts = dev_get_drvdata(dev);
940 struct device_node *np_stc, *np_stcc; 1699 struct device_node *np_stc, *np_stcc;
941 const char *name; 1700 const char *name;
942 u32 val; 1701 int i;
943 int i, r;
944 1702
945 for (i = 0; i < THROTTLE_SIZE; i++) { 1703 for (i = 0; i < THROTTLE_SIZE; i++) {
946 ts->throt_cfgs[i].name = throt_names[i]; 1704 ts->throt_cfgs[i].name = throt_names[i];
@@ -958,6 +1716,7 @@ static void soctherm_init_hw_throt_cdev(struct platform_device *pdev)
958 for_each_child_of_node(np_stc, np_stcc) { 1716 for_each_child_of_node(np_stc, np_stcc) {
959 struct soctherm_throt_cfg *stc; 1717 struct soctherm_throt_cfg *stc;
960 struct thermal_cooling_device *tcd; 1718 struct thermal_cooling_device *tcd;
1719 int err;
961 1720
962 name = np_stcc->name; 1721 name = np_stcc->name;
963 stc = find_throttle_cfg_by_name(ts, name); 1722 stc = find_throttle_cfg_by_name(ts, name);
@@ -967,51 +1726,34 @@ static void soctherm_init_hw_throt_cdev(struct platform_device *pdev)
967 continue; 1726 continue;
968 } 1727 }
969 1728
970 r = of_property_read_u32(np_stcc, "nvidia,priority", &val); 1729 if (stc->init) {
971 if (r) { 1730 dev_err(dev, "throttle-cfg: %s: redefined!\n", name);
972 dev_info(dev, 1731 of_node_put(np_stcc);
973 "throttle-cfg: %s: missing priority\n", name); 1732 break;
974 continue;
975 } 1733 }
976 stc->priority = val; 1734
977 1735 err = soctherm_throt_cfg_parse(dev, np_stcc, stc);
978 if (ts->soc->use_ccroc) { 1736 if (err)
979 r = of_property_read_u32(np_stcc, 1737 continue;
980 "nvidia,cpu-throt-level", 1738
981 &val); 1739 if (stc->id >= THROTTLE_OC1) {
982 if (r) { 1740 soctherm_oc_cfg_parse(dev, np_stcc, stc);
983 dev_info(dev, 1741 stc->init = true;
984 "throttle-cfg: %s: missing cpu-throt-level\n",
985 name);
986 continue;
987 }
988 stc->cpu_throt_level = val;
989 } else { 1742 } else {
990 r = of_property_read_u32(np_stcc,
991 "nvidia,cpu-throt-percent",
992 &val);
993 if (r) {
994 dev_info(dev,
995 "throttle-cfg: %s: missing cpu-throt-percent\n",
996 name);
997 continue;
998 }
999 stc->cpu_throt_depth = val;
1000 }
1001 1743
1002 tcd = thermal_of_cooling_device_register(np_stcc, 1744 tcd = thermal_of_cooling_device_register(np_stcc,
1003 (char *)name, ts, 1745 (char *)name, ts,
1004 &throt_cooling_ops); 1746 &throt_cooling_ops);
1005 of_node_put(np_stcc); 1747 if (IS_ERR_OR_NULL(tcd)) {
1006 if (IS_ERR_OR_NULL(tcd)) { 1748 dev_err(dev,
1007 dev_err(dev, 1749 "throttle-cfg: %s: failed to register cooling device\n",
1008 "throttle-cfg: %s: failed to register cooling device\n", 1750 name);
1009 name); 1751 continue;
1010 continue; 1752 }
1753 stc->cdev = tcd;
1754 stc->init = true;
1011 } 1755 }
1012 1756
1013 stc->cdev = tcd;
1014 stc->init = true;
1015 } 1757 }
1016 1758
1017 of_node_put(np_stc); 1759 of_node_put(np_stc);
@@ -1141,6 +1883,50 @@ static void throttlectl_cpu_mn(struct tegra_soctherm *ts,
1141} 1883}
1142 1884
1143/** 1885/**
1886 * throttlectl_gpu_level_select() - selects throttling level for GPU
1887 * @throt: the LIGHT/HEAVY of throttle event id
1888 *
1889 * This function programs soctherm's interface to GK20a NV_THERM to select
1890 * pre-configured "Low", "Medium" or "Heavy" throttle levels.
1891 *
1892 * Return: boolean true if HW was programmed
1893 */
1894static void throttlectl_gpu_level_select(struct tegra_soctherm *ts,
1895 enum soctherm_throttle_id throt)
1896{
1897 u32 r, level, throt_vect;
1898
1899 level = ts->throt_cfgs[throt].gpu_throt_level;
1900 throt_vect = THROT_LEVEL_TO_DEPTH(level);
1901 r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
1902 r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
1903 r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT_GPU_MASK, throt_vect);
1904 writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
1905}
1906
1907static int soctherm_oc_cfg_program(struct tegra_soctherm *ts,
1908 enum soctherm_throttle_id throt)
1909{
1910 u32 r;
1911 struct soctherm_oc_cfg *oc = &ts->throt_cfgs[throt].oc_cfg;
1912
1913 if (oc->mode == OC_THROTTLE_MODE_DISABLED)
1914 return -EINVAL;
1915
1916 r = REG_SET_MASK(0, OC1_CFG_HW_RESTORE_MASK, 1);
1917 r = REG_SET_MASK(r, OC1_CFG_THROTTLE_MODE_MASK, oc->mode);
1918 r = REG_SET_MASK(r, OC1_CFG_ALARM_POLARITY_MASK, oc->active_low);
1919 r = REG_SET_MASK(r, OC1_CFG_EN_THROTTLE_MASK, 1);
1920 writel(r, ts->regs + ALARM_CFG(throt));
1921 writel(oc->throt_period, ts->regs + ALARM_THROTTLE_PERIOD(throt));
1922 writel(oc->alarm_cnt_thresh, ts->regs + ALARM_CNT_THRESHOLD(throt));
1923 writel(oc->alarm_filter, ts->regs + ALARM_FILTER(throt));
1924 soctherm_oc_intr_enable(ts, throt, oc->intr_en);
1925
1926 return 0;
1927}
1928
1929/**
1144 * soctherm_throttle_program() - programs pulse skippers' configuration 1930 * soctherm_throttle_program() - programs pulse skippers' configuration
1145 * @throt: the LIGHT/HEAVY of the throttle event id. 1931 * @throt: the LIGHT/HEAVY of the throttle event id.
1146 * 1932 *
@@ -1156,12 +1942,17 @@ static void soctherm_throttle_program(struct tegra_soctherm *ts,
1156 if (!stc.init) 1942 if (!stc.init)
1157 return; 1943 return;
1158 1944
1945 if ((throt >= THROTTLE_OC1) && (soctherm_oc_cfg_program(ts, throt)))
1946 return;
1947
1159 /* Setup PSKIP parameters */ 1948 /* Setup PSKIP parameters */
1160 if (ts->soc->use_ccroc) 1949 if (ts->soc->use_ccroc)
1161 throttlectl_cpu_level_select(ts, throt); 1950 throttlectl_cpu_level_select(ts, throt);
1162 else 1951 else
1163 throttlectl_cpu_mn(ts, throt); 1952 throttlectl_cpu_mn(ts, throt);
1164 1953
1954 throttlectl_gpu_level_select(ts, throt);
1955
1165 r = REG_SET_MASK(0, THROT_PRIORITY_LITE_PRIO_MASK, stc.priority); 1956 r = REG_SET_MASK(0, THROT_PRIORITY_LITE_PRIO_MASK, stc.priority);
1166 writel(r, ts->regs + THROT_PRIORITY_CTRL(throt)); 1957 writel(r, ts->regs + THROT_PRIORITY_CTRL(throt));
1167 1958
@@ -1215,6 +2006,57 @@ static void tegra_soctherm_throttle(struct device *dev)
1215 writel(v, ts->regs + THERMCTL_STATS_CTL); 2006 writel(v, ts->regs + THERMCTL_STATS_CTL);
1216} 2007}
1217 2008
2009static int soctherm_interrupts_init(struct platform_device *pdev,
2010 struct tegra_soctherm *tegra)
2011{
2012 struct device_node *np = pdev->dev.of_node;
2013 int ret;
2014
2015 ret = soctherm_oc_int_init(np, TEGRA_SOC_OC_IRQ_MAX);
2016 if (ret < 0) {
2017 dev_err(&pdev->dev, "soctherm_oc_int_init failed\n");
2018 return ret;
2019 }
2020
2021 tegra->thermal_irq = platform_get_irq(pdev, 0);
2022 if (tegra->thermal_irq < 0) {
2023 dev_dbg(&pdev->dev, "get 'thermal_irq' failed.\n");
2024 return 0;
2025 }
2026
2027 tegra->edp_irq = platform_get_irq(pdev, 1);
2028 if (tegra->edp_irq < 0) {
2029 dev_dbg(&pdev->dev, "get 'edp_irq' failed.\n");
2030 return 0;
2031 }
2032
2033 ret = devm_request_threaded_irq(&pdev->dev,
2034 tegra->thermal_irq,
2035 soctherm_thermal_isr,
2036 soctherm_thermal_isr_thread,
2037 IRQF_ONESHOT,
2038 dev_name(&pdev->dev),
2039 tegra);
2040 if (ret < 0) {
2041 dev_err(&pdev->dev, "request_irq 'thermal_irq' failed.\n");
2042 return ret;
2043 }
2044
2045 ret = devm_request_threaded_irq(&pdev->dev,
2046 tegra->edp_irq,
2047 soctherm_edp_isr,
2048 soctherm_edp_isr_thread,
2049 IRQF_ONESHOT,
2050 "soctherm_edp",
2051 tegra);
2052 if (ret < 0) {
2053 dev_err(&pdev->dev, "request_irq 'edp_irq' failed.\n");
2054 return ret;
2055 }
2056
2057 return 0;
2058}
2059
1218static void soctherm_init(struct platform_device *pdev) 2060static void soctherm_init(struct platform_device *pdev)
1219{ 2061{
1220 struct tegra_soctherm *tegra = platform_get_drvdata(pdev); 2062 struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
@@ -1292,6 +2134,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
1292 if (!tegra) 2134 if (!tegra)
1293 return -ENOMEM; 2135 return -ENOMEM;
1294 2136
2137 mutex_init(&tegra->thermctl_lock);
1295 dev_set_drvdata(&pdev->dev, tegra); 2138 dev_set_drvdata(&pdev->dev, tegra);
1296 2139
1297 tegra->soc = soc; 2140 tegra->soc = soc;
@@ -1370,6 +2213,8 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
1370 if (err) 2213 if (err)
1371 return err; 2214 return err;
1372 2215
2216 soctherm_thermtrips_parse(pdev);
2217
1373 soctherm_init_hw_throt_cdev(pdev); 2218 soctherm_init_hw_throt_cdev(pdev);
1374 2219
1375 soctherm_init(pdev); 2220 soctherm_init(pdev);
@@ -1406,6 +2251,8 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
1406 goto disable_clocks; 2251 goto disable_clocks;
1407 } 2252 }
1408 2253
2254 err = soctherm_interrupts_init(pdev, tegra);
2255
1409 soctherm_debug_init(pdev); 2256 soctherm_debug_init(pdev);
1410 2257
1411 return 0; 2258 return 0;
diff --git a/drivers/thermal/tegra/soctherm.h b/drivers/thermal/tegra/soctherm.h
index e96ca73fd780..70501e73d586 100644
--- a/drivers/thermal/tegra/soctherm.h
+++ b/drivers/thermal/tegra/soctherm.h
@@ -1,3 +1,4 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. 3 * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved.
3 * 4 *
@@ -29,6 +30,14 @@
29#define THERMCTL_THERMTRIP_CTL 0x80 30#define THERMCTL_THERMTRIP_CTL 0x80
30/* BITs are defined in device file */ 31/* BITs are defined in device file */
31 32
33#define THERMCTL_INTR_ENABLE 0x88
34#define THERMCTL_INTR_DISABLE 0x8c
35#define TH_INTR_UP_DN_EN 0x3
36#define THERM_IRQ_MEM_MASK (TH_INTR_UP_DN_EN << 24)
37#define THERM_IRQ_GPU_MASK (TH_INTR_UP_DN_EN << 16)
38#define THERM_IRQ_CPU_MASK (TH_INTR_UP_DN_EN << 8)
39#define THERM_IRQ_TSENSE_MASK (TH_INTR_UP_DN_EN << 0)
40
32#define SENSOR_PDIV 0x1c0 41#define SENSOR_PDIV 0x1c0
33#define SENSOR_PDIV_CPU_MASK (0xf << 12) 42#define SENSOR_PDIV_CPU_MASK (0xf << 12)
34#define SENSOR_PDIV_GPU_MASK (0xf << 8) 43#define SENSOR_PDIV_GPU_MASK (0xf << 8)
@@ -70,6 +79,7 @@ struct tegra_tsensor_group {
70 u32 thermtrip_enable_mask; 79 u32 thermtrip_enable_mask;
71 u32 thermtrip_any_en_mask; 80 u32 thermtrip_any_en_mask;
72 u32 thermtrip_threshold_mask; 81 u32 thermtrip_threshold_mask;
82 u32 thermctl_isr_mask;
73 u16 thermctl_lvl0_offset; 83 u16 thermctl_lvl0_offset;
74 u32 thermctl_lvl0_up_thresh_mask; 84 u32 thermctl_lvl0_up_thresh_mask;
75 u32 thermctl_lvl0_dn_thresh_mask; 85 u32 thermctl_lvl0_dn_thresh_mask;
@@ -92,6 +102,11 @@ struct tegra_tsensor {
92 const struct tegra_tsensor_group *group; 102 const struct tegra_tsensor_group *group;
93}; 103};
94 104
105struct tsensor_group_thermtrips {
106 u8 id;
107 u32 temp;
108};
109
95struct tegra_soctherm_fuse { 110struct tegra_soctherm_fuse {
96 u32 fuse_base_cp_mask, fuse_base_cp_shift; 111 u32 fuse_base_cp_mask, fuse_base_cp_shift;
97 u32 fuse_base_ft_mask, fuse_base_ft_shift; 112 u32 fuse_base_ft_mask, fuse_base_ft_shift;
@@ -113,6 +128,7 @@ struct tegra_soctherm_soc {
113 const int thresh_grain; 128 const int thresh_grain;
114 const unsigned int bptt; 129 const unsigned int bptt;
115 const bool use_ccroc; 130 const bool use_ccroc;
131 struct tsensor_group_thermtrips *thermtrips;
116}; 132};
117 133
118int tegra_calc_shared_calib(const struct tegra_soctherm_fuse *tfuse, 134int tegra_calc_shared_calib(const struct tegra_soctherm_fuse *tfuse,
diff --git a/drivers/thermal/tegra/tegra124-soctherm.c b/drivers/thermal/tegra/tegra124-soctherm.c
index 36768630f78c..20ad27f4d1a1 100644
--- a/drivers/thermal/tegra/tegra124-soctherm.c
+++ b/drivers/thermal/tegra/tegra124-soctherm.c
@@ -1,5 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. 3 * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
3 * 4 *
4 * This software is licensed under the terms of the GNU General Public 5 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and 6 * License version 2, as published by the Free Software Foundation, and
@@ -55,6 +56,7 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_cpu = {
55 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK, 56 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
56 .thermtrip_enable_mask = TEGRA124_THERMTRIP_CPU_EN_MASK, 57 .thermtrip_enable_mask = TEGRA124_THERMTRIP_CPU_EN_MASK,
57 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_CPU_THRESH_MASK, 58 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_CPU_THRESH_MASK,
59 .thermctl_isr_mask = THERM_IRQ_CPU_MASK,
58 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_CPU, 60 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_CPU,
59 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK, 61 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
60 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK, 62 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
@@ -73,6 +75,7 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_gpu = {
73 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK, 75 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
74 .thermtrip_enable_mask = TEGRA124_THERMTRIP_GPU_EN_MASK, 76 .thermtrip_enable_mask = TEGRA124_THERMTRIP_GPU_EN_MASK,
75 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_GPUMEM_THRESH_MASK, 77 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_GPUMEM_THRESH_MASK,
78 .thermctl_isr_mask = THERM_IRQ_GPU_MASK,
76 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_GPU, 79 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_GPU,
77 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK, 80 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
78 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK, 81 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
@@ -89,6 +92,7 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_pll = {
89 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK, 92 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
90 .thermtrip_enable_mask = TEGRA124_THERMTRIP_TSENSE_EN_MASK, 93 .thermtrip_enable_mask = TEGRA124_THERMTRIP_TSENSE_EN_MASK,
91 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_TSENSE_THRESH_MASK, 94 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_TSENSE_THRESH_MASK,
95 .thermctl_isr_mask = THERM_IRQ_TSENSE_MASK,
92 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_TSENSE, 96 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_TSENSE,
93 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK, 97 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
94 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK, 98 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
@@ -107,6 +111,7 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_mem = {
107 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK, 111 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
108 .thermtrip_enable_mask = TEGRA124_THERMTRIP_MEM_EN_MASK, 112 .thermtrip_enable_mask = TEGRA124_THERMTRIP_MEM_EN_MASK,
109 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_GPUMEM_THRESH_MASK, 113 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_GPUMEM_THRESH_MASK,
114 .thermctl_isr_mask = THERM_IRQ_MEM_MASK,
110 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_MEM, 115 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_MEM,
111 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK, 116 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
112 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK, 117 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
diff --git a/drivers/thermal/tegra/tegra132-soctherm.c b/drivers/thermal/tegra/tegra132-soctherm.c
index 97fa30501eb1..b76308fdad9e 100644
--- a/drivers/thermal/tegra/tegra132-soctherm.c
+++ b/drivers/thermal/tegra/tegra132-soctherm.c
@@ -1,5 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. 3 * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
3 * 4 *
4 * This software is licensed under the terms of the GNU General Public 5 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and 6 * License version 2, as published by the Free Software Foundation, and
@@ -55,6 +56,7 @@ static const struct tegra_tsensor_group tegra132_tsensor_group_cpu = {
55 .thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK, 56 .thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK,
56 .thermtrip_enable_mask = TEGRA132_THERMTRIP_CPU_EN_MASK, 57 .thermtrip_enable_mask = TEGRA132_THERMTRIP_CPU_EN_MASK,
57 .thermtrip_threshold_mask = TEGRA132_THERMTRIP_CPU_THRESH_MASK, 58 .thermtrip_threshold_mask = TEGRA132_THERMTRIP_CPU_THRESH_MASK,
59 .thermctl_isr_mask = THERM_IRQ_CPU_MASK,
58 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_CPU, 60 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_CPU,
59 .thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK, 61 .thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK,
60 .thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK, 62 .thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK,
@@ -73,6 +75,7 @@ static const struct tegra_tsensor_group tegra132_tsensor_group_gpu = {
73 .thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK, 75 .thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK,
74 .thermtrip_enable_mask = TEGRA132_THERMTRIP_GPU_EN_MASK, 76 .thermtrip_enable_mask = TEGRA132_THERMTRIP_GPU_EN_MASK,
75 .thermtrip_threshold_mask = TEGRA132_THERMTRIP_GPUMEM_THRESH_MASK, 77 .thermtrip_threshold_mask = TEGRA132_THERMTRIP_GPUMEM_THRESH_MASK,
78 .thermctl_isr_mask = THERM_IRQ_GPU_MASK,
76 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_GPU, 79 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_GPU,
77 .thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK, 80 .thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK,
78 .thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK, 81 .thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK,
@@ -89,6 +92,7 @@ static const struct tegra_tsensor_group tegra132_tsensor_group_pll = {
89 .thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK, 92 .thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK,
90 .thermtrip_enable_mask = TEGRA132_THERMTRIP_TSENSE_EN_MASK, 93 .thermtrip_enable_mask = TEGRA132_THERMTRIP_TSENSE_EN_MASK,
91 .thermtrip_threshold_mask = TEGRA132_THERMTRIP_TSENSE_THRESH_MASK, 94 .thermtrip_threshold_mask = TEGRA132_THERMTRIP_TSENSE_THRESH_MASK,
95 .thermctl_isr_mask = THERM_IRQ_TSENSE_MASK,
92 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_TSENSE, 96 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_TSENSE,
93 .thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK, 97 .thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK,
94 .thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK, 98 .thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK,
@@ -107,6 +111,7 @@ static const struct tegra_tsensor_group tegra132_tsensor_group_mem = {
107 .thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK, 111 .thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK,
108 .thermtrip_enable_mask = TEGRA132_THERMTRIP_MEM_EN_MASK, 112 .thermtrip_enable_mask = TEGRA132_THERMTRIP_MEM_EN_MASK,
109 .thermtrip_threshold_mask = TEGRA132_THERMTRIP_GPUMEM_THRESH_MASK, 113 .thermtrip_threshold_mask = TEGRA132_THERMTRIP_GPUMEM_THRESH_MASK,
114 .thermctl_isr_mask = THERM_IRQ_MEM_MASK,
110 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_MEM, 115 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_MEM,
111 .thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK, 116 .thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK,
112 .thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK, 117 .thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK,
diff --git a/drivers/thermal/tegra/tegra210-soctherm.c b/drivers/thermal/tegra/tegra210-soctherm.c
index ad53169a8e95..d31b50050faa 100644
--- a/drivers/thermal/tegra/tegra210-soctherm.c
+++ b/drivers/thermal/tegra/tegra210-soctherm.c
@@ -1,5 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. 3 * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
3 * 4 *
4 * This software is licensed under the terms of the GNU General Public 5 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and 6 * License version 2, as published by the Free Software Foundation, and
@@ -56,6 +57,7 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_cpu = {
56 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK, 57 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
57 .thermtrip_enable_mask = TEGRA210_THERMTRIP_CPU_EN_MASK, 58 .thermtrip_enable_mask = TEGRA210_THERMTRIP_CPU_EN_MASK,
58 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_CPU_THRESH_MASK, 59 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_CPU_THRESH_MASK,
60 .thermctl_isr_mask = THERM_IRQ_CPU_MASK,
59 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_CPU, 61 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_CPU,
60 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK, 62 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
61 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK, 63 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
@@ -74,6 +76,7 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_gpu = {
74 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK, 76 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
75 .thermtrip_enable_mask = TEGRA210_THERMTRIP_GPU_EN_MASK, 77 .thermtrip_enable_mask = TEGRA210_THERMTRIP_GPU_EN_MASK,
76 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_GPUMEM_THRESH_MASK, 78 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_GPUMEM_THRESH_MASK,
79 .thermctl_isr_mask = THERM_IRQ_GPU_MASK,
77 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_GPU, 80 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_GPU,
78 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK, 81 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
79 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK, 82 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
@@ -90,6 +93,7 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_pll = {
90 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK, 93 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
91 .thermtrip_enable_mask = TEGRA210_THERMTRIP_TSENSE_EN_MASK, 94 .thermtrip_enable_mask = TEGRA210_THERMTRIP_TSENSE_EN_MASK,
92 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_TSENSE_THRESH_MASK, 95 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_TSENSE_THRESH_MASK,
96 .thermctl_isr_mask = THERM_IRQ_TSENSE_MASK,
93 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_TSENSE, 97 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_TSENSE,
94 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK, 98 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
95 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK, 99 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
@@ -108,6 +112,7 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_mem = {
108 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK, 112 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
109 .thermtrip_enable_mask = TEGRA210_THERMTRIP_MEM_EN_MASK, 113 .thermtrip_enable_mask = TEGRA210_THERMTRIP_MEM_EN_MASK,
110 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_GPUMEM_THRESH_MASK, 114 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_GPUMEM_THRESH_MASK,
115 .thermctl_isr_mask = THERM_IRQ_MEM_MASK,
111 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_MEM, 116 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_MEM,
112 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK, 117 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
113 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK, 118 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
@@ -203,6 +208,13 @@ static const struct tegra_soctherm_fuse tegra210_soctherm_fuse = {
203 .fuse_spare_realignment = 0, 208 .fuse_spare_realignment = 0,
204}; 209};
205 210
211struct tsensor_group_thermtrips tegra210_tsensor_thermtrips[] = {
212 {.id = TEGRA124_SOCTHERM_SENSOR_NUM},
213 {.id = TEGRA124_SOCTHERM_SENSOR_NUM},
214 {.id = TEGRA124_SOCTHERM_SENSOR_NUM},
215 {.id = TEGRA124_SOCTHERM_SENSOR_NUM},
216};
217
206const struct tegra_soctherm_soc tegra210_soctherm = { 218const struct tegra_soctherm_soc tegra210_soctherm = {
207 .tsensors = tegra210_tsensors, 219 .tsensors = tegra210_tsensors,
208 .num_tsensors = ARRAY_SIZE(tegra210_tsensors), 220 .num_tsensors = ARRAY_SIZE(tegra210_tsensors),
@@ -212,4 +224,5 @@ const struct tegra_soctherm_soc tegra210_soctherm = {
212 .thresh_grain = TEGRA210_THRESH_GRAIN, 224 .thresh_grain = TEGRA210_THRESH_GRAIN,
213 .bptt = TEGRA210_BPTT, 225 .bptt = TEGRA210_BPTT,
214 .use_ccroc = false, 226 .use_ccroc = false,
227 .thermtrips = tegra210_tsensor_thermtrips,
215}; 228};
diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c
index e22fc60ad36d..deb244f12de4 100644
--- a/drivers/thermal/thermal-generic-adc.c
+++ b/drivers/thermal/thermal-generic-adc.c
@@ -29,6 +29,9 @@ static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val)
29 int temp, temp_hi, temp_lo, adc_hi, adc_lo; 29 int temp, temp_hi, temp_lo, adc_hi, adc_lo;
30 int i; 30 int i;
31 31
32 if (!gti->lookup_table)
33 return val;
34
32 for (i = 0; i < gti->nlookup_table; i++) { 35 for (i = 0; i < gti->nlookup_table; i++) {
33 if (val >= gti->lookup_table[2 * i + 1]) 36 if (val >= gti->lookup_table[2 * i + 1])
34 break; 37 break;
@@ -81,9 +84,9 @@ static int gadc_thermal_read_linear_lookup_table(struct device *dev,
81 84
82 ntable = of_property_count_elems_of_size(np, "temperature-lookup-table", 85 ntable = of_property_count_elems_of_size(np, "temperature-lookup-table",
83 sizeof(u32)); 86 sizeof(u32));
84 if (ntable < 0) { 87 if (ntable <= 0) {
85 dev_err(dev, "Lookup table is not provided\n"); 88 dev_notice(dev, "no lookup table, assuming DAC channel returns milliCelcius\n");
86 return ntable; 89 return 0;
87 } 90 }
88 91
89 if (ntable % 2) { 92 if (ntable % 2) {
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 6590bb5cb688..e0b530603db6 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -1046,6 +1046,55 @@ thermal_of_cooling_device_register(struct device_node *np,
1046} 1046}
1047EXPORT_SYMBOL_GPL(thermal_of_cooling_device_register); 1047EXPORT_SYMBOL_GPL(thermal_of_cooling_device_register);
1048 1048
1049static void thermal_cooling_device_release(struct device *dev, void *res)
1050{
1051 thermal_cooling_device_unregister(
1052 *(struct thermal_cooling_device **)res);
1053}
1054
1055/**
1056 * devm_thermal_of_cooling_device_register() - register an OF thermal cooling
1057 * device
1058 * @dev: a valid struct device pointer of a sensor device.
1059 * @np: a pointer to a device tree node.
1060 * @type: the thermal cooling device type.
1061 * @devdata: device private data.
1062 * @ops: standard thermal cooling devices callbacks.
1063 *
1064 * This function will register a cooling device with device tree node reference.
1065 * This interface function adds a new thermal cooling device (fan/processor/...)
1066 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
1067 * to all the thermal zone devices registered at the same time.
1068 *
1069 * Return: a pointer to the created struct thermal_cooling_device or an
1070 * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
1071 */
1072struct thermal_cooling_device *
1073devm_thermal_of_cooling_device_register(struct device *dev,
1074 struct device_node *np,
1075 char *type, void *devdata,
1076 const struct thermal_cooling_device_ops *ops)
1077{
1078 struct thermal_cooling_device **ptr, *tcd;
1079
1080 ptr = devres_alloc(thermal_cooling_device_release, sizeof(*ptr),
1081 GFP_KERNEL);
1082 if (!ptr)
1083 return ERR_PTR(-ENOMEM);
1084
1085 tcd = __thermal_cooling_device_register(np, type, devdata, ops);
1086 if (IS_ERR(tcd)) {
1087 devres_free(ptr);
1088 return tcd;
1089 }
1090
1091 *ptr = tcd;
1092 devres_add(dev, ptr);
1093
1094 return tcd;
1095}
1096EXPORT_SYMBOL_GPL(devm_thermal_of_cooling_device_register);
1097
1049static void __unbind(struct thermal_zone_device *tz, int mask, 1098static void __unbind(struct thermal_zone_device *tz, int mask,
1050 struct thermal_cooling_device *cdev) 1099 struct thermal_cooling_device *cdev)
1051{ 1100{
diff --git a/drivers/thermal/thermal_mmio.c b/drivers/thermal/thermal_mmio.c
new file mode 100644
index 000000000000..de3cceea23bc
--- /dev/null
+++ b/drivers/thermal/thermal_mmio.c
@@ -0,0 +1,129 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 */
5
6#include <linux/module.h>
7#include <linux/of_address.h>
8#include <linux/platform_device.h>
9#include <linux/thermal.h>
10
11struct thermal_mmio {
12 void __iomem *mmio_base;
13 u32 (*read_mmio)(void __iomem *mmio_base);
14 u32 mask;
15 int factor;
16};
17
18static u32 thermal_mmio_readb(void __iomem *mmio_base)
19{
20 return readb(mmio_base);
21}
22
23static int thermal_mmio_get_temperature(void *private, int *temp)
24{
25 int t;
26 struct thermal_mmio *sensor =
27 (struct thermal_mmio *)private;
28
29 t = sensor->read_mmio(sensor->mmio_base) & sensor->mask;
30 t *= sensor->factor;
31
32 *temp = t;
33
34 return 0;
35}
36
37static struct thermal_zone_of_device_ops thermal_mmio_ops = {
38 .get_temp = thermal_mmio_get_temperature,
39};
40
41static int thermal_mmio_probe(struct platform_device *pdev)
42{
43 struct resource *resource;
44 struct thermal_mmio *sensor;
45 int (*sensor_init_func)(struct platform_device *pdev,
46 struct thermal_mmio *sensor);
47 struct thermal_zone_device *thermal_zone;
48 int ret;
49 int temperature;
50
51 sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
52 if (!sensor)
53 return -ENOMEM;
54
55 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
56 if (IS_ERR(resource)) {
57 dev_err(&pdev->dev,
58 "fail to get platform memory resource (%ld)\n",
59 PTR_ERR(resource));
60 return PTR_ERR(resource);
61 }
62
63 sensor->mmio_base = devm_ioremap_resource(&pdev->dev, resource);
64 if (IS_ERR(sensor->mmio_base)) {
65 dev_err(&pdev->dev, "failed to ioremap memory (%ld)\n",
66 PTR_ERR(sensor->mmio_base));
67 return PTR_ERR(sensor->mmio_base);
68 }
69
70 sensor_init_func = device_get_match_data(&pdev->dev);
71 if (sensor_init_func) {
72 ret = sensor_init_func(pdev, sensor);
73 if (ret) {
74 dev_err(&pdev->dev,
75 "failed to initialize sensor (%d)\n",
76 ret);
77 return ret;
78 }
79 }
80
81 thermal_zone = devm_thermal_zone_of_sensor_register(&pdev->dev,
82 0,
83 sensor,
84 &thermal_mmio_ops);
85 if (IS_ERR(thermal_zone)) {
86 dev_err(&pdev->dev,
87 "failed to register sensor (%ld)\n",
88 PTR_ERR(thermal_zone));
89 return PTR_ERR(thermal_zone);
90 }
91
92 thermal_mmio_get_temperature(sensor, &temperature);
93 dev_info(&pdev->dev,
94 "thermal mmio sensor %s registered, current temperature: %d\n",
95 pdev->name, temperature);
96
97 return 0;
98}
99
100static int al_thermal_init(struct platform_device *pdev,
101 struct thermal_mmio *sensor)
102{
103 sensor->read_mmio = thermal_mmio_readb;
104 sensor->mask = 0xff;
105 sensor->factor = 1000;
106
107 return 0;
108}
109
110static const struct of_device_id thermal_mmio_id_table[] = {
111 { .compatible = "amazon,al-thermal", .data = al_thermal_init},
112 {}
113};
114MODULE_DEVICE_TABLE(of, thermal_mmio_id_table);
115
116static struct platform_driver thermal_mmio_driver = {
117 .probe = thermal_mmio_probe,
118 .driver = {
119 .name = "thermal-mmio",
120 .owner = THIS_MODULE,
121 .of_match_table = of_match_ptr(thermal_mmio_id_table),
122 },
123};
124
125module_platform_driver(thermal_mmio_driver);
126
127MODULE_AUTHOR("Talel Shenhar <talel@amazon.com>");
128MODULE_DESCRIPTION("Thermal MMIO Driver");
129MODULE_LICENSE("GPL v2");
diff --git a/include/dt-bindings/thermal/tegra124-soctherm.h b/include/dt-bindings/thermal/tegra124-soctherm.h
index c15e8b709a0d..444c7bdde146 100644
--- a/include/dt-bindings/thermal/tegra124-soctherm.h
+++ b/include/dt-bindings/thermal/tegra124-soctherm.h
@@ -12,9 +12,9 @@
12#define TEGRA124_SOCTHERM_SENSOR_PLLX 3 12#define TEGRA124_SOCTHERM_SENSOR_PLLX 3
13#define TEGRA124_SOCTHERM_SENSOR_NUM 4 13#define TEGRA124_SOCTHERM_SENSOR_NUM 4
14 14
15#define TEGRA_SOCTHERM_THROT_LEVEL_LOW 0 15#define TEGRA_SOCTHERM_THROT_LEVEL_NONE 0
16#define TEGRA_SOCTHERM_THROT_LEVEL_MED 1 16#define TEGRA_SOCTHERM_THROT_LEVEL_LOW 1
17#define TEGRA_SOCTHERM_THROT_LEVEL_HIGH 2 17#define TEGRA_SOCTHERM_THROT_LEVEL_MED 2
18#define TEGRA_SOCTHERM_THROT_LEVEL_NONE -1 18#define TEGRA_SOCTHERM_THROT_LEVEL_HIGH 3
19 19
20#endif 20#endif
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 5f4705f46c2f..4a22099ed8c0 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -447,6 +447,11 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *, void *,
447struct thermal_cooling_device * 447struct thermal_cooling_device *
448thermal_of_cooling_device_register(struct device_node *np, char *, void *, 448thermal_of_cooling_device_register(struct device_node *np, char *, void *,
449 const struct thermal_cooling_device_ops *); 449 const struct thermal_cooling_device_ops *);
450struct thermal_cooling_device *
451devm_thermal_of_cooling_device_register(struct device *dev,
452 struct device_node *np,
453 char *type, void *devdata,
454 const struct thermal_cooling_device_ops *ops);
450void thermal_cooling_device_unregister(struct thermal_cooling_device *); 455void thermal_cooling_device_unregister(struct thermal_cooling_device *);
451struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name); 456struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
452int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); 457int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
@@ -503,6 +508,14 @@ static inline struct thermal_cooling_device *
503thermal_of_cooling_device_register(struct device_node *np, 508thermal_of_cooling_device_register(struct device_node *np,
504 char *type, void *devdata, const struct thermal_cooling_device_ops *ops) 509 char *type, void *devdata, const struct thermal_cooling_device_ops *ops)
505{ return ERR_PTR(-ENODEV); } 510{ return ERR_PTR(-ENODEV); }
511static inline struct thermal_cooling_device *
512devm_thermal_of_cooling_device_register(struct device *dev,
513 struct device_node *np,
514 char *type, void *devdata,
515 const struct thermal_cooling_device_ops *ops)
516{
517 return ERR_PTR(-ENODEV);
518}
506static inline void thermal_cooling_device_unregister( 519static inline void thermal_cooling_device_unregister(
507 struct thermal_cooling_device *cdev) 520 struct thermal_cooling_device *cdev)
508{ } 521{ }