Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'thermal-6.15-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more thermal control updates from Rafael Wysocki:
"These are mostly assorted updates of thermal drivers used on ARM
platforms:

- Use dev_err_probe() helpers to simplify the init code in the Qoriq
thermal driver (Frank Li)

- Power down the Qoriq's TMU at suspend time (Alice Guo)

- Add ipq5332, ipq5424 compatible to the QCom's tsens thermal driver
and TSENS enable / calibration support for V2 (Praveenkumar I)

- Add missing rk3328 mapping entry (Trevor Woerner)

- Remove duplicate struct declaration from the thermal core header
file (Xueqin Luo)

- Disable the monitoring mode during suspend in the LVTS Mediatek
driver to prevent temperature acquisition glitches (Nícolas F. R.
A. Prado)

- Disable Stage 3 thermal threshold in the LVTS Mediatek driver
because it disables the suspend ability and does not have an
interrupt handler (Nícolas F. R. A. Prado)

- Fix low temperature offset interrupt in the LVTS Mediatek driver to
prevent multiple interrupts from triggering when the system is at
its normal functionning temperature (Nícolas F. R. A. Prado)

- Enable interrupts in the LVTS Mediatek driver only on sensors that
are in use (Nícolas F. R. A. Prado)

- Add the BCM74110 compatible DT binding and the corresponding code
to support a chip based on a different process node than previous
chips (Florian Fainelli)

- Correct indentation and style in DTS example (Krzysztof Kozlowski)

- Unify hexadecimal annotatation in the rcar_gen3 driver (Niklas
Söderlund)

- Factor out the code logic to read fuses on Gen3 and Gen4 in the
rcar_gen3 thermal driver (Niklas Söderlund)

- Drop unused driver data from the QCom's spmi temperature alarm
driver (Johan Hovold)"

* tag 'thermal-6.15-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
thermal/drivers/qcom-spmi-temp-alarm: Drop unused driver data
thermal: rcar_gen3: Reuse logic to read fuses on Gen3 and Gen4
thermal: rcar_gen3: Use lowercase hex constants
dt-bindings: thermal: Correct indentation and style in DTS example
thermal/drivers/brcmstb_thermal: Add support for BCM74110
dt-bindings: thermal: Update for BCM74110
thermal/drivers/mediatek/lvts: Only update IRQ enable for valid sensors
thermal/drivers/mediatek/lvts: Start sensor interrupts disabled
thermal/drivers/mediatek/lvts: Disable low offset IRQ for minimum threshold
thermal/drivers/mediatek/lvts: Disable Stage 3 thermal threshold
thermal/drivers/mediatek/lvts: Disable monitor mode during suspend
thermal: core: Remove duplicate struct declaration
thermal/drivers/rockchip: Add missing rk3328 mapping entry
thermal/drivers/tsens: Add TSENS enable and calibration support for V2
dt-bindings: thermal: tsens: Add ipq5332, ipq5424 compatible
thermal/drivers/qoriq: Power down TMU on system suspend
thermal/drivers/qoriq: Use dev_err_probe() simplify the code

