History

Merge tag 'thermal-v7.3-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/thermal/linux

Pull thermal driver updates for 7.3-rc1 from Daniel Lezcano: "- Move thermal_zone_device_enable() to the right place in order to prevent calling it if the thermal zone registration failed (Dan Carpenter) - Improve bitfield manipulations on Armada (Bryan B. Lima) - Remove unneeded 'fast_io' on Sun8i and Armada (Wolfram Sang) - Fix wrong boundary when clamping the low values in the set_trips() callback and fix wrong mask when setting the temperature interval on Airoha (Christian Marangi) - Make use of the regmap API in order to support the Airoha AN7583 (Christian Marangi) - Fix adc_tm5_get_temp() return check value on the QCom SPMI ADC sensor (Rakesh Kota) - Fix unbalanced clock enablement when the resume fails on the iMX driver (Can Peng) - Add Qualcomm Master BandGap thermal monitor support (Satya Priya Kakitapalli) - Add Maili Temperature bindings compatible (Haritha S K) - Add a devm action to clean hardware interrupts, sampling, and control registers on Spacemit K1 (Pei Xiao) - Fix trivial typo in an OF code comment (Marek Vasut) - Remove unecessary print on Qcom SPMI ADC driver when a call to devm_request_threaded_irq() fails as this one already prints a message (Jishnu Prakash) - Add support for QCom PMIC5 Gen3 ADC by using auxialiary driver and shared interrupt with the IIO driver (Jishnu Prakash) - Make resets optional on MT8196 and add the corresponding property in the DT bindings (AngeloGioacchino Del Regno) - Fix clock staying enabled with the resume operation fails on Qoriq (Can Peng) - Fix wrong closing brace position in thermal library header (Andreas Haufler) - Fix low and high trip point validation by moving the check after the clamp on the spacemit driver (surendra) - Remove redundant error messages on IRQ request failure (Pan Chuang) * tag 'thermal-v7.3-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/thermal/linux: (26 commits) thermal/drivers: Remove redundant error messages on IRQ request failure thermal/drivers/spacemit: Validate clamped trip thresholds tools/lib/thermal: Fix misplaced extern "C" closing brace thermal/drivers/qoriq: Disable clock on resume failure thermal/drivers/mediatek/lvts_thermal: Make reset optional for MT8196 dt-bindings: thermal: mediatek: Make resets optional for MT8196 thermal/drivers/qcom: add support for PMIC5 Gen3 ADC thermal monitoring iio: adc: qcom-spmi-adc5-gen3: Share SDAM0 IRQ with ADC_TM auxiliary driver iio: adc: qcom-spmi-adc5-gen3: Remove an unnecessary print thermal/of: Fix trivial enabled typo thermal/drivers/spacemit/k1: Add shutdown action and reorder registration order dt-bindings: thermal: qcom-tsens: Document the Maili Temperature Sensor thermal/drivers/qcom: Add support for Qualcomm MBG thermal monitoring dt-bindings: thermal: Add Qualcomm MBG thermal monitor support thermal/drivers/imx: Disable clock on runtime resume failure thermal/drivers/qcom-spmi-adc-tm5: Drop IIO_VAL_INT check in adc_tm5_get_temp thermal/drivers/airoha: Add support for AN7583 Thermal Sensor dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC thermal/drivers/airoha: Generalize get_thermal_ADC and set_mux function thermal/drivers/airoha: Generalize probe function ...

Rafael J. Wysocki committed 3 months ago

Commit ccda0152 parents 2d5667b 55c16e138 files · +992 −275Browse files

Unified · Split

