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

thermal/drivers/qcom-spmi-temp-alarm: Add support for GEN2 rev 1 PMIC peripherals

Add support for TEMP_ALARM GEN2 PMIC peripherals with digital
major revision 1. This revision utilizes a different temperature
threshold mapping than earlier revisions.

Signed-off-by: David Collins <collinsd@codeaurora.org>
Signed-off-by: Guru Das Srinagesh <gurus@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/69c90a004b3f5b7ae282f5ec5ca2920a48f23e02.1596040416.git.gurus@codeaurora.org

authored by

David Collins and committed by
Daniel Lezcano
aa92b331 34ab17cc

+61 -30
+61 -30
drivers/thermal/qcom/qcom-spmi-temp-alarm.c
··· 17 17 18 18 #include "../thermal_core.h" 19 19 20 + #define QPNP_TM_REG_DIG_MAJOR 0x01 20 21 #define QPNP_TM_REG_TYPE 0x04 21 22 #define QPNP_TM_REG_SUBTYPE 0x05 22 23 #define QPNP_TM_REG_STATUS 0x08 ··· 39 38 40 39 #define ALARM_CTRL_FORCE_ENABLE BIT(7) 41 40 42 - /* 43 - * Trip point values based on threshold control 44 - * 0 = {105 C, 125 C, 145 C} 45 - * 1 = {110 C, 130 C, 150 C} 46 - * 2 = {115 C, 135 C, 155 C} 47 - * 3 = {120 C, 140 C, 160 C} 48 - */ 49 - #define TEMP_STAGE_STEP 20000 /* Stage step: 20.000 C */ 50 - #define TEMP_STAGE_HYSTERESIS 2000 41 + #define THRESH_COUNT 4 42 + #define STAGE_COUNT 3 51 43 52 - #define TEMP_THRESH_MIN 105000 /* Threshold Min: 105 C */ 53 - #define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */ 44 + /* Over-temperature trip point values in mC */ 45 + static const long temp_map_gen1[THRESH_COUNT][STAGE_COUNT] = { 46 + { 105000, 125000, 145000 }, 47 + { 110000, 130000, 150000 }, 48 + { 115000, 135000, 155000 }, 49 + { 120000, 140000, 160000 }, 50 + }; 51 + 52 + static const long temp_map_gen2_v1[THRESH_COUNT][STAGE_COUNT] = { 53 + { 90000, 110000, 140000 }, 54 + { 95000, 115000, 145000 }, 55 + { 100000, 120000, 150000 }, 56 + { 105000, 125000, 155000 }, 57 + }; 58 + 59 + #define TEMP_THRESH_STEP 5000 /* Threshold step: 5 C */ 54 60 55 61 #define THRESH_MIN 0 56 62 #define THRESH_MAX 3 57 63 58 - /* Stage 2 Threshold Min: 125 C */ 59 - #define STAGE2_THRESHOLD_MIN 125000 60 - /* Stage 2 Threshold Max: 140 C */ 61 - #define STAGE2_THRESHOLD_MAX 140000 64 + #define TEMP_STAGE_HYSTERESIS 2000 62 65 63 66 /* Temperature in Milli Celsius reported during stage 0 if no ADC is present */ 64 67 #define DEFAULT_TEMP 37000 ··· 82 77 bool initialized; 83 78 84 79 struct iio_channel *adc; 80 + const long (*temp_map)[THRESH_COUNT][STAGE_COUNT]; 85 81 }; 86 82 87 83 /* This array maps from GEN2 alarm state to GEN1 alarm stage */ ··· 104 98 static int qpnp_tm_write(struct qpnp_tm_chip *chip, u16 addr, u8 data) 105 99 { 106 100 return regmap_write(chip->map, chip->base + addr, data); 101 + } 102 + 103 + /** 104 + * qpnp_tm_decode_temp() - return temperature in mC corresponding to the 105 + * specified over-temperature stage 106 + * @chip: Pointer to the qpnp_tm chip 107 + * @stage: Over-temperature stage 108 + * 109 + * Return: temperature in mC 110 + */ 111 + static long qpnp_tm_decode_temp(struct qpnp_tm_chip *chip, unsigned int stage) 112 + { 113 + if (!chip->temp_map || chip->thresh >= THRESH_COUNT || stage == 0 || 114 + stage > STAGE_COUNT) 115 + return 0; 116 + 117 + return (*chip->temp_map)[chip->thresh][stage - 1]; 107 118 } 108 119 109 120 /** ··· 172 149 173 150 if (stage_new > stage_old) { 174 151 /* increasing stage, use lower bound */ 175 - chip->temp = (stage_new - 1) * TEMP_STAGE_STEP + 176 - chip->thresh * TEMP_THRESH_STEP + 177 - TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN; 152 + chip->temp = qpnp_tm_decode_temp(chip, stage_new) 153 + + TEMP_STAGE_HYSTERESIS; 178 154 } else if (stage_new < stage_old) { 179 155 /* decreasing stage, use upper bound */ 180 - chip->temp = stage_new * TEMP_STAGE_STEP + 181 - chip->thresh * TEMP_THRESH_STEP - 182 - TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN; 156 + chip->temp = qpnp_tm_decode_temp(chip, stage_new + 1) 157 + - TEMP_STAGE_HYSTERESIS; 183 158 } 184 159 185 160 chip->stage = stage; ··· 220 199 static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip, 221 200 int temp) 222 201 { 223 - u8 reg; 202 + long stage2_threshold_min = (*chip->temp_map)[THRESH_MIN][1]; 203 + long stage2_threshold_max = (*chip->temp_map)[THRESH_MAX][1]; 224 204 bool disable_s2_shutdown = false; 205 + u8 reg; 225 206 226 207 WARN_ON(!mutex_is_locked(&chip->lock)); 227 208 228 209 /* 229 210 * Default: S2 and S3 shutdown enabled, thresholds at 230 - * 105C/125C/145C, monitoring at 25Hz 211 + * lowest threshold set, monitoring at 25Hz 231 212 */ 232 213 reg = SHUTDOWN_CTRL1_RATE_25HZ; 233 214 234 215 if (temp == THERMAL_TEMP_INVALID || 235 - temp < STAGE2_THRESHOLD_MIN) { 216 + temp < stage2_threshold_min) { 236 217 chip->thresh = THRESH_MIN; 237 218 goto skip; 238 219 } 239 220 240 - if (temp <= STAGE2_THRESHOLD_MAX) { 221 + if (temp <= stage2_threshold_max) { 241 222 chip->thresh = THRESH_MAX - 242 - ((STAGE2_THRESHOLD_MAX - temp) / 223 + ((stage2_threshold_max - temp) / 243 224 TEMP_THRESH_STEP); 244 225 disable_s2_shutdown = true; 245 226 } else { ··· 349 326 ? chip->stage : alarm_state_map[chip->stage]; 350 327 351 328 if (stage) 352 - chip->temp = chip->thresh * TEMP_THRESH_STEP + 353 - (stage - 1) * TEMP_STAGE_STEP + 354 - TEMP_THRESH_MIN; 329 + chip->temp = qpnp_tm_decode_temp(chip, stage); 355 330 356 331 crit_temp = qpnp_tm_get_critical_trip_temp(chip); 357 332 ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp); ··· 371 350 { 372 351 struct qpnp_tm_chip *chip; 373 352 struct device_node *node; 374 - u8 type, subtype; 353 + u8 type, subtype, dig_major; 375 354 u32 res; 376 355 int ret, irq; 377 356 ··· 421 400 return ret; 422 401 } 423 402 403 + ret = qpnp_tm_read(chip, QPNP_TM_REG_DIG_MAJOR, &dig_major); 404 + if (ret < 0) { 405 + dev_err(&pdev->dev, "could not read dig_major\n"); 406 + return ret; 407 + } 408 + 424 409 if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1 425 410 && subtype != QPNP_TM_SUBTYPE_GEN2)) { 426 411 dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n", ··· 435 408 } 436 409 437 410 chip->subtype = subtype; 411 + if (subtype == QPNP_TM_SUBTYPE_GEN2 && dig_major >= 1) 412 + chip->temp_map = &temp_map_gen2_v1; 413 + else 414 + chip->temp_map = &temp_map_gen1; 438 415 439 416 /* 440 417 * Register the sensor before initializing the hardware to be able to