+406 -164
+24 -24
Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
··· 142 142 examples: 143 143 - | 144 144 thermal-sensor@1f04000 { 145 - compatible = "allwinner,sun8i-a83t-ths"; 146 - reg = <0x01f04000 0x100>; 147 - interrupts = <0 31 0>; 148 - nvmem-cells = <&ths_calibration>; 149 - nvmem-cell-names = "calibration"; 150 - #thermal-sensor-cells = <1>; 145 + compatible = "allwinner,sun8i-a83t-ths"; 146 + reg = <0x01f04000 0x100>; 147 + interrupts = <0 31 0>; 148 + nvmem-cells = <&ths_calibration>; 149 + nvmem-cell-names = "calibration"; 150 + #thermal-sensor-cells = <1>; 151 151 }; 152 152 153 153 - | 154 154 thermal-sensor@1c25000 { 155 - compatible = "allwinner,sun8i-h3-ths"; 156 - reg = <0x01c25000 0x400>; 157 - clocks = <&ccu 0>, <&ccu 1>; 158 - clock-names = "bus", "mod"; 159 - resets = <&ccu 2>; 160 - interrupts = <0 31 0>; 161 - nvmem-cells = <&ths_calibration>; 162 - nvmem-cell-names = "calibration"; 163 - #thermal-sensor-cells = <0>; 155 + compatible = "allwinner,sun8i-h3-ths"; 156 + reg = <0x01c25000 0x400>; 157 + clocks = <&ccu 0>, <&ccu 1>; 158 + clock-names = "bus", "mod"; 159 + resets = <&ccu 2>; 160 + interrupts = <0 31 0>; 161 + nvmem-cells = <&ths_calibration>; 162 + nvmem-cell-names = "calibration"; 163 + #thermal-sensor-cells = <0>; 164 164 }; 165 165 166 166 - | 167 167 thermal-sensor@5070400 { 168 - compatible = "allwinner,sun50i-h6-ths"; 169 - reg = <0x05070400 0x100>; 170 - clocks = <&ccu 0>; 171 - clock-names = "bus"; 172 - resets = <&ccu 2>; 173 - interrupts = <0 15 0>; 174 - nvmem-cells = <&ths_calibration>; 175 - nvmem-cell-names = "calibration"; 176 - #thermal-sensor-cells = <1>; 168 + compatible = "allwinner,sun50i-h6-ths"; 169 + reg = <0x05070400 0x100>; 170 + clocks = <&ccu 0>; 171 + clock-names = "bus"; 172 + resets = <&ccu 2>; 173 + interrupts = <0 15 0>; 174 + nvmem-cells = <&ths_calibration>; 175 + nvmem-cell-names = "calibration"; 176 + #thermal-sensor-cells = <1>; 177 177 }; 178 178 179 179 ...
+1
Documentation/devicetree/bindings/thermal/brcm,avs-tmon.yaml
··· 18 18 compatible: 19 19 items: 20 20 - enum: 21 + - brcm,avs-tmon-bcm74110 21 22 - brcm,avs-tmon-bcm7216 22 23 - brcm,avs-tmon-bcm7445 23 24 - const: brcm,avs-tmon
+18 -18
Documentation/devicetree/bindings/thermal/imx-thermal.yaml
··· 80 80 #include <dt-bindings/interrupt-controller/arm-gic.h> 81 81 82 82 efuse@21bc000 { 83 - #address-cells = <1>; 84 - #size-cells = <1>; 85 - compatible = "fsl,imx6sx-ocotp", "syscon"; 86 - reg = <0x021bc000 0x4000>; 87 - clocks = <&clks IMX6SX_CLK_OCOTP>; 83 + #address-cells = <1>; 84 + #size-cells = <1>; 85 + compatible = "fsl,imx6sx-ocotp", "syscon"; 86 + reg = <0x021bc000 0x4000>; 87 + clocks = <&clks IMX6SX_CLK_OCOTP>; 88 88 89 - tempmon_calib: calib@38 { 90 - reg = <0x38 4>; 91 - }; 89 + tempmon_calib: calib@38 { 90 + reg = <0x38 4>; 91 + }; 92 92 93 - tempmon_temp_grade: temp-grade@20 { 94 - reg = <0x20 4>; 95 - }; 93 + tempmon_temp_grade: temp-grade@20 { 94 + reg = <0x20 4>; 95 + }; 96 96 }; 97 97 98 98 anatop@20c8000 { ··· 103 103 <0 127 IRQ_TYPE_LEVEL_HIGH>; 104 104 105 105 tempmon { 106 - compatible = "fsl,imx6sx-tempmon"; 107 - interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; 108 - fsl,tempmon = <&anatop>; 109 - nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>; 110 - nvmem-cell-names = "calib", "temp_grade"; 111 - clocks = <&clks IMX6SX_CLK_PLL3_USB_OTG>; 112 - #thermal-sensor-cells = <0>; 106 + compatible = "fsl,imx6sx-tempmon"; 107 + interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; 108 + fsl,tempmon = <&anatop>; 109 + nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>; 110 + nvmem-cell-names = "calib", "temp_grade"; 111 + clocks = <&clks IMX6SX_CLK_PLL3_USB_OTG>; 112 + #thermal-sensor-cells = <0>; 113 113 }; 114 114 };
+4 -4
Documentation/devicetree/bindings/thermal/imx8mm-thermal.yaml
··· 63 63 #include <dt-bindings/clock/imx8mm-clock.h> 64 64 65 65 thermal-sensor@30260000 { 66 - compatible = "fsl,imx8mm-tmu"; 67 - reg = <0x30260000 0x10000>; 68 - clocks = <&clk IMX8MM_CLK_TMU_ROOT>; 69 - #thermal-sensor-cells = <0>; 66 + compatible = "fsl,imx8mm-tmu"; 67 + reg = <0x30260000 0x10000>; 68 + clocks = <&clk IMX8MM_CLK_TMU_ROOT>; 69 + #thermal-sensor-cells = <0>; 70 70 }; 71 71 72 72 ...
+18
Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
··· 75 75 76 76 - description: v2 of TSENS with combined interrupt 77 77 enum: 78 + - qcom,ipq5332-tsens 79 + - qcom,ipq5424-tsens 78 80 - qcom,ipq8074-tsens 79 81 80 82 - description: v2 of TSENS with combined interrupt ··· 214 212 - const: s9_p2_backup 215 213 - const: s10_p1_backup 216 214 - const: s10_p2_backup 215 + - minItems: 8 216 + items: 217 + - const: mode 218 + - const: base0 219 + - const: base1 220 + - pattern: '^tsens_sens[0-9]+_off$' 221 + - pattern: '^tsens_sens[0-9]+_off$' 222 + - pattern: '^tsens_sens[0-9]+_off$' 223 + - pattern: '^tsens_sens[0-9]+_off$' 224 + - pattern: '^tsens_sens[0-9]+_off$' 225 + - pattern: '^tsens_sens[0-9]+_off$' 226 + - pattern: '^tsens_sens[0-9]+_off$' 217 227 218 228 "#qcom,sensors": 219 229 description: ··· 285 271 compatible: 286 272 contains: 287 273 enum: 274 + - qcom,ipq5332-tsens 275 + - qcom,ipq5424-tsens 288 276 - qcom,ipq8074-tsens 289 277 then: 290 278 properties: ··· 302 286 compatible: 303 287 contains: 304 288 enum: 289 + - qcom,ipq5332-tsens 290 + - qcom,ipq5424-tsens 305 291 - qcom,ipq8074-tsens 306 292 - qcom,tsens-v0_1 307 293 - qcom,tsens-v1
+9 -2
drivers/thermal/broadcom/brcmstb_thermal.c
··· 286 286 return 0; 287 287 } 288 288 289 - static const struct thermal_zone_device_ops brcmstb_16nm_of_ops = { 289 + static const struct thermal_zone_device_ops brcmstb_of_ops = { 290 290 .get_temp = brcmstb_get_temp, 291 + }; 292 + 293 + static const struct brcmstb_thermal_params brcmstb_8nm_params = { 294 + .offset = 418670, 295 + .mult = 509, 296 + .of_ops = &brcmstb_of_ops, 291 297 }; 292 298 293 299 static const struct brcmstb_thermal_params brcmstb_16nm_params = { 294 300 .offset = 457829, 295 301 .mult = 557, 296 - .of_ops = &brcmstb_16nm_of_ops, 302 + .of_ops = &brcmstb_of_ops, 297 303 }; 298 304 299 305 static const struct thermal_zone_device_ops brcmstb_28nm_of_ops = { ··· 314 308 }; 315 309 316 310 static const struct of_device_id brcmstb_thermal_id_table[] = { 311 + { .compatible = "brcm,avs-tmon-bcm74110", .data = &brcmstb_8nm_params }, 317 312 { .compatible = "brcm,avs-tmon-bcm7216", .data = &brcmstb_16nm_params }, 318 313 { .compatible = "brcm,avs-tmon", .data = &brcmstb_28nm_params }, 319 314 {},
+72 -31
drivers/thermal/mediatek/lvts_thermal.c
··· 65 65 #define LVTS_HW_FILTER 0x0 66 66 #define LVTS_TSSEL_CONF 0x13121110 67 67 #define LVTS_CALSCALE_CONF 0x300 68 - #define LVTS_MONINT_CONF 0x8300318C 69 68 70 - #define LVTS_MONINT_OFFSET_SENSOR0 0xC 71 - #define LVTS_MONINT_OFFSET_SENSOR1 0x180 72 - #define LVTS_MONINT_OFFSET_SENSOR2 0x3000 73 - #define LVTS_MONINT_OFFSET_SENSOR3 0x3000000 69 + #define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR0 BIT(3) 70 + #define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR1 BIT(8) 71 + #define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR2 BIT(13) 72 + #define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR3 BIT(25) 73 + #define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR0 BIT(2) 74 + #define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR1 BIT(7) 75 + #define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR2 BIT(12) 76 + #define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR3 BIT(24) 74 77 75 78 #define LVTS_INT_SENSOR0 0x0009001F 76 79 #define LVTS_INT_SENSOR1 0x001203E0 ··· 93 90 94 91 #define LVTS_MSR_READ_TIMEOUT_US 400 95 92 #define LVTS_MSR_READ_WAIT_US (LVTS_MSR_READ_TIMEOUT_US / 2) 96 - 97 - #define LVTS_HW_TSHUT_TEMP 105000 98 93 99 94 #define LVTS_MINIMUM_THRESHOLD 20000 100 95 ··· 146 145 struct lvts_sensor sensors[LVTS_SENSOR_MAX]; 147 146 const struct lvts_data *lvts_data; 148 147 u32 calibration[LVTS_SENSOR_MAX]; 149 - u32 hw_tshut_raw_temp; 150 148 u8 valid_sensor_mask; 151 149 int mode; 152 150 void __iomem *base; ··· 329 329 330 330 static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl) 331 331 { 332 - static const u32 masks[] = { 333 - LVTS_MONINT_OFFSET_SENSOR0, 334 - LVTS_MONINT_OFFSET_SENSOR1, 335 - LVTS_MONINT_OFFSET_SENSOR2, 336 - LVTS_MONINT_OFFSET_SENSOR3, 332 + static const u32 high_offset_inten_masks[] = { 333 + LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR0, 334 + LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR1, 335 + LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR2, 336 + LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR3, 337 + }; 338 + static const u32 low_offset_inten_masks[] = { 339 + LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR0, 340 + LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR1, 341 + LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR2, 342 + LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR3, 337 343 }; 338 344 u32 value = 0; 339 345 int i; 340 346 341 347 value = readl(LVTS_MONINT(lvts_ctrl->base)); 342 348 343 - for (i = 0; i < ARRAY_SIZE(masks); i++) { 349 + lvts_for_each_valid_sensor(i, lvts_ctrl) { 344 350 if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh 345 - && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh) 346 - value |= masks[i]; 347 - else 348 - value &= ~masks[i]; 351 + && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh) { 352 + /* 353 + * The minimum threshold needs to be configured in the 354 + * OFFSETL register to get working interrupts, but we 355 + * don't actually want to generate interrupts when 356 + * crossing it. 357 + */ 358 + if (lvts_ctrl->low_thresh == -INT_MAX) { 359 + value &= ~low_offset_inten_masks[i]; 360 + value |= high_offset_inten_masks[i]; 361 + } else { 362 + value |= low_offset_inten_masks[i] | high_offset_inten_masks[i]; 363 + } 364 + } else { 365 + value &= ~(low_offset_inten_masks[i] | high_offset_inten_masks[i]); 366 + } 349 367 } 350 368 351 369 writel(value, LVTS_MONINT(lvts_ctrl->base)); ··· 855 837 */ 856 838 lvts_ctrl[i].mode = lvts_data->lvts_ctrl[i].mode; 857 839 858 - /* 859 - * The temperature to raw temperature must be done 860 - * after initializing the calibration. 861 - */ 862 - lvts_ctrl[i].hw_tshut_raw_temp = 863 - lvts_temp_to_raw(LVTS_HW_TSHUT_TEMP, 864 - lvts_data->temp_factor); 865 - 866 840 lvts_ctrl[i].low_thresh = INT_MIN; 867 841 lvts_ctrl[i].high_thresh = INT_MIN; 868 842 } ··· 868 858 lvts_td->num_lvts_ctrl = lvts_data->num_lvts_ctrl; 869 859 870 860 return 0; 861 + } 862 + 863 + static void lvts_ctrl_monitor_enable(struct device *dev, struct lvts_ctrl *lvts_ctrl, bool enable) 864 + { 865 + /* 866 + * Bitmaps to enable each sensor on filtered mode in the MONCTL0 867 + * register. 868 + */ 869 + static const u8 sensor_filt_bitmap[] = { BIT(0), BIT(1), BIT(2), BIT(3) }; 870 + u32 sensor_map = 0; 871 + int i; 872 + 873 + if (lvts_ctrl->mode != LVTS_MSR_FILTERED_MODE) 874 + return; 875 + 876 + if (enable) { 877 + lvts_for_each_valid_sensor(i, lvts_ctrl) 878 + sensor_map |= sensor_filt_bitmap[i]; 879 + } 880 + 881 + /* 882 + * Bits: 883 + * 9: Single point access flow 884 + * 0-3: Enable sensing point 0-3 885 + */ 886 + writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base)); 871 887 } 872 888 873 889 /* ··· 929 893 * 10 : Selected sensor with bits 19-18 930 894 * 11 : Reserved 931 895 */ 932 - writel(BIT(16), LVTS_PROTCTL(lvts_ctrl->base)); 933 896 934 897 /* 935 898 * LVTS_PROTTA : Stage 1 temperature threshold ··· 941 906 * 942 907 * writel(0x0, LVTS_PROTTA(lvts_ctrl->base)); 943 908 * writel(0x0, LVTS_PROTTB(lvts_ctrl->base)); 909 + * writel(0x0, LVTS_PROTTC(lvts_ctrl->base)); 944 910 */ 945 - writel(lvts_ctrl->hw_tshut_raw_temp, LVTS_PROTTC(lvts_ctrl->base)); 946 911 947 912 /* 948 913 * LVTS_MONINT : Interrupt configuration register ··· 950 915 * The LVTS_MONINT register layout is the same as the LVTS_MONINTSTS 951 916 * register, except we set the bits to enable the interrupt. 952 917 */ 953 - writel(LVTS_MONINT_CONF, LVTS_MONINT(lvts_ctrl->base)); 918 + writel(0, LVTS_MONINT(lvts_ctrl->base)); 954 919 955 920 return 0; 956 921 } ··· 1416 1381 1417 1382 lvts_td = dev_get_drvdata(dev); 1418 1383 1419 - for (i = 0; i < lvts_td->num_lvts_ctrl; i++) 1384 + for (i = 0; i < lvts_td->num_lvts_ctrl; i++) { 1385 + lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], false); 1386 + usleep_range(100, 200); 1420 1387 lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false); 1388 + } 1421 1389 1422 1390 clk_disable_unprepare(lvts_td->clk); 1423 1391 ··· 1438 1400 if (ret) 1439 1401 return ret; 1440 1402 1441 - for (i = 0; i < lvts_td->num_lvts_ctrl; i++) 1403 + for (i = 0; i < lvts_td->num_lvts_ctrl; i++) { 1442 1404 lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], true); 1405 + usleep_range(100, 200); 1406 + lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], true); 1407 + } 1443 1408 1444 1409 return 0; 1445 1410 }
-1
drivers/thermal/qcom/qcom-spmi-temp-alarm.c
··· 360 360 if (!chip) 361 361 return -ENOMEM; 362 362 363 - dev_set_drvdata(&pdev->dev, chip); 364 363 chip->dev = &pdev->dev; 365 364 366 365 mutex_init(&chip->lock);
+178
drivers/thermal/qcom/tsens-v2.c
··· 4 4 * Copyright (c) 2018, Linaro Limited 5 5 */ 6 6 7 + #include <linux/bitfield.h> 7 8 #include <linux/bitops.h> 9 + #include <linux/nvmem-consumer.h> 8 10 #include <linux/regmap.h> 9 11 #include "tsens.h" 10 12 11 13 /* ----- SROT ------ */ 12 14 #define SROT_HW_VER_OFF 0x0000 13 15 #define SROT_CTRL_OFF 0x0004 16 + #define SROT_MEASURE_PERIOD 0x0008 17 + #define SROT_Sn_CONVERSION 0x0060 18 + #define V2_SHIFT_DEFAULT 0x0003 19 + #define V2_SLOPE_DEFAULT 0x0cd0 20 + #define V2_CZERO_DEFAULT 0x016a 21 + #define ONE_PT_SLOPE 0x0cd0 22 + #define TWO_PT_SHIFTED_GAIN 921600 23 + #define ONE_PT_CZERO_CONST 94 24 + #define SW_RST_DEASSERT 0x0 25 + #define SW_RST_ASSERT 0x1 26 + #define MEASURE_PERIOD_2mSEC 0x1 27 + #define RESULT_FORMAT_TEMP 0x1 28 + #define TSENS_ENABLE 0x1 29 + #define SENSOR_CONVERSION(n) (((n) * 4) + SROT_Sn_CONVERSION) 30 + #define CONVERSION_SHIFT_MASK GENMASK(24, 23) 31 + #define CONVERSION_SLOPE_MASK GENMASK(22, 10) 32 + #define CONVERSION_CZERO_MASK GENMASK(9, 0) 14 33 15 34 /* ----- TM ------ */ 16 35 #define TM_INT_EN_OFF 0x0004 ··· 69 50 .trip_max_temp = 204000, 70 51 }; 71 52 53 + static struct tsens_features ipq5332_feat = { 54 + .ver_major = VER_2_X_NO_RPM, 55 + .crit_int = 1, 56 + .combo_int = 1, 57 + .adc = 0, 58 + .srot_split = 1, 59 + .max_sensors = 16, 60 + .trip_min_temp = 0, 61 + .trip_max_temp = 204000, 62 + }; 63 + 72 64 static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = { 73 65 /* ----- SROT ------ */ 74 66 /* VERSION */ ··· 89 59 /* CTRL_OFF */ 90 60 [TSENS_EN] = REG_FIELD(SROT_CTRL_OFF, 0, 0), 91 61 [TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1, 1), 62 + [SENSOR_EN] = REG_FIELD(SROT_CTRL_OFF, 3, 18), 63 + [CODE_OR_TEMP] = REG_FIELD(SROT_CTRL_OFF, 21, 21), 64 + 65 + [MAIN_MEASURE_PERIOD] = REG_FIELD(SROT_MEASURE_PERIOD, 0, 7), 92 66 93 67 /* ----- TM ------ */ 94 68 /* INTERRUPT ENABLE */ ··· 138 104 [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0), 139 105 }; 140 106 107 + static int tsens_v2_calibrate_sensor(struct device *dev, struct tsens_sensor *sensor, 108 + struct regmap *map, u32 mode, u32 base0, u32 base1) 109 + { 110 + u32 shift = V2_SHIFT_DEFAULT; 111 + u32 slope = V2_SLOPE_DEFAULT; 112 + u32 czero = V2_CZERO_DEFAULT; 113 + char name[20]; 114 + u32 val; 115 + int ret; 116 + 117 + /* Read offset value */ 118 + ret = snprintf(name, sizeof(name), "tsens_sens%d_off", sensor->hw_id); 119 + if (ret < 0) 120 + return ret; 121 + 122 + ret = nvmem_cell_read_variable_le_u32(dev, name, &sensor->offset); 123 + if (ret) 124 + return ret; 125 + 126 + /* Based on calib mode, program SHIFT, SLOPE and CZERO */ 127 + switch (mode) { 128 + case TWO_PT_CALIB: 129 + slope = (TWO_PT_SHIFTED_GAIN / (base1 - base0)); 130 + 131 + czero = (base0 + sensor->offset - ((base1 - base0) / 3)); 132 + 133 + break; 134 + case ONE_PT_CALIB2: 135 + czero = base0 + sensor->offset - ONE_PT_CZERO_CONST; 136 + 137 + slope = ONE_PT_SLOPE; 138 + 139 + break; 140 + default: 141 + dev_dbg(dev, "calibrationless mode\n"); 142 + } 143 + 144 + val = FIELD_PREP(CONVERSION_SHIFT_MASK, shift) | 145 + FIELD_PREP(CONVERSION_SLOPE_MASK, slope) | 146 + FIELD_PREP(CONVERSION_CZERO_MASK, czero); 147 + 148 + regmap_write(map, SENSOR_CONVERSION(sensor->hw_id), val); 149 + 150 + return 0; 151 + } 152 + 153 + static int tsens_v2_calibration(struct tsens_priv *priv) 154 + { 155 + struct device *dev = priv->dev; 156 + u32 mode, base0, base1; 157 + int i, ret; 158 + 159 + if (priv->num_sensors > MAX_SENSORS) 160 + return -EINVAL; 161 + 162 + ret = nvmem_cell_read_variable_le_u32(priv->dev, "mode", &mode); 163 + if (ret == -ENOENT) 164 + dev_warn(priv->dev, "Calibration data not present in DT\n"); 165 + if (ret < 0) 166 + return ret; 167 + 168 + dev_dbg(priv->dev, "calibration mode is %d\n", mode); 169 + 170 + ret = nvmem_cell_read_variable_le_u32(priv->dev, "base0", &base0); 171 + if (ret < 0) 172 + return ret; 173 + 174 + ret = nvmem_cell_read_variable_le_u32(priv->dev, "base1", &base1); 175 + if (ret < 0) 176 + return ret; 177 + 178 + /* Calibrate each sensor */ 179 + for (i = 0; i < priv->num_sensors; i++) { 180 + ret = tsens_v2_calibrate_sensor(dev, &priv->sensor[i], priv->srot_map, 181 + mode, base0, base1); 182 + if (ret < 0) 183 + return ret; 184 + } 185 + 186 + return 0; 187 + } 188 + 189 + static int __init init_tsens_v2_no_rpm(struct tsens_priv *priv) 190 + { 191 + struct device *dev = priv->dev; 192 + int i, ret; 193 + u32 val = 0; 194 + 195 + ret = init_common(priv); 196 + if (ret < 0) 197 + return ret; 198 + 199 + priv->rf[CODE_OR_TEMP] = devm_regmap_field_alloc(dev, priv->srot_map, 200 + priv->fields[CODE_OR_TEMP]); 201 + if (IS_ERR(priv->rf[CODE_OR_TEMP])) 202 + return PTR_ERR(priv->rf[CODE_OR_TEMP]); 203 + 204 + priv->rf[MAIN_MEASURE_PERIOD] = devm_regmap_field_alloc(dev, priv->srot_map, 205 + priv->fields[MAIN_MEASURE_PERIOD]); 206 + if (IS_ERR(priv->rf[MAIN_MEASURE_PERIOD])) 207 + return PTR_ERR(priv->rf[MAIN_MEASURE_PERIOD]); 208 + 209 + regmap_field_write(priv->rf[TSENS_SW_RST], SW_RST_ASSERT); 210 + 211 + regmap_field_write(priv->rf[MAIN_MEASURE_PERIOD], MEASURE_PERIOD_2mSEC); 212 + 213 + /* Enable available sensors */ 214 + for (i = 0; i < priv->num_sensors; i++) 215 + val |= 1 << priv->sensor[i].hw_id; 216 + 217 + regmap_field_write(priv->rf[SENSOR_EN], val); 218 + 219 + /* Select temperature format, unit is deci-Celsius */ 220 + regmap_field_write(priv->rf[CODE_OR_TEMP], RESULT_FORMAT_TEMP); 221 + 222 + regmap_field_write(priv->rf[TSENS_SW_RST], SW_RST_DEASSERT); 223 + 224 + regmap_field_write(priv->rf[TSENS_EN], TSENS_ENABLE); 225 + 226 + return 0; 227 + } 228 + 141 229 static const struct tsens_ops ops_generic_v2 = { 142 230 .init = init_common, 143 231 .get_temp = get_temp_tsens_valid, ··· 276 120 .ops = &ops_generic_v2, 277 121 .feat = &ipq8074_feat, 278 122 .fields = tsens_v2_regfields, 123 + }; 124 + 125 + static const struct tsens_ops ops_ipq5332 = { 126 + .init = init_tsens_v2_no_rpm, 127 + .get_temp = get_temp_tsens_valid, 128 + .calibrate = tsens_v2_calibration, 129 + }; 130 + 131 + const struct tsens_plat_data data_ipq5332 = { 132 + .num_sensors = 5, 133 + .ops = &ops_ipq5332, 134 + .hw_ids = (unsigned int []){11, 12, 13, 14, 15}, 135 + .feat = &ipq5332_feat, 136 + .fields = tsens_v2_regfields, 137 + }; 138 + 139 + const struct tsens_plat_data data_ipq5424 = { 140 + .num_sensors = 7, 141 + .ops = &ops_ipq5332, 142 + .hw_ids = (unsigned int []){9, 10, 11, 12, 13, 14, 15}, 143 + .feat = &ipq5332_feat, 144 + .fields = tsens_v2_regfields, 279 145 }; 280 146 281 147 /* Kept around for backward compatibility with old msm8996.dtsi */
+7 -1
drivers/thermal/qcom/tsens.c
··· 975 975 ret = regmap_field_read(priv->rf[TSENS_EN], &enabled); 976 976 if (ret) 977 977 goto err_put_device; 978 - if (!enabled) { 978 + if (!enabled && (tsens_version(priv) != VER_2_X_NO_RPM)) { 979 979 dev_err(dev, "%s: device not enabled\n", __func__); 980 980 ret = -ENODEV; 981 981 goto err_put_device; ··· 1102 1102 1103 1103 static const struct of_device_id tsens_table[] = { 1104 1104 { 1105 + .compatible = "qcom,ipq5332-tsens", 1106 + .data = &data_ipq5332, 1107 + }, { 1108 + .compatible = "qcom,ipq5424-tsens", 1109 + .data = &data_ipq5424, 1110 + }, { 1105 1111 .compatible = "qcom,ipq8064-tsens", 1106 1112 .data = &data_8960, 1107 1113 }, {
+3
drivers/thermal/qcom/tsens.h
··· 35 35 VER_0_1, 36 36 VER_1_X, 37 37 VER_2_X, 38 + VER_2_X_NO_RPM, 38 39 }; 39 40 40 41 enum tsens_irq_type { ··· 169 168 TSENS_SW_RST, 170 169 SENSOR_EN, 171 170 CODE_OR_TEMP, 171 + MAIN_MEASURE_PERIOD, 172 172 173 173 /* ----- TM ------ */ 174 174 /* TRDY */ ··· 653 651 654 652 /* TSENS v2 targets */ 655 653 extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2; 654 + extern const struct tsens_plat_data data_ipq5332, data_ipq5424; 656 655 657 656 #endif /* __QCOM_TSENS_H__ */
+23 -24
drivers/thermal/qoriq_thermal.c
··· 18 18 #define SITES_MAX 16 19 19 #define TMR_DISABLE 0x0 20 20 #define TMR_ME 0x80000000 21 + #define TMR_CMD BIT(29) 21 22 #define TMR_ALPF 0x0c000000 22 23 #define TMR_ALPF_V2 0x03000000 23 24 #define TMTMIR_DEFAULT 0x0000000f ··· 266 265 struct qoriq_tmu_data *data = p; 267 266 268 267 regmap_write(data->regmap, REGS_TMR, TMR_DISABLE); 269 - clk_disable_unprepare(data->clk); 270 268 } 271 269 272 270 static int qoriq_tmu_probe(struct platform_device *pdev) ··· 296 296 297 297 base = devm_platform_ioremap_resource(pdev, 0); 298 298 ret = PTR_ERR_OR_ZERO(base); 299 - if (ret) { 300 - dev_err(dev, "Failed to get memory region\n"); 301 - return ret; 302 - } 299 + if (ret) 300 + return dev_err_probe(dev, ret, "Failed to get memory region\n"); 303 301 304 302 data->regmap = devm_regmap_init_mmio(dev, base, &regmap_config); 305 303 ret = PTR_ERR_OR_ZERO(data->regmap); 306 - if (ret) { 307 - dev_err(dev, "Failed to init regmap (%d)\n", ret); 308 - return ret; 309 - } 304 + if (ret) 305 + return dev_err_probe(dev, ret, "Failed to init regmap\n"); 310 306 311 - data->clk = devm_clk_get_optional(dev, NULL); 307 + data->clk = devm_clk_get_optional_enabled(dev, NULL); 312 308 if (IS_ERR(data->clk)) 313 309 return PTR_ERR(data->clk); 314 - 315 - ret = clk_prepare_enable(data->clk); 316 - if (ret) { 317 - dev_err(dev, "Failed to enable clock\n"); 318 - return ret; 319 - } 320 310 321 311 ret = devm_add_action_or_reset(dev, qoriq_tmu_action, data); 322 312 if (ret) ··· 314 324 315 325 /* version register offset at: 0xbf8 on both v1 and v2 */ 316 326 ret = regmap_read(data->regmap, REGS_IPBRR(0), &ver); 317 - if (ret) { 318 - dev_err(&pdev->dev, "Failed to read IP block version\n"); 319 - return ret; 320 - } 327 + if (ret) 328 + return dev_err_probe(dev, ret, "Failed to read IP block version\n"); 329 + 321 330 data->ver = (ver >> 8) & 0xff; 322 331 323 332 qoriq_tmu_init_device(data); /* TMU initialization */ ··· 326 337 return ret; 327 338 328 339 ret = qoriq_tmu_register_tmu_zone(dev, data); 329 - if (ret < 0) { 330 - dev_err(dev, "Failed to register sensors\n"); 331 - return ret; 332 - } 340 + if (ret < 0) 341 + return dev_err_probe(dev, ret, "Failed to register sensors\n"); 333 342 334 343 platform_set_drvdata(pdev, data); 335 344 ··· 343 356 if (ret) 344 357 return ret; 345 358 359 + if (data->ver > TMU_VER1) { 360 + ret = regmap_set_bits(data->regmap, REGS_TMR, TMR_CMD); 361 + if (ret) 362 + return ret; 363 + } 364 + 346 365 clk_disable_unprepare(data->clk); 347 366 348 367 return 0; ··· 362 369 ret = clk_prepare_enable(data->clk); 363 370 if (ret) 364 371 return ret; 372 + 373 + if (data->ver > TMU_VER1) { 374 + ret = regmap_clear_bits(data->regmap, REGS_TMR, TMR_CMD); 375 + if (ret) 376 + return ret; 377 + } 365 378 366 379 /* Enable monitoring */ 367 380 return regmap_update_bits(data->regmap, REGS_TMR, TMR_ME, TMR_ME);
+48 -57
drivers/thermal/renesas/rcar_gen3_thermal.c
··· 21 21 /* Register offsets */ 22 22 #define REG_GEN3_IRQSTR 0x04 23 23 #define REG_GEN3_IRQMSK 0x08 24 - #define REG_GEN3_IRQCTL 0x0C 24 + #define REG_GEN3_IRQCTL 0x0c 25 25 #define REG_GEN3_IRQEN 0x10 26 26 #define REG_GEN3_IRQTEMP1 0x14 27 27 #define REG_GEN3_IRQTEMP2 0x18 28 - #define REG_GEN3_IRQTEMP3 0x1C 28 + #define REG_GEN3_IRQTEMP3 0x1c 29 29 #define REG_GEN3_THCTR 0x20 30 30 #define REG_GEN3_TEMP 0x28 31 31 #define REG_GEN3_THCODE1 0x50 ··· 38 38 #define REG_GEN4_THSFMON00 0x180 39 39 #define REG_GEN4_THSFMON01 0x184 40 40 #define REG_GEN4_THSFMON02 0x188 41 - #define REG_GEN4_THSFMON15 0x1BC 42 - #define REG_GEN4_THSFMON16 0x1C0 43 - #define REG_GEN4_THSFMON17 0x1C4 41 + #define REG_GEN4_THSFMON15 0x1bc 42 + #define REG_GEN4_THSFMON16 0x1c0 43 + #define REG_GEN4_THSFMON17 0x1c4 44 44 45 45 /* IRQ{STR,MSK,EN} bits */ 46 46 #define IRQ_TEMP1 BIT(0) ··· 57 57 /* THSCP bits */ 58 58 #define THSCP_COR_PARA_VLD (BIT(15) | BIT(14)) 59 59 60 - #define CTEMP_MASK 0xFFF 60 + #define CTEMP_MASK 0xfff 61 61 62 62 #define MCELSIUS(temp) ((temp) * 1000) 63 - #define GEN3_FUSE_MASK 0xFFF 64 - #define GEN4_FUSE_MASK 0xFFF 63 + #define GEN3_FUSE_MASK 0xfff 64 + #define GEN4_FUSE_MASK 0xfff 65 65 66 66 #define TSC_MAX_NUM 5 67 67 68 68 struct rcar_gen3_thermal_priv; 69 69 70 + struct rcar_gen3_thermal_fuse_info { 71 + u32 ptat[3]; 72 + u32 thcode[3]; 73 + u32 mask; 74 + }; 75 + 70 76 struct rcar_thermal_info { 71 77 int scale; 72 78 int adj_below; 73 79 int adj_above; 74 - void (*read_fuses)(struct rcar_gen3_thermal_priv *priv); 80 + const struct rcar_gen3_thermal_fuse_info *fuses; 75 81 }; 76 82 77 83 struct equation_set_coef { ··· 259 253 return IRQ_HANDLED; 260 254 } 261 255 262 - static void rcar_gen3_thermal_read_fuses_gen3(struct rcar_gen3_thermal_priv *priv) 256 + static void rcar_gen3_thermal_fetch_fuses(struct rcar_gen3_thermal_priv *priv) 263 257 { 264 - unsigned int i; 258 + const struct rcar_gen3_thermal_fuse_info *fuses = priv->info->fuses; 265 259 266 260 /* 267 261 * Set the pseudo calibration points with fused values. 268 262 * PTAT is shared between all TSCs but only fused for the first 269 263 * TSC while THCODEs are fused for each TSC. 270 264 */ 271 - priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT1) & 272 - GEN3_FUSE_MASK; 273 - priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT2) & 274 - GEN3_FUSE_MASK; 275 - priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT3) & 276 - GEN3_FUSE_MASK; 265 + priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], fuses->ptat[0]) 266 + & fuses->mask; 267 + priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], fuses->ptat[1]) 268 + & fuses->mask; 269 + priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], fuses->ptat[2]) 270 + & fuses->mask; 277 271 278 - for (i = 0; i < priv->num_tscs; i++) { 272 + for (unsigned int i = 0; i < priv->num_tscs; i++) { 279 273 struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; 280 274 281 - tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE1) & 282 - GEN3_FUSE_MASK; 283 - tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE2) & 284 - GEN3_FUSE_MASK; 285 - tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE3) & 286 - GEN3_FUSE_MASK; 287 - } 288 - } 289 - 290 - static void rcar_gen3_thermal_read_fuses_gen4(struct rcar_gen3_thermal_priv *priv) 291 - { 292 - unsigned int i; 293 - 294 - /* 295 - * Set the pseudo calibration points with fused values. 296 - * PTAT is shared between all TSCs but only fused for the first 297 - * TSC while THCODEs are fused for each TSC. 298 - */ 299 - priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON16) & 300 - GEN4_FUSE_MASK; 301 - priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON17) & 302 - GEN4_FUSE_MASK; 303 - priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON15) & 304 - GEN4_FUSE_MASK; 305 - 306 - for (i = 0; i < priv->num_tscs; i++) { 307 - struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; 308 - 309 - tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON01) & 310 - GEN4_FUSE_MASK; 311 - tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON02) & 312 - GEN4_FUSE_MASK; 313 - tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON00) & 314 - GEN4_FUSE_MASK; 275 + tsc->thcode[0] = rcar_gen3_thermal_read(tsc, fuses->thcode[0]) 276 + & fuses->mask; 277 + tsc->thcode[1] = rcar_gen3_thermal_read(tsc, fuses->thcode[1]) 278 + & fuses->mask; 279 + tsc->thcode[2] = rcar_gen3_thermal_read(tsc, fuses->thcode[2]) 280 + & fuses->mask; 315 281 } 316 282 } 317 283 ··· 294 316 295 317 /* If fuses are not set, fallback to pseudo values. */ 296 318 thscp = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_THSCP); 297 - if (!priv->info->read_fuses || 319 + if (!priv->info->fuses || 298 320 (thscp & THSCP_COR_PARA_VLD) != THSCP_COR_PARA_VLD) { 299 321 /* Default THCODE values in case FUSEs are not set. */ 300 322 static const int thcodes[TSC_MAX_NUM][3] = { ··· 320 342 return false; 321 343 } 322 344 323 - priv->info->read_fuses(priv); 345 + rcar_gen3_thermal_fetch_fuses(priv); 346 + 324 347 return true; 325 348 } 326 349 ··· 349 370 usleep_range(1000, 2000); 350 371 } 351 372 373 + static const struct rcar_gen3_thermal_fuse_info rcar_gen3_thermal_fuse_info_gen3 = { 374 + .ptat = { REG_GEN3_PTAT1, REG_GEN3_PTAT2, REG_GEN3_PTAT3 }, 375 + .thcode = { REG_GEN3_THCODE1, REG_GEN3_THCODE2, REG_GEN3_THCODE3 }, 376 + .mask = GEN3_FUSE_MASK, 377 + }; 378 + 379 + static const struct rcar_gen3_thermal_fuse_info rcar_gen3_thermal_fuse_info_gen4 = { 380 + .ptat = { REG_GEN4_THSFMON16, REG_GEN4_THSFMON17, REG_GEN4_THSFMON15 }, 381 + .thcode = { REG_GEN4_THSFMON01, REG_GEN4_THSFMON02, REG_GEN4_THSFMON00 }, 382 + .mask = GEN4_FUSE_MASK, 383 + }; 384 + 352 385 static const struct rcar_thermal_info rcar_m3w_thermal_info = { 353 386 .scale = 157, 354 387 .adj_below = -41, 355 388 .adj_above = 116, 356 - .read_fuses = rcar_gen3_thermal_read_fuses_gen3, 389 + .fuses = &rcar_gen3_thermal_fuse_info_gen3, 357 390 }; 358 391 359 392 static const struct rcar_thermal_info rcar_gen3_thermal_info = { 360 393 .scale = 167, 361 394 .adj_below = -41, 362 395 .adj_above = 126, 363 - .read_fuses = rcar_gen3_thermal_read_fuses_gen3, 396 + .fuses = &rcar_gen3_thermal_fuse_info_gen3, 364 397 }; 365 398 366 399 static const struct rcar_thermal_info rcar_gen4_thermal_info = { 367 400 .scale = 167, 368 401 .adj_below = -41, 369 402 .adj_above = 126, 370 - .read_fuses = rcar_gen3_thermal_read_fuses_gen4, 403 + .fuses = &rcar_gen3_thermal_fuse_info_gen4, 371 404 }; 372 405 373 406 static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
+1
drivers/thermal/rockchip_thermal.c
··· 386 386 {296, -40000}, 387 387 {304, -35000}, 388 388 {313, -30000}, 389 + {322, -25000}, 389 390 {331, -20000}, 390 391 {340, -15000}, 391 392 {349, -10000},
-2
include/linux/thermal.h
··· 86 86 #define THERMAL_TRIP_PRIV_TO_INT(_val_) (uintptr_t)(_val_) 87 87 #define THERMAL_INT_TO_TRIP_PRIV(_val_) (void *)(uintptr_t)(_val_) 88 88 89 - struct thermal_zone_device; 90 - 91 89 struct cooling_spec { 92 90 unsigned long upper; /* Highest cooling state */ 93 91 unsigned long lower; /* Lowest cooling state */