38 files
  1. Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml +14 −0
  2. Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +4 −0
  3. Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml +12 −1
  4. Documentation/devicetree/bindings/thermal/qcom,pm8775-mbg-tm.yaml +72 −0
  5. Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +1 −0
  6. drivers/iio/adc/qcom-spmi-adc5-gen3.c +19 −50
  7. drivers/thermal/airoha_thermal.c +313 −69
  8. drivers/thermal/armada_thermal.c +45 −61
  9. drivers/thermal/broadcom/brcmstb_thermal.c +1 −2
  10. drivers/thermal/db8500_thermal.c +2 −6
  11. drivers/thermal/hisi_thermal.c +1 −3
  12. drivers/thermal/imx91_thermal.c +1 −1
  13. drivers/thermal/imx_thermal.c +8 −5
  14. drivers/thermal/loongson2_thermal.c +1 −1
  15. drivers/thermal/max77620_thermal.c +2 −6
  16. drivers/thermal/mediatek/lvts_thermal.c +15 −2
  17. drivers/thermal/qcom/Kconfig +23 −0
  18. drivers/thermal/qcom/Makefile +2 −0
  19. drivers/thermal/qcom/lmh.c +0 −1
  20. drivers/thermal/qcom/qcom-spmi-adc-tm5.c +0 −3
  21. drivers/thermal/qcom/qcom-spmi-mbg-tm.c +256 −0
  22. drivers/thermal/qcom/tsens.c +1 −4
  23. drivers/thermal/qoriq_thermal.c +11 −2
  24. drivers/thermal/renesas/rcar_thermal.c +6 −13
  25. drivers/thermal/renesas/rzg3e_thermal.c +1 −3
  26. drivers/thermal/rockchip_thermal.c +1 −2
  27. drivers/thermal/samsung/exynos_tmu.c +1 −3
  28. drivers/thermal/spacemit/k1_tsensor.c +62 −16
  29. drivers/thermal/st/st_thermal_memmap.c +1 −3
  30. drivers/thermal/st/stm_thermal.c +1 −4
  31. drivers/thermal/sun8i_thermal.c +0 −1
  32. drivers/thermal/tegra/soctherm.c +2 −6
  33. drivers/thermal/tegra/tegra30-tsensor.c +1 −2
  34. drivers/thermal/thermal-fw.c +12 −0
  35. drivers/thermal/thermal_fw.c +97 −0
  36. drivers/thermal/thermal_of.c +1 −1
  37. include/linux/iio/adc/qcom-adc5-gen3-common.h +0 −2
  38. tools/lib/thermal/include/thermal.h +2 −2
Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml+14−0
@@ -19,15 +19,29 @@ properties: · 18 unmodified lines
19 items:19 items:
20 - enum:20 - enum:
21 - airoha,en7581-chip-scu21 - airoha,en7581-chip-scu
22 - airoha,an7583-chip-scu
22 - const: syscon23 - const: syscon
23 24
24 reg:25 reg:
25 maxItems: 126 maxItems: 1
26 27
28 '#thermal-sensor-cells':
29 const: 0
30
27required:31required:
28 - compatible32 - compatible
29 - reg33 - reg
30 34
35if:
36 properties:
37 compatible:
38 contains:
39 const: airoha,en7581-chip-scu
40
41then:
42 properties:
43 '#thermal-sensor-cells': false
44
31additionalProperties: false45additionalProperties: false
32 46
33examples:47examples:
Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml+4−0
@@ -193,6 +193,10 @@ patternProperties: · 192 unmodified lines
193 type: object193 type: object
194 $ref: /schemas/thermal/qcom,spmi-temp-alarm.yaml#194 $ref: /schemas/thermal/qcom,spmi-temp-alarm.yaml#
195 195
196 "^temperature-sensor@[0-9a-f]+$":
197 type: object
198 $ref: /schemas/thermal/qcom,pm8775-mbg-tm.yaml#
199
196 "^typec@[0-9a-f]+$":200 "^typec@[0-9a-f]+$":
197 type: object201 type: object
198 $ref: /schemas/usb/qcom,pmic-typec.yaml#202 $ref: /schemas/usb/qcom,pmic-typec.yaml#
Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml+12−1
@@ -94,12 +94,23 @@ allOf: · 93 unmodified lines
94 nvmem-cell-names:94 nvmem-cell-names:
95 minItems: 295 minItems: 2
96 96
97 - if:
98 properties:
99 compatible:
100 not:
101 contains:
102 enum:
103 - mediatek,mt8196-lvts-ap
104 - mediatek,mt8196-lvts-mcu
105 then:
106 required:
107 - resets
108
97required:109required:
98 - compatible110 - compatible
99 - reg111 - reg
100 - interrupts112 - interrupts
101 - clocks113 - clocks
102 - resets
103 - nvmem-cells114 - nvmem-cells
104 - nvmem-cell-names115 - nvmem-cell-names
105 116
Documentation/devicetree/bindings/thermal/qcom,pm8775-mbg-tm.yaml+72−0
@@ -0,0 +1,72 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/thermal/qcom,pm8775-mbg-tm.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Qualcomm's SPMI PMIC MBG Thermal Monitoring
8
9maintainers:
10 - Jishnu Prakash <jishnu.prakash@oss.qualcomm.com>
11 - Kamal Wadhwa <kamal.wadhwa@oss.qualcomm.com>
12
13description:
14 Qualcomm's MBG(Master Bandgap) temperature alarm monitors the die
15 temperature and generates an interrupt if the PMIC die temperature is
16 over a set of programmable temperature thresholds. It allows monitoring
17 for both hot and cold, LVL1 and LVL2 thresholds, which makes it different
18 from the existing temp alarm peripheral. The interrupt comes over SPMI
19 and the MBG's fault status register gives details to understand whether
20 it is a hot/cold and LVL1/LVL2 violation.
21
22properties:
23 compatible:
24 const: qcom,pm8775-mbg-tm
25
26 reg:
27 maxItems: 1
28
29 interrupts:
30 maxItems: 1
31
32 io-channels:
33 items:
34 - description: ADC channel, which reports chip die temperature.
35
36 io-channel-names:
37 items:
38 - const: thermal
39
40 '#thermal-sensor-cells':
41 const: 0
42
43required:
44 - compatible
45 - reg
46 - interrupts
47 - io-channels
48 - io-channel-names
49
50allOf:
51 - $ref: thermal-sensor.yaml#
52
53unevaluatedProperties: false
54
55examples:
56 - |
57 #include <dt-bindings/interrupt-controller/irq.h>
58
59 pmic {
60 #address-cells = <1>;
61 #size-cells = <0>;
62
63 temperature-sensor@d700 {
64 compatible = "qcom,pm8775-mbg-tm";
65 reg = <0xd700>;
66 interrupts = <0x1 0xd7 0x0 IRQ_TYPE_EDGE_RISING>;
67 io-channels = <&pm8775_adc 0x3>;
68 io-channel-names = "thermal";
69 #thermal-sensor-cells = <0>;
70 };
71 };
72...
Documentation/devicetree/bindings/thermal/qcom-tsens.yaml+1−0
@@ -58,6 +58,7 @@ properties: · 57 unmodified lines
58 - qcom,glymur-tsens58 - qcom,glymur-tsens
59 - qcom,hawi-tsens59 - qcom,hawi-tsens
60 - qcom,kaanapali-tsens60 - qcom,kaanapali-tsens
61 - qcom,maili-tsens
61 - qcom,milos-tsens62 - qcom,milos-tsens
62 - qcom,nord-tsens63 - qcom,nord-tsens
63 - qcom,msm8953-tsens64 - qcom,msm8953-tsens
drivers/iio/adc/qcom-spmi-adc5-gen3.c+19−50
@@ -55,9 +55,6 @@ struct adc5_channel_prop { · 54 unmodified lines
55 * requests from multiple clients.55 * requests from multiple clients.
56 * @data: software configuration data.56 * @data: software configuration data.
57 * @n_tm_channels: number of ADC channels used for TM measurements.57 * @n_tm_channels: number of ADC channels used for TM measurements.
58 * @handler: TM callback to be called for threshold violation interrupt
59 * on first SDAM.
60 * @tm_aux: pointer to auxiliary TM device.
61 */58 */
62struct adc5_chip {59struct adc5_chip {
63 struct device *dev;60 struct device *dev;
@@ -69,8 +66,6 @@ struct adc5_chip { · 5 unmodified lines
69 struct mutex lock;66 struct mutex lock;
70 const struct adc5_data *data;67 const struct adc5_data *data;
71 unsigned int n_tm_channels;68 unsigned int n_tm_channels;
72 void (*handler)(struct auxiliary_device *tm_aux);
73 struct auxiliary_device *tm_aux;
74};69};
75 70
76int adc5_gen3_read(struct adc5_device_data *adc, unsigned int sdam_index,71int adc5_gen3_read(struct adc5_device_data *adc, unsigned int sdam_index,
@@ -286,23 +281,21 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) · 209 unmodified lines
286{281{
287 struct adc5_chip *adc = dev_id;282 struct adc5_chip *adc = dev_id;
288 struct device *dev = adc->dev;283 struct device *dev = adc->dev;
289 struct auxiliary_device *adev;
290 u8 status, eoc_status, val;284 u8 status, eoc_status, val;
291 u8 tm_status[2];
292 int ret;285 int ret;
293 286
294 ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM,287 ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM,
295 ADC5_GEN3_STATUS1, &status, sizeof(status));288 ADC5_GEN3_STATUS1, &status, sizeof(status));
296 if (ret) {289 if (ret) {
297 dev_err(dev, "adc read status1 failed with %d\n", ret);290 dev_err(dev, "adc read status1 failed with %d\n", ret);
298 return IRQ_HANDLED;291 return IRQ_NONE;
299 }292 }
300 293
301 ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM,294 ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM,
302 ADC5_GEN3_EOC_STS, &eoc_status, sizeof(eoc_status));295 ADC5_GEN3_EOC_STS, &eoc_status, sizeof(eoc_status));
303 if (ret) {296 if (ret) {
304 dev_err(dev, "adc read eoc status failed with %d\n", ret);297 dev_err(dev, "adc read eoc status failed with %d\n", ret);
305 return IRQ_HANDLED;298 return IRQ_NONE;
306 }299 }
307 300
308 if (status & ADC5_GEN3_STATUS1_CONV_FAULT) {301 if (status & ADC5_GEN3_STATUS1_CONV_FAULT) {
@@ -315,30 +308,13 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) · 6 unmodified lines
315 return IRQ_HANDLED;308 return IRQ_HANDLED;
316 }309 }
317 310
318 /* CHAN0 is the preconfigured channel for immediate conversion */311 dev_dbg(dev, "Interrupt status:%#x, EOC status:%#x\n", status, eoc_status);
319 if (eoc_status & ADC5_GEN3_EOC_CHAN_0)
320 complete(&adc->complete);
321
322 ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM,
323 ADC5_GEN3_TM_HIGH_STS, tm_status, sizeof(tm_status));
324 if (ret) {
325 dev_err(dev, "adc read TM status failed with %d\n", ret);
326 return IRQ_HANDLED;
327 }
328
329 dev_dbg(dev, "Interrupt status:%#x, EOC status:%#x, high:%#x, low:%#x\n",
330 status, eoc_status, tm_status[0], tm_status[1]);
331 312
332 if (tm_status[0] || tm_status[1]) {313 /* CHAN0 is the preconfigured channel for immediate conversion */
333 adev = adc->tm_aux;314 if (!(eoc_status & ADC5_GEN3_EOC_CHAN_0))
334 if (!adev || !adev->dev.driver) {315 return IRQ_NONE;
335 dev_err(dev, "adc_tm auxiliary device not initialized\n");
336 return IRQ_HANDLED;
337 }
338
339 adc->handler(adev);
340 }
341 316
317 complete(&adc->complete);
342 return IRQ_HANDLED;318 return IRQ_HANDLED;
343}319}
344 320
@@ -683,8 +659,6 @@ static int adc5_gen3_add_aux_tm_device(struct adc5_chip *adc) · 338 unmodified lines
683 if (ret)659 if (ret)
684 return ret;660 return ret;
685 661
686 adc->tm_aux = &aux_device->aux_dev;
687
688 return 0;662 return 0;
689}663}
690 664
@@ -740,16 +714,6 @@ int adc5_gen3_therm_code_to_temp(struct device *dev, · 49 unmodified lines
740}714}
741EXPORT_SYMBOL_NS_GPL(adc5_gen3_therm_code_to_temp, "QCOM_SPMI_ADC5_GEN3");715EXPORT_SYMBOL_NS_GPL(adc5_gen3_therm_code_to_temp, "QCOM_SPMI_ADC5_GEN3");
742 716
743void adc5_gen3_register_tm_event_notifier(struct device *dev,
744 void (*handler)(struct auxiliary_device *))
745{
746 struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
747 struct adc5_chip *adc = iio_priv(indio_dev);
748
749 adc->handler = handler;
750}
751EXPORT_SYMBOL_NS_GPL(adc5_gen3_register_tm_event_notifier, "QCOM_SPMI_ADC5_GEN3");
752
753static int adc5_gen3_probe(struct platform_device *pdev)717static int adc5_gen3_probe(struct platform_device *pdev)
754{718{
755 struct device *dev = &pdev->dev;719 struct device *dev = &pdev->dev;
@@ -816,14 +780,19 @@ static int adc5_gen3_probe(struct platform_device *pdev) · 60 unmodified lines
816 return -ENOMEM;780 return -ENOMEM;
817 }781 }
818 782
819 ret = devm_request_irq(dev, adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq,783 /*
820 adc5_gen3_isr, 0,784 * This interrupt is shared with the ADC_TM auxiliary driver, which
821 adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq_name,785 * is threaded and uses IRQF_ONESHOT. Since shared interrupts need
822 adc);786 * to agree on IRQF_ONESHOT configuration and there is a kernel
787 * warning for using IRQF_ONESHOT with non-threaded interrupts,
788 * make this also a threaded IRQ.
789 */
790 ret = devm_request_threaded_irq(dev, adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq,
791 NULL, adc5_gen3_isr, IRQF_ONESHOT | IRQF_SHARED,
792 adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq_name,
793 adc);
823 if (ret)794 if (ret)
824 return dev_err_probe(dev, ret,795 return ret;
825 "Failed to request SDAM%d irq\n",
826 ADC5_GEN3_VADC_SDAM);
827 796
828 ret = adc5_get_fw_data(adc);797 ret = adc5_get_fw_data(adc);
829 if (ret)798 if (ret)
drivers/thermal/airoha_thermal.c+313−69
@@ -18,6 +18,12 @@ · 17 unmodified lines
18#define EN7581_DOUT_TADC 0x2f818#define EN7581_DOUT_TADC 0x2f8
19#define EN7581_DOUT_TADC_MASK GENMASK(15, 0)19#define EN7581_DOUT_TADC_MASK GENMASK(15, 0)
20 20
21#define AN7583_MUX_SENSOR 0x2a0
22#define AN7583_LOAD_ADJ GENMASK(3, 2)
23#define AN7583_MUX_TADC 0x2e4
24#define AN7583_MUX_TADC_MASK GENMASK(3, 1)
25#define AN7583_DOUT_TADC 0x2f0
26
21/* PTP_THERMAL regs */27/* PTP_THERMAL regs */
22#define EN7581_TEMPMONCTL0 0x80028#define EN7581_TEMPMONCTL0 0x800
23#define EN7581_SENSE3_EN BIT(3)29#define EN7581_SENSE3_EN BIT(3)
@@ -181,6 +187,11 @@ · 157 unmodified lines
181#define EN7581_SCU_THERMAL_PROTECT_KEY 0x12187#define EN7581_SCU_THERMAL_PROTECT_KEY 0x12
182#define EN7581_SCU_THERMAL_MUX_DIODE1 0x7188#define EN7581_SCU_THERMAL_MUX_DIODE1 0x7
183 189
190#define AN7583_SCU_THERMAL_PROTECT_KEY 0x80
191#define AN7583_NUM_SENSOR 3
192
193#define AIROHA_THERMAL_NO_MUX_SENSOR -1
194
184/* Convert temp to raw value as read from ADC ((((temp / 100) - init) * slope) / 1000) + offset */195/* Convert temp to raw value as read from ADC ((((temp / 100) - init) * slope) / 1000) + offset */
185#define TEMP_TO_RAW(priv, temp) ((((((temp) / 100) - (priv)->init_temp) * \196#define TEMP_TO_RAW(priv, temp) ((((((temp) / 100) - (priv)->init_temp) * \
186 (priv)->default_slope) / 1000) + \197 (priv)->default_slope) / 1000) + \
@@ -193,42 +204,131 @@ · 6 unmodified lines
193 204
194#define AIROHA_MAX_SAMPLES 6205#define AIROHA_MAX_SAMPLES 6
195 206
207/*
208 * AN7583 supports all these ADC mux but the original driver
209 * always checked temp with the AN7583_BGP_TEMP_SENSOR.
210 * Assume using the other sensor temperature is invalid and
211 * always read from AN7583_BGP_TEMP_SENSOR.
212 *
213 * On top of this it's defined that AN7583 supports 3
214 * sensor: AN7583_BGP_TEMP_SENSOR, AN7583_GBE_TEMP_SENSOR,
215 * AN7583_CPU_TEMP_SENSOR.
216 *
217 * Provide the ADC mux for reference.
218 */
219enum an7583_thermal_adc_mux {
220 AN7583_BGP_TEMP_SENSOR,
221 AN7583_PAD_AVS,
222 AN7583_CORE_POWER,
223 AN7583_AVSDAC_OUT,
224 AN7583_VCM,
225 AN7583_GBE_TEMP_SENSOR,
226 AN7583_CPU_TEMP_SENSOR,
227
228 AN7583_ADC_MUX_MAX,
229};
230
231enum an7583_thermal_diode_mux {
232 AN7583_D0_TADC,
233 AN7583_ZERO_TADC,
234 AN7583_D1_TADC,
235};
236
237enum airoha_thermal_chip_scu_field {
238 AIROHA_THERMAL_DOUT_TADC,
239 AIROHA_THERMAL_MUX_SENSOR,
240 AIROHA_THERMAL_MUX_TADC,
241
242 /* keep last */
243 AIROHA_THERMAL_FIELD_MAX,
244};
245
196struct airoha_thermal_priv {246struct airoha_thermal_priv {
197 void __iomem *base;247 struct regmap *map;
198 struct regmap *chip_scu;248 struct regmap *chip_scu;
249 struct regmap_field *chip_scu_fields[AIROHA_THERMAL_FIELD_MAX];
199 struct resource scu_adc_res;250 struct resource scu_adc_res;
200 251
252 u32 pllrg_protect;
253 int current_adc;
254
201 struct thermal_zone_device *tz;255 struct thermal_zone_device *tz;
202 int init_temp;256 int init_temp;
203 int default_slope;257 int default_slope;
204 int default_offset;258 int default_offset;
205};259};
206 260
261struct airoha_thermal_soc_data {
262 u32 pllrg_protect;
263
264 const struct thermal_zone_device_ops *thdev_ops;
265 int (*probe)(struct platform_device *pdev,
266 struct airoha_thermal_priv *priv);
267 int (*post_probe)(struct platform_device *pdev);
268};
269
270static const unsigned int an7583_thermal_coeff[AN7583_ADC_MUX_MAX] = {
271 [AN7583_BGP_TEMP_SENSOR] = 973,
272 [AN7583_GBE_TEMP_SENSOR] = 995,
273 [AN7583_CPU_TEMP_SENSOR] = 1035,
274};
275
276static const unsigned int an7583_thermal_slope[AN7583_ADC_MUX_MAX] = {
277 [AN7583_BGP_TEMP_SENSOR] = 7440,
278 [AN7583_GBE_TEMP_SENSOR] = 7620,
279 [AN7583_CPU_TEMP_SENSOR] = 8390,
280};
281
282static const unsigned int an7583_thermal_offset[AN7583_ADC_MUX_MAX] = {
283 [AN7583_BGP_TEMP_SENSOR] = 294,
284 [AN7583_GBE_TEMP_SENSOR] = 298,
285 [AN7583_CPU_TEMP_SENSOR] = 344,
286};
287
207static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)288static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
208{289{
209 u32 val;290 u32 val;
210 291
211 regmap_read(priv->chip_scu, EN7581_DOUT_TADC, &val);292 regmap_field_read(priv->chip_scu_fields[AIROHA_THERMAL_DOUT_TADC],
212 return FIELD_GET(EN7581_DOUT_TADC_MASK, val);293 &val);
294 return val;
213}295}
214 296
215static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)297static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv,
298 int tdac_idx, int sensor_idx)
216{299{
217 u32 adc_mux, pllrg;300 u32 pllrg;
218 301
219 /* Save PLLRG current value */302 /* Save PLLRG current value */
220 regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);303 regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
221 304
222 /* Give access to thermal regs */305 /* Give access to Thermal regs */
223 regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);306 regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
224 adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);307 priv->pllrg_protect);
225 regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);308
309 /*
310 * Configure Thermal Sensor mux to sensor_idx.
311 * (if not supported, sensor_idx is AIROHA_THERMAL_NO_MUX_SENSOR)
312 */
313 if (sensor_idx != AIROHA_THERMAL_NO_MUX_SENSOR)
314 regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_SENSOR],
315 sensor_idx);
316
317 /* Configure Thermal ADC mux to tdac_idx */
318 if (priv->current_adc != tdac_idx) {
319 regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
320 tdac_idx);
321 priv->current_adc = tdac_idx;
322 }
226 323
227 /* Restore PLLRG value on exit */324 /* Restore PLLRG value on exit */
228 regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);325 regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
326
327 /* Sleep 10 ms for Thermal ADC to enable */
328 usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
229}329}
230 330
231static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)331static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
232{332{
233 struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);333 struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
234 int min_value, max_value, avg_value, value;334 int min_value, max_value, avg_value, value;
@@ -253,7 +353,7 @@ static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp) · 18 unmodified lines
253 return 0;353 return 0;
254}354}
255 355
256static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,356static int en7581_thermal_set_trips(struct thermal_zone_device *tz, int low,
257 int high)357 int high)
258{358{
259 struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);359 struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
@@ -265,44 +365,44 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low, · 5 unmodified lines
265 RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));365 RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
266 366
267 /* We offset the high temp of 1°C to trigger correct event */367 /* We offset the high temp of 1°C to trigger correct event */
268 writel(TEMP_TO_RAW(priv, high) >> 4,368 regmap_write(priv->map, EN7581_TEMPOFFSETH,
269 priv->base + EN7581_TEMPOFFSETH);369 TEMP_TO_RAW(priv, high) >> 4);
270 370
271 enable_monitor = true;371 enable_monitor = true;
272 }372 }
273 373
274 if (low != -INT_MAX) {374 if (low != -INT_MAX) {
275 /* Validate low and clamp it to a supported value */375 /* Validate low and clamp it to a supported value */
276 low = clamp_t(int, high, RAW_TO_TEMP(priv, 0),376 low = clamp_t(int, low, RAW_TO_TEMP(priv, 0),
277 RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));377 RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
278 378
279 /* We offset the low temp of 1°C to trigger correct event */379 /* We offset the low temp of 1°C to trigger correct event */
280 writel(TEMP_TO_RAW(priv, low) >> 4,380 regmap_write(priv->map, EN7581_TEMPOFFSETL,
281 priv->base + EN7581_TEMPOFFSETL);381 TEMP_TO_RAW(priv, low) >> 4);
282 382
283 enable_monitor = true;383 enable_monitor = true;
284 }384 }
285 385
286 /* Enable sensor 0 monitor after trip are set */386 /* Enable sensor 0 monitor after trip are set */
287 if (enable_monitor)387 if (enable_monitor)
288 writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0);388 regmap_write(priv->map, EN7581_TEMPMONCTL0, EN7581_SENSE0_EN);
289 389
290 return 0;390 return 0;
291}391}
292 392
293static const struct thermal_zone_device_ops thdev_ops = {393static const struct thermal_zone_device_ops en7581_thdev_ops = {
294 .get_temp = airoha_thermal_get_temp,394 .get_temp = en7581_thermal_get_temp,
295 .set_trips = airoha_thermal_set_trips,395 .set_trips = en7581_thermal_set_trips,
296};396};
297 397
298static irqreturn_t airoha_thermal_irq(int irq, void *data)398static irqreturn_t en7581_thermal_irq(int irq, void *data)
299{399{
300 struct airoha_thermal_priv *priv = data;400 struct airoha_thermal_priv *priv = data;
301 enum thermal_notify_event event;401 enum thermal_notify_event event;
302 bool update = false;402 bool update = false;
303 u32 status;403 u32 status = 0;
304 404
305 status = readl(priv->base + EN7581_TEMPMONINTSTS);405 regmap_read(priv->map, EN7581_TEMPMONINTSTS, &status);
306 switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) {406 switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) {
307 case EN7581_HOFSINTSTS0:407 case EN7581_HOFSINTSTS0:
308 event = THERMAL_TRIP_VIOLATED;408 event = THERMAL_TRIP_VIOLATED;
@@ -318,7 +418,7 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data) · 9 unmodified lines
318 }418 }
319 419
320 /* Reset Interrupt */420 /* Reset Interrupt */
321 writel(status, priv->base + EN7581_TEMPMONINTSTS);421 regmap_write(priv->map, EN7581_TEMPMONINTSTS, status);
322 422
323 if (update)423 if (update)
324 thermal_zone_device_update(priv->tz, event);424 thermal_zone_device_update(priv->tz, event);
@@ -326,21 +426,21 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data) · 1 unmodified line
326 return IRQ_HANDLED;426 return IRQ_HANDLED;
327}427}
328 428
329static void airoha_thermal_setup_adc_val(struct device *dev,429static void en7581_thermal_setup_adc_val(struct device *dev,
330 struct airoha_thermal_priv *priv)430 struct airoha_thermal_priv *priv)
331{431{
332 u32 efuse_calib_info, cpu_sensor;432 u32 efuse_calib_info = 0;
433 u32 cpu_sensor = 0;
333 434
334 /* Setup thermal sensor to ADC mode and setup the mux to DIODE1 */435 /* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */
335 airoha_init_thermal_ADC_mode(priv);436 airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1,
336 /* sleep 10 ms for ADC to enable */437 AIROHA_THERMAL_NO_MUX_SENSOR);
337 usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
338 438
339 efuse_calib_info = readl(priv->base + EN7581_EFUSE_TEMP_OFFSET_REG);439 regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
340 if (efuse_calib_info) {440 if (efuse_calib_info) {
341 priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info);441 priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info);
342 /* Different slope are applied if the sensor is used for CPU or for package */442 /* Different slope are applied if the sensor is used for CPU or for package */
343 cpu_sensor = readl(priv->base + EN7581_EFUSE_TEMP_CPU_SENSOR_REG);443 regmap_read(priv->map, EN7581_EFUSE_TEMP_CPU_SENSOR_REG, &cpu_sensor);
344 if (cpu_sensor) {444 if (cpu_sensor) {
345 priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT;445 priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT;
346 priv->init_temp = EN7581_INIT_TEMP_FTK_X10;446 priv->init_temp = EN7581_INIT_TEMP_FTK_X10;
@@ -356,11 +456,11 @@ static void airoha_thermal_setup_adc_val(struct device *dev, · 9 unmodified lines
356 }456 }
357}457}
358 458
359static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)459static void en7581_thermal_setup_monitor(struct airoha_thermal_priv *priv)
360{460{
361 /* Set measure mode */461 /* Set measure mode */
362 writel(FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4),462 regmap_write(priv->map, EN7581_TEMPMSRCTL0,
363 priv->base + EN7581_TEMPMSRCTL0);463 FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4));
364 464
365 /*465 /*
366 * Configure ADC valid reading addr466 * Configure ADC valid reading addr
@@ -375,15 +475,15 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv) · 8 unmodified lines
375 * We set valid instead of volt as we don't enable valid/volt475 * We set valid instead of volt as we don't enable valid/volt
376 * split reading and AHB read valid addr in such case.476 * split reading and AHB read valid addr in such case.
377 */477 */
378 writel(priv->scu_adc_res.start + EN7581_DOUT_TADC,478 regmap_write(priv->map, EN7581_TEMPADCVALIDADDR,
379 priv->base + EN7581_TEMPADCVALIDADDR);479 priv->scu_adc_res.start + EN7581_DOUT_TADC);
380 480
381 /*481 /*
382 * Configure valid bit on a fake value of bit 16. The ADC outputs482 * Configure valid bit on a fake value of bit 16. The ADC outputs
383 * max of 2 bytes for voltage.483 * max of 2 bytes for voltage.
384 */484 */
385 writel(FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16),485 regmap_write(priv->map, EN7581_TEMPADCVALIDMASK,
386 priv->base + EN7581_TEMPADCVALIDMASK);486 FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16));
387 487
388 /*488 /*
389 * AHB supports max 12 bytes for ADC voltage. Shift the read489 * AHB supports max 12 bytes for ADC voltage. Shift the read
@@ -391,40 +491,53 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv) · 1 unmodified line
391 * in the order of half a °C and is acceptable in the context491 * in the order of half a °C and is acceptable in the context
392 * of triggering interrupt in critical condition.492 * of triggering interrupt in critical condition.
393 */493 */
394 writel(FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4),494 regmap_write(priv->map, EN7581_TEMPADCVOLTAGESHIFT,
395 priv->base + EN7581_TEMPADCVOLTAGESHIFT);495 FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4));
396 496
397 /* BUS clock is 300MHz counting unit is 3 * 68.64 * 256 = 52.715us */497 /* BUS clock is 300MHz counting unit is 3 * 68.64 * 256 = 52.715us */
398 writel(FIELD_PREP(EN7581_PERIOD_UNIT, 3),498 regmap_write(priv->map, EN7581_TEMPMONCTL1,
399 priv->base + EN7581_TEMPMONCTL1);499 FIELD_PREP(EN7581_PERIOD_UNIT, 3));
400 500
401 /*501 /*
402 * filt interval is 1 * 52.715us = 52.715us,502 * filt interval is 1 * 52.715us = 52.715us,
403 * sen interval is 379 * 52.715us = 19.97ms503 * sen interval is 379 * 52.715us = 19.97ms
404 */504 */
405 writel(FIELD_PREP(EN7581_FILT_INTERVAL, 1) |505 regmap_write(priv->map, EN7581_TEMPMONCTL2,
406 FIELD_PREP(EN7581_FILT_INTERVAL, 379),506 FIELD_PREP(EN7581_FILT_INTERVAL, 1) |
407 priv->base + EN7581_TEMPMONCTL2);507 FIELD_PREP(EN7581_SEN_INTERVAL, 379));
408 508
409 /* AHB poll is set to 146 * 68.64 = 10.02us */509 /* AHB poll is set to 146 * 68.64 = 10.02us */
410 writel(FIELD_PREP(EN7581_ADC_POLL_INTVL, 146),510 regmap_write(priv->map, EN7581_TEMPAHBPOLL,
411 priv->base + EN7581_TEMPAHBPOLL);511 FIELD_PREP(EN7581_ADC_POLL_INTVL, 146));
412}512}
413 513
414static int airoha_thermal_probe(struct platform_device *pdev)514static const struct regmap_config en7581_thermal_regmap_config = {
515 .reg_bits = 32,
516 .reg_stride = 4,
517 .val_bits = 32,
518};
519
520static const struct reg_field en7581_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = {
521 [AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(EN7581_DOUT_TADC, 0, 15),
522 [AIROHA_THERMAL_MUX_TADC] = REG_FIELD(EN7581_PWD_TADC, 1, 3),
523};
524
525static int en7581_thermal_probe(struct platform_device *pdev,
526 struct airoha_thermal_priv *priv)
415{527{
416 struct airoha_thermal_priv *priv;
417 struct device_node *chip_scu_np;528 struct device_node *chip_scu_np;
418 struct device *dev = &pdev->dev;529 struct device *dev = &pdev->dev;
419 int irq, ret;530 void __iomem *base;
531 int i, irq, ret;
420 532
421 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);533 base = devm_platform_ioremap_resource(pdev, 0);
422 if (!priv)534 if (IS_ERR(base))
423 return -ENOMEM;535 return PTR_ERR(base);
424 536
425 priv->base = devm_platform_ioremap_resource(pdev, 0);537 priv->map = devm_regmap_init_mmio(dev, base,
426 if (IS_ERR(priv->base))538 &en7581_thermal_regmap_config);
427 return PTR_ERR(priv->base);539 if (IS_ERR(priv->map))
540 return PTR_ERR(priv->map);
428 541
429 chip_scu_np = of_parse_phandle(dev->of_node, "airoha,chip-scu", 0);542 chip_scu_np = of_parse_phandle(dev->of_node, "airoha,chip-scu", 0);
430 if (!chip_scu_np)543 if (!chip_scu_np)
@@ -434,6 +547,23 @@ static int airoha_thermal_probe(struct platform_device *pdev) · 3 unmodified lines
434 if (IS_ERR(priv->chip_scu))547 if (IS_ERR(priv->chip_scu))
435 return PTR_ERR(priv->chip_scu);548 return PTR_ERR(priv->chip_scu);
436 549
550 for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
551 struct regmap_field *field;
552
553 /* Skip registering MUX_SENSOR field as not supported */
554 if (i == AIROHA_THERMAL_MUX_SENSOR)
555 continue;
556
557 field = devm_regmap_field_alloc(dev, priv->chip_scu,
558 en7581_chip_scu_fields[i]);
559 if (IS_ERR(field)) {
560 of_node_put(chip_scu_np);
561 return PTR_ERR(field);
562 }
563
564 priv->chip_scu_fields[i] = field;
565 }
566
437 of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res);567 of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res);
438 of_node_put(chip_scu_np);568 of_node_put(chip_scu_np);
439 569
@@ -442,18 +572,122 @@ static int airoha_thermal_probe(struct platform_device *pdev) · 2 unmodified lines
442 return irq;572 return irq;
443 573
444 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,574 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
445 airoha_thermal_irq, IRQF_ONESHOT,575 en7581_thermal_irq, IRQF_ONESHOT,
446 pdev->name, priv);576 pdev->name, priv);
447 if (ret) {577 if (ret)
448 dev_err(dev, "Can't get interrupt working.\n");
449 return ret;578 return ret;
579
580 en7581_thermal_setup_monitor(priv);
581 en7581_thermal_setup_adc_val(dev, priv);
582
583 return 0;
584}
585
586static int en7581_thermal_post_probe(struct platform_device *pdev)
587{
588 struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
589
590 /* Enable LOW and HIGH interrupt (if supported) */
591 regmap_write(priv->map, EN7581_TEMPMONINT,
592 EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
593
594 return 0;
595}
596
597static int an7583_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
598{
599 struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
600 int sensor_idx;
601 int delta_diode, delta_gain;
602 int coeff, slope, offset;
603
604 int diode_zero, diode_d0, diode_d1;
605
606 /* Always read sensor AN7583_BGP_TEMP_SENSOR */
607 sensor_idx = AN7583_BGP_TEMP_SENSOR;
608
609 coeff = an7583_thermal_coeff[sensor_idx];
610 slope = an7583_thermal_slope[sensor_idx];
611 offset = an7583_thermal_offset[sensor_idx];
612
613 airoha_set_thermal_mux(priv, AN7583_ZERO_TADC, sensor_idx);
614 diode_zero = airoha_get_thermal_ADC(priv);
615 airoha_set_thermal_mux(priv, AN7583_D0_TADC, sensor_idx);
616 diode_d0 = airoha_get_thermal_ADC(priv);
617 airoha_set_thermal_mux(priv, AN7583_D1_TADC, sensor_idx);
618 diode_d1 = airoha_get_thermal_ADC(priv);
619
620 delta_diode = diode_d1 - diode_d0;
621 delta_gain = (delta_diode * coeff) / 100 + (diode_zero - diode_d1);
622 if (!delta_gain)
623 return -EINVAL;
624
625 *temp = (slope * delta_diode * 10) / delta_gain - offset * 10;
626 *temp *= 100;
627
628 return 0;
629}
630
631static const struct thermal_zone_device_ops an7583_tz_ops = {
632 .get_temp = an7583_thermal_get_temp,
633};
634
635static const struct reg_field an7583_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = {
636 [AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(AN7583_DOUT_TADC, 0, 31),
637 [AIROHA_THERMAL_MUX_TADC] = REG_FIELD(AN7583_MUX_TADC, 1, 3),
638 [AIROHA_THERMAL_MUX_SENSOR] = REG_FIELD(AN7583_MUX_SENSOR, 2, 3),
639};
640
641static int an7583_thermal_probe(struct platform_device *pdev,
642 struct airoha_thermal_priv *priv)
643{
644 struct device *dev = &pdev->dev;
645 int i;
646
647 priv->chip_scu = device_node_to_regmap(dev->of_node);
648 if (IS_ERR(priv->chip_scu))
649 return PTR_ERR(priv->chip_scu);
650
651 for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
652 struct regmap_field *field;
653
654 field = devm_regmap_field_alloc(dev, priv->chip_scu,
655 an7583_chip_scu_fields[i]);
656 if (IS_ERR(field))
657 return PTR_ERR(field);
658
659 priv->chip_scu_fields[i] = field;
450 }660 }
451 661
452 airoha_thermal_setup_monitor(priv);662 return 0;
453 airoha_thermal_setup_adc_val(dev, priv);663}
664
665static int airoha_thermal_probe(struct platform_device *pdev)
666{
667 const struct airoha_thermal_soc_data *soc_data;
668 struct airoha_thermal_priv *priv;
669 struct device *dev = &pdev->dev;
670 int ret;
671
672 soc_data = device_get_match_data(dev);
673
674 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
675 if (!priv)
676 return -ENOMEM;
677
678 priv->pllrg_protect = soc_data->pllrg_protect;
679 priv->current_adc = -1;
680
681 if (!soc_data->probe)
682 return -EINVAL;
683
684 ret = soc_data->probe(pdev, priv);
685 if (ret)
686 return ret;
454 687
455 /* register of thermal sensor and get info from DT */688 /* register of thermal sensor and get info from DT */
456 priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops);689 priv->tz = devm_thermal_of_zone_register(dev, 0, priv,
690 soc_data->thdev_ops);
457 if (IS_ERR(priv->tz)) {691 if (IS_ERR(priv->tz)) {
458 dev_err(dev, "register thermal zone sensor failed\n");692 dev_err(dev, "register thermal zone sensor failed\n");
459 return PTR_ERR(priv->tz);693 return PTR_ERR(priv->tz);
@@ -461,15 +695,25 @@ static int airoha_thermal_probe(struct platform_device *pdev) · 1 unmodified line
461 695
462 platform_set_drvdata(pdev, priv);696 platform_set_drvdata(pdev, priv);
463 697
464 /* Enable LOW and HIGH interrupt */698 return soc_data->post_probe ? soc_data->post_probe(pdev) : 0;
465 writel(EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0,
466 priv->base + EN7581_TEMPMONINT);
467
468 return 0;
469}699}
470 700
701static const struct airoha_thermal_soc_data en7581_data = {
702 .pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
703 .thdev_ops = &en7581_thdev_ops,
704 .probe = &en7581_thermal_probe,
705 .post_probe = &en7581_thermal_post_probe,
706};
707
708static const struct airoha_thermal_soc_data an7583_data = {
709 .pllrg_protect = AN7583_SCU_THERMAL_PROTECT_KEY,
710 .thdev_ops = &an7583_tz_ops,
711 .probe = &an7583_thermal_probe,
712};
713
471static const struct of_device_id airoha_thermal_match[] = {714static const struct of_device_id airoha_thermal_match[] = {
472 { .compatible = "airoha,en7581-thermal" },715 { .compatible = "airoha,en7581-thermal", .data = &en7581_data },
716 { .compatible = "airoha,an7583-chip-scu", .data = &an7583_data },
473 {},717 {},
474};718};
475MODULE_DEVICE_TABLE(of, airoha_thermal_match);719MODULE_DEVICE_TABLE(of, airoha_thermal_match);
drivers/thermal/armada_thermal.c+45−61
@@ -20,41 +20,35 @@ · 19 unmodified lines
20#include <linux/interrupt.h>20#include <linux/interrupt.h>
21 21
22/* Thermal Manager Control and Status Register */22/* Thermal Manager Control and Status Register */
23#define PMU_TDC0_SW_RST_MASK (0x1 << 1)23#define PMU_TDC0_SW_RST_MASK BIT(1)
24#define PMU_TM_DISABLE_OFFS 024#define PMU_TM_DISABLE_MASK BIT(0)
25#define PMU_TM_DISABLE_MASK (0x1 << PMU_TM_DISABLE_OFFS)25#define PMU_TDC0_REF_CAL_CNT_MASK GENMASK(19, 11)
26#define PMU_TDC0_REF_CAL_CNT_OFFS 1126#define PMU_TDC0_OTF_CAL_MASK BIT(30)
27#define PMU_TDC0_REF_CAL_CNT_MASK (0x1ff << PMU_TDC0_REF_CAL_CNT_OFFS)27#define PMU_TDC0_START_CAL_MASK BIT(25)
28#define PMU_TDC0_OTF_CAL_MASK (0x1 << 30)28
29#define PMU_TDC0_START_CAL_MASK (0x1 << 25)29#define A375_UNIT_CONTROL_MASK GENMASK(29, 27)
30
31#define A375_UNIT_CONTROL_SHIFT 27
32#define A375_UNIT_CONTROL_MASK 0x7
33#define A375_READOUT_INVERT BIT(15)30#define A375_READOUT_INVERT BIT(15)
34#define A375_HW_RESETn BIT(8)31#define A375_HW_RESETn BIT(8)
35 32
36/* Errata fields */33/* Errata fields */
37#define CONTROL0_TSEN_TC_TRIM_MASK 0x734#define CONTROL0_TSEN_TC_TRIM_MASK GENMASK(2, 0)
38#define CONTROL0_TSEN_TC_TRIM_VAL 0x335#define CONTROL0_TSEN_TC_TRIM_VAL 0x3
39 36
40#define CONTROL0_TSEN_START BIT(0)37#define CONTROL0_TSEN_START BIT(0)
41#define CONTROL0_TSEN_RESET BIT(1)38#define CONTROL0_TSEN_RESET BIT(1)
42#define CONTROL0_TSEN_ENABLE BIT(2)39#define CONTROL0_TSEN_ENABLE BIT(2)
43#define CONTROL0_TSEN_AVG_BYPASS BIT(6)40#define CONTROL0_TSEN_AVG_BYPASS BIT(6)
44#define CONTROL0_TSEN_CHAN_SHIFT 1341#define CONTROL0_TSEN_CHAN_MASK GENMASK(16, 13)
45#define CONTROL0_TSEN_CHAN_MASK 0xF42#define CONTROL0_TSEN_OSR_MASK GENMASK(25, 24)
46#define CONTROL0_TSEN_OSR_SHIFT 2443#define CONTROL0_TSEN_OSR_MAX FIELD_MAX(CONTROL0_TSEN_OSR_MASK)
47#define CONTROL0_TSEN_OSR_MAX 0x344#define CONTROL0_TSEN_MODE_MASK GENMASK(31, 30)
48#define CONTROL0_TSEN_MODE_SHIFT 30
49#define CONTROL0_TSEN_MODE_EXTERNAL 0x245#define CONTROL0_TSEN_MODE_EXTERNAL 0x2
50#define CONTROL0_TSEN_MODE_MASK 0x3
51 46
52#define CONTROL1_TSEN_AVG_MASK 0x747#define CONTROL1_TSEN_AVG_MASK GENMASK(2, 0)
53#define CONTROL1_EXT_TSEN_SW_RESET BIT(7)48#define CONTROL1_EXT_TSEN_SW_RESET BIT(7)
54#define CONTROL1_EXT_TSEN_HW_RESETn BIT(8)49#define CONTROL1_EXT_TSEN_HW_RESETn BIT(8)
55#define CONTROL1_TSEN_INT_EN BIT(25)50#define CONTROL1_TSEN_INT_EN BIT(25)
56#define CONTROL1_TSEN_SELECT_OFF 2151#define CONTROL1_TSEN_SELECT_MASK GENMASK(22, 21)
57#define CONTROL1_TSEN_SELECT_MASK 0x3
58 52
59#define STATUS_POLL_PERIOD_US 100053#define STATUS_POLL_PERIOD_US 1000
60#define STATUS_POLL_TIMEOUT_US 10000054#define STATUS_POLL_TIMEOUT_US 100000
@@ -140,23 +134,21 @@ static void armadaxp_init(struct platform_device *pdev, · 79 unmodified lines
140 u32 reg;134 u32 reg;
141 135
142 regmap_read(priv->syscon, data->syscon_control1_off, &reg);136 regmap_read(priv->syscon, data->syscon_control1_off, &reg);
143 reg |= PMU_TDC0_OTF_CAL_MASK;137 FIELD_MODIFY(PMU_TDC0_OTF_CAL_MASK, &reg, 1);
144 138
145 /* Reference calibration value */139 /* Reference calibration value */
146 reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;140 FIELD_MODIFY(PMU_TDC0_REF_CAL_CNT_MASK, &reg, 0xf1);
147 reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
148 141
149 /* Reset the sensor */142 /* Reset the sensor */
150 reg |= PMU_TDC0_SW_RST_MASK;143 FIELD_MODIFY(PMU_TDC0_SW_RST_MASK, &reg, 1);
151
152 regmap_write(priv->syscon, data->syscon_control1_off, reg);144 regmap_write(priv->syscon, data->syscon_control1_off, reg);
153 145
154 reg &= ~PMU_TDC0_SW_RST_MASK;146 FIELD_MODIFY(PMU_TDC0_SW_RST_MASK, &reg, 0);
155 regmap_write(priv->syscon, data->syscon_control1_off, reg);147 regmap_write(priv->syscon, data->syscon_control1_off, reg);
156 148
157 /* Enable the sensor */149 /* Enable the sensor */
158 regmap_read(priv->syscon, data->syscon_status_off, &reg);150 regmap_read(priv->syscon, data->syscon_status_off, &reg);
159 reg &= ~PMU_TM_DISABLE_MASK;151 FIELD_MODIFY(PMU_TM_DISABLE_MASK, &reg, 0);
160 regmap_write(priv->syscon, data->syscon_status_off, reg);152 regmap_write(priv->syscon, data->syscon_status_off, reg);
161}153}
162 154
@@ -167,14 +159,13 @@ static void armada370_init(struct platform_device *pdev, · 4 unmodified lines
167 u32 reg;159 u32 reg;
168 160
169 regmap_read(priv->syscon, data->syscon_control1_off, &reg);161 regmap_read(priv->syscon, data->syscon_control1_off, &reg);
170 reg |= PMU_TDC0_OTF_CAL_MASK;162 FIELD_MODIFY(PMU_TDC0_OTF_CAL_MASK, &reg, 1);
171 163
172 /* Reference calibration value */164 /* Reference calibration value */
173 reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;165 FIELD_MODIFY(PMU_TDC0_REF_CAL_CNT_MASK, &reg, 0xf1);
174 reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
175 166
176 /* Reset the sensor */167 /* Reset the sensor */
177 reg &= ~PMU_TDC0_START_CAL_MASK;168 FIELD_MODIFY(PMU_TDC0_START_CAL_MASK, &reg, 0);
178 169
179 regmap_write(priv->syscon, data->syscon_control1_off, reg);170 regmap_write(priv->syscon, data->syscon_control1_off, reg);
180 171
@@ -188,14 +179,14 @@ static void armada375_init(struct platform_device *pdev, · 7 unmodified lines
188 u32 reg;179 u32 reg;
189 180
190 regmap_read(priv->syscon, data->syscon_control1_off, &reg);181 regmap_read(priv->syscon, data->syscon_control1_off, &reg);
191 reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT);182 FIELD_MODIFY(A375_UNIT_CONTROL_MASK, &reg, 0);
192 reg &= ~A375_READOUT_INVERT;183 FIELD_MODIFY(A375_READOUT_INVERT, &reg, 0);
193 reg &= ~A375_HW_RESETn;184 FIELD_MODIFY(A375_HW_RESETn, &reg, 0);
194 regmap_write(priv->syscon, data->syscon_control1_off, reg);185 regmap_write(priv->syscon, data->syscon_control1_off, reg);
195 186
196 msleep(20);187 msleep(20);
197 188
198 reg |= A375_HW_RESETn;189 FIELD_MODIFY(A375_HW_RESETn, &reg, 1);
199 regmap_write(priv->syscon, data->syscon_control1_off, reg);190 regmap_write(priv->syscon, data->syscon_control1_off, reg);
200 191
201 msleep(50);192 msleep(50);
@@ -220,14 +211,13 @@ static void armada380_init(struct platform_device *pdev, · 18 unmodified lines
220 211
221 /* Disable the HW/SW reset */212 /* Disable the HW/SW reset */
222 regmap_read(priv->syscon, data->syscon_control1_off, &reg);213 regmap_read(priv->syscon, data->syscon_control1_off, &reg);
223 reg |= CONTROL1_EXT_TSEN_HW_RESETn;214 FIELD_MODIFY(CONTROL1_EXT_TSEN_HW_RESETn, &reg, 1);
224 reg &= ~CONTROL1_EXT_TSEN_SW_RESET;215 FIELD_MODIFY(CONTROL1_EXT_TSEN_SW_RESET, &reg, 0);
225 regmap_write(priv->syscon, data->syscon_control1_off, reg);216 regmap_write(priv->syscon, data->syscon_control1_off, reg);
226 217
227 /* Set Tsen Tc Trim to correct default value (errata #132698) */218 /* Set Tsen Tc Trim to correct default value (errata #132698) */
228 regmap_read(priv->syscon, data->syscon_control0_off, &reg);219 regmap_read(priv->syscon, data->syscon_control0_off, &reg);
229 reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;220 FIELD_MODIFY(CONTROL0_TSEN_TC_TRIM_MASK, &reg, CONTROL0_TSEN_TC_TRIM_VAL);
230 reg |= CONTROL0_TSEN_TC_TRIM_VAL;
231 regmap_write(priv->syscon, data->syscon_control0_off, reg);221 regmap_write(priv->syscon, data->syscon_control0_off, reg);
232}222}
233 223
@@ -238,14 +228,15 @@ static void armada_ap80x_init(struct platform_device *pdev, · 4 unmodified lines
238 u32 reg;228 u32 reg;
239 229
240 regmap_read(priv->syscon, data->syscon_control0_off, &reg);230 regmap_read(priv->syscon, data->syscon_control0_off, &reg);
241 reg &= ~CONTROL0_TSEN_RESET;231 FIELD_MODIFY(CONTROL0_TSEN_RESET, &reg, 0);
242 reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE;232 FIELD_MODIFY(CONTROL0_TSEN_START, &reg, 1);
233 FIELD_MODIFY(CONTROL0_TSEN_ENABLE, &reg, 1);
243 234
244 /* Sample every ~2ms */235 /* Sample every ~2ms */
245 reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;236 FIELD_MODIFY(CONTROL0_TSEN_OSR_MASK, &reg, CONTROL0_TSEN_OSR_MAX);
246 237
247 /* Enable average (2 samples by default) */238 /* Enable average (2 samples by default) */
248 reg &= ~CONTROL0_TSEN_AVG_BYPASS;239 FIELD_MODIFY(CONTROL0_TSEN_AVG_BYPASS, &reg, 0);
249 240
250 regmap_write(priv->syscon, data->syscon_control0_off, reg);241 regmap_write(priv->syscon, data->syscon_control0_off, reg);
251}242}
@@ -260,13 +251,12 @@ static void armada_cp110_init(struct platform_device *pdev, · 8 unmodified lines
260 251
261 /* Sample every ~2ms */252 /* Sample every ~2ms */
262 regmap_read(priv->syscon, data->syscon_control0_off, &reg);253 regmap_read(priv->syscon, data->syscon_control0_off, &reg);
263 reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;254 FIELD_MODIFY(CONTROL0_TSEN_OSR_MASK, &reg, CONTROL0_TSEN_OSR_MAX);
264 regmap_write(priv->syscon, data->syscon_control0_off, reg);255 regmap_write(priv->syscon, data->syscon_control0_off, reg);
265 256
266 /* Average the output value over 2^1 = 2 samples */257 /* Average the output value over 2^1 = 2 samples */
267 regmap_read(priv->syscon, data->syscon_control1_off, &reg);258 regmap_read(priv->syscon, data->syscon_control1_off, &reg);
268 reg &= ~CONTROL1_TSEN_AVG_MASK;259 FIELD_MODIFY(CONTROL1_TSEN_AVG_MASK, &reg, 1);
269 reg |= 1;
270 regmap_write(priv->syscon, data->syscon_control1_off, reg);260 regmap_write(priv->syscon, data->syscon_control1_off, reg);
271}261}
272 262
@@ -313,7 +303,7 @@ armada_disable_overheat_interrupt(struct armada_thermal_priv *priv) · 40 unmodified lines
313 u32 reg;303 u32 reg;
314 304
315 regmap_read(priv->syscon, data->syscon_control1_off, &reg);305 regmap_read(priv->syscon, data->syscon_control1_off, &reg);
316 reg &= ~CONTROL1_TSEN_INT_EN;306 FIELD_MODIFY(CONTROL1_TSEN_INT_EN, &reg, 0);
317 regmap_write(priv->syscon, data->syscon_control1_off, reg);307 regmap_write(priv->syscon, data->syscon_control1_off, reg);
318}308}
319 309
@@ -331,20 +321,18 @@ static int armada_select_channel(struct armada_thermal_priv *priv, int channel) · 11 unmodified lines
331 321
332 /* Stop the measurements */322 /* Stop the measurements */
333 regmap_read(priv->syscon, data->syscon_control0_off, &ctrl0);323 regmap_read(priv->syscon, data->syscon_control0_off, &ctrl0);
334 ctrl0 &= ~CONTROL0_TSEN_START;324 FIELD_MODIFY(CONTROL0_TSEN_START, &ctrl0, 0);
335 regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);325 regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
336 326
337 /* Reset the mode, internal sensor will be automatically selected */
338 ctrl0 &= ~(CONTROL0_TSEN_MODE_MASK << CONTROL0_TSEN_MODE_SHIFT);
339
340 /* Other channels are external and should be selected accordingly */327 /* Other channels are external and should be selected accordingly */
341 if (channel) {328 if (channel) {
342 /* Change the mode to external */329 /* Change the mode to external */
343 ctrl0 |= CONTROL0_TSEN_MODE_EXTERNAL <<330 FIELD_MODIFY(CONTROL0_TSEN_MODE_MASK, &ctrl0, CONTROL0_TSEN_MODE_EXTERNAL);
344 CONTROL0_TSEN_MODE_SHIFT;
345 /* Select the sensor */331 /* Select the sensor */
346 ctrl0 &= ~(CONTROL0_TSEN_CHAN_MASK << CONTROL0_TSEN_CHAN_SHIFT);332 FIELD_MODIFY(CONTROL0_TSEN_CHAN_MASK, &ctrl0, channel - 1);
347 ctrl0 |= (channel - 1) << CONTROL0_TSEN_CHAN_SHIFT;333 } else {
334 /* Reset the mode, internal sensor will be automatically selected */
335 FIELD_MODIFY(CONTROL0_TSEN_MODE_MASK, &ctrl0, 0);
348 }336 }
349 337
350 /* Actually set the mode/channel */338 /* Actually set the mode/channel */
@@ -352,7 +340,7 @@ static int armada_select_channel(struct armada_thermal_priv *priv, int channel) · 1 unmodified line
352 priv->current_channel = channel;340 priv->current_channel = channel;
353 341
354 /* Re-start the measurements */342 /* Re-start the measurements */
355 ctrl0 |= CONTROL0_TSEN_START;343 FIELD_MODIFY(CONTROL0_TSEN_START, &ctrl0, 1);
356 regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);344 regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
357 345
358 /*346 /*
@@ -722,7 +710,6 @@ static const struct regmap_config armada_thermal_regmap_config = { · 363 unmodified lines
722 .reg_bits = 32,710 .reg_bits = 32,
723 .reg_stride = 4,711 .reg_stride = 4,
724 .val_bits = 32,712 .val_bits = 32,
725 .fast_io = true,
726};713};
727 714
728static int armada_thermal_probe_legacy(struct platform_device *pdev,715static int armada_thermal_probe_legacy(struct platform_device *pdev,
@@ -913,11 +900,8 @@ static int armada_thermal_probe(struct platform_device *pdev) · 184 unmodified lines
913 armada_overheat_isr,900 armada_overheat_isr,
914 armada_overheat_isr_thread,901 armada_overheat_isr_thread,
915 0, NULL, priv);902 0, NULL, priv);
916 if (ret) {903 if (ret)
917 dev_err(&pdev->dev, "Cannot request threaded IRQ %d\n",
918 irq);
919 return ret;904 return ret;
920 }
921 }905 }
922 906
923 /*907 /*
drivers/thermal/broadcom/brcmstb_thermal.c+1−2
@@ -356,8 +356,7 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) · 355 unmodified lines
356 IRQF_ONESHOT,356 IRQF_ONESHOT,
357 DRV_NAME, priv);357 DRV_NAME, priv);
358 if (ret < 0)358 if (ret < 0)
359 return dev_err_probe(&pdev->dev, ret,359 return ret;
360 "could not request IRQ\n");
361 }360 }
362 361
363 dev_info(&pdev->dev, "registered AVS TMON of-sensor driver\n");362 dev_info(&pdev->dev, "registered AVS TMON of-sensor driver\n");
drivers/thermal/db8500_thermal.c+2−6
@@ -167,10 +167,8 @@ static int db8500_thermal_probe(struct platform_device *pdev) · 166 unmodified lines
167 ret = devm_request_threaded_irq(dev, low_irq, NULL,167 ret = devm_request_threaded_irq(dev, low_irq, NULL,
168 prcmu_low_irq_handler, IRQF_NO_SUSPEND | IRQF_ONESHOT,168 prcmu_low_irq_handler, IRQF_NO_SUSPEND | IRQF_ONESHOT,
169 "dbx500_temp_low", th);169 "dbx500_temp_low", th);
170 if (ret < 0) {170 if (ret < 0)
171 dev_err(dev, "failed to allocate temp low irq\n");
172 return ret;171 return ret;
173 }
174 172
175 high_irq = platform_get_irq_byname(pdev, "IRQ_HOTMON_HIGH");173 high_irq = platform_get_irq_byname(pdev, "IRQ_HOTMON_HIGH");
176 if (high_irq < 0)174 if (high_irq < 0)
@@ -179,10 +177,8 @@ static int db8500_thermal_probe(struct platform_device *pdev) · 2 unmodified lines
179 ret = devm_request_threaded_irq(dev, high_irq, NULL,177 ret = devm_request_threaded_irq(dev, high_irq, NULL,
180 prcmu_high_irq_handler, IRQF_NO_SUSPEND | IRQF_ONESHOT,178 prcmu_high_irq_handler, IRQF_NO_SUSPEND | IRQF_ONESHOT,
181 "dbx500_temp_high", th);179 "dbx500_temp_high", th);
182 if (ret < 0) {180 if (ret < 0)
183 dev_err(dev, "failed to allocate temp high irq\n");
184 return ret;181 return ret;
185 }
186 182
187 /* register of thermal sensor and get info from DT */183 /* register of thermal sensor and get info from DT */
188 th->tz = devm_thermal_of_zone_register(dev, 0, th, &thdev_ops);184 th->tz = devm_thermal_of_zone_register(dev, 0, th, &thdev_ops);
drivers/thermal/hisi_thermal.c+1−3
@@ -578,10 +578,8 @@ static int hisi_thermal_probe(struct platform_device *pdev) · 577 unmodified lines
578 hisi_thermal_alarm_irq_thread,578 hisi_thermal_alarm_irq_thread,
579 IRQF_ONESHOT, sensor->irq_name,579 IRQF_ONESHOT, sensor->irq_name,
580 sensor);580 sensor);
581 if (ret < 0) {581 if (ret < 0)
582 dev_err(dev, "Failed to request alarm irq: %d\n", ret);
583 return ret;582 return ret;
584 }
585 583
586 ret = data->ops->enable_sensor(sensor);584 ret = data->ops->enable_sensor(sensor);
587 if (ret) {585 if (ret) {
drivers/thermal/imx91_thermal.c+1−1
@@ -331,7 +331,7 @@ static int imx91_tmu_probe(struct platform_device *pdev) · 330 unmodified lines
331 IRQF_ONESHOT, "imx91_thermal", tmu);331 IRQF_ONESHOT, "imx91_thermal", tmu);
332 332
333 if (ret < 0)333 if (ret < 0)
334 return dev_err_probe(dev, ret, "failed to request alarm irq\n");334 return ret;
335 335
336 pm_runtime_put(dev);336 pm_runtime_put(dev);
337 337
drivers/thermal/imx_thermal.c+8−5
@@ -732,10 +732,8 @@ static int imx_thermal_probe(struct platform_device *pdev) · 731 unmodified lines
732 ret = devm_request_threaded_irq(dev, data->irq,732 ret = devm_request_threaded_irq(dev, data->irq,
733 imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,733 imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
734 0, "imx_thermal", data);734 0, "imx_thermal", data);
735 if (ret < 0) {735 if (ret < 0)
736 dev_err(dev, "failed to request alarm irq: %d\n", ret);
737 goto thermal_zone_unregister;736 goto thermal_zone_unregister;
738 }
739 737
740 pm_runtime_put(data->dev);738 pm_runtime_put(data->dev);
741 739
@@ -832,12 +830,12 @@ static int imx_thermal_runtime_resume(struct device *dev) · 90 unmodified lines
832 ret = regmap_write(map, socdata->sensor_ctrl + REG_CLR,830 ret = regmap_write(map, socdata->sensor_ctrl + REG_CLR,
833 socdata->power_down_mask);831 socdata->power_down_mask);
834 if (ret)832 if (ret)
835 return ret;833 goto disable_clk;
836 834
837 ret = regmap_write(map, socdata->sensor_ctrl + REG_SET,835 ret = regmap_write(map, socdata->sensor_ctrl + REG_SET,
838 socdata->measure_temp_mask);836 socdata->measure_temp_mask);
839 if (ret)837 if (ret)
840 return ret;838 goto disable_clk;
841 839
842 /*840 /*
843 * According to the temp sensor designers, it may require up to ~17us841 * According to the temp sensor designers, it may require up to ~17us
@@ -846,6 +844,11 @@ static int imx_thermal_runtime_resume(struct device *dev) · 2 unmodified lines
846 usleep_range(20, 50);844 usleep_range(20, 50);
847 845
848 return 0;846 return 0;
847
848disable_clk:
849 clk_disable_unprepare(data->thermal_clk);
850
851 return ret;
849}852}
850 853
851static const struct dev_pm_ops imx_thermal_pm_ops = {854static const struct dev_pm_ops imx_thermal_pm_ops = {
drivers/thermal/loongson2_thermal.c+1−1
@@ -173,7 +173,7 @@ static int loongson2_thermal_probe(struct platform_device *pdev) · 172 unmodified lines
173 ret = devm_request_threaded_irq(dev, irq, NULL, loongson2_thermal_irq_thread,173 ret = devm_request_threaded_irq(dev, irq, NULL, loongson2_thermal_irq_thread,
174 IRQF_ONESHOT, "loongson2_thermal", tzd);174 IRQF_ONESHOT, "loongson2_thermal", tzd);
175 if (ret < 0)175 if (ret < 0)
176 return dev_err_probe(dev, ret, "failed to request alarm irq\n");176 return ret;
177 177
178 devm_thermal_add_hwmon_sysfs(dev, tzd);178 devm_thermal_add_hwmon_sysfs(dev, tzd);
179 179
drivers/thermal/max77620_thermal.c+2−6
@@ -121,19 +121,15 @@ static int max77620_thermal_probe(struct platform_device *pdev) · 120 unmodified lines
121 max77620_thermal_irq,121 max77620_thermal_irq,
122 IRQF_ONESHOT | IRQF_SHARED,122 IRQF_ONESHOT | IRQF_SHARED,
123 dev_name(&pdev->dev), mtherm);123 dev_name(&pdev->dev), mtherm);
124 if (ret < 0) {124 if (ret < 0)
125 dev_err(&pdev->dev, "Failed to request irq1: %d\n", ret);
126 return ret;125 return ret;
127 }
128 126
129 ret = devm_request_threaded_irq(&pdev->dev, mtherm->irq_tjalarm2, NULL,127 ret = devm_request_threaded_irq(&pdev->dev, mtherm->irq_tjalarm2, NULL,
130 max77620_thermal_irq,128 max77620_thermal_irq,
131 IRQF_ONESHOT | IRQF_SHARED,129 IRQF_ONESHOT | IRQF_SHARED,
132 dev_name(&pdev->dev), mtherm);130 dev_name(&pdev->dev), mtherm);
133 if (ret < 0) {131 if (ret < 0)
134 dev_err(&pdev->dev, "Failed to request irq2: %d\n", ret);
135 return ret;132 return ret;
136 }
137 133
138 return 0;134 return 0;
139}135}
drivers/thermal/mediatek/lvts_thermal.c+15−2
@@ -1470,7 +1470,20 @@ static int lvts_probe(struct platform_device *pdev) · 1469 unmodified lines
1470 if (IS_ERR(lvts_td->base))1470 if (IS_ERR(lvts_td->base))
1471 return dev_err_probe(dev, PTR_ERR(lvts_td->base), "Failed to map io resource\n");1471 return dev_err_probe(dev, PTR_ERR(lvts_td->base), "Failed to map io resource\n");
1472 1472
1473 lvts_td->reset = devm_reset_control_get_by_index(dev, 0);1473 /*
1474 * Depending on the SoC+Firmware combination, the LVTS hardware may be
1475 * may be actively used by one or even multiple concurrent MCUs!
1476 * In this case, resetting it may produce either a severe slowdown of
1477 * the entire system, or even a thermal protection AP reset, as some
1478 * MCU(s) may be reading a very high or very low temperature while the
1479 * LVTS is being reset.
1480 *
1481 * On those, don't fail if no reset is found as that may be omitted on
1482 * purpose, but still check if there's one, because some board(s) may
1483 * be running on a different bootchain with reduced firmwares or using
1484 * firmwares with reduced functionality.
1485 */
1486 lvts_td->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
1474 if (IS_ERR(lvts_td->reset))1487 if (IS_ERR(lvts_td->reset))
1475 return dev_err_probe(dev, PTR_ERR(lvts_td->reset), "Failed to get reset control\n");1488 return dev_err_probe(dev, PTR_ERR(lvts_td->reset), "Failed to get reset control\n");
1476 1489
@@ -1491,7 +1504,7 @@ static int lvts_probe(struct platform_device *pdev) · 14 unmodified lines
1491 ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,1504 ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,
1492 IRQF_ONESHOT, dev_name(dev), lvts_td);1505 IRQF_ONESHOT, dev_name(dev), lvts_td);
1493 if (ret)1506 if (ret)
1494 return dev_err_probe(dev, ret, "Failed to request interrupt\n");1507 return ret;
1495 1508
1496 platform_set_drvdata(pdev, lvts_td);1509 platform_set_drvdata(pdev, lvts_td);
1497 1510
drivers/thermal/qcom/Kconfig+23−0
@@ -21,6 +21,29 @@ config QCOM_SPMI_ADC_TM5 · 20 unmodified lines
21 Thermal client sets threshold temperature for both warm and cool and21 Thermal client sets threshold temperature for both warm and cool and
22 gets updated when a threshold is reached.22 gets updated when a threshold is reached.
23 23
24config QCOM_SPMI_MBG_TM
25 tristate "Qualcomm SPMI PMIC MBG Temperature monitor"
26 depends on QCOM_SPMI_ADC5_GEN3
27 select REGMAP_SPMI
28 help
29 This enables Qualcomm PMIC MBG (Master Bandgap) thermal monitor.
30
31 The MBG block monitors PMIC die temperature in hardware and raises an
32 interrupt when the programmed threshold is crossed.
33
34 Temperature is read from the associated ADC channel, and threshold
35 interrupts are forwarded to the thermal framework as trip-violation
36 events. Current support handles a single LVL1 upper (hot) trip.
37
38config QCOM_SPMI_ADC_TM5_GEN3
39 tristate "Qualcomm SPMI PMIC Thermal Monitor ADC5 Gen3"
40 depends on QCOM_SPMI_ADC5_GEN3
41 help
42 This enables the auxiliary thermal driver for the ADC5 Gen3 thermal
43 monitoring device. It shows up as a thermal zone with multiple trip points.
44 Thermal client sets threshold temperature for both warm and cool and
45 gets updated when a threshold is reached.
46
24config QCOM_SPMI_TEMP_ALARM47config QCOM_SPMI_TEMP_ALARM
25 tristate "Qualcomm SPMI PMIC Temperature Alarm"48 tristate "Qualcomm SPMI PMIC Temperature Alarm"
26 depends on OF && SPMI && IIO49 depends on OF && SPMI && IIO
drivers/thermal/qcom/Makefile+2−0
@@ -4,5 +4,7 @@ obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o · 3 unmodified lines
4qcom_tsens-y += tsens.o tsens-v2.o tsens-v1.o tsens-v0_1.o \4qcom_tsens-y += tsens.o tsens-v2.o tsens-v1.o tsens-v0_1.o \
5 tsens-8960.o5 tsens-8960.o
6obj-$(CONFIG_QCOM_SPMI_ADC_TM5) += qcom-spmi-adc-tm5.o6obj-$(CONFIG_QCOM_SPMI_ADC_TM5) += qcom-spmi-adc-tm5.o
7obj-$(CONFIG_QCOM_SPMI_ADC_TM5_GEN3) += qcom-spmi-adc-tm5-gen3.o
8obj-$(CONFIG_QCOM_SPMI_MBG_TM) += qcom-spmi-mbg-tm.o
7obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o9obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
8obj-$(CONFIG_QCOM_LMH) += lmh.o10obj-$(CONFIG_QCOM_LMH) += lmh.o
drivers/thermal/qcom/lmh.c+0−1
@@ -223,7 +223,6 @@ static int lmh_probe(struct platform_device *pdev) · 222 unmodified lines
223 IRQF_NO_THREAD | IRQF_NO_SUSPEND,223 IRQF_NO_THREAD | IRQF_NO_SUSPEND,
224 "lmh-irq", lmh_data);224 "lmh-irq", lmh_data);
225 if (ret) {225 if (ret) {
226 dev_err(dev, "Error %d registering irq %x\n", ret, lmh_data->irq);
227 irq_domain_remove(lmh_data->domain);226 irq_domain_remove(lmh_data->domain);
228 return ret;227 return ret;
229 }228 }
drivers/thermal/qcom/qcom-spmi-adc-tm5.c+0−3
@@ -369,9 +369,6 @@ static int adc_tm5_get_temp(struct thermal_zone_device *tz, int *temp) · 368 unmodified lines
369 if (ret < 0)369 if (ret < 0)
370 return ret;370 return ret;
371 371
372 if (ret != IIO_VAL_INT)
373 return -EINVAL;
374
375 return 0;372 return 0;
376}373}
377 374
drivers/thermal/qcom/qcom-spmi-mbg-tm.c+256−0
@@ -0,0 +1,256 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4 */
5
6#include <linux/interrupt.h>
7#include <linux/irq.h>
8#include <linux/module.h>
9#include <linux/of.h>
10#include <linux/platform_device.h>
11#include <linux/regmap.h>
12#include <linux/thermal.h>
13#include <linux/iio/consumer.h>
14
15#define MBG_TEMP_MON2_FAULT_STATUS 0x50
16
17#define MON_FAULT_STATUS_MASK GENMASK(7, 4)
18#define MON_FAULT_LVL1_UPR 0x5
19
20#define MON2_LVL1_UP_THRESH 0x59
21
22#define MBG_TEMP_MON2_MISC_CFG 0x5f
23#define MON2_UP_THRESH_EN BIT(1)
24
25#define MBG_TEMP_STEP_MV 8
26#define MBG_TEMP_DEFAULT_TEMP_MV 600
27#define MBG_TEMP_CONSTANT 1000
28#define MBG_MIN_TRIP_TEMP 25000
29#define MBG_MAX_SUPPORTED_TEMP 160000
30
31/**
32 * struct mbg_tm_chip - MBG thermal monitor device data.
33 * @map: regmap for accessing MBG thermal registers.
34 * @dev: mbg_tm_chip device.
35 * @tz_dev: thermal zone device registered with the thermal framework.
36 * @lock: mbg_tm_chip lock for set trip temperature.
37 * @base: base register offset for this MBG instance
38 * @irq: interrupt line used to signal threshold events
39 * @last_temp: last measured temperature.
40 * @last_thres_crossed: indicates whether the last interrupt crossed a threshold
41 * @adc: IIO ADC channel used for temperature sensing
42 */
43struct mbg_tm_chip {
44 struct regmap *map;
45 struct device *dev;
46 struct thermal_zone_device *tz_dev;
47 struct mutex lock;
48 unsigned int base;
49 int irq;
50 int last_temp;
51 bool last_thres_crossed;
52 struct iio_channel *adc;
53};
54
55/**
56 * struct mbg_map_table - temperature to voltage mapping entry
57 * @min_temp: minimum temperature supported by this mapping entry
58 * @vtemp0: reference voltage or ADC code corresponding to the temperature
59 * @tc: temperature coefficient used for conversion calculations
60 */
61struct mbg_map_table {
62 int min_temp;
63 int vtemp0;
64 int tc;
65};
66
67static const struct mbg_map_table map_table[] = {
68 { -60000, 4337, 1967 },
69 { -40000, 4731, 1964 },
70 { -20000, 5124, 1957 },
71 { 0, 5515, 1949 },
72 { 20000, 5905, 1940 },
73 { 40000, 6293, 1930 },
74 { 60000, 6679, 1921 },
75 { 80000, 7064, 1910 },
76 { 100000, 7446, 1896 },
77 { 120000, 7825, 1878 },
78 { 140000, 8201, 1859 },
79};
80
81static int mbg_tm_get_temp(struct thermal_zone_device *tz, int *temp)
82{
83 struct mbg_tm_chip *chip = thermal_zone_device_priv(tz);
84 int ret, milli_celsius;
85
86 scoped_guard(mutex, &chip->lock) {
87 if (chip->last_thres_crossed) {
88 dev_dbg(chip->dev, "last_temp: %d\n", chip->last_temp);
89 chip->last_thres_crossed = false;
90 *temp = chip->last_temp;
91 return 0;
92 }
93 }
94
95 ret = iio_read_channel_processed(chip->adc, &milli_celsius);
96 if (ret < 0) {
97 dev_err(chip->dev, "Failed to read iio channel with %d\n", ret);
98 return ret;
99 }
100
101 *temp = milli_celsius;
102
103 return 0;
104}
105
106static int temp_to_vtemp_mv(int temp)
107{
108 int idx, vtemp, tc = 0, t0 = 0, vtemp0 = 0;
109
110 for (idx = 0; idx < ARRAY_SIZE(map_table); idx++)
111 if (temp >= map_table[idx].min_temp &&
112 temp < (map_table[idx].min_temp + 20000)) {
113 tc = map_table[idx].tc;
114 t0 = map_table[idx].min_temp;
115 vtemp0 = map_table[idx].vtemp0;
116 break;
117 }
118
119 /*
120 * Formula to calculate vtemp(mV) from a given temp
121 * vtemp = (temp - minT) * tc + vtemp0
122 * tc, t0 and vtemp0 values are mentioned in the map_table array.
123 */
124 vtemp = ((temp - t0) * tc + vtemp0 * 100000) / 1000000;
125
126 /* step size is 8mV */
127 return abs(vtemp - MBG_TEMP_DEFAULT_TEMP_MV) / MBG_TEMP_STEP_MV;
128}
129
130static int mbg_tm_set_trip_temp(struct thermal_zone_device *tz, int low_temp,
131 int temp)
132{
133 struct mbg_tm_chip *chip = thermal_zone_device_priv(tz);
134 int ret = 0;
135
136 guard(mutex)(&chip->lock);
137
138 /* The HW has a limitation that the trip set must be above 25C */
139 if (temp > MBG_MIN_TRIP_TEMP && temp < MBG_MAX_SUPPORTED_TEMP) {
140 ret = regmap_write(chip->map, chip->base + MON2_LVL1_UP_THRESH,
141 temp_to_vtemp_mv(temp));
142 if (ret < 0)
143 return ret;
144
145 ret = regmap_set_bits(chip->map, chip->base + MBG_TEMP_MON2_MISC_CFG,
146 MON2_UP_THRESH_EN);
147 if (ret < 0)
148 return ret;
149 } else {
150 dev_err(chip->dev, "Set trip b/w 25C and 160C\n");
151 ret = regmap_clear_bits(chip->map, chip->base + MBG_TEMP_MON2_MISC_CFG,
152 MON2_UP_THRESH_EN);
153 return -ERANGE;
154 }
155
156 /*
157 * Configure the last_temp one degree higher, to ensure the
158 * violated temp is returned to thermal framework when it reads
159 * temperature for the first time after the violation happens.
160 * This is needed to account for the inaccuracy in the conversion
161 * formula used which leads to the thermal framework setting back
162 * the same thresholds in case the temperature it reads does not
163 * show violation.
164 */
165 chip->last_temp = temp + MBG_TEMP_CONSTANT;
166
167 return ret;
168}
169
170static const struct thermal_zone_device_ops mbg_tm_ops = {
171 .get_temp = mbg_tm_get_temp,
172 .set_trips = mbg_tm_set_trip_temp,
173};
174
175static irqreturn_t mbg_tm_isr(int irq, void *data)
176{
177 struct mbg_tm_chip *chip = data;
178 int ret, val;
179
180 scoped_guard(mutex, &chip->lock) {
181 ret = regmap_read(chip->map, chip->base + MBG_TEMP_MON2_FAULT_STATUS, &val);
182 if (ret < 0)
183 return IRQ_HANDLED;
184 if (FIELD_GET(MON_FAULT_STATUS_MASK, val) == MON_FAULT_LVL1_UPR)
185 chip->last_thres_crossed = true;
186 }
187
188 if (FIELD_GET(MON_FAULT_STATUS_MASK, val) == MON_FAULT_LVL1_UPR) {
189 dev_dbg(chip->dev, "Notifying Thermal, fault status=%d\n", val);
190 thermal_zone_device_update(chip->tz_dev, THERMAL_TRIP_VIOLATED);
191 } else {
192 dev_dbg(chip->dev, "Lvl1 upper threshold not violated, ignoring interrupt\n");
193 }
194
195 return IRQ_HANDLED;
196}
197
198static int mbg_tm_probe(struct platform_device *pdev)
199{
200 struct mbg_tm_chip *chip;
201 struct device_node *node = pdev->dev.of_node;
202 u32 res;
203 int ret;
204
205 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
206 if (!chip)
207 return -ENOMEM;
208
209 chip->dev = &pdev->dev;
210
211 mutex_init(&chip->lock);
212
213 chip->map = dev_get_regmap(pdev->dev.parent, NULL);
214 if (!chip->map)
215 return -ENXIO;
216
217 ret = device_property_read_u32(chip->dev, "reg", &res);
218 if (ret < 0)
219 return dev_err_probe(chip->dev, ret, "Couldn't read reg property\n");
220
221 chip->base = res;
222
223 chip->irq = platform_get_irq(pdev, 0);
224 if (chip->irq < 0)
225 return dev_err_probe(chip->dev, chip->irq, "Failed to get irq\n");
226
227 chip->adc = devm_iio_channel_get(&pdev->dev, "thermal");
228 if (IS_ERR(chip->adc))
229 return dev_err_probe(chip->dev, PTR_ERR(chip->adc), "Failed to get adc channel\n");
230
231 chip->tz_dev = devm_thermal_of_zone_register(chip->dev, 0, chip, &mbg_tm_ops);
232 if (IS_ERR(chip->tz_dev))
233 return dev_err_probe(chip->dev, PTR_ERR(chip->tz_dev),
234 "Failed to register sensor\n");
235
236 return devm_request_threaded_irq(&pdev->dev, chip->irq, NULL, mbg_tm_isr, IRQF_ONESHOT,
237 node->name, chip);
238}
239
240static const struct of_device_id mbg_tm_match_table[] = {
241 { .compatible = "qcom,pm8775-mbg-tm" },
242 { }
243};
244MODULE_DEVICE_TABLE(of, mbg_tm_match_table);
245
246static struct platform_driver mbg_tm_driver = {
247 .driver = {
248 .name = "qcom-spmi-mbg-tm",
249 .of_match_table = mbg_tm_match_table,
250 },
251 .probe = mbg_tm_probe,
252};
253module_platform_driver(mbg_tm_driver);
254
255MODULE_DESCRIPTION("PMIC MBG Temperature monitor driver");
256MODULE_LICENSE("GPL");
drivers/thermal/qcom/tsens.c+1−4
@@ -1258,10 +1258,7 @@ static int tsens_register_irq(struct tsens_priv *priv, char *irqname, · 1257 unmodified lines
1258 dev_name(&pdev->dev),1258 dev_name(&pdev->dev),
1259 priv);1259 priv);
1260 1260
1261 if (ret)1261 if (!ret)
1262 dev_err(&pdev->dev, "%s: failed to get irq\n",
1263 __func__);
1264 else
1265 *irq_num = irq;1262 *irq_num = irq;
1266 }1263 }
1267 1264
drivers/thermal/qoriq_thermal.c+11−2
@@ -415,11 +415,20 @@ static int qoriq_tmu_resume(struct device *dev) · 414 unmodified lines
415 if (data->ver > TMU_VER1) {415 if (data->ver > TMU_VER1) {
416 ret = regmap_clear_bits(data->regmap, REGS_TMR, TMR_CMD);416 ret = regmap_clear_bits(data->regmap, REGS_TMR, TMR_CMD);
417 if (ret)417 if (ret)
418 return ret;418 goto disable_clk;
419 }419 }
420 420
421 /* Enable monitoring */421 /* Enable monitoring */
422 return regmap_update_bits(data->regmap, REGS_TMR, TMR_ME, TMR_ME);422 ret = regmap_update_bits(data->regmap, REGS_TMR, TMR_ME, TMR_ME);
423 if (ret)
424 goto disable_clk;
425
426 return 0;
427
428disable_clk:
429 clk_disable_unprepare(data->clk);
430
431 return ret;
423}432}
424 433
425static DEFINE_SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,434static DEFINE_SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,
drivers/thermal/renesas/rcar_thermal.c+6−13
@@ -446,10 +446,8 @@ static int rcar_thermal_probe(struct platform_device *pdev) · 445 unmodified lines
446 446
447 ret = devm_request_irq(dev, irq, rcar_thermal_irq,447 ret = devm_request_irq(dev, irq, rcar_thermal_irq,
448 IRQF_SHARED, dev_name(dev), common);448 IRQF_SHARED, dev_name(dev), common);
449 if (ret) {449 if (ret)
450 dev_err(dev, "irq request failed\n");
451 goto error_unregister;450 goto error_unregister;
452 }
453 451
454 /* update ENR bits */452 /* update ENR bits */
455 if (chip->irq_per_ch)453 if (chip->irq_per_ch)
@@ -492,12 +490,6 @@ static int rcar_thermal_probe(struct platform_device *pdev) · 36 unmodified lines
492 "rcar_thermal", trips, ARRAY_SIZE(trips), priv,490 "rcar_thermal", trips, ARRAY_SIZE(trips), priv,
493 &rcar_thermal_zone_ops, NULL, 0,491 &rcar_thermal_zone_ops, NULL, 0,
494 idle);492 idle);
495
496 ret = thermal_zone_device_enable(priv->zone);
497 if (ret) {
498 thermal_zone_device_unregister(priv->zone);
499 priv->zone = ERR_PTR(ret);
500 }
501 }493 }
502 if (IS_ERR(priv->zone)) {494 if (IS_ERR(priv->zone)) {
503 dev_err(dev, "can't register thermal zone\n");495 dev_err(dev, "can't register thermal zone\n");
@@ -506,11 +498,12 @@ static int rcar_thermal_probe(struct platform_device *pdev) · 2 unmodified lines
506 goto error_unregister;498 goto error_unregister;
507 }499 }
508 500
509 if (chip->use_of_thermal) {501 if (chip->use_of_thermal)
510 ret = thermal_add_hwmon_sysfs(priv->zone);502 ret = thermal_add_hwmon_sysfs(priv->zone);
511 if (ret)503 else
512 goto error_unregister;504 ret = thermal_zone_device_enable(priv->zone);
513 }505 if (ret)
506 goto error_unregister;
514 507
515 rcar_thermal_irq_enable(priv);508 rcar_thermal_irq_enable(priv);
516 509
drivers/thermal/renesas/rzg3e_thermal.c+1−3
@@ -461,10 +461,8 @@ static int rzg3e_thermal_probe(struct platform_device *pdev) · 460 unmodified lines
461 ret = devm_request_threaded_irq(dev, irq, rzg3e_thermal_irq,461 ret = devm_request_threaded_irq(dev, irq, rzg3e_thermal_irq,
462 rzg3e_thermal_irq_thread,462 rzg3e_thermal_irq_thread,
463 IRQF_ONESHOT, "rzg3e_thermal", priv);463 IRQF_ONESHOT, "rzg3e_thermal", priv);
464 if (ret) {464 if (ret)
465 dev_err(dev, "Failed to request IRQ: %d\n", ret);
466 goto err_pm_put;465 goto err_pm_put;
467 }
468 466
469 /* Add hwmon sysfs interface */467 /* Add hwmon sysfs interface */
470 ret = devm_thermal_add_hwmon_sysfs(dev, priv->zone);468 ret = devm_thermal_add_hwmon_sysfs(dev, priv->zone);
drivers/thermal/rockchip_thermal.c+1−2
@@ -1773,8 +1773,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev) · 1772 unmodified lines
1773 IRQF_ONESHOT,1773 IRQF_ONESHOT,
1774 "rockchip_thermal", thermal);1774 "rockchip_thermal", thermal);
1775 if (error)1775 if (error)
1776 return dev_err_probe(&pdev->dev, error,1776 return error;
1777 "failed to request tsadc irq.\n");
1778 1777
1779 thermal->chip->control(thermal->regs, true);1778 thermal->chip->control(thermal->regs, true);
1780 1779
drivers/thermal/samsung/exynos_tmu.c+1−3
@@ -1102,10 +1102,8 @@ static int exynos_tmu_probe(struct platform_device *pdev) · 1101 unmodified lines
1102 IRQF_TRIGGER_RISING1102 IRQF_TRIGGER_RISING
1103 | IRQF_SHARED | IRQF_ONESHOT,1103 | IRQF_SHARED | IRQF_ONESHOT,
1104 dev_name(dev), data);1104 dev_name(dev), data);
1105 if (ret) {1105 if (ret)
1106 dev_err(dev, "Failed to request irq: %d\n", data->irq);
1107 goto err_sclk;1106 goto err_sclk;
1108 }
1109 1107
1110 exynos_tmu_control(pdev, true);1108 exynos_tmu_control(pdev, true);
1111 return 0;1109 return 0;
drivers/thermal/spacemit/k1_tsensor.c+62−16
@@ -156,13 +156,12 @@ static int k1_tsensor_set_trips(struct thermal_zone_device *tz, int low, int hig · 155 unmodified lines
156 struct k1_tsensor *ts = ch->ts;156 struct k1_tsensor *ts = ch->ts;
157 u32 val;157 u32 val;
158 158
159 if (low >= high)
160 return -EINVAL;
161
162 low = clamp_val(low / 1000 + TEMPERATURE_OFFSET, TEMPERATURE_OFFSET,159 low = clamp_val(low / 1000 + TEMPERATURE_OFFSET, TEMPERATURE_OFFSET,
163 FIELD_MAX(K1_TSENSOR_THRSH_LOW_MASK));160 FIELD_MAX(K1_TSENSOR_THRSH_LOW_MASK));
164 high = clamp_val(high / 1000 + TEMPERATURE_OFFSET, TEMPERATURE_OFFSET,161 high = clamp_val(high / 1000 + TEMPERATURE_OFFSET, TEMPERATURE_OFFSET,
165 FIELD_MAX(K1_TSENSOR_THRSH_HIGH_MASK));162 FIELD_MAX(K1_TSENSOR_THRSH_HIGH_MASK));
163 if (low >= high)
164 return -EINVAL;
166 165
167 val = readl(ts->base + K1_TSENSOR_THRSH_REG(ch->id));166 val = readl(ts->base + K1_TSENSOR_THRSH_REG(ch->id));
168 167
@@ -199,6 +198,39 @@ static irqreturn_t k1_tsensor_irq_thread(int irq, void *data) · 30 unmodified lines
199 return IRQ_HANDLED;198 return IRQ_HANDLED;
200}199}
201 200
201static void k1_tsensor_shutdown(struct k1_tsensor *ts)
202{
203 u32 val;
204
205 /* Disable all interrupts */
206 writel(0xffffffff, ts->base + K1_TSENSOR_INT_EN_REG);
207
208 /* Disable all sensors */
209 val = readl(ts->base + K1_TSENSOR_EN_REG);
210 val &= ~K1_TSENSOR_EN_ALL;
211 writel(val, ts->base + K1_TSENSOR_EN_REG);
212
213 /* Clear the sampling configuration set by k1_tsensor_init() */
214 val = readl(ts->base + K1_TSENSOR_TIME_REG);
215 val &= ~(K1_TSENSOR_TIME_FILTER_PERIOD |
216 K1_TSENSOR_TIME_ADC_CNT_RST |
217 K1_TSENSOR_TIME_WAIT_REF_CNT);
218 writel(val, ts->base + K1_TSENSOR_TIME_REG);
219
220 /* Clear the control bits configured by k1_tsensor_init() */
221 val = readl(ts->base + K1_TSENSOR_PCTRL_REG);
222 val &= ~(K1_TSENSOR_PCTRL_RAW_SEL |
223 K1_TSENSOR_PCTRL_TEMP_MODE |
224 K1_TSENSOR_PCTRL_HW_AUTO_MODE |
225 K1_TSENSOR_PCTRL_ENABLE);
226 writel(val, ts->base + K1_TSENSOR_PCTRL_REG);
227}
228
229static void k1_tsensor_shutdown_action(void *data)
230{
231 k1_tsensor_shutdown(data);
232}
233
202static int k1_tsensor_probe(struct platform_device *pdev)234static int k1_tsensor_probe(struct platform_device *pdev)
203{235{
204 struct device *dev = &pdev->dev;236 struct device *dev = &pdev->dev;
@@ -229,34 +261,48 @@ static int k1_tsensor_probe(struct platform_device *pdev) · 24 unmodified lines
229 261
230 k1_tsensor_init(ts);262 k1_tsensor_init(ts);
231 263
232 irq = platform_get_irq(pdev, 0);
233 if (irq < 0)
234 return irq;
235
236 ret = devm_request_threaded_irq(dev, irq, NULL,
237 k1_tsensor_irq_thread,
238 IRQF_ONESHOT, "k1_tsensor", ts);
239 if (ret < 0)
240 return ret;
241
242 for (i = 0; i < MAX_SENSOR_NUMBER; ++i) {264 for (i = 0; i < MAX_SENSOR_NUMBER; ++i) {
243 ts->ch[i].id = i;265 ts->ch[i].id = i;
244 ts->ch[i].ts = ts;266 ts->ch[i].ts = ts;
245 ts->ch[i].tzd = devm_thermal_of_zone_register(dev, i, ts->ch + i, &k1_tsensor_ops);267 ts->ch[i].tzd = devm_thermal_of_zone_register(dev, i, ts->ch + i, &k1_tsensor_ops);
246 if (IS_ERR(ts->ch[i].tzd))268 if (IS_ERR(ts->ch[i].tzd)) {
247 return PTR_ERR(ts->ch[i].tzd);269 ret = PTR_ERR(ts->ch[i].tzd);
270 goto err_shutdown;
271 }
248 272
249 /* Attach sysfs hwmon attributes for userspace monitoring */273 /* Attach sysfs hwmon attributes for userspace monitoring */
250 ret = devm_thermal_add_hwmon_sysfs(dev, ts->ch[i].tzd);274 ret = devm_thermal_add_hwmon_sysfs(dev, ts->ch[i].tzd);
251 if (ret)275 if (ret)
252 dev_warn(dev, "Failed to add hwmon sysfs attributes\n");276 dev_warn(dev, "Failed to add hwmon sysfs attributes\n");
277 }
253 278
254 k1_tsensor_enable_irq(ts->ch + i);279 irq = platform_get_irq(pdev, 0);
280 if (irq < 0) {
281 ret = irq;
282 goto err_shutdown;
255 }283 }
256 284
285 ret = devm_request_threaded_irq(dev, irq, NULL,
286 k1_tsensor_irq_thread,
287 IRQF_ONESHOT, "k1_tsensor", ts);
288 if (ret < 0)
289 goto err_shutdown;
290
291 ret = devm_add_action_or_reset(dev, k1_tsensor_shutdown_action, ts);
292 if (ret)
293 return ret;
294
295 /* Enable interrupts only after all zones and the handler are ready */
296 for (i = 0; i < MAX_SENSOR_NUMBER; ++i)
297 k1_tsensor_enable_irq(ts->ch + i);
298
257 platform_set_drvdata(pdev, ts);299 platform_set_drvdata(pdev, ts);
258 300
259 return 0;301 return 0;
302
303err_shutdown:
304 k1_tsensor_shutdown(ts);
305 return ret;
260}306}
261 307
262static const struct of_device_id k1_tsensor_dt_ids[] = {308static const struct of_device_id k1_tsensor_dt_ids[] = {
drivers/thermal/st/st_thermal_memmap.c+1−3
@@ -101,10 +101,8 @@ static int st_mmap_register_enable_irq(struct st_thermal_sensor *sensor) · 100 unmodified lines
101 NULL, st_mmap_thermal_trip_handler,101 NULL, st_mmap_thermal_trip_handler,
102 IRQF_TRIGGER_RISING | IRQF_ONESHOT,102 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
103 dev->driver->name, sensor);103 dev->driver->name, sensor);
104 if (ret) {104 if (ret)
105 dev_err(dev, "failed to register IRQ %d\n", sensor->irq);
106 return ret;105 return ret;
107 }
108 106
109 return st_mmap_enable_irq(sensor);107 return st_mmap_enable_irq(sensor);
110}108}
drivers/thermal/st/stm_thermal.c+1−4
@@ -390,11 +390,8 @@ static int stm_register_irq(struct stm_thermal_sensor *sensor) · 389 unmodified lines
390 stm_thermal_irq_handler,390 stm_thermal_irq_handler,
391 IRQF_ONESHOT,391 IRQF_ONESHOT,
392 dev->driver->name, sensor);392 dev->driver->name, sensor);
393 if (ret) {393 if (ret)
394 dev_err(dev, "%s: Failed to register IRQ %d\n", __func__,
395 sensor->irq);
396 return ret;394 return ret;
397 }
398 395
399 dev_dbg(dev, "%s: thermal IRQ registered", __func__);396 dev_dbg(dev, "%s: thermal IRQ registered", __func__);
400 397
drivers/thermal/sun8i_thermal.c+0−1
@@ -149,7 +149,6 @@ static const struct regmap_config config = { · 148 unmodified lines
149 .reg_bits = 32,149 .reg_bits = 32,
150 .val_bits = 32,150 .val_bits = 32,
151 .reg_stride = 4,151 .reg_stride = 4,
152 .fast_io = true,
153 .max_register = 0xfc,152 .max_register = 0xfc,
154};153};
155 154
drivers/thermal/tegra/soctherm.c+2−6
@@ -2007,10 +2007,8 @@ static int soctherm_interrupts_init(struct platform_device *pdev, · 2006 unmodified lines
2007 IRQF_ONESHOT,2007 IRQF_ONESHOT,
2008 dev_name(&pdev->dev),2008 dev_name(&pdev->dev),
2009 tegra);2009 tegra);
2010 if (ret < 0) {2010 if (ret < 0)
2011 dev_err(&pdev->dev, "request_irq 'thermal_irq' failed.\n");
2012 return ret;2011 return ret;
2013 }
2014 2012
2015 ret = devm_request_threaded_irq(&pdev->dev,2013 ret = devm_request_threaded_irq(&pdev->dev,
2016 tegra->edp_irq,2014 tegra->edp_irq,
@@ -2019,10 +2017,8 @@ static int soctherm_interrupts_init(struct platform_device *pdev, · 2 unmodified lines
2019 IRQF_ONESHOT,2017 IRQF_ONESHOT,
2020 "soctherm_edp",2018 "soctherm_edp",
2021 tegra);2019 tegra);
2022 if (ret < 0) {2020 if (ret < 0)
2023 dev_err(&pdev->dev, "request_irq 'edp_irq' failed.\n");
2024 return ret;2021 return ret;
2025 }
2026 2022
2027 return 0;2023 return 0;
2028}2024}
drivers/thermal/tegra/tegra30-tsensor.c+1−2
@@ -602,8 +602,7 @@ static int tegra_tsensor_probe(struct platform_device *pdev) · 601 unmodified lines
602 tegra_tsensor_isr, IRQF_ONESHOT,602 tegra_tsensor_isr, IRQF_ONESHOT,
603 "tegra_tsensor", ts);603 "tegra_tsensor", ts);
604 if (err)604 if (err)
605 return dev_err_probe(&pdev->dev, err,605 return err;
606 "failed to request interrupt\n");
607 606
608 return 0;607 return 0;
609}608}
drivers/thermal/thermal-fw.c+12−0
@@ -0,0 +1,12 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * of-thermal-testing.c - Generic Thermal Management device tree testing support
4 *
5 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
6 */
7#include <linux/platform_device.h>
8#include <linux/fwnode.h>
9#include <linux/module.h>
10
11
12
drivers/thermal/thermal_fw.c+97−0
@@ -0,0 +1,97 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * thermal-fw.c - Thermal components creation from firmware description
4 *
5 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
6 */
7#include <linux/fwnode.h>
8#include <linux/module.h>
9#include <linux/platform_device.h>
10#include <linux/thermal.h>
11
12/**
13 * thermal_fwnode_cooling_device_register() - register an thermal cooling device
14 * @np: a pointer to a device tree node.
15 * @of_index: a cooling device index in the cooling controller
16 * @type: the thermal cooling device type.
17 * @devdata: device private data.
18 * @ops: standard thermal cooling devices callbacks.
19 *
20 * This function will register a cooling device with device tree node reference.
21 * This interface function adds a new thermal cooling device (fan/processor/...)
22 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
23 * to all the thermal zone devices registered at the same time.
24 *
25 * Return: a pointer to the created struct thermal_cooling_device or an
26 * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
27 */
28struct thermal_cooling_device *
29thermal_fwnode_cooling_device_register(struct fwnode_handle *fwnode, int fwn_index,
30 const char *type, void *devdata,
31 const struct thermal_cooling_device_ops *ops)
32{
33 struct thermal_cooling_device *cdev;
34
35 cdev = __thermal_cooling_device_register(type, devdata, ops);
36 if (IS_ERR(cdev))
37 return cdev;
38
39 cdev->np = (struct device_node *)fwnode;
40 cdev->of_index = fwn_index;
41 thermal_cooling_device_init_complete(cdev);
42
43 return cdev;
44}
45EXPORT_SYMBOL_GPL(thermal_fwnode_cooling_device_register);
46
47static struct thermal_cooling_device *
48__devm_thermal_fwnode_cooling_device_register(struct device *dev, struct fwnode_handle *fwnode,
49 int fwn_index, const char *type, void *devdata,
50 const struct thermal_cooling_device_ops *ops)
51{
52 struct thermal_cooling_device **ptr, *tcd;
53
54 ptr = devres_alloc(thermal_cooling_device_release, sizeof(*ptr),
55 GFP_KERNEL);
56 if (!ptr)
57 return ERR_PTR(-ENOMEM);
58
59 tcd = thermal_fwnode_cooling_device_register(fwnode, fwn_index, type, devdata, ops);
60 if (IS_ERR(tcd)) {
61 devres_free(ptr);
62 return tcd;
63 }
64
65 *ptr = tcd;
66 devres_add(dev, ptr);
67
68 return tcd;
69}
70
71/**
72 * devm_thermal_fwnode_cooling_device_register() - register a thermal cooling device
73 * @dev: a valid struct device pointer of a sensor device.
74 * @fw_index: a cooling device index in the cooling controller
75 * @type: the thermal cooling device type.
76 * @devdata: device private data.
77 * @ops: standard thermal cooling devices callbacks.
78 *
79 * This function will register a cooling device with a firmware node reference.
80 * This interface function adds a new thermal cooling device (fan/processor/...)
81 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
82 * to all the thermal zone devices registered at the same time.
83 *
84 * Return: a pointer to the created struct thermal_cooling_device or an
85 * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
86 */
87struct thermal_cooling_device *
88devm_thermal_fwnode_cooling_device_register(struct device *dev, int fwn_index,
89 const char *type, void *devdata,
90 const struct thermal_cooling_device_ops *ops)
91{
92 return __devm_thermal_fwnode_cooling_device_register(dev, dev_fwnode(dev), fwn_index,
93 type, devdata, ops);
94}
95EXPORT_SYMBOL_GPL(devm_thermal_fwnode_cooling_device_register);
96
97
drivers/thermal/thermal_of.c+1−1
@@ -444,7 +444,7 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * · 443 unmodified lines
444 444
445 ret = thermal_zone_device_enable(tz);445 ret = thermal_zone_device_enable(tz);
446 if (ret) {446 if (ret) {
447 pr_err("Failed to enabled thermal zone '%s', id=%d: %d\n",447 pr_err("Failed to enable thermal zone '%s', id=%d: %d\n",
448 tz->type, tz->id, ret);448 tz->type, tz->id, ret);
449 thermal_of_zone_unregister(tz);449 thermal_of_zone_unregister(tz);
450 return ERR_PTR(ret);450 return ERR_PTR(ret);
include/linux/iio/adc/qcom-adc5-gen3-common.h+0−2
@@ -205,7 +205,5 @@ int adc5_gen3_get_scaled_reading(struct device *dev, · 204 unmodified lines
205int adc5_gen3_therm_code_to_temp(struct device *dev,205int adc5_gen3_therm_code_to_temp(struct device *dev,
206 struct adc5_channel_common_prop *common_props,206 struct adc5_channel_common_prop *common_props,
207 u16 code, int *val);207 u16 code, int *val);
208void adc5_gen3_register_tm_event_notifier(struct device *dev,
209 void (*handler)(struct auxiliary_device *));
210 208
211#endif /* QCOM_ADC5_GEN3_COMMON_H */209#endif /* QCOM_ADC5_GEN3_COMMON_H */
tools/lib/thermal/include/thermal.h+2−2
@@ -175,8 +175,8 @@ LIBTHERMAL_API thermal_error_t thermal_sampling_handle(struct thermal_handler *t · 174 unmodified lines
175 175
176LIBTHERMAL_API int thermal_sampling_fd(struct thermal_handler *th);176LIBTHERMAL_API int thermal_sampling_fd(struct thermal_handler *th);
177 177
178#endif /* __LIBTHERMAL_H */
179
180#ifdef __cplusplus178#ifdef __cplusplus
181}179}
182#endif180#endif
181
182#endif /* __LIBTHERMAL_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t