summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-12-15 10:16:04 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2022-12-15 10:16:04 -0800
commit601c1aa855a686643259c4a34e96ee692cdaf01f (patch)
treef2b7364f873b8f7373d69517e8b9be2e1e1ac782
parentc0f234ff90a211272138be1611ba53f3155ebd78 (diff)
parentbd7bcc4f963c8898176ad864288959375154e038 (diff)
Merge tag 'thermal-6.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more thermal control updates from Rafael Wysocki: "These are updates of assorted thermal drivers, mostly for ARM platforms, generally isolated and fairly straightforward, and the recent Intel HFI driver fix for systems without HFI support. Specifics: - Avoid clearing the HFI status bit on systems without HFI support which triggers unchecked MSR access errors (Srinivas Pandruvada) - Add sm8450 and sm8550 QCom compatible string to DT bindings (Luca Weiss, Neil Armstrong) - Use devm_platform_get_and_ioremap_resource on the ST platform to group two calls into a single one (Minghao Chi) - Use GENMASK instead of bitmaps and validate the temperature after reading it in the imx8mm_thermal driver (Marcus Folkesson) - Convert generic-adc-thermal to DT schema (Rob Herring) - Fix debug print message with inverted logic in the k3_j72xx_bandgap driver (Keerthy) - Fix memory leak on thermal_of_zone_register() failure (Ido Schimmel) - Add support for IPQ8074 in the tsens thermal driver along with the DT bindings (Robert Marko) - Fix and rework the debugfs code in the tsens driver (Christian Marangi) - Add calibration and DT documentation for the imx8mm driver (Marek Vasut) - Add DT bindings and compatible for the Mediatek SoCs mt7981 and mt7983 (Daniel Golle) - Don't show an error message if it happens at probe time while it will be deferred on the QCom SPMI ADC driver (Johan Hovold) - Add HWMon support for the imx8mm board (Alexander Stein) - Remove pointless include from the power allocator governor (Christophe JAILLET) - Add interrupt DT bindings for QCom SoCs SC8280XP, SM6350 and SM8450 (Krzysztof Kozlowski) - Fix inaccurate warning message for the QCom tsens gen2 (Luca Weiss) - Demote error log of thermal zone register to debug in the tsens QCom driver (Manivannan Sadhasivam) - Consolidate the the efuse values and the errata handling in the TI Bandgap driver (Bryan Brattlof) - Document Renesas RZ/Five as compatible with RZ/G2UL in the DT bindings (Lad Prabhakar) - Fix the irq handler return value in the LMh driver (Bjorn Andersson) - Delete empty platform remove callback from imx_sc_thermal (Uwe Kleine-König)" * tag 'thermal-6.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (35 commits) thermal/drivers/imx_sc_thermal: Drop empty platform remove function thermal/drivers/qcom/lmh: Fix irq handler return value dt-bindings: thermal: qcom-tsens: Add compatible for sm8550 thermal/drivers/st: Use devm_platform_get_and_ioremap_resource() dt-bindings: thermal: rzg2l-thermal: Document RZ/Five SoC dt-bindings: thermal: k3-j72xx: conditionally require efuse reg range dt-bindings: thermal: k3-j72xx: elaborate on binding description thermal/drivers/k3_j72xx_bandgap: Map fuse_base only for erratum workaround thermal/drivers/k3_j72xx_bandgap: Remove fuse_base from structure thermal/drivers/k3_j72xx_bandgap: Use bool for i2128 erratum flag thermal/drivers/k3_j72xx_bandgap: Simplify k3_thermal_get_temp() function thermal/drivers/qcom: Demote error log of thermal zone register to debug thermal/drivers/qcom/temp-alarm: Fix inaccurate warning for gen2 dt-bindings: thermal: qcom-tsens: narrow interrupts for SC8280XP, SM6350 and SM8450 thermal/core/power allocator: Remove a useless include thermal/drivers/imx8mm: Add hwmon support thermal: qcom-spmi-adc-tm5: suppress probe-deferral error message dt-bindings: thermal: mediatek: add compatible string for MT7986 and MT7981 SoC thermal: ti-soc-thermal: Drop comma after SoC match table sentinel thermal/drivers/imx: Add support for loading calibration data from OCOTP ...
-rw-r--r--Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml84
-rw-r--r--Documentation/devicetree/bindings/thermal/imx8mm-thermal.yaml7
-rw-r--r--Documentation/devicetree/bindings/thermal/mediatek-thermal.txt2
-rw-r--r--Documentation/devicetree/bindings/thermal/qcom-tsens.yaml81
-rw-r--r--Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml2
-rw-r--r--Documentation/devicetree/bindings/thermal/thermal-generic-adc.txt95
-rw-r--r--Documentation/devicetree/bindings/thermal/ti,j72xx-thermal.yaml35
-rw-r--r--drivers/thermal/gov_power_allocator.c1
-rw-r--r--drivers/thermal/imx8mm_thermal.c180
-rw-r--r--drivers/thermal/imx_sc_thermal.c6
-rw-r--r--drivers/thermal/intel/therm_throt.c5
-rw-r--r--drivers/thermal/k3_j72xx_bandgap.c67
-rw-r--r--drivers/thermal/qcom/lmh.c2
-rw-r--r--drivers/thermal/qcom/qcom-spmi-adc-tm5.c8
-rw-r--r--drivers/thermal/qcom/qcom-spmi-temp-alarm.c3
-rw-r--r--drivers/thermal/qcom/tsens-8960.c3
-rw-r--r--drivers/thermal/qcom/tsens-v0_1.c3
-rw-r--r--drivers/thermal/qcom/tsens-v1.c3
-rw-r--r--drivers/thermal/qcom/tsens-v2.c20
-rw-r--r--drivers/thermal/qcom/tsens.c68
-rw-r--r--drivers/thermal/qcom/tsens.h8
-rw-r--r--drivers/thermal/st/stm_thermal.c4
-rw-r--r--drivers/thermal/thermal_of.c8
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-bandgap.c2
24 files changed, 510 insertions, 187 deletions
diff --git a/Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml b/Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml
new file mode 100644
index 000000000000..f1fc3b0d8608
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/generic-adc-thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: General Purpose Analog To Digital Converter (ADC) based thermal sensor
+
+maintainers:
+ - Laxman Dewangan <ldewangan@nvidia.com>
+
+description:
+ On some of platforms, thermal sensor like thermistors are connected to
+ one of ADC channel and sensor resistance is read via voltage across the
+ sensor resistor. The voltage read across the sensor is mapped to
+ temperature using voltage-temperature lookup table.
+
+properties:
+ compatible:
+ const: generic-adc-thermal
+
+ '#thermal-sensor-cells':
+ const: 0
+
+ io-channels:
+ maxItems: 1
+
+ io-channel-names:
+ const: sensor-channel
+
+ temperature-lookup-table:
+ description: |
+ Lookup table to map the relation between ADC value and temperature.
+ When ADC is read, the value is looked up on the table to get the
+ equivalent temperature.
+
+ If not specified, driver assumes the ADC channel gives milliCelsius
+ directly.
+ $ref: /schemas/types.yaml#/definitions/int32-matrix
+ items:
+ items:
+ - description: Temperature in milliCelsius
+ - description: ADC read value
+
+required:
+ - compatible
+ - '#thermal-sensor-cells'
+ - io-channels
+ - io-channel-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/thermal/thermal.h>
+
+ thermal-sensor {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&ads1015 1>;
+ io-channel-names = "sensor-channel";
+ temperature-lookup-table = <
+ (-40000) 2578
+ (-39000) 2577
+ (-38000) 2576
+ (-37000) 2575
+ (-36000) 2574
+ (-35000) 2573
+ (-34000) 2572
+ (-33000) 2571
+ (-32000) 2569
+ (-31000) 2568
+ (-30000) 2567
+ /* skip */
+ 118000 254
+ 119000 247
+ 120000 240
+ 121000 233
+ 122000 226
+ 123000 220
+ 124000 214
+ 125000 208>;
+ };
+...
diff --git a/Documentation/devicetree/bindings/thermal/imx8mm-thermal.yaml b/Documentation/devicetree/bindings/thermal/imx8mm-thermal.yaml
index 89c54e08ee61..b90726229ac9 100644
--- a/Documentation/devicetree/bindings/thermal/imx8mm-thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/imx8mm-thermal.yaml
@@ -32,6 +32,13 @@ properties:
clocks:
maxItems: 1
+ nvmem-cells:
+ maxItems: 1
+ description: Phandle to the calibration data provided by ocotp
+
+ nvmem-cell-names:
+ const: calib
+
"#thermal-sensor-cells":
description: |
Number of cells required to uniquely identify the thermal
diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
index 5c7e7bdd029a..38b32bb447e3 100644
--- a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
@@ -13,6 +13,8 @@ Required properties:
- "mediatek,mt2701-thermal" : For MT2701 family of SoCs
- "mediatek,mt2712-thermal" : For MT2712 family of SoCs
- "mediatek,mt7622-thermal" : For MT7622 SoC
+ - "mediatek,mt7981-thermal", "mediatek,mt7986-thermal" : For MT7981 SoC
+ - "mediatek,mt7986-thermal" : For MT7986 SoC
- "mediatek,mt8183-thermal" : For MT8183 family of SoCs
- "mediatek,mt8516-thermal", "mediatek,mt2701-thermal : For MT8516 family of SoCs
- reg: Address range of the thermal controller
diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
index c41fcf404117..0231f187b097 100644
--- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
@@ -58,8 +58,14 @@ properties:
- qcom,sm8150-tsens
- qcom,sm8250-tsens
- qcom,sm8350-tsens
+ - qcom,sm8450-tsens
+ - qcom,sm8550-tsens
- const: qcom,tsens-v2
+ - description: v2 of TSENS with combined interrupt
+ enum:
+ - qcom,ipq8074-tsens
+
reg:
items:
- description: TM registers
@@ -67,15 +73,11 @@ properties:
interrupts:
minItems: 1
- items:
- - description: Combined interrupt if upper or lower threshold crossed
- - description: Interrupt if critical threshold crossed
+ maxItems: 2
interrupt-names:
minItems: 1
- items:
- - const: uplow
- - const: critical
+ maxItems: 2
nvmem-cells:
minItems: 1
@@ -129,22 +131,64 @@ allOf:
then:
properties:
interrupts:
- maxItems: 1
+ items:
+ - description: Combined interrupt if upper or lower threshold crossed
interrupt-names:
- maxItems: 1
+ items:
+ - const: uplow
- else:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,msm8953-tsens
+ - qcom,msm8996-tsens
+ - qcom,msm8998-tsens
+ - qcom,sc7180-tsens
+ - qcom,sc7280-tsens
+ - qcom,sc8180x-tsens
+ - qcom,sc8280xp-tsens
+ - qcom,sdm630-tsens
+ - qcom,sdm845-tsens
+ - qcom,sm6350-tsens
+ - qcom,sm8150-tsens
+ - qcom,sm8250-tsens
+ - qcom,sm8350-tsens
+ - qcom,sm8450-tsens
+ - qcom,tsens-v2
+ then:
properties:
interrupts:
- minItems: 2
+ items:
+ - description: Combined interrupt if upper or lower threshold crossed
+ - description: Interrupt if critical threshold crossed
interrupt-names:
- minItems: 2
+ items:
+ - const: uplow
+ - const: critical
- if:
properties:
compatible:
contains:
enum:
+ - qcom,ipq8074-tsens
+ then:
+ properties:
+ interrupts:
+ items:
+ - description: Combined interrupt if upper, lower or critical thresholds crossed
+ interrupt-names:
+ items:
+ - const: combined
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,ipq8074-tsens
- qcom,tsens-v0_1
- qcom,tsens-v1
- qcom,tsens-v2
@@ -227,4 +271,19 @@ examples:
#qcom,sensors = <13>;
#thermal-sensor-cells = <1>;
};
+
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ // Example 4 (for any IPQ8074 based SoC-s):
+ tsens4: thermal-sensor@4a9000 {
+ compatible = "qcom,ipq8074-tsens";
+ reg = <0x4a9000 0x1000>,
+ <0x4a8000 0x1000>;
+
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "combined";
+
+ #qcom,sensors = <16>;
+ #thermal-sensor-cells = <1>;
+ };
...
diff --git a/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml b/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml
index 1d8373397848..03f4b926e53c 100644
--- a/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml
@@ -17,7 +17,7 @@ properties:
compatible:
items:
- enum:
- - renesas,r9a07g043-tsu # RZ/G2UL
+ - renesas,r9a07g043-tsu # RZ/G2UL and RZ/Five
- renesas,r9a07g044-tsu # RZ/G2{L,LC}
- renesas,r9a07g054-tsu # RZ/V2L
- const: renesas,rzg2l-tsu
diff --git a/Documentation/devicetree/bindings/thermal/thermal-generic-adc.txt b/Documentation/devicetree/bindings/thermal/thermal-generic-adc.txt
deleted file mode 100644
index e136946a2f4f..000000000000
--- a/Documentation/devicetree/bindings/thermal/thermal-generic-adc.txt
+++ /dev/null
@@ -1,95 +0,0 @@
-General Purpose Analog To Digital Converter (ADC) based thermal sensor.
-
-On some of platforms, thermal sensor like thermistors are connected to
-one of ADC channel and sensor resistance is read via voltage across the
-sensor resistor. The voltage read across the sensor is mapped to
-temperature using voltage-temperature lookup table.
-
-Required properties:
-===================
-- compatible: Must be "generic-adc-thermal".
-- #thermal-sensor-cells: Should be 1. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description
- of this property.
-Optional properties:
-===================
-- temperature-lookup-table: Two dimensional array of Integer; lookup table
- to map the relation between ADC value and
- temperature. When ADC is read, the value is
- looked up on the table to get the equivalent
- temperature.
-
- The first value of the each row of array is the
- temperature in milliCelsius and second value of
- the each row of array is the ADC read value.
-
- If not specified, driver assumes the ADC channel
- gives milliCelsius directly.
-
-Example :
-#include <dt-bindings/thermal/thermal.h>
-
-i2c@7000c400 {
- ads1015: ads1015@4a {
- reg = <0x4a>;
- compatible = "ads1015";
- sampling-frequency = <3300>;
- #io-channel-cells = <1>;
- };
-};
-
-tboard_thermistor: thermal-sensor {
- compatible = "generic-adc-thermal";
- #thermal-sensor-cells = <0>;
- io-channels = <&ads1015 1>;
- io-channel-names = "sensor-channel";
- temperature-lookup-table = < (-40000) 2578
- (-39000) 2577
- (-38000) 2576
- (-37000) 2575
- (-36000) 2574
- (-35000) 2573
- (-34000) 2572
- (-33000) 2571
- (-32000) 2569
- (-31000) 2568
- (-30000) 2567
- ::::::::::
- 118000 254
- 119000 247
- 120000 240
- 121000 233
- 122000 226
- 123000 220
- 124000 214
- 125000 208>;
-};
-
-dummy_cool_dev: dummy-cool-dev {
- compatible = "dummy-cooling-dev";
- #cooling-cells = <2>; /* min followed by max */
-};
-
-thermal-zones {
- Tboard {
- polling-delay = <15000>; /* milliseconds */
- polling-delay-passive = <0>; /* milliseconds */
- thermal-sensors = <&tboard_thermistor>;
-
- trips {
- therm_est_trip: therm_est_trip {
- temperature = <40000>;
- type = "active";
- hysteresis = <1000>;
- };
- };
-
- cooling-maps {
- map0 {
- trip = <&therm_est_trip>;
- cooling-device = <&dummy_cool_dev THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
- contribution = <100>;
- };
-
- };
- };
-};
diff --git a/Documentation/devicetree/bindings/thermal/ti,j72xx-thermal.yaml b/Documentation/devicetree/bindings/thermal/ti,j72xx-thermal.yaml
index c74f124ebfc0..0509c9cec224 100644
--- a/Documentation/devicetree/bindings/thermal/ti,j72xx-thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/ti,j72xx-thermal.yaml
@@ -9,6 +9,19 @@ title: Texas Instruments J72XX VTM (DTS) binding
maintainers:
- Keerthy <j-keerthy@ti.com>
+description: |
+ The TI K3 family of SoCs typically have a Voltage & Thermal
+ Management (VTM) device to control up to 8 temperature diode
+ sensors to measure silicon junction temperatures from different
+ hotspots of the chip as well as provide temperature, interrupt
+ and alerting information.
+
+ The following polynomial equation can then be used to convert
+ value returned by this device into a temperature in Celsius
+
+ Temp(C) = (-9.2627e-12) * x^4 + (6.0373e-08) * x^3 + \
+ (-1.7058e-04) * x^2 + (3.2512e-01) * x + (-4.9003e+01)
+
properties:
compatible:
enum:
@@ -19,7 +32,12 @@ properties:
items:
- description: VTM cfg1 register space
- description: VTM cfg2 register space
- - description: VTM efuse register space
+ - description: |
+ A software trimming method must be applied to some Jacinto
+ devices to function properly. This eFuse region provides
+ the information needed for these SoCs to report
+ temperatures accurately.
+ minItems: 2
power-domains:
maxItems: 1
@@ -27,6 +45,21 @@ properties:
"#thermal-sensor-cells":
const: 1
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: ti,j721e-vtm
+ then:
+ properties:
+ reg:
+ minItems: 3
+ else:
+ properties:
+ reg:
+ maxItems: 2
+
required:
- compatible
- reg
diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c
index 2d1aeaba38a8..d5d4eae16771 100644
--- a/drivers/thermal/gov_power_allocator.c
+++ b/drivers/thermal/gov_power_allocator.c
@@ -8,7 +8,6 @@
#define pr_fmt(fmt) "Power allocator: " fmt
-#include <linux/rculist.h>
#include <linux/slab.h>
#include <linux/thermal.h>
diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c
index e2c2673025a7..d247b48696cb 100644
--- a/drivers/thermal/imx8mm_thermal.c
+++ b/drivers/thermal/imx8mm_thermal.c
@@ -10,21 +10,40 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/thermal.h>
#include "thermal_core.h"
+#include "thermal_hwmon.h"
#define TER 0x0 /* TMU enable */
#define TPS 0x4
#define TRITSR 0x20 /* TMU immediate temp */
+/* TMU calibration data registers */
+#define TASR 0x28
+#define TASR_BUF_SLOPE_MASK GENMASK(19, 16)
+#define TASR_BUF_VREF_MASK GENMASK(4, 0) /* TMU_V1 */
+#define TASR_BUF_VERF_SEL_MASK GENMASK(1, 0) /* TMU_V2 */
+#define TCALIV(n) (0x30 + ((n) * 4))
+#define TCALIV_EN BIT(31)
+#define TCALIV_HR_MASK GENMASK(23, 16) /* TMU_V1 */
+#define TCALIV_RT_MASK GENMASK(7, 0) /* TMU_V1 */
+#define TCALIV_SNSR105C_MASK GENMASK(27, 16) /* TMU_V2 */
+#define TCALIV_SNSR25C_MASK GENMASK(11, 0) /* TMU_V2 */
+#define TRIM 0x3c
+#define TRIM_BJT_CUR_MASK GENMASK(23, 20)
+#define TRIM_BGR_MASK GENMASK(31, 28)
+#define TRIM_VLSB_MASK GENMASK(15, 12)
+#define TRIM_EN_CH BIT(7)
#define TER_ADC_PD BIT(30)
#define TER_EN BIT(31)
-#define TRITSR_TEMP0_VAL_MASK 0xff
-#define TRITSR_TEMP1_VAL_MASK 0xff0000
+#define TRITSR_TEMP0_VAL_MASK GENMASK(7, 0)
+#define TRITSR_TEMP1_VAL_MASK GENMASK(23, 16)
#define PROBE_SEL_ALL GENMASK(31, 30)
@@ -32,6 +51,25 @@
#define SIGN_BIT BIT(7)
#define TEMP_VAL_MASK GENMASK(6, 0)
+/* TMU OCOTP calibration data bitfields */
+#define ANA0_EN BIT(25)
+#define ANA0_BUF_VREF_MASK GENMASK(24, 20)
+#define ANA0_BUF_SLOPE_MASK GENMASK(19, 16)
+#define ANA0_HR_MASK GENMASK(15, 8)
+#define ANA0_RT_MASK GENMASK(7, 0)
+#define TRIM2_VLSB_MASK GENMASK(23, 20)
+#define TRIM2_BGR_MASK GENMASK(19, 16)
+#define TRIM2_BJT_CUR_MASK GENMASK(15, 12)
+#define TRIM2_BUF_SLOP_SEL_MASK GENMASK(11, 8)
+#define TRIM2_BUF_VERF_SEL_MASK GENMASK(7, 6)
+#define TRIM3_TCA25_0_LSB_MASK GENMASK(31, 28)
+#define TRIM3_TCA40_0_MASK GENMASK(27, 16)
+#define TRIM4_TCA40_1_MASK GENMASK(31, 20)
+#define TRIM4_TCA105_0_MASK GENMASK(19, 8)
+#define TRIM4_TCA25_0_MSB_MASK GENMASK(7, 0)
+#define TRIM5_TCA105_1_MASK GENMASK(23, 12)
+#define TRIM5_TCA25_1_MASK GENMASK(11, 0)
+
#define VER1_TEMP_LOW_LIMIT 10000
#define VER2_TEMP_LOW_LIMIT -40000
#define VER2_TEMP_HIGH_LIMIT 125000
@@ -65,8 +103,14 @@ static int imx8mm_tmu_get_temp(void *data, int *temp)
u32 val;
val = readl_relaxed(tmu->base + TRITSR) & TRITSR_TEMP0_VAL_MASK;
+
+ /*
+ * Do not validate against the V bit (bit 31) due to errata
+ * ERR051272: TMU: Bit 31 of registers TMU_TSCR/TMU_TRITSR/TMU_TRATSR invalid
+ */
+
*temp = val * 1000;
- if (*temp < VER1_TEMP_LOW_LIMIT)
+ if (*temp < VER1_TEMP_LOW_LIMIT || *temp > VER2_TEMP_HIGH_LIMIT)
return -EAGAIN;
return 0;
@@ -128,6 +172,129 @@ static void imx8mm_tmu_probe_sel_all(struct imx8mm_tmu *tmu)
writel_relaxed(val, tmu->base + TPS);
}
+static int imx8mm_tmu_probe_set_calib_v1(struct platform_device *pdev,
+ struct imx8mm_tmu *tmu)
+{
+ struct device *dev = &pdev->dev;
+ u32 ana0;
+ int ret;
+
+ ret = nvmem_cell_read_u32(&pdev->dev, "calib", &ana0);
+ if (ret) {
+ dev_warn(dev, "Failed to read OCOTP nvmem cell (%d).\n", ret);
+ return ret;
+ }
+
+ writel(FIELD_PREP(TASR_BUF_VREF_MASK,
+ FIELD_GET(ANA0_BUF_VREF_MASK, ana0)) |
+ FIELD_PREP(TASR_BUF_SLOPE_MASK,
+ FIELD_GET(ANA0_BUF_SLOPE_MASK, ana0)),
+ tmu->base + TASR);
+
+ writel(FIELD_PREP(TCALIV_RT_MASK, FIELD_GET(ANA0_RT_MASK, ana0)) |
+ FIELD_PREP(TCALIV_HR_MASK, FIELD_GET(ANA0_HR_MASK, ana0)) |
+ ((ana0 & ANA0_EN) ? TCALIV_EN : 0),
+ tmu->base + TCALIV(0));
+
+ return 0;
+}
+
+static int imx8mm_tmu_probe_set_calib_v2(struct platform_device *pdev,
+ struct imx8mm_tmu *tmu)
+{
+ struct device *dev = &pdev->dev;
+ struct nvmem_cell *cell;
+ u32 trim[4] = { 0 };
+ size_t len;
+ void *buf;
+
+ cell = nvmem_cell_get(dev, "calib");
+ if (IS_ERR(cell))
+ return PTR_ERR(cell);
+
+ buf = nvmem_cell_read(cell, &len);
+ nvmem_cell_put(cell);
+
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
+ memcpy(trim, buf, min(len, sizeof(trim)));
+ kfree(buf);
+
+ if (len != 16) {
+ dev_err(dev,
+ "OCOTP nvmem cell length is %zu, must be 16.\n", len);
+ return -EINVAL;
+ }
+
+ /* Blank sample hardware */
+ if (!trim[0] && !trim[1] && !trim[2] && !trim[3]) {
+ /* Use a default 25C binary codes */
+ writel(FIELD_PREP(TCALIV_SNSR25C_MASK, 0x63c),
+ tmu->base + TCALIV(0));
+ writel(FIELD_PREP(TCALIV_SNSR25C_MASK, 0x63c),
+ tmu->base + TCALIV(1));
+ return 0;
+ }
+
+ writel(FIELD_PREP(TASR_BUF_VERF_SEL_MASK,
+ FIELD_GET(TRIM2_BUF_VERF_SEL_MASK, trim[0])) |
+ FIELD_PREP(TASR_BUF_SLOPE_MASK,
+ FIELD_GET(TRIM2_BUF_SLOP_SEL_MASK, trim[0])),
+ tmu->base + TASR);
+
+ writel(FIELD_PREP(TRIM_BJT_CUR_MASK,
+ FIELD_GET(TRIM2_BJT_CUR_MASK, trim[0])) |
+ FIELD_PREP(TRIM_BGR_MASK, FIELD_GET(TRIM2_BGR_MASK, trim[0])) |
+ FIELD_PREP(TRIM_VLSB_MASK, FIELD_GET(TRIM2_VLSB_MASK, trim[0])) |
+ TRIM_EN_CH,
+ tmu->base + TRIM);
+
+ writel(FIELD_PREP(TCALIV_SNSR25C_MASK,
+ FIELD_GET(TRIM3_TCA25_0_LSB_MASK, trim[1]) |
+ (FIELD_GET(TRIM4_TCA25_0_MSB_MASK, trim[2]) << 4)) |
+ FIELD_PREP(TCALIV_SNSR105C_MASK,
+ FIELD_GET(TRIM4_TCA105_0_MASK, trim[2])),
+ tmu->base + TCALIV(0));
+
+ writel(FIELD_PREP(TCALIV_SNSR25C_MASK,
+ FIELD_GET(TRIM5_TCA25_1_MASK, trim[3])) |
+ FIELD_PREP(TCALIV_SNSR105C_MASK,
+ FIELD_GET(TRIM5_TCA105_1_MASK, trim[3])),
+ tmu->base + TCALIV(1));
+
+ writel(FIELD_PREP(TCALIV_SNSR25C_MASK,
+ FIELD_GET(TRIM3_TCA40_0_MASK, trim[1])) |
+ FIELD_PREP(TCALIV_SNSR105C_MASK,
+ FIELD_GET(TRIM4_TCA40_1_MASK, trim[2])),
+ tmu->base + TCALIV(2));
+
+ return 0;
+}
+
+static int imx8mm_tmu_probe_set_calib(struct platform_device *pdev,
+ struct imx8mm_tmu *tmu)
+{
+ struct device *dev = &pdev->dev;
+
+ /*
+ * Lack of calibration data OCOTP reference is not considered
+ * fatal to retain compatibility with old DTs. It is however
+ * strongly recommended to update such old DTs to get correct
+ * temperature compensation values for each SoC.
+ */
+ if (!of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) {
+ dev_warn(dev,
+ "No OCOTP nvmem reference found, SoC-specific calibration not loaded. Please update your DT.\n");
+ return 0;
+ }
+
+ if (tmu->socdata->version == TMU_VER1)
+ return imx8mm_tmu_probe_set_calib_v1(pdev, tmu);
+
+ return imx8mm_tmu_probe_set_calib_v2(pdev, tmu);
+}
+
static int imx8mm_tmu_probe(struct platform_device *pdev)
{
const struct thermal_soc_data *data;
@@ -176,10 +343,17 @@ static int imx8mm_tmu_probe(struct platform_device *pdev)
goto disable_clk;
}
tmu->sensors[i].hw_id = i;
+
+ if (devm_thermal_add_hwmon_sysfs(tmu->sensors[i].tzd))
+ dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n");
}
platform_set_drvdata(pdev, tmu);
+ ret = imx8mm_tmu_probe_set_calib(pdev, tmu);
+ if (ret)
+ goto disable_clk;
+
/* enable all the probes for V2 TMU */
if (tmu->socdata->version == TMU_VER2)
imx8mm_tmu_probe_sel_all(tmu);
diff --git a/drivers/thermal/imx_sc_thermal.c b/drivers/thermal/imx_sc_thermal.c
index 5d92b70a5d53..4df925e3a80b 100644
--- a/drivers/thermal/imx_sc_thermal.c
+++ b/drivers/thermal/imx_sc_thermal.c
@@ -127,11 +127,6 @@ static int imx_sc_thermal_probe(struct platform_device *pdev)
return 0;
}
-static int imx_sc_thermal_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static int imx_sc_sensors[] = { IMX_SC_R_SYSTEM, IMX_SC_R_PMIC_0, -1 };
static const struct of_device_id imx_sc_thermal_table[] = {
@@ -142,7 +137,6 @@ MODULE_DEVICE_TABLE(of, imx_sc_thermal_table);
static struct platform_driver imx_sc_thermal_driver = {
.probe = imx_sc_thermal_probe,
- .remove = imx_sc_thermal_remove,
.driver = {
.name = "imx-sc-thermal",
.of_match_table = imx_sc_thermal_table,
diff --git a/drivers/thermal/intel/therm_throt.c b/drivers/thermal/intel/therm_throt.c
index 4bb7fddaa143..2e22bb82b738 100644
--- a/drivers/thermal/intel/therm_throt.c
+++ b/drivers/thermal/intel/therm_throt.c
@@ -194,7 +194,7 @@ static const struct attribute_group thermal_attr_group = {
#define THERM_STATUS_PROCHOT_LOG BIT(1)
#define THERM_STATUS_CLEAR_CORE_MASK (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11) | BIT(13) | BIT(15))
-#define THERM_STATUS_CLEAR_PKG_MASK (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11) | BIT(26))
+#define THERM_STATUS_CLEAR_PKG_MASK (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11))
/*
* Clear the bits in package thermal status register for bit = 1
@@ -211,6 +211,9 @@ void thermal_clear_package_intr_status(int level, u64 bit_mask)
} else {
msr = MSR_IA32_PACKAGE_THERM_STATUS;
msr_val = THERM_STATUS_CLEAR_PKG_MASK;
+ if (boot_cpu_has(X86_FEATURE_HFI))
+ msr_val |= BIT(26);
+
}
msr_val &= ~bit_mask;
diff --git a/drivers/thermal/k3_j72xx_bandgap.c b/drivers/thermal/k3_j72xx_bandgap.c
index 16b6bcf1bf4f..031ea1091909 100644
--- a/drivers/thermal/k3_j72xx_bandgap.c
+++ b/drivers/thermal/k3_j72xx_bandgap.c
@@ -177,7 +177,6 @@ struct k3_j72xx_bandgap {
struct device *dev;
void __iomem *base;
void __iomem *cfg2_base;
- void __iomem *fuse_base;
struct k3_thermal_data *ts_data[K3_VTM_MAX_NUM_TS];
};
@@ -249,14 +248,7 @@ static inline int k3_bgp_read_temp(struct k3_thermal_data *devdata,
/* Get temperature callback function for thermal zone */
static int k3_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
{
- struct k3_thermal_data *data = tz->devdata;
- int ret = 0;
-
- ret = k3_bgp_read_temp(data, temp);
- if (ret)
- return ret;
-
- return ret;
+ return k3_bgp_read_temp(tz->devdata, temp);
}
static const struct thermal_zone_device_ops k3_of_thermal_ops = {
@@ -283,7 +275,7 @@ static int k3_j72xx_bandgap_temp_to_adc_code(int temp)
}
static void get_efuse_values(int id, struct k3_thermal_data *data, int *err,
- struct k3_j72xx_bandgap *bgp)
+ void __iomem *fuse_base)
{
int i, tmp, pow;
int ct_offsets[5][K3_VTM_CORRECTION_TEMP_CNT] = {
@@ -305,16 +297,16 @@ static void get_efuse_values(int id, struct k3_thermal_data *data, int *err,
/* Extract the offset value using bit-mask */
if (ct_offsets[id][i] == -1 && i == 1) {
/* 25C offset Case of Sensor 2 split between 2 regs */
- tmp = (readl(bgp->fuse_base + 0x8) & 0xE0000000) >> (29);
- tmp |= ((readl(bgp->fuse_base + 0xC) & 0x1F) << 3);
+ tmp = (readl(fuse_base + 0x8) & 0xE0000000) >> (29);
+ tmp |= ((readl(fuse_base + 0xC) & 0x1F) << 3);
pow = tmp & 0x80;
} else if (ct_offsets[id][i] == -1 && i == 2) {
/* 125C Case of Sensor 3 split between 2 regs */
- tmp = (readl(bgp->fuse_base + 0x4) & 0xF8000000) >> (27);
- tmp |= ((readl(bgp->fuse_base + 0x8) & 0xF) << 5);
+ tmp = (readl(fuse_base + 0x4) & 0xF8000000) >> (27);
+ tmp |= ((readl(fuse_base + 0x8) & 0xF) << 5);
pow = tmp & 0x100;
} else {
- tmp = readl(bgp->fuse_base + ct_offsets[id][i]);
+ tmp = readl(fuse_base + ct_offsets[id][i]);
tmp &= ct_bm[id][i];
tmp = tmp >> __ffs(ct_bm[id][i]);
@@ -347,7 +339,7 @@ static void print_look_up_table(struct device *dev, int *ref_table)
}
struct k3_j72xx_bandgap_data {
- unsigned int has_errata_i2128;
+ const bool has_errata_i2128;
};
static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
@@ -358,11 +350,12 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct k3_j72xx_bandgap *bgp;
struct k3_thermal_data *data;
- int workaround_needed = 0;
+ bool workaround_needed = false;
const struct k3_j72xx_bandgap_data *driver_data;
struct thermal_zone_device *ti_thermal;
int *ref_table;
struct err_values err_vals;
+ void __iomem *fuse_base;
const s64 golden_factors[] = {
-490019999999999936,
@@ -393,15 +386,32 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
if (IS_ERR(bgp->cfg2_base))
return PTR_ERR(bgp->cfg2_base);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
- bgp->fuse_base = devm_ioremap_resource(dev, res);
- if (IS_ERR(bgp->fuse_base))
- return PTR_ERR(bgp->fuse_base);
-
driver_data = of_device_get_match_data(dev);
if (driver_data)
workaround_needed = driver_data->has_errata_i2128;
+ /*
+ * Some of TI's J721E SoCs require a software trimming procedure
+ * for the temperature monitors to function properly. To determine
+ * if this particular SoC is NOT affected, both bits in the
+ * WKUP_SPARE_FUSE0[31:30] will be set (0xC0000000) indicating
+ * when software trimming should NOT be applied.
+ *
+ * https://www.ti.com/lit/er/sprz455c/sprz455c.pdf
+ */
+ if (workaround_needed) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ fuse_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(fuse_base))
+ return PTR_ERR(fuse_base);
+
+ if ((readl(fuse_base) & 0xc0000000) == 0xc0000000)
+ workaround_needed = false;
+ }
+
+ dev_dbg(bgp->dev, "Work around %sneeded\n",
+ workaround_needed ? "" : "not ");
+
pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
@@ -434,13 +444,6 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
goto err_free_ref_table;
}
- /* Workaround not needed if bit30/bit31 is set even for J721e */
- if (workaround_needed && (readl(bgp->fuse_base + 0x0) & 0xc0000000) == 0xc0000000)
- workaround_needed = false;
-
- dev_dbg(bgp->dev, "Work around %sneeded\n",
- workaround_needed ? "not " : "");
-
if (!workaround_needed)
init_table(5, ref_table, golden_factors);
else
@@ -459,7 +462,7 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
err_vals.refs[1] = PLUS30CREF;
err_vals.refs[2] = PLUS125CREF;
err_vals.refs[3] = PLUS150CREF;
- get_efuse_values(id, &data[id], err_vals.errs, bgp);
+ get_efuse_values(id, &data[id], err_vals.errs, fuse_base);
}
if (id == 0 && workaround_needed)
@@ -529,11 +532,11 @@ static int k3_j72xx_bandgap_remove(struct platform_device *pdev)
}
static const struct k3_j72xx_bandgap_data k3_j72xx_bandgap_j721e_data = {
- .has_errata_i2128 = 1,
+ .has_errata_i2128 = true,
};
static const struct k3_j72xx_bandgap_data k3_j72xx_bandgap_j7200_data = {
- .has_errata_i2128 = 0,
+ .has_errata_i2128 = false,
};
static const struct of_device_id of_k3_j72xx_bandgap_match[] = {
diff --git a/drivers/thermal/qcom/lmh.c b/drivers/thermal/qcom/lmh.c
index d3d9b9fa49e8..4122a51e9874 100644
--- a/drivers/thermal/qcom/lmh.c
+++ b/drivers/thermal/qcom/lmh.c
@@ -45,7 +45,7 @@ static irqreturn_t lmh_handle_irq(int hw_irq, void *data)
if (irq)
generic_handle_irq(irq);
- return 0;
+ return IRQ_HANDLED;
}
static void lmh_enable_interrupt(struct irq_data *d)
diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
index 1b2c43eab27d..ff47fc9ac9c5 100644
--- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
+++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
@@ -678,7 +678,7 @@ static int adc_tm5_register_tzd(struct adc_tm5_chip *adc_tm)
&adc_tm5_thermal_ops);
if (IS_ERR(tzd)) {
if (PTR_ERR(tzd) == -ENODEV) {
- dev_warn(adc_tm->dev, "thermal sensor on channel %d is not used\n",
+ dev_dbg(adc_tm->dev, "thermal sensor on channel %d is not used\n",
adc_tm->channels[i].channel);
continue;
}
@@ -1030,10 +1030,8 @@ static int adc_tm5_probe(struct platform_device *pdev)
return irq;
ret = adc_tm5_get_dt_data(adc_tm, node);
- if (ret) {
- dev_err(dev, "get dt data failed: %d\n", ret);
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "get dt data failed\n");
ret = adc_tm->data->init(adc_tm);
if (ret) {
diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
index be785ab37e53..ad84978109e6 100644
--- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
+++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
@@ -252,7 +252,8 @@ static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
disable_s2_shutdown = true;
else
dev_warn(chip->dev,
- "No ADC is configured and critical temperature is above the maximum stage 2 threshold of 140 C! Configuring stage 2 shutdown at 140 C.\n");
+ "No ADC is configured and critical temperature %d mC is above the maximum stage 2 threshold of %ld mC! Configuring stage 2 shutdown at %ld mC.\n",
+ temp, stage2_threshold_max, stage2_threshold_max);
}
skip:
diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
index 67c1748cdf73..4585904fb380 100644
--- a/drivers/thermal/qcom/tsens-8960.c
+++ b/drivers/thermal/qcom/tsens-8960.c
@@ -269,9 +269,12 @@ static const struct tsens_ops ops_8960 = {
static struct tsens_features tsens_8960_feat = {
.ver_major = VER_0,
.crit_int = 0,
+ .combo_int = 0,
.adc = 1,
.srot_split = 0,
.max_sensors = 11,
+ .trip_min_temp = -40000,
+ .trip_max_temp = 120000,
};
struct tsens_plat_data data_8960 = {
diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
index 327f37202c69..04d012e4f728 100644
--- a/drivers/thermal/qcom/tsens-v0_1.c
+++ b/drivers/thermal/qcom/tsens-v0_1.c
@@ -539,9 +539,12 @@ static int calibrate_9607(struct tsens_priv *priv)
static struct tsens_features tsens_v0_1_feat = {
.ver_major = VER_0_1,
.crit_int = 0,
+ .combo_int = 0,
.adc = 1,
.srot_split = 1,
.max_sensors = 11,
+ .trip_min_temp = -40000,
+ .trip_max_temp = 120000,
};
static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = {
diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
index 573e261ccca7..1d7f8a80bd13 100644
--- a/drivers/thermal/qcom/tsens-v1.c
+++ b/drivers/thermal/qcom/tsens-v1.c
@@ -302,9 +302,12 @@ static int calibrate_8976(struct tsens_priv *priv)
static struct tsens_features tsens_v1_feat = {
.ver_major = VER_1_X,
.crit_int = 0,
+ .combo_int = 0,
.adc = 1,
.srot_split = 1,
.max_sensors = 11,
+ .trip_min_temp = -40000,
+ .trip_max_temp = 120000,
};
static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index b293ed32174b..29a61d2d6ca3 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -31,9 +31,23 @@
static struct tsens_features tsens_v2_feat = {
.ver_major = VER_2_X,
.crit_int = 1,
+ .combo_int = 0,
.adc = 0,
.srot_split = 1,
.max_sensors = 16,
+ .trip_min_temp = -40000,
+ .trip_max_temp = 120000,
+};
+
+static struct tsens_features ipq8074_feat = {
+ .ver_major = VER_2_X,
+ .crit_int = 1,
+ .combo_int = 1,
+ .adc = 0,
+ .srot_split = 1,
+ .max_sensors = 16,
+ .trip_min_temp = 0,
+ .trip_max_temp = 204000,
};
static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
@@ -101,6 +115,12 @@ struct tsens_plat_data data_tsens_v2 = {
.fields = tsens_v2_regfields,
};
+struct tsens_plat_data data_ipq8074 = {
+ .ops = &ops_generic_v2,
+ .feat = &ipq8074_feat,
+ .fields = tsens_v2_regfields,
+};
+
/* Kept around for backward compatibility with old msm8996.dtsi */
struct tsens_plat_data data_8996 = {
.num_sensors = 13,
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index b1b10005fb28..b5b136ff323f 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -532,6 +532,27 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
return IRQ_HANDLED;
}
+/**
+ * tsens_combined_irq_thread() - Threaded interrupt handler for combined interrupts
+ * @irq: irq number
+ * @data: tsens controller private data
+ *
+ * Handle the combined interrupt as if it were 2 separate interrupts, so call the
+ * critical handler first and then the up/low one.
+ *
+ * Return: IRQ_HANDLED
+ */
+static irqreturn_t tsens_combined_irq_thread(int irq, void *data)
+{
+ irqreturn_t ret;
+
+ ret = tsens_critical_irq_thread(irq, data);
+ if (ret != IRQ_HANDLED)
+ return ret;
+
+ return tsens_irq_thread(irq, data);
+}
+
static int tsens_set_trips(struct thermal_zone_device *tz, int low, int high)
{
struct tsens_sensor *s = tz->devdata;
@@ -552,8 +573,8 @@ static int tsens_set_trips(struct thermal_zone_device *tz, int low, int high)
dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
hw_id, __func__, low, high);
- cl_high = clamp_val(high, -40000, 120000);
- cl_low = clamp_val(low, -40000, 120000);
+ cl_high = clamp_val(high, priv->feat->trip_min_temp, priv->feat->trip_max_temp);
+ cl_low = clamp_val(low, priv->feat->trip_min_temp, priv->feat->trip_max_temp);
high_val = tsens_mC_to_hw(s, cl_high);
low_val = tsens_mC_to_hw(s, cl_low);
@@ -692,7 +713,7 @@ static int dbg_version_show(struct seq_file *s, void *data)
return ret;
seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);
} else {
- seq_puts(s, "0.1.0\n");
+ seq_printf(s, "0.%d.0\n", priv->feat->ver_major);
}
return 0;
@@ -704,21 +725,14 @@ DEFINE_SHOW_ATTRIBUTE(dbg_sensors);
static void tsens_debug_init(struct platform_device *pdev)
{
struct tsens_priv *priv = platform_get_drvdata(pdev);
- struct dentry *root, *file;
- root = debugfs_lookup("tsens", NULL);
- if (!root)
+ priv->debug_root = debugfs_lookup("tsens", NULL);
+ if (!priv->debug_root)
priv->debug_root = debugfs_create_dir("tsens", NULL);
- else
- priv->debug_root = root;
-
- file = debugfs_lookup("version", priv->debug_root);
- if (!file)
- debugfs_create_file("version", 0444, priv->debug_root,
- pdev, &dbg_version_fops);
/* A directory for each instance of the TSENS IP */
priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);
+ debugfs_create_file("version", 0444, priv->debug, pdev, &dbg_version_fops);
debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);
}
#else
@@ -918,8 +932,6 @@ int __init init_common(struct tsens_priv *priv)
if (tsens_version(priv) >= VER_0_1)
tsens_enable_irq(priv);
- tsens_debug_init(op);
-
err_put_device:
put_device(&op->dev);
return ret;
@@ -960,6 +972,9 @@ static const struct of_device_id tsens_table[] = {
.compatible = "qcom,ipq8064-tsens",
.data = &data_8960,
}, {
+ .compatible = "qcom,ipq8074-tsens",
+ .data = &data_ipq8074,
+ }, {
.compatible = "qcom,mdm9607-tsens",
.data = &data_9607,
}, {
@@ -1071,13 +1086,18 @@ static int tsens_register(struct tsens_priv *priv)
tsens_mC_to_hw(priv->sensor, 0));
}
- ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
- if (ret < 0)
- return ret;
+ if (priv->feat->combo_int) {
+ ret = tsens_register_irq(priv, "combined",
+ tsens_combined_irq_thread);
+ } else {
+ ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
+ if (ret < 0)
+ return ret;
- if (priv->feat->crit_int)
- ret = tsens_register_irq(priv, "critical",
- tsens_critical_irq_thread);
+ if (priv->feat->crit_int)
+ ret = tsens_register_irq(priv, "critical",
+ tsens_critical_irq_thread);
+ }
return ret;
}
@@ -1153,7 +1173,11 @@ static int tsens_probe(struct platform_device *pdev)
}
}
- return tsens_register(priv);
+ ret = tsens_register(priv);
+ if (!ret)
+ tsens_debug_init(pdev);
+
+ return ret;
}
static int tsens_remove(struct platform_device *pdev)
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index ba05c8233356..899af128855f 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -493,19 +493,25 @@ enum regfield_ids {
* struct tsens_features - Features supported by the IP
* @ver_major: Major number of IP version
* @crit_int: does the IP support critical interrupts?
+ * @combo_int: does the IP use one IRQ for up, low and critical thresholds?
* @adc: do the sensors only output adc code (instead of temperature)?
* @srot_split: does the IP neatly splits the register space into SROT and TM,
* with SROT only being available to secure boot firmware?
* @has_watchdog: does this IP support watchdog functionality?
* @max_sensors: maximum sensors supported by this version of the IP
+ * @trip_min_temp: minimum trip temperature supported by this version of the IP
+ * @trip_max_temp: maximum trip temperature supported by this version of the IP
*/
struct tsens_features {
unsigned int ver_major;
unsigned int crit_int:1;
+ unsigned int combo_int:1;
unsigned int adc:1;
unsigned int srot_split:1;
unsigned int has_watchdog:1;
unsigned int max_sensors;
+ int trip_min_temp;
+ int trip_max_temp;
};
/**
@@ -591,6 +597,6 @@ extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607;
extern struct tsens_plat_data data_tsens_v1, data_8976;
/* TSENS v2 targets */
-extern struct tsens_plat_data data_8996, data_tsens_v2;
+extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2;
#endif /* __QCOM_TSENS_H__ */
diff --git a/drivers/thermal/st/stm_thermal.c b/drivers/thermal/st/stm_thermal.c
index 78feb802a87d..e7834ccc7976 100644
--- a/drivers/thermal/st/stm_thermal.c
+++ b/drivers/thermal/st/stm_thermal.c
@@ -488,7 +488,6 @@ MODULE_DEVICE_TABLE(of, stm_thermal_of_match);
static int stm_thermal_probe(struct platform_device *pdev)
{
struct stm_thermal_sensor *sensor;
- struct resource *res;
void __iomem *base;
int ret;
@@ -506,8 +505,7 @@ static int stm_thermal_probe(struct platform_device *pdev)
sensor->dev = &pdev->dev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(&pdev->dev, res);
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
if (IS_ERR(base))
return PTR_ERR(base);
diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index d4b6335ace15..aacba30bc10c 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -604,13 +604,15 @@ struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor,
if (IS_ERR(np)) {
if (PTR_ERR(np) != -ENODEV)
pr_err("Failed to find thermal zone for %pOFn id=%d\n", sensor, id);
- return ERR_CAST(np);
+ ret = PTR_ERR(np);
+ goto out_kfree_of_ops;
}
trips = thermal_of_trips_init(np, &ntrips);
if (IS_ERR(trips)) {
pr_err("Failed to find trip points for %pOFn id=%d\n", sensor, id);
- return ERR_CAST(trips);
+ ret = PTR_ERR(trips);
+ goto out_kfree_of_ops;
}
ret = thermal_of_monitor_init(np, &delay, &pdelay);
@@ -659,6 +661,8 @@ out_kfree_tzp:
kfree(tzp);
out_kfree_trips:
kfree(trips);
+out_kfree_of_ops:
+ kfree(of_ops);
return ERR_PTR(ret);
}
diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
index 67050a1a5b07..a1c9a1530183 100644
--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
@@ -878,7 +878,7 @@ static struct ti_bandgap *ti_bandgap_build(struct platform_device *pdev)
*/
static const struct soc_device_attribute soc_no_cpu_notifier[] = {
{ .machine = "OMAP4430" },
- { /* sentinel */ },
+ { /* sentinel */ }
};
/*** Device driver call backs ***/