1375 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.4 * Copyright (c) 2019, 2020, Linaro Ltd.5 */6 7#include <linux/debugfs.h>8#include <linux/err.h>9#include <linux/io.h>10#include <linux/module.h>11#include <linux/nvmem-consumer.h>12#include <linux/of.h>13#include <linux/of_address.h>14#include <linux/of_platform.h>15#include <linux/mfd/syscon.h>16#include <linux/platform_device.h>17#include <linux/pm.h>18#include <linux/regmap.h>19#include <linux/slab.h>20#include <linux/suspend.h>21#include <linux/thermal.h>22#include "../thermal_hwmon.h"23#include "tsens.h"24 25/**26 * struct tsens_irq_data - IRQ status and temperature violations27 * @up_viol: upper threshold violated28 * @up_thresh: upper threshold temperature value29 * @up_irq_mask: mask register for upper threshold irqs30 * @up_irq_clear: clear register for uppper threshold irqs31 * @low_viol: lower threshold violated32 * @low_thresh: lower threshold temperature value33 * @low_irq_mask: mask register for lower threshold irqs34 * @low_irq_clear: clear register for lower threshold irqs35 * @crit_viol: critical threshold violated36 * @crit_thresh: critical threshold temperature value37 * @crit_irq_mask: mask register for critical threshold irqs38 * @crit_irq_clear: clear register for critical threshold irqs39 *40 * Structure containing data about temperature threshold settings and41 * irq status if they were violated.42 */43struct tsens_irq_data {44 u32 up_viol;45 int up_thresh;46 u32 up_irq_mask;47 u32 up_irq_clear;48 u32 low_viol;49 int low_thresh;50 u32 low_irq_mask;51 u32 low_irq_clear;52 u32 crit_viol;53 u32 crit_thresh;54 u32 crit_irq_mask;55 u32 crit_irq_clear;56};57 58char *qfprom_read(struct device *dev, const char *cname)59{60 struct nvmem_cell *cell;61 ssize_t data;62 char *ret;63 64 cell = nvmem_cell_get(dev, cname);65 if (IS_ERR(cell))66 return ERR_CAST(cell);67 68 ret = nvmem_cell_read(cell, &data);69 nvmem_cell_put(cell);70 71 return ret;72}73 74int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, bool backup)75{76 u32 mode;77 u32 base1, base2;78 char name[] = "sXX_pY_backup"; /* s10_p1_backup */79 int i, ret;80 81 if (priv->num_sensors > MAX_SENSORS)82 return -EINVAL;83 84 ret = snprintf(name, sizeof(name), "mode%s", backup ? "_backup" : "");85 if (ret < 0)86 return ret;87 88 ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &mode);89 if (ret == -ENOENT)90 dev_warn(priv->dev, "Please migrate to separate nvmem cells for calibration data\n");91 if (ret < 0)92 return ret;93 94 dev_dbg(priv->dev, "calibration mode is %d\n", mode);95 96 ret = snprintf(name, sizeof(name), "base1%s", backup ? "_backup" : "");97 if (ret < 0)98 return ret;99 100 ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &base1);101 if (ret < 0)102 return ret;103 104 ret = snprintf(name, sizeof(name), "base2%s", backup ? "_backup" : "");105 if (ret < 0)106 return ret;107 108 ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &base2);109 if (ret < 0)110 return ret;111 112 for (i = 0; i < priv->num_sensors; i++) {113 ret = snprintf(name, sizeof(name), "s%d_p1%s", priv->sensor[i].hw_id,114 backup ? "_backup" : "");115 if (ret < 0)116 return ret;117 118 ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p1[i]);119 if (ret)120 return ret;121 122 ret = snprintf(name, sizeof(name), "s%d_p2%s", priv->sensor[i].hw_id,123 backup ? "_backup" : "");124 if (ret < 0)125 return ret;126 127 ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p2[i]);128 if (ret)129 return ret;130 }131 132 switch (mode) {133 case ONE_PT_CALIB:134 for (i = 0; i < priv->num_sensors; i++)135 p1[i] = p1[i] + (base1 << shift);136 break;137 case TWO_PT_CALIB:138 case TWO_PT_CALIB_NO_OFFSET:139 for (i = 0; i < priv->num_sensors; i++)140 p2[i] = (p2[i] + base2) << shift;141 fallthrough;142 case ONE_PT_CALIB2:143 case ONE_PT_CALIB2_NO_OFFSET:144 for (i = 0; i < priv->num_sensors; i++)145 p1[i] = (p1[i] + base1) << shift;146 break;147 default:148 dev_dbg(priv->dev, "calibrationless mode\n");149 for (i = 0; i < priv->num_sensors; i++) {150 p1[i] = 500;151 p2[i] = 780;152 }153 }154 155 /* Apply calibration offset workaround except for _NO_OFFSET modes */156 switch (mode) {157 case TWO_PT_CALIB:158 for (i = 0; i < priv->num_sensors; i++)159 p2[i] += priv->sensor[i].p2_calib_offset;160 fallthrough;161 case ONE_PT_CALIB2:162 for (i = 0; i < priv->num_sensors; i++)163 p1[i] += priv->sensor[i].p1_calib_offset;164 break;165 }166 167 return mode;168}169 170int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift)171{172 u32 p1[MAX_SENSORS], p2[MAX_SENSORS];173 int mode;174 175 mode = tsens_read_calibration(priv, shift, p1, p2, false);176 if (mode < 0)177 return mode;178 179 compute_intercept_slope(priv, p1, p2, mode);180 181 return 0;182}183 184int tsens_calibrate_common(struct tsens_priv *priv)185{186 return tsens_calibrate_nvmem(priv, 2);187}188 189static u32 tsens_read_cell(const struct tsens_single_value *cell, u8 len, u32 *data0, u32 *data1)190{191 u32 val;192 u32 *data = cell->blob ? data1 : data0;193 194 if (cell->shift + len <= 32) {195 val = data[cell->idx] >> cell->shift;196 } else {197 u8 part = 32 - cell->shift;198 199 val = data[cell->idx] >> cell->shift;200 val |= data[cell->idx + 1] << part;201 }202 203 return val & ((1 << len) - 1);204}205 206int tsens_read_calibration_legacy(struct tsens_priv *priv,207 const struct tsens_legacy_calibration_format *format,208 u32 *p1, u32 *p2,209 u32 *cdata0, u32 *cdata1)210{211 u32 mode, invalid;212 u32 base1, base2;213 int i;214 215 mode = tsens_read_cell(&format->mode, 2, cdata0, cdata1);216 invalid = tsens_read_cell(&format->invalid, 1, cdata0, cdata1);217 if (invalid)218 mode = NO_PT_CALIB;219 dev_dbg(priv->dev, "calibration mode is %d\n", mode);220 221 base1 = tsens_read_cell(&format->base[0], format->base_len, cdata0, cdata1);222 base2 = tsens_read_cell(&format->base[1], format->base_len, cdata0, cdata1);223 224 for (i = 0; i < priv->num_sensors; i++) {225 p1[i] = tsens_read_cell(&format->sp[i][0], format->sp_len, cdata0, cdata1);226 p2[i] = tsens_read_cell(&format->sp[i][1], format->sp_len, cdata0, cdata1);227 }228 229 switch (mode) {230 case ONE_PT_CALIB:231 for (i = 0; i < priv->num_sensors; i++)232 p1[i] = p1[i] + (base1 << format->base_shift);233 break;234 case TWO_PT_CALIB:235 for (i = 0; i < priv->num_sensors; i++)236 p2[i] = (p2[i] + base2) << format->base_shift;237 fallthrough;238 case ONE_PT_CALIB2:239 for (i = 0; i < priv->num_sensors; i++)240 p1[i] = (p1[i] + base1) << format->base_shift;241 break;242 default:243 dev_dbg(priv->dev, "calibrationless mode\n");244 for (i = 0; i < priv->num_sensors; i++) {245 p1[i] = 500;246 p2[i] = 780;247 }248 }249 250 return mode;251}252 253/*254 * Use this function on devices where slope and offset calculations255 * depend on calibration data read from qfprom. On others the slope256 * and offset values are derived from tz->tzp->slope and tz->tzp->offset257 * resp.258 */259void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,260 u32 *p2, u32 mode)261{262 int i;263 int num, den;264 265 for (i = 0; i < priv->num_sensors; i++) {266 dev_dbg(priv->dev,267 "%s: sensor%d - data_point1:%#x data_point2:%#x\n",268 __func__, i, p1[i], p2 ? p2[i] : 0);269 270 if (!priv->sensor[i].slope)271 priv->sensor[i].slope = SLOPE_DEFAULT;272 if (mode == TWO_PT_CALIB || mode == TWO_PT_CALIB_NO_OFFSET) {273 /*274 * slope (m) = adc_code2 - adc_code1 (y2 - y1)/275 * temp_120_degc - temp_30_degc (x2 - x1)276 */277 num = p2[i] - p1[i];278 num *= SLOPE_FACTOR;279 den = CAL_DEGC_PT2 - CAL_DEGC_PT1;280 priv->sensor[i].slope = num / den;281 }282 283 priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -284 (CAL_DEGC_PT1 *285 priv->sensor[i].slope);286 dev_dbg(priv->dev, "%s: offset:%d\n", __func__,287 priv->sensor[i].offset);288 }289}290 291static inline u32 degc_to_code(int degc, const struct tsens_sensor *s)292{293 u64 code = div_u64(((u64)degc * s->slope + s->offset), SLOPE_FACTOR);294 295 pr_debug("%s: raw_code: 0x%llx, degc:%d\n", __func__, code, degc);296 return clamp_val(code, THRESHOLD_MIN_ADC_CODE, THRESHOLD_MAX_ADC_CODE);297}298 299static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)300{301 int degc, num, den;302 303 num = (adc_code * SLOPE_FACTOR) - s->offset;304 den = s->slope;305 306 if (num > 0)307 degc = num + (den / 2);308 else if (num < 0)309 degc = num - (den / 2);310 else311 degc = num;312 313 degc /= den;314 315 return degc;316}317 318/**319 * tsens_hw_to_mC - Return sign-extended temperature in mCelsius.320 * @s: Pointer to sensor struct321 * @field: Index into regmap_field array pointing to temperature data322 *323 * This function handles temperature returned in ADC code or deciCelsius324 * depending on IP version.325 *326 * Return: Temperature in milliCelsius on success, a negative errno will327 * be returned in error cases328 */329static int tsens_hw_to_mC(const struct tsens_sensor *s, int field)330{331 struct tsens_priv *priv = s->priv;332 u32 resolution;333 u32 temp = 0;334 int ret;335 336 resolution = priv->fields[LAST_TEMP_0].msb -337 priv->fields[LAST_TEMP_0].lsb;338 339 ret = regmap_field_read(priv->rf[field], &temp);340 if (ret)341 return ret;342 343 /* Convert temperature from ADC code to milliCelsius */344 if (priv->feat->adc)345 return code_to_degc(temp, s) * 1000;346 347 /* deciCelsius -> milliCelsius along with sign extension */348 return sign_extend32(temp, resolution) * 100;349}350 351/**352 * tsens_mC_to_hw - Convert temperature to hardware register value353 * @s: Pointer to sensor struct354 * @temp: temperature in milliCelsius to be programmed to hardware355 *356 * This function outputs the value to be written to hardware in ADC code357 * or deciCelsius depending on IP version.358 *359 * Return: ADC code or temperature in deciCelsius.360 */361static int tsens_mC_to_hw(const struct tsens_sensor *s, int temp)362{363 struct tsens_priv *priv = s->priv;364 365 /* milliC to adc code */366 if (priv->feat->adc)367 return degc_to_code(temp / 1000, s);368 369 /* milliC to deciC */370 return temp / 100;371}372 373static inline enum tsens_ver tsens_version(struct tsens_priv *priv)374{375 return priv->feat->ver_major;376}377 378static void tsens_set_interrupt_v1(struct tsens_priv *priv, u32 hw_id,379 enum tsens_irq_type irq_type, bool enable)380{381 u32 index = 0;382 383 switch (irq_type) {384 case UPPER:385 index = UP_INT_CLEAR_0 + hw_id;386 break;387 case LOWER:388 index = LOW_INT_CLEAR_0 + hw_id;389 break;390 case CRITICAL:391 /* No critical interrupts before v2 */392 return;393 }394 regmap_field_write(priv->rf[index], enable ? 0 : 1);395}396 397static void tsens_set_interrupt_v2(struct tsens_priv *priv, u32 hw_id,398 enum tsens_irq_type irq_type, bool enable)399{400 u32 index_mask = 0, index_clear = 0;401 402 /*403 * To enable the interrupt flag for a sensor:404 * - clear the mask bit405 * To disable the interrupt flag for a sensor:406 * - Mask further interrupts for this sensor407 * - Write 1 followed by 0 to clear the interrupt408 */409 switch (irq_type) {410 case UPPER:411 index_mask = UP_INT_MASK_0 + hw_id;412 index_clear = UP_INT_CLEAR_0 + hw_id;413 break;414 case LOWER:415 index_mask = LOW_INT_MASK_0 + hw_id;416 index_clear = LOW_INT_CLEAR_0 + hw_id;417 break;418 case CRITICAL:419 index_mask = CRIT_INT_MASK_0 + hw_id;420 index_clear = CRIT_INT_CLEAR_0 + hw_id;421 break;422 }423 424 if (enable) {425 regmap_field_write(priv->rf[index_mask], 0);426 } else {427 regmap_field_write(priv->rf[index_mask], 1);428 regmap_field_write(priv->rf[index_clear], 1);429 regmap_field_write(priv->rf[index_clear], 0);430 }431}432 433/**434 * tsens_set_interrupt - Set state of an interrupt435 * @priv: Pointer to tsens controller private data436 * @hw_id: Hardware ID aka. sensor number437 * @irq_type: irq_type from enum tsens_irq_type438 * @enable: false = disable, true = enable439 *440 * Call IP-specific function to set state of an interrupt441 *442 * Return: void443 */444static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,445 enum tsens_irq_type irq_type, bool enable)446{447 dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,448 irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",449 enable ? "en" : "dis");450 if (tsens_version(priv) > VER_1_X)451 tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);452 else453 tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);454}455 456/**457 * tsens_threshold_violated - Check if a sensor temperature violated a preset threshold458 * @priv: Pointer to tsens controller private data459 * @hw_id: Hardware ID aka. sensor number460 * @d: Pointer to irq state data461 *462 * Return: 0 if threshold was not violated, 1 if it was violated and negative463 * errno in case of errors464 */465static int tsens_threshold_violated(struct tsens_priv *priv, u32 hw_id,466 struct tsens_irq_data *d)467{468 int ret;469 470 ret = regmap_field_read(priv->rf[UPPER_STATUS_0 + hw_id], &d->up_viol);471 if (ret)472 return ret;473 ret = regmap_field_read(priv->rf[LOWER_STATUS_0 + hw_id], &d->low_viol);474 if (ret)475 return ret;476 477 if (priv->feat->crit_int) {478 ret = regmap_field_read(priv->rf[CRITICAL_STATUS_0 + hw_id],479 &d->crit_viol);480 if (ret)481 return ret;482 }483 484 if (d->up_viol || d->low_viol || d->crit_viol)485 return 1;486 487 return 0;488}489 490static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,491 const struct tsens_sensor *s,492 struct tsens_irq_data *d)493{494 int ret;495 496 ret = regmap_field_read(priv->rf[UP_INT_CLEAR_0 + hw_id], &d->up_irq_clear);497 if (ret)498 return ret;499 ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear);500 if (ret)501 return ret;502 if (tsens_version(priv) > VER_1_X) {503 ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask);504 if (ret)505 return ret;506 ret = regmap_field_read(priv->rf[LOW_INT_MASK_0 + hw_id], &d->low_irq_mask);507 if (ret)508 return ret;509 ret = regmap_field_read(priv->rf[CRIT_INT_CLEAR_0 + hw_id],510 &d->crit_irq_clear);511 if (ret)512 return ret;513 ret = regmap_field_read(priv->rf[CRIT_INT_MASK_0 + hw_id],514 &d->crit_irq_mask);515 if (ret)516 return ret;517 518 d->crit_thresh = tsens_hw_to_mC(s, CRIT_THRESH_0 + hw_id);519 } else {520 /* No mask register on older TSENS */521 d->up_irq_mask = 0;522 d->low_irq_mask = 0;523 d->crit_irq_clear = 0;524 d->crit_irq_mask = 0;525 d->crit_thresh = 0;526 }527 528 d->up_thresh = tsens_hw_to_mC(s, UP_THRESH_0 + hw_id);529 d->low_thresh = tsens_hw_to_mC(s, LOW_THRESH_0 + hw_id);530 531 dev_dbg(priv->dev, "[%u] %s%s: status(%u|%u|%u) | clr(%u|%u|%u) | mask(%u|%u|%u)\n",532 hw_id, __func__,533 (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",534 d->low_viol, d->up_viol, d->crit_viol,535 d->low_irq_clear, d->up_irq_clear, d->crit_irq_clear,536 d->low_irq_mask, d->up_irq_mask, d->crit_irq_mask);537 dev_dbg(priv->dev, "[%u] %s%s: thresh: (%d:%d:%d)\n", hw_id, __func__,538 (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",539 d->low_thresh, d->up_thresh, d->crit_thresh);540 541 return 0;542}543 544static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver)545{546 if (ver > VER_1_X)547 return mask & (1 << hw_id);548 549 /* v1, v0.1 don't have a irq mask register */550 return 0;551}552 553/**554 * tsens_critical_irq_thread() - Threaded handler for critical interrupts555 * @irq: irq number556 * @data: tsens controller private data557 *558 * Check FSM watchdog bark status and clear if needed.559 * Check all sensors to find ones that violated their critical threshold limits.560 * Clear and then re-enable the interrupt.561 *562 * The level-triggered interrupt might deassert if the temperature returned to563 * within the threshold limits by the time the handler got scheduled. We564 * consider the irq to have been handled in that case.565 *566 * Return: IRQ_HANDLED567 */568static irqreturn_t tsens_critical_irq_thread(int irq, void *data)569{570 struct tsens_priv *priv = data;571 struct tsens_irq_data d;572 int temp, ret, i;573 u32 wdog_status, wdog_count;574 575 if (priv->feat->has_watchdog) {576 ret = regmap_field_read(priv->rf[WDOG_BARK_STATUS],577 &wdog_status);578 if (ret)579 return ret;580 581 if (wdog_status) {582 /* Clear WDOG interrupt */583 regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 1);584 regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 0);585 ret = regmap_field_read(priv->rf[WDOG_BARK_COUNT],586 &wdog_count);587 if (ret)588 return ret;589 if (wdog_count)590 dev_dbg(priv->dev, "%s: watchdog count: %d\n",591 __func__, wdog_count);592 593 /* Fall through to handle critical interrupts if any */594 }595 }596 597 for (i = 0; i < priv->num_sensors; i++) {598 const struct tsens_sensor *s = &priv->sensor[i];599 u32 hw_id = s->hw_id;600 601 if (!s->tzd)602 continue;603 if (!tsens_threshold_violated(priv, hw_id, &d))604 continue;605 ret = get_temp_tsens_valid(s, &temp);606 if (ret) {607 dev_err(priv->dev, "[%u] %s: error reading sensor\n",608 hw_id, __func__);609 continue;610 }611 612 tsens_read_irq_state(priv, hw_id, s, &d);613 if (d.crit_viol &&614 !masked_irq(hw_id, d.crit_irq_mask, tsens_version(priv))) {615 /* Mask critical interrupts, unused on Linux */616 tsens_set_interrupt(priv, hw_id, CRITICAL, false);617 }618 }619 620 return IRQ_HANDLED;621}622 623/**624 * tsens_irq_thread - Threaded interrupt handler for uplow interrupts625 * @irq: irq number626 * @data: tsens controller private data627 *628 * Check all sensors to find ones that violated their threshold limits. If the629 * temperature is still outside the limits, call thermal_zone_device_update() to630 * update the thresholds, else re-enable the interrupts.631 *632 * The level-triggered interrupt might deassert if the temperature returned to633 * within the threshold limits by the time the handler got scheduled. We634 * consider the irq to have been handled in that case.635 *636 * Return: IRQ_HANDLED637 */638static irqreturn_t tsens_irq_thread(int irq, void *data)639{640 struct tsens_priv *priv = data;641 struct tsens_irq_data d;642 int i;643 644 for (i = 0; i < priv->num_sensors; i++) {645 const struct tsens_sensor *s = &priv->sensor[i];646 u32 hw_id = s->hw_id;647 648 if (!s->tzd)649 continue;650 if (!tsens_threshold_violated(priv, hw_id, &d))651 continue;652 653 thermal_zone_device_update(s->tzd, THERMAL_EVENT_UNSPECIFIED);654 655 if (tsens_version(priv) < VER_0_1) {656 /* Constraint: There is only 1 interrupt control register for all657 * 11 temperature sensor. So monitoring more than 1 sensor based658 * on interrupts will yield inconsistent result. To overcome this659 * issue we will monitor only sensor 0 which is the master sensor.660 */661 break;662 }663 }664 665 return IRQ_HANDLED;666}667 668/**669 * tsens_combined_irq_thread() - Threaded interrupt handler for combined interrupts670 * @irq: irq number671 * @data: tsens controller private data672 *673 * Handle the combined interrupt as if it were 2 separate interrupts, so call the674 * critical handler first and then the up/low one.675 *676 * Return: IRQ_HANDLED677 */678static irqreturn_t tsens_combined_irq_thread(int irq, void *data)679{680 irqreturn_t ret;681 682 ret = tsens_critical_irq_thread(irq, data);683 if (ret != IRQ_HANDLED)684 return ret;685 686 return tsens_irq_thread(irq, data);687}688 689static int tsens_set_trips(struct thermal_zone_device *tz, int low, int high)690{691 struct tsens_sensor *s = thermal_zone_device_priv(tz);692 struct tsens_priv *priv = s->priv;693 struct device *dev = priv->dev;694 struct tsens_irq_data d;695 unsigned long flags;696 int high_val, low_val, cl_high, cl_low;697 u32 hw_id = s->hw_id;698 699 if (tsens_version(priv) < VER_0_1) {700 /* Pre v0.1 IP had a single register for each type of interrupt701 * and thresholds702 */703 hw_id = 0;704 }705 706 dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",707 hw_id, __func__, low, high);708 709 cl_high = clamp_val(high, priv->feat->trip_min_temp, priv->feat->trip_max_temp);710 cl_low = clamp_val(low, priv->feat->trip_min_temp, priv->feat->trip_max_temp);711 712 high_val = tsens_mC_to_hw(s, cl_high);713 low_val = tsens_mC_to_hw(s, cl_low);714 715 spin_lock_irqsave(&priv->ul_lock, flags);716 717 tsens_read_irq_state(priv, hw_id, s, &d);718 719 /* Write the new thresholds and clear the status */720 regmap_field_write(priv->rf[LOW_THRESH_0 + hw_id], low_val);721 regmap_field_write(priv->rf[UP_THRESH_0 + hw_id], high_val);722 tsens_set_interrupt(priv, hw_id, LOWER, true);723 tsens_set_interrupt(priv, hw_id, UPPER, true);724 725 spin_unlock_irqrestore(&priv->ul_lock, flags);726 727 dev_dbg(dev, "[%u] %s: (%d:%d)->(%d:%d)\n",728 hw_id, __func__, d.low_thresh, d.up_thresh, cl_low, cl_high);729 730 return 0;731}732 733static int tsens_enable_irq(struct tsens_priv *priv)734{735 int ret;736 int val = tsens_version(priv) > VER_1_X ? 7 : 1;737 738 ret = regmap_field_write(priv->rf[INT_EN], val);739 if (ret < 0)740 dev_err(priv->dev, "%s: failed to enable interrupts\n",741 __func__);742 743 return ret;744}745 746static void tsens_disable_irq(struct tsens_priv *priv)747{748 regmap_field_write(priv->rf[INT_EN], 0);749}750 751int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)752{753 struct tsens_priv *priv = s->priv;754 int hw_id = s->hw_id;755 u32 temp_idx = LAST_TEMP_0 + hw_id;756 u32 valid_idx = VALID_0 + hw_id;757 u32 valid;758 int ret;759 760 /* VER_0 doesn't have VALID bit */761 if (tsens_version(priv) == VER_0)762 goto get_temp;763 764 /* Valid bit is 0 for 6 AHB clock cycles.765 * At 19.2MHz, 1 AHB clock is ~60ns.766 * We should enter this loop very, very rarely.767 * Wait 1 us since it's the min of poll_timeout macro.768 * Old value was 400 ns.769 */770 ret = regmap_field_read_poll_timeout(priv->rf[valid_idx], valid,771 valid, 1, 20 * USEC_PER_MSEC);772 if (ret)773 return ret;774 775get_temp:776 /* Valid bit is set, OK to read the temperature */777 *temp = tsens_hw_to_mC(s, temp_idx);778 779 return 0;780}781 782int get_temp_common(const struct tsens_sensor *s, int *temp)783{784 struct tsens_priv *priv = s->priv;785 int hw_id = s->hw_id;786 int last_temp = 0, ret, trdy;787 unsigned long timeout;788 789 timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);790 do {791 if (tsens_version(priv) == VER_0) {792 ret = regmap_field_read(priv->rf[TRDY], &trdy);793 if (ret)794 return ret;795 if (!trdy)796 continue;797 }798 799 ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);800 if (ret)801 return ret;802 803 *temp = code_to_degc(last_temp, s) * 1000;804 805 return 0;806 } while (time_before(jiffies, timeout));807 808 return -ETIMEDOUT;809}810 811#ifdef CONFIG_DEBUG_FS812static int dbg_sensors_show(struct seq_file *s, void *data)813{814 struct platform_device *pdev = s->private;815 struct tsens_priv *priv = platform_get_drvdata(pdev);816 int i;817 818 seq_printf(s, "max: %2d\nnum: %2d\n\n",819 priv->feat->max_sensors, priv->num_sensors);820 821 seq_puts(s, " id slope offset\n--------------------------\n");822 for (i = 0; i < priv->num_sensors; i++) {823 seq_printf(s, "%8d %8d %8d\n", priv->sensor[i].hw_id,824 priv->sensor[i].slope, priv->sensor[i].offset);825 }826 827 return 0;828}829 830static int dbg_version_show(struct seq_file *s, void *data)831{832 struct platform_device *pdev = s->private;833 struct tsens_priv *priv = platform_get_drvdata(pdev);834 u32 maj_ver, min_ver, step_ver;835 int ret;836 837 if (tsens_version(priv) > VER_0_1) {838 ret = regmap_field_read(priv->rf[VER_MAJOR], &maj_ver);839 if (ret)840 return ret;841 ret = regmap_field_read(priv->rf[VER_MINOR], &min_ver);842 if (ret)843 return ret;844 ret = regmap_field_read(priv->rf[VER_STEP], &step_ver);845 if (ret)846 return ret;847 seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);848 } else {849 seq_printf(s, "0.%d.0\n", priv->feat->ver_major);850 }851 852 return 0;853}854 855DEFINE_SHOW_ATTRIBUTE(dbg_version);856DEFINE_SHOW_ATTRIBUTE(dbg_sensors);857 858static void tsens_debug_init(struct platform_device *pdev)859{860 struct tsens_priv *priv = platform_get_drvdata(pdev);861 862 priv->debug_root = debugfs_lookup("tsens", NULL);863 if (!priv->debug_root)864 priv->debug_root = debugfs_create_dir("tsens", NULL);865 866 /* A directory for each instance of the TSENS IP */867 priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);868 debugfs_create_file("version", 0444, priv->debug, pdev, &dbg_version_fops);869 debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);870}871#else872static inline void tsens_debug_init(struct platform_device *pdev) {}873#endif874 875static const struct regmap_config tsens_config = {876 .name = "tm",877 .reg_bits = 32,878 .val_bits = 32,879 .reg_stride = 4,880};881 882static const struct regmap_config tsens_srot_config = {883 .name = "srot",884 .reg_bits = 32,885 .val_bits = 32,886 .reg_stride = 4,887};888 889int __init init_common(struct tsens_priv *priv)890{891 void __iomem *tm_base, *srot_base;892 struct device *dev = priv->dev;893 u32 ver_minor;894 struct resource *res;895 u32 enabled;896 int ret, i, j;897 struct platform_device *op = of_find_device_by_node(priv->dev->of_node);898 899 if (!op)900 return -EINVAL;901 902 if (op->num_resources > 1) {903 /* DT with separate SROT and TM address space */904 priv->tm_offset = 0;905 res = platform_get_resource(op, IORESOURCE_MEM, 1);906 srot_base = devm_ioremap_resource(dev, res);907 if (IS_ERR(srot_base)) {908 ret = PTR_ERR(srot_base);909 goto err_put_device;910 }911 912 priv->srot_map = devm_regmap_init_mmio(dev, srot_base,913 &tsens_srot_config);914 if (IS_ERR(priv->srot_map)) {915 ret = PTR_ERR(priv->srot_map);916 goto err_put_device;917 }918 } else {919 /* old DTs where SROT and TM were in a contiguous 2K block */920 priv->tm_offset = 0x1000;921 }922 923 if (tsens_version(priv) >= VER_0_1) {924 res = platform_get_resource(op, IORESOURCE_MEM, 0);925 tm_base = devm_ioremap_resource(dev, res);926 if (IS_ERR(tm_base)) {927 ret = PTR_ERR(tm_base);928 goto err_put_device;929 }930 931 priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);932 } else { /* VER_0 share the same gcc regs using a syscon */933 struct device *parent = priv->dev->parent;934 935 if (parent)936 priv->tm_map = syscon_node_to_regmap(parent->of_node);937 }938 939 if (IS_ERR_OR_NULL(priv->tm_map)) {940 if (!priv->tm_map)941 ret = -ENODEV;942 else943 ret = PTR_ERR(priv->tm_map);944 goto err_put_device;945 }946 947 /* VER_0 have only tm_map */948 if (!priv->srot_map)949 priv->srot_map = priv->tm_map;950 951 if (tsens_version(priv) > VER_0_1) {952 for (i = VER_MAJOR; i <= VER_STEP; i++) {953 priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,954 priv->fields[i]);955 if (IS_ERR(priv->rf[i])) {956 ret = PTR_ERR(priv->rf[i]);957 goto err_put_device;958 }959 }960 ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor);961 if (ret)962 goto err_put_device;963 }964 965 priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,966 priv->fields[TSENS_EN]);967 if (IS_ERR(priv->rf[TSENS_EN])) {968 ret = PTR_ERR(priv->rf[TSENS_EN]);969 goto err_put_device;970 }971 /* in VER_0 TSENS need to be explicitly enabled */972 if (tsens_version(priv) == VER_0)973 regmap_field_write(priv->rf[TSENS_EN], 1);974 975 ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);976 if (ret)977 goto err_put_device;978 if (!enabled) {979 dev_err(dev, "%s: device not enabled\n", __func__);980 ret = -ENODEV;981 goto err_put_device;982 }983 984 priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,985 priv->fields[SENSOR_EN]);986 if (IS_ERR(priv->rf[SENSOR_EN])) {987 ret = PTR_ERR(priv->rf[SENSOR_EN]);988 goto err_put_device;989 }990 priv->rf[INT_EN] = devm_regmap_field_alloc(dev, priv->tm_map,991 priv->fields[INT_EN]);992 if (IS_ERR(priv->rf[INT_EN])) {993 ret = PTR_ERR(priv->rf[INT_EN]);994 goto err_put_device;995 }996 997 priv->rf[TSENS_SW_RST] =998 devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[TSENS_SW_RST]);999 if (IS_ERR(priv->rf[TSENS_SW_RST])) {1000 ret = PTR_ERR(priv->rf[TSENS_SW_RST]);1001 goto err_put_device;1002 }1003 1004 priv->rf[TRDY] = devm_regmap_field_alloc(dev, priv->tm_map, priv->fields[TRDY]);1005 if (IS_ERR(priv->rf[TRDY])) {1006 ret = PTR_ERR(priv->rf[TRDY]);1007 goto err_put_device;1008 }1009 1010 /* This loop might need changes if enum regfield_ids is reordered */1011 for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {1012 for (i = 0; i < priv->feat->max_sensors; i++) {1013 int idx = j + i;1014 1015 priv->rf[idx] = devm_regmap_field_alloc(dev,1016 priv->tm_map,1017 priv->fields[idx]);1018 if (IS_ERR(priv->rf[idx])) {1019 ret = PTR_ERR(priv->rf[idx]);1020 goto err_put_device;1021 }1022 }1023 }1024 1025 if (priv->feat->crit_int || tsens_version(priv) < VER_0_1) {1026 /* Loop might need changes if enum regfield_ids is reordered */1027 for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) {1028 for (i = 0; i < priv->feat->max_sensors; i++) {1029 int idx = j + i;1030 1031 priv->rf[idx] =1032 devm_regmap_field_alloc(dev,1033 priv->tm_map,1034 priv->fields[idx]);1035 if (IS_ERR(priv->rf[idx])) {1036 ret = PTR_ERR(priv->rf[idx]);1037 goto err_put_device;1038 }1039 }1040 }1041 }1042 1043 if (tsens_version(priv) > VER_1_X && ver_minor > 2) {1044 /* Watchdog is present only on v2.3+ */1045 priv->feat->has_watchdog = 1;1046 for (i = WDOG_BARK_STATUS; i <= CC_MON_MASK; i++) {1047 priv->rf[i] = devm_regmap_field_alloc(dev, priv->tm_map,1048 priv->fields[i]);1049 if (IS_ERR(priv->rf[i])) {1050 ret = PTR_ERR(priv->rf[i]);1051 goto err_put_device;1052 }1053 }1054 /*1055 * Watchdog is already enabled, unmask the bark.1056 * Disable cycle completion monitoring1057 */1058 regmap_field_write(priv->rf[WDOG_BARK_MASK], 0);1059 regmap_field_write(priv->rf[CC_MON_MASK], 1);1060 }1061 1062 spin_lock_init(&priv->ul_lock);1063 1064 /* VER_0 interrupt doesn't need to be enabled */1065 if (tsens_version(priv) >= VER_0_1)1066 tsens_enable_irq(priv);1067 1068err_put_device:1069 put_device(&op->dev);1070 return ret;1071}1072 1073static int tsens_get_temp(struct thermal_zone_device *tz, int *temp)1074{1075 struct tsens_sensor *s = thermal_zone_device_priv(tz);1076 struct tsens_priv *priv = s->priv;1077 1078 return priv->ops->get_temp(s, temp);1079}1080 1081static int __maybe_unused tsens_suspend(struct device *dev)1082{1083 struct tsens_priv *priv = dev_get_drvdata(dev);1084 1085 if (priv->ops && priv->ops->suspend)1086 return priv->ops->suspend(priv);1087 1088 return 0;1089}1090 1091static int __maybe_unused tsens_resume(struct device *dev)1092{1093 struct tsens_priv *priv = dev_get_drvdata(dev);1094 1095 if (priv->ops && priv->ops->resume)1096 return priv->ops->resume(priv);1097 1098 return 0;1099}1100 1101static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);1102 1103static const struct of_device_id tsens_table[] = {1104 {1105 .compatible = "qcom,ipq8064-tsens",1106 .data = &data_8960,1107 }, {1108 .compatible = "qcom,ipq8074-tsens",1109 .data = &data_ipq8074,1110 }, {1111 .compatible = "qcom,mdm9607-tsens",1112 .data = &data_9607,1113 }, {1114 .compatible = "qcom,msm8226-tsens",1115 .data = &data_8226,1116 }, {1117 .compatible = "qcom,msm8909-tsens",1118 .data = &data_8909,1119 }, {1120 .compatible = "qcom,msm8916-tsens",1121 .data = &data_8916,1122 }, {1123 .compatible = "qcom,msm8939-tsens",1124 .data = &data_8939,1125 }, {1126 .compatible = "qcom,msm8956-tsens",1127 .data = &data_8956,1128 }, {1129 .compatible = "qcom,msm8960-tsens",1130 .data = &data_8960,1131 }, {1132 .compatible = "qcom,msm8974-tsens",1133 .data = &data_8974,1134 }, {1135 .compatible = "qcom,msm8976-tsens",1136 .data = &data_8976,1137 }, {1138 .compatible = "qcom,msm8996-tsens",1139 .data = &data_8996,1140 }, {1141 .compatible = "qcom,tsens-v1",1142 .data = &data_tsens_v1,1143 }, {1144 .compatible = "qcom,tsens-v2",1145 .data = &data_tsens_v2,1146 },1147 {}1148};1149MODULE_DEVICE_TABLE(of, tsens_table);1150 1151static const struct thermal_zone_device_ops tsens_of_ops = {1152 .get_temp = tsens_get_temp,1153 .set_trips = tsens_set_trips,1154};1155 1156static int tsens_register_irq(struct tsens_priv *priv, char *irqname,1157 irq_handler_t thread_fn)1158{1159 struct platform_device *pdev;1160 int ret, irq;1161 1162 pdev = of_find_device_by_node(priv->dev->of_node);1163 if (!pdev)1164 return -ENODEV;1165 1166 irq = platform_get_irq_byname(pdev, irqname);1167 if (irq < 0) {1168 ret = irq;1169 /* For old DTs with no IRQ defined */1170 if (irq == -ENXIO)1171 ret = 0;1172 } else {1173 /* VER_0 interrupt is TRIGGER_RISING, VER_0_1 and up is ONESHOT */1174 if (tsens_version(priv) == VER_0)1175 ret = devm_request_threaded_irq(&pdev->dev, irq,1176 thread_fn, NULL,1177 IRQF_TRIGGER_RISING,1178 dev_name(&pdev->dev),1179 priv);1180 else1181 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,1182 thread_fn, IRQF_ONESHOT,1183 dev_name(&pdev->dev),1184 priv);1185 1186 if (ret)1187 dev_err(&pdev->dev, "%s: failed to get irq\n",1188 __func__);1189 else1190 enable_irq_wake(irq);1191 }1192 1193 put_device(&pdev->dev);1194 return ret;1195}1196 1197#ifdef CONFIG_SUSPEND1198static int tsens_reinit(struct tsens_priv *priv)1199{1200 if (tsens_version(priv) >= VER_2_X) {1201 /*1202 * Re-enable the watchdog, unmask the bark.1203 * Disable cycle completion monitoring1204 */1205 if (priv->feat->has_watchdog) {1206 regmap_field_write(priv->rf[WDOG_BARK_MASK], 0);1207 regmap_field_write(priv->rf[CC_MON_MASK], 1);1208 }1209 1210 /* Re-enable interrupts */1211 tsens_enable_irq(priv);1212 }1213 1214 return 0;1215}1216 1217int tsens_resume_common(struct tsens_priv *priv)1218{1219 if (pm_suspend_target_state == PM_SUSPEND_MEM)1220 tsens_reinit(priv);1221 1222 return 0;1223}1224 1225#endif /* !CONFIG_SUSPEND */1226 1227static int tsens_register(struct tsens_priv *priv)1228{1229 int i, ret;1230 struct thermal_zone_device *tzd;1231 1232 for (i = 0; i < priv->num_sensors; i++) {1233 priv->sensor[i].priv = priv;1234 tzd = devm_thermal_of_zone_register(priv->dev, priv->sensor[i].hw_id,1235 &priv->sensor[i],1236 &tsens_of_ops);1237 if (IS_ERR(tzd))1238 continue;1239 priv->sensor[i].tzd = tzd;1240 if (priv->ops->enable)1241 priv->ops->enable(priv, i);1242 1243 devm_thermal_add_hwmon_sysfs(priv->dev, tzd);1244 }1245 1246 /* VER_0 require to set MIN and MAX THRESH1247 * These 2 regs are set using the:1248 * - CRIT_THRESH_0 for MAX THRESH hardcoded to 120°C1249 * - CRIT_THRESH_1 for MIN THRESH hardcoded to 0°C1250 */1251 if (tsens_version(priv) < VER_0_1) {1252 regmap_field_write(priv->rf[CRIT_THRESH_0],1253 tsens_mC_to_hw(priv->sensor, 120000));1254 1255 regmap_field_write(priv->rf[CRIT_THRESH_1],1256 tsens_mC_to_hw(priv->sensor, 0));1257 }1258 1259 if (priv->feat->combo_int) {1260 ret = tsens_register_irq(priv, "combined",1261 tsens_combined_irq_thread);1262 } else {1263 ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);1264 if (ret < 0)1265 return ret;1266 1267 if (priv->feat->crit_int)1268 ret = tsens_register_irq(priv, "critical",1269 tsens_critical_irq_thread);1270 }1271 1272 return ret;1273}1274 1275static int tsens_probe(struct platform_device *pdev)1276{1277 int ret, i;1278 struct device *dev;1279 struct device_node *np;1280 struct tsens_priv *priv;1281 const struct tsens_plat_data *data;1282 const struct of_device_id *id;1283 u32 num_sensors;1284 1285 if (pdev->dev.of_node)1286 dev = &pdev->dev;1287 else1288 dev = pdev->dev.parent;1289 1290 np = dev->of_node;1291 1292 id = of_match_node(tsens_table, np);1293 if (id)1294 data = id->data;1295 else1296 data = &data_8960;1297 1298 num_sensors = data->num_sensors;1299 1300 if (np)1301 of_property_read_u32(np, "#qcom,sensors", &num_sensors);1302 1303 if (num_sensors <= 0) {1304 dev_err(dev, "%s: invalid number of sensors\n", __func__);1305 return -EINVAL;1306 }1307 1308 priv = devm_kzalloc(dev,1309 struct_size(priv, sensor, num_sensors),1310 GFP_KERNEL);1311 if (!priv)1312 return -ENOMEM;1313 1314 priv->dev = dev;1315 priv->num_sensors = num_sensors;1316 priv->ops = data->ops;1317 for (i = 0; i < priv->num_sensors; i++) {1318 if (data->hw_ids)1319 priv->sensor[i].hw_id = data->hw_ids[i];1320 else1321 priv->sensor[i].hw_id = i;1322 }1323 priv->feat = data->feat;1324 priv->fields = data->fields;1325 1326 platform_set_drvdata(pdev, priv);1327 1328 if (!priv->ops || !priv->ops->init || !priv->ops->get_temp)1329 return -EINVAL;1330 1331 ret = priv->ops->init(priv);1332 if (ret < 0) {1333 dev_err(dev, "%s: init failed\n", __func__);1334 return ret;1335 }1336 1337 if (priv->ops->calibrate) {1338 ret = priv->ops->calibrate(priv);1339 if (ret < 0)1340 return dev_err_probe(dev, ret, "%s: calibration failed\n",1341 __func__);1342 }1343 1344 ret = tsens_register(priv);1345 if (!ret)1346 tsens_debug_init(pdev);1347 1348 return ret;1349}1350 1351static void tsens_remove(struct platform_device *pdev)1352{1353 struct tsens_priv *priv = platform_get_drvdata(pdev);1354 1355 debugfs_remove_recursive(priv->debug_root);1356 tsens_disable_irq(priv);1357 if (priv->ops->disable)1358 priv->ops->disable(priv);1359}1360 1361static struct platform_driver tsens_driver = {1362 .probe = tsens_probe,1363 .remove_new = tsens_remove,1364 .driver = {1365 .name = "qcom-tsens",1366 .pm = &tsens_pm_ops,1367 .of_match_table = tsens_table,1368 },1369};1370module_platform_driver(tsens_driver);1371 1372MODULE_LICENSE("GPL v2");1373MODULE_DESCRIPTION("QCOM Temperature Sensor driver");1374MODULE_ALIAS("platform:qcom-tsens");1375