mirror of
https://github.com/torvalds/linux.git
synced 2024-12-03 09:31:26 +00:00
- Add the sm8450 QCom compatible string in the DT bindings (Luca
Weiss) - Use devm_platform_get_and_ioremap_resource on the ST platform to group two calls into a single one (Minghao Chi) - Add the sm8550 QCom compatible string in the DT bindings (Neil Armstrong) - Use GENMASK instead of bitmaps and validate the temperature after reading it (Marcus Folkesson) - Convert generic-adc-thermal to DT schema (Rob Herring) - Fix the debug print message where the logic is inverted (Keerthy) - Fix memory leak on thermal_of_zone_register() failure (Ido Schimmel) - Add support for IPQ8074 in the tsens 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 the HWMon support on the imx8mm board (Alexander Stein) - Remove a pointless include in 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 on the tsens QCom driver (Manivannan Sadhasivam) - Consolidate the TI Bandgap driver regarding how is handled the efuse values and the errata handling (Bryan Brattlof) - Document the 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 platform remove callback as it is empty (Uwe Kleine-König) -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEGn3N4YVz0WNVyHskqDIjiipP6E8FAmOZ4+sACgkQqDIjiipP 6E/xWwgAoEK401wQQZSuq4wCAf7djcHRzWTKOpIq6bKtabSmJa/NFBfTQ0dXbuxy CaJqGcsvubyQnzdKvAEld4lbs2tnHw1hNo07exQvBqDueF2iNEdHWqupfIKE7dWH jMuKoCRWS5cPNkmSKIchLsN44lBHplocxERiuZp/DAZeVFNbJH0AqevmPw9IWJ1Q BgbtjNxygyKQvOtqjl4RcAq+/eqHxJR/sYtpFXJs+3bORK55PnjAe+uyb6BayYRd lGevOcas5YNMnLclu9H8s/VGVU5/ld5iA/tZKdipedOzX4AJ2wk5ev0FA4j1AVnj ozlRUec4SXxK9YCp3pBWAwuBWW6L/w== =H6vB -----END PGP SIGNATURE----- Merge tag 'thermal-v6.2-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux Pull thermal driver changes for 6.2-rc1 from Daniel Lezcano: "- Add the sm8450 QCom compatible string in the DT bindings (Luca Weiss) - Use devm_platform_get_and_ioremap_resource on the ST platform to group two calls into a single one (Minghao Chi) - Add the sm8550 QCom compatible string in the DT bindings (Neil Armstrong) - Use GENMASK instead of bitmaps and validate the temperature after reading it (Marcus Folkesson) - Convert generic-adc-thermal to DT schema (Rob Herring) - Fix the debug print message where the logic is inverted (Keerthy) - Fix memory leak on thermal_of_zone_register() failure (Ido Schimmel) - Add support for IPQ8074 in the tsens 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 the HWMon support on the imx8mm board (Alexander Stein) - Remove a pointless include in 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 on the tsens QCom driver (Manivannan Sadhasivam) - Consolidate the TI Bandgap driver regarding how is handled the efuse values and the errata handling (Bryan Brattlof) - Document the 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 platform remove callback as it is empty (Uwe Kleine-König)" * tag 'thermal-v6.2-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux: (34 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 ...
This commit is contained in:
commit
bd7bcc4f96
@ -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>;
|
||||
};
|
||||
...
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -57,8 +57,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
|
||||
@ -66,15 +72,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
|
||||
@ -128,22 +130,64 @@ allOf:
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
items:
|
||||
- description: Combined interrupt if upper or lower threshold crossed
|
||||
interrupt-names:
|
||||
maxItems: 1
|
||||
|
||||
else:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 2
|
||||
interrupt-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: uplow
|
||||
|
||||
- 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:
|
||||
items:
|
||||
- description: Combined interrupt if upper or lower threshold crossed
|
||||
- description: Interrupt if critical threshold crossed
|
||||
interrupt-names:
|
||||
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
|
||||
@ -226,4 +270,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>;
|
||||
};
|
||||
...
|
||||
|
@ -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
|
||||
|
@ -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>;
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
};
|
@ -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
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#define pr_fmt(fmt) "Power allocator: " fmt
|
||||
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/thermal.h>
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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[] = {
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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 = {
|
||||
|
@ -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] = {
|
||||
|
@ -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] = {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
@ -959,6 +971,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)
|
||||
|
@ -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__ */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 ***/
|
||||
|
Loading…
Reference in New Issue
Block a user