Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
0004  * Copyright (c) 2019, 2020, Linaro Ltd.
0005  */
0006 
0007 #include <linux/debugfs.h>
0008 #include <linux/err.h>
0009 #include <linux/io.h>
0010 #include <linux/module.h>
0011 #include <linux/nvmem-consumer.h>
0012 #include <linux/of.h>
0013 #include <linux/of_address.h>
0014 #include <linux/of_platform.h>
0015 #include <linux/mfd/syscon.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/pm.h>
0018 #include <linux/regmap.h>
0019 #include <linux/slab.h>
0020 #include <linux/thermal.h>
0021 #include "../thermal_hwmon.h"
0022 #include "tsens.h"
0023 
0024 /**
0025  * struct tsens_irq_data - IRQ status and temperature violations
0026  * @up_viol:        upper threshold violated
0027  * @up_thresh:      upper threshold temperature value
0028  * @up_irq_mask:    mask register for upper threshold irqs
0029  * @up_irq_clear:   clear register for uppper threshold irqs
0030  * @low_viol:       lower threshold violated
0031  * @low_thresh:     lower threshold temperature value
0032  * @low_irq_mask:   mask register for lower threshold irqs
0033  * @low_irq_clear:  clear register for lower threshold irqs
0034  * @crit_viol:      critical threshold violated
0035  * @crit_thresh:    critical threshold temperature value
0036  * @crit_irq_mask:  mask register for critical threshold irqs
0037  * @crit_irq_clear: clear register for critical threshold irqs
0038  *
0039  * Structure containing data about temperature threshold settings and
0040  * irq status if they were violated.
0041  */
0042 struct tsens_irq_data {
0043     u32 up_viol;
0044     int up_thresh;
0045     u32 up_irq_mask;
0046     u32 up_irq_clear;
0047     u32 low_viol;
0048     int low_thresh;
0049     u32 low_irq_mask;
0050     u32 low_irq_clear;
0051     u32 crit_viol;
0052     u32 crit_thresh;
0053     u32 crit_irq_mask;
0054     u32 crit_irq_clear;
0055 };
0056 
0057 char *qfprom_read(struct device *dev, const char *cname)
0058 {
0059     struct nvmem_cell *cell;
0060     ssize_t data;
0061     char *ret;
0062 
0063     cell = nvmem_cell_get(dev, cname);
0064     if (IS_ERR(cell))
0065         return ERR_CAST(cell);
0066 
0067     ret = nvmem_cell_read(cell, &data);
0068     nvmem_cell_put(cell);
0069 
0070     return ret;
0071 }
0072 
0073 /*
0074  * Use this function on devices where slope and offset calculations
0075  * depend on calibration data read from qfprom. On others the slope
0076  * and offset values are derived from tz->tzp->slope and tz->tzp->offset
0077  * resp.
0078  */
0079 void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
0080                  u32 *p2, u32 mode)
0081 {
0082     int i;
0083     int num, den;
0084 
0085     for (i = 0; i < priv->num_sensors; i++) {
0086         dev_dbg(priv->dev,
0087             "%s: sensor%d - data_point1:%#x data_point2:%#x\n",
0088             __func__, i, p1[i], p2[i]);
0089 
0090         if (!priv->sensor[i].slope)
0091             priv->sensor[i].slope = SLOPE_DEFAULT;
0092         if (mode == TWO_PT_CALIB) {
0093             /*
0094              * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
0095              *  temp_120_degc - temp_30_degc (x2 - x1)
0096              */
0097             num = p2[i] - p1[i];
0098             num *= SLOPE_FACTOR;
0099             den = CAL_DEGC_PT2 - CAL_DEGC_PT1;
0100             priv->sensor[i].slope = num / den;
0101         }
0102 
0103         priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
0104                 (CAL_DEGC_PT1 *
0105                 priv->sensor[i].slope);
0106         dev_dbg(priv->dev, "%s: offset:%d\n", __func__,
0107             priv->sensor[i].offset);
0108     }
0109 }
0110 
0111 static inline u32 degc_to_code(int degc, const struct tsens_sensor *s)
0112 {
0113     u64 code = div_u64(((u64)degc * s->slope + s->offset), SLOPE_FACTOR);
0114 
0115     pr_debug("%s: raw_code: 0x%llx, degc:%d\n", __func__, code, degc);
0116     return clamp_val(code, THRESHOLD_MIN_ADC_CODE, THRESHOLD_MAX_ADC_CODE);
0117 }
0118 
0119 static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
0120 {
0121     int degc, num, den;
0122 
0123     num = (adc_code * SLOPE_FACTOR) - s->offset;
0124     den = s->slope;
0125 
0126     if (num > 0)
0127         degc = num + (den / 2);
0128     else if (num < 0)
0129         degc = num - (den / 2);
0130     else
0131         degc = num;
0132 
0133     degc /= den;
0134 
0135     return degc;
0136 }
0137 
0138 /**
0139  * tsens_hw_to_mC - Return sign-extended temperature in mCelsius.
0140  * @s:     Pointer to sensor struct
0141  * @field: Index into regmap_field array pointing to temperature data
0142  *
0143  * This function handles temperature returned in ADC code or deciCelsius
0144  * depending on IP version.
0145  *
0146  * Return: Temperature in milliCelsius on success, a negative errno will
0147  * be returned in error cases
0148  */
0149 static int tsens_hw_to_mC(const struct tsens_sensor *s, int field)
0150 {
0151     struct tsens_priv *priv = s->priv;
0152     u32 resolution;
0153     u32 temp = 0;
0154     int ret;
0155 
0156     resolution = priv->fields[LAST_TEMP_0].msb -
0157         priv->fields[LAST_TEMP_0].lsb;
0158 
0159     ret = regmap_field_read(priv->rf[field], &temp);
0160     if (ret)
0161         return ret;
0162 
0163     /* Convert temperature from ADC code to milliCelsius */
0164     if (priv->feat->adc)
0165         return code_to_degc(temp, s) * 1000;
0166 
0167     /* deciCelsius -> milliCelsius along with sign extension */
0168     return sign_extend32(temp, resolution) * 100;
0169 }
0170 
0171 /**
0172  * tsens_mC_to_hw - Convert temperature to hardware register value
0173  * @s: Pointer to sensor struct
0174  * @temp: temperature in milliCelsius to be programmed to hardware
0175  *
0176  * This function outputs the value to be written to hardware in ADC code
0177  * or deciCelsius depending on IP version.
0178  *
0179  * Return: ADC code or temperature in deciCelsius.
0180  */
0181 static int tsens_mC_to_hw(const struct tsens_sensor *s, int temp)
0182 {
0183     struct tsens_priv *priv = s->priv;
0184 
0185     /* milliC to adc code */
0186     if (priv->feat->adc)
0187         return degc_to_code(temp / 1000, s);
0188 
0189     /* milliC to deciC */
0190     return temp / 100;
0191 }
0192 
0193 static inline enum tsens_ver tsens_version(struct tsens_priv *priv)
0194 {
0195     return priv->feat->ver_major;
0196 }
0197 
0198 static void tsens_set_interrupt_v1(struct tsens_priv *priv, u32 hw_id,
0199                    enum tsens_irq_type irq_type, bool enable)
0200 {
0201     u32 index = 0;
0202 
0203     switch (irq_type) {
0204     case UPPER:
0205         index = UP_INT_CLEAR_0 + hw_id;
0206         break;
0207     case LOWER:
0208         index = LOW_INT_CLEAR_0 + hw_id;
0209         break;
0210     case CRITICAL:
0211         /* No critical interrupts before v2 */
0212         return;
0213     }
0214     regmap_field_write(priv->rf[index], enable ? 0 : 1);
0215 }
0216 
0217 static void tsens_set_interrupt_v2(struct tsens_priv *priv, u32 hw_id,
0218                    enum tsens_irq_type irq_type, bool enable)
0219 {
0220     u32 index_mask = 0, index_clear = 0;
0221 
0222     /*
0223      * To enable the interrupt flag for a sensor:
0224      *    - clear the mask bit
0225      * To disable the interrupt flag for a sensor:
0226      *    - Mask further interrupts for this sensor
0227      *    - Write 1 followed by 0 to clear the interrupt
0228      */
0229     switch (irq_type) {
0230     case UPPER:
0231         index_mask  = UP_INT_MASK_0 + hw_id;
0232         index_clear = UP_INT_CLEAR_0 + hw_id;
0233         break;
0234     case LOWER:
0235         index_mask  = LOW_INT_MASK_0 + hw_id;
0236         index_clear = LOW_INT_CLEAR_0 + hw_id;
0237         break;
0238     case CRITICAL:
0239         index_mask  = CRIT_INT_MASK_0 + hw_id;
0240         index_clear = CRIT_INT_CLEAR_0 + hw_id;
0241         break;
0242     }
0243 
0244     if (enable) {
0245         regmap_field_write(priv->rf[index_mask], 0);
0246     } else {
0247         regmap_field_write(priv->rf[index_mask],  1);
0248         regmap_field_write(priv->rf[index_clear], 1);
0249         regmap_field_write(priv->rf[index_clear], 0);
0250     }
0251 }
0252 
0253 /**
0254  * tsens_set_interrupt - Set state of an interrupt
0255  * @priv: Pointer to tsens controller private data
0256  * @hw_id: Hardware ID aka. sensor number
0257  * @irq_type: irq_type from enum tsens_irq_type
0258  * @enable: false = disable, true = enable
0259  *
0260  * Call IP-specific function to set state of an interrupt
0261  *
0262  * Return: void
0263  */
0264 static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,
0265                 enum tsens_irq_type irq_type, bool enable)
0266 {
0267     dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,
0268         irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",
0269         enable ? "en" : "dis");
0270     if (tsens_version(priv) > VER_1_X)
0271         tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);
0272     else
0273         tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);
0274 }
0275 
0276 /**
0277  * tsens_threshold_violated - Check if a sensor temperature violated a preset threshold
0278  * @priv: Pointer to tsens controller private data
0279  * @hw_id: Hardware ID aka. sensor number
0280  * @d: Pointer to irq state data
0281  *
0282  * Return: 0 if threshold was not violated, 1 if it was violated and negative
0283  * errno in case of errors
0284  */
0285 static int tsens_threshold_violated(struct tsens_priv *priv, u32 hw_id,
0286                     struct tsens_irq_data *d)
0287 {
0288     int ret;
0289 
0290     ret = regmap_field_read(priv->rf[UPPER_STATUS_0 + hw_id], &d->up_viol);
0291     if (ret)
0292         return ret;
0293     ret = regmap_field_read(priv->rf[LOWER_STATUS_0 + hw_id], &d->low_viol);
0294     if (ret)
0295         return ret;
0296 
0297     if (priv->feat->crit_int) {
0298         ret = regmap_field_read(priv->rf[CRITICAL_STATUS_0 + hw_id],
0299                     &d->crit_viol);
0300         if (ret)
0301             return ret;
0302     }
0303 
0304     if (d->up_viol || d->low_viol || d->crit_viol)
0305         return 1;
0306 
0307     return 0;
0308 }
0309 
0310 static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
0311                 const struct tsens_sensor *s,
0312                 struct tsens_irq_data *d)
0313 {
0314     int ret;
0315 
0316     ret = regmap_field_read(priv->rf[UP_INT_CLEAR_0 + hw_id], &d->up_irq_clear);
0317     if (ret)
0318         return ret;
0319     ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear);
0320     if (ret)
0321         return ret;
0322     if (tsens_version(priv) > VER_1_X) {
0323         ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask);
0324         if (ret)
0325             return ret;
0326         ret = regmap_field_read(priv->rf[LOW_INT_MASK_0 + hw_id], &d->low_irq_mask);
0327         if (ret)
0328             return ret;
0329         ret = regmap_field_read(priv->rf[CRIT_INT_CLEAR_0 + hw_id],
0330                     &d->crit_irq_clear);
0331         if (ret)
0332             return ret;
0333         ret = regmap_field_read(priv->rf[CRIT_INT_MASK_0 + hw_id],
0334                     &d->crit_irq_mask);
0335         if (ret)
0336             return ret;
0337 
0338         d->crit_thresh = tsens_hw_to_mC(s, CRIT_THRESH_0 + hw_id);
0339     } else {
0340         /* No mask register on older TSENS */
0341         d->up_irq_mask = 0;
0342         d->low_irq_mask = 0;
0343         d->crit_irq_clear = 0;
0344         d->crit_irq_mask = 0;
0345         d->crit_thresh = 0;
0346     }
0347 
0348     d->up_thresh  = tsens_hw_to_mC(s, UP_THRESH_0 + hw_id);
0349     d->low_thresh = tsens_hw_to_mC(s, LOW_THRESH_0 + hw_id);
0350 
0351     dev_dbg(priv->dev, "[%u] %s%s: status(%u|%u|%u) | clr(%u|%u|%u) | mask(%u|%u|%u)\n",
0352         hw_id, __func__,
0353         (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",
0354         d->low_viol, d->up_viol, d->crit_viol,
0355         d->low_irq_clear, d->up_irq_clear, d->crit_irq_clear,
0356         d->low_irq_mask, d->up_irq_mask, d->crit_irq_mask);
0357     dev_dbg(priv->dev, "[%u] %s%s: thresh: (%d:%d:%d)\n", hw_id, __func__,
0358         (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",
0359         d->low_thresh, d->up_thresh, d->crit_thresh);
0360 
0361     return 0;
0362 }
0363 
0364 static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver)
0365 {
0366     if (ver > VER_1_X)
0367         return mask & (1 << hw_id);
0368 
0369     /* v1, v0.1 don't have a irq mask register */
0370     return 0;
0371 }
0372 
0373 /**
0374  * tsens_critical_irq_thread() - Threaded handler for critical interrupts
0375  * @irq: irq number
0376  * @data: tsens controller private data
0377  *
0378  * Check FSM watchdog bark status and clear if needed.
0379  * Check all sensors to find ones that violated their critical threshold limits.
0380  * Clear and then re-enable the interrupt.
0381  *
0382  * The level-triggered interrupt might deassert if the temperature returned to
0383  * within the threshold limits by the time the handler got scheduled. We
0384  * consider the irq to have been handled in that case.
0385  *
0386  * Return: IRQ_HANDLED
0387  */
0388 static irqreturn_t tsens_critical_irq_thread(int irq, void *data)
0389 {
0390     struct tsens_priv *priv = data;
0391     struct tsens_irq_data d;
0392     int temp, ret, i;
0393     u32 wdog_status, wdog_count;
0394 
0395     if (priv->feat->has_watchdog) {
0396         ret = regmap_field_read(priv->rf[WDOG_BARK_STATUS],
0397                     &wdog_status);
0398         if (ret)
0399             return ret;
0400 
0401         if (wdog_status) {
0402             /* Clear WDOG interrupt */
0403             regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 1);
0404             regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 0);
0405             ret = regmap_field_read(priv->rf[WDOG_BARK_COUNT],
0406                         &wdog_count);
0407             if (ret)
0408                 return ret;
0409             if (wdog_count)
0410                 dev_dbg(priv->dev, "%s: watchdog count: %d\n",
0411                     __func__, wdog_count);
0412 
0413             /* Fall through to handle critical interrupts if any */
0414         }
0415     }
0416 
0417     for (i = 0; i < priv->num_sensors; i++) {
0418         const struct tsens_sensor *s = &priv->sensor[i];
0419         u32 hw_id = s->hw_id;
0420 
0421         if (!s->tzd)
0422             continue;
0423         if (!tsens_threshold_violated(priv, hw_id, &d))
0424             continue;
0425         ret = get_temp_tsens_valid(s, &temp);
0426         if (ret) {
0427             dev_err(priv->dev, "[%u] %s: error reading sensor\n",
0428                 hw_id, __func__);
0429             continue;
0430         }
0431 
0432         tsens_read_irq_state(priv, hw_id, s, &d);
0433         if (d.crit_viol &&
0434             !masked_irq(hw_id, d.crit_irq_mask, tsens_version(priv))) {
0435             /* Mask critical interrupts, unused on Linux */
0436             tsens_set_interrupt(priv, hw_id, CRITICAL, false);
0437         }
0438     }
0439 
0440     return IRQ_HANDLED;
0441 }
0442 
0443 /**
0444  * tsens_irq_thread - Threaded interrupt handler for uplow interrupts
0445  * @irq: irq number
0446  * @data: tsens controller private data
0447  *
0448  * Check all sensors to find ones that violated their threshold limits. If the
0449  * temperature is still outside the limits, call thermal_zone_device_update() to
0450  * update the thresholds, else re-enable the interrupts.
0451  *
0452  * The level-triggered interrupt might deassert if the temperature returned to
0453  * within the threshold limits by the time the handler got scheduled. We
0454  * consider the irq to have been handled in that case.
0455  *
0456  * Return: IRQ_HANDLED
0457  */
0458 static irqreturn_t tsens_irq_thread(int irq, void *data)
0459 {
0460     struct tsens_priv *priv = data;
0461     struct tsens_irq_data d;
0462     bool enable = true, disable = false;
0463     unsigned long flags;
0464     int temp, ret, i;
0465 
0466     for (i = 0; i < priv->num_sensors; i++) {
0467         bool trigger = false;
0468         const struct tsens_sensor *s = &priv->sensor[i];
0469         u32 hw_id = s->hw_id;
0470 
0471         if (!s->tzd)
0472             continue;
0473         if (!tsens_threshold_violated(priv, hw_id, &d))
0474             continue;
0475         ret = get_temp_tsens_valid(s, &temp);
0476         if (ret) {
0477             dev_err(priv->dev, "[%u] %s: error reading sensor\n",
0478                 hw_id, __func__);
0479             continue;
0480         }
0481 
0482         spin_lock_irqsave(&priv->ul_lock, flags);
0483 
0484         tsens_read_irq_state(priv, hw_id, s, &d);
0485 
0486         if (d.up_viol &&
0487             !masked_irq(hw_id, d.up_irq_mask, tsens_version(priv))) {
0488             tsens_set_interrupt(priv, hw_id, UPPER, disable);
0489             if (d.up_thresh > temp) {
0490                 dev_dbg(priv->dev, "[%u] %s: re-arm upper\n",
0491                     hw_id, __func__);
0492                 tsens_set_interrupt(priv, hw_id, UPPER, enable);
0493             } else {
0494                 trigger = true;
0495                 /* Keep irq masked */
0496             }
0497         } else if (d.low_viol &&
0498                !masked_irq(hw_id, d.low_irq_mask, tsens_version(priv))) {
0499             tsens_set_interrupt(priv, hw_id, LOWER, disable);
0500             if (d.low_thresh < temp) {
0501                 dev_dbg(priv->dev, "[%u] %s: re-arm low\n",
0502                     hw_id, __func__);
0503                 tsens_set_interrupt(priv, hw_id, LOWER, enable);
0504             } else {
0505                 trigger = true;
0506                 /* Keep irq masked */
0507             }
0508         }
0509 
0510         spin_unlock_irqrestore(&priv->ul_lock, flags);
0511 
0512         if (trigger) {
0513             dev_dbg(priv->dev, "[%u] %s: TZ update trigger (%d mC)\n",
0514                 hw_id, __func__, temp);
0515             thermal_zone_device_update(s->tzd,
0516                            THERMAL_EVENT_UNSPECIFIED);
0517         } else {
0518             dev_dbg(priv->dev, "[%u] %s: no violation:  %d\n",
0519                 hw_id, __func__, temp);
0520         }
0521 
0522         if (tsens_version(priv) < VER_0_1) {
0523             /* Constraint: There is only 1 interrupt control register for all
0524              * 11 temperature sensor. So monitoring more than 1 sensor based
0525              * on interrupts will yield inconsistent result. To overcome this
0526              * issue we will monitor only sensor 0 which is the master sensor.
0527              */
0528             break;
0529         }
0530     }
0531 
0532     return IRQ_HANDLED;
0533 }
0534 
0535 static int tsens_set_trips(void *_sensor, int low, int high)
0536 {
0537     struct tsens_sensor *s = _sensor;
0538     struct tsens_priv *priv = s->priv;
0539     struct device *dev = priv->dev;
0540     struct tsens_irq_data d;
0541     unsigned long flags;
0542     int high_val, low_val, cl_high, cl_low;
0543     u32 hw_id = s->hw_id;
0544 
0545     if (tsens_version(priv) < VER_0_1) {
0546         /* Pre v0.1 IP had a single register for each type of interrupt
0547          * and thresholds
0548          */
0549         hw_id = 0;
0550     }
0551 
0552     dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
0553         hw_id, __func__, low, high);
0554 
0555     cl_high = clamp_val(high, -40000, 120000);
0556     cl_low  = clamp_val(low, -40000, 120000);
0557 
0558     high_val = tsens_mC_to_hw(s, cl_high);
0559     low_val  = tsens_mC_to_hw(s, cl_low);
0560 
0561     spin_lock_irqsave(&priv->ul_lock, flags);
0562 
0563     tsens_read_irq_state(priv, hw_id, s, &d);
0564 
0565     /* Write the new thresholds and clear the status */
0566     regmap_field_write(priv->rf[LOW_THRESH_0 + hw_id], low_val);
0567     regmap_field_write(priv->rf[UP_THRESH_0 + hw_id], high_val);
0568     tsens_set_interrupt(priv, hw_id, LOWER, true);
0569     tsens_set_interrupt(priv, hw_id, UPPER, true);
0570 
0571     spin_unlock_irqrestore(&priv->ul_lock, flags);
0572 
0573     dev_dbg(dev, "[%u] %s: (%d:%d)->(%d:%d)\n",
0574         hw_id, __func__, d.low_thresh, d.up_thresh, cl_low, cl_high);
0575 
0576     return 0;
0577 }
0578 
0579 static int tsens_enable_irq(struct tsens_priv *priv)
0580 {
0581     int ret;
0582     int val = tsens_version(priv) > VER_1_X ? 7 : 1;
0583 
0584     ret = regmap_field_write(priv->rf[INT_EN], val);
0585     if (ret < 0)
0586         dev_err(priv->dev, "%s: failed to enable interrupts\n",
0587             __func__);
0588 
0589     return ret;
0590 }
0591 
0592 static void tsens_disable_irq(struct tsens_priv *priv)
0593 {
0594     regmap_field_write(priv->rf[INT_EN], 0);
0595 }
0596 
0597 int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)
0598 {
0599     struct tsens_priv *priv = s->priv;
0600     int hw_id = s->hw_id;
0601     u32 temp_idx = LAST_TEMP_0 + hw_id;
0602     u32 valid_idx = VALID_0 + hw_id;
0603     u32 valid;
0604     int ret;
0605 
0606     /* VER_0 doesn't have VALID bit */
0607     if (tsens_version(priv) == VER_0)
0608         goto get_temp;
0609 
0610     /* Valid bit is 0 for 6 AHB clock cycles.
0611      * At 19.2MHz, 1 AHB clock is ~60ns.
0612      * We should enter this loop very, very rarely.
0613      * Wait 1 us since it's the min of poll_timeout macro.
0614      * Old value was 400 ns.
0615      */
0616     ret = regmap_field_read_poll_timeout(priv->rf[valid_idx], valid,
0617                          valid, 1, 20 * USEC_PER_MSEC);
0618     if (ret)
0619         return ret;
0620 
0621 get_temp:
0622     /* Valid bit is set, OK to read the temperature */
0623     *temp = tsens_hw_to_mC(s, temp_idx);
0624 
0625     return 0;
0626 }
0627 
0628 int get_temp_common(const struct tsens_sensor *s, int *temp)
0629 {
0630     struct tsens_priv *priv = s->priv;
0631     int hw_id = s->hw_id;
0632     int last_temp = 0, ret, trdy;
0633     unsigned long timeout;
0634 
0635     timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
0636     do {
0637         if (tsens_version(priv) == VER_0) {
0638             ret = regmap_field_read(priv->rf[TRDY], &trdy);
0639             if (ret)
0640                 return ret;
0641             if (!trdy)
0642                 continue;
0643         }
0644 
0645         ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);
0646         if (ret)
0647             return ret;
0648 
0649         *temp = code_to_degc(last_temp, s) * 1000;
0650 
0651         return 0;
0652     } while (time_before(jiffies, timeout));
0653 
0654     return -ETIMEDOUT;
0655 }
0656 
0657 #ifdef CONFIG_DEBUG_FS
0658 static int dbg_sensors_show(struct seq_file *s, void *data)
0659 {
0660     struct platform_device *pdev = s->private;
0661     struct tsens_priv *priv = platform_get_drvdata(pdev);
0662     int i;
0663 
0664     seq_printf(s, "max: %2d\nnum: %2d\n\n",
0665            priv->feat->max_sensors, priv->num_sensors);
0666 
0667     seq_puts(s, "      id    slope   offset\n--------------------------\n");
0668     for (i = 0;  i < priv->num_sensors; i++) {
0669         seq_printf(s, "%8d %8d %8d\n", priv->sensor[i].hw_id,
0670                priv->sensor[i].slope, priv->sensor[i].offset);
0671     }
0672 
0673     return 0;
0674 }
0675 
0676 static int dbg_version_show(struct seq_file *s, void *data)
0677 {
0678     struct platform_device *pdev = s->private;
0679     struct tsens_priv *priv = platform_get_drvdata(pdev);
0680     u32 maj_ver, min_ver, step_ver;
0681     int ret;
0682 
0683     if (tsens_version(priv) > VER_0_1) {
0684         ret = regmap_field_read(priv->rf[VER_MAJOR], &maj_ver);
0685         if (ret)
0686             return ret;
0687         ret = regmap_field_read(priv->rf[VER_MINOR], &min_ver);
0688         if (ret)
0689             return ret;
0690         ret = regmap_field_read(priv->rf[VER_STEP], &step_ver);
0691         if (ret)
0692             return ret;
0693         seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);
0694     } else {
0695         seq_puts(s, "0.1.0\n");
0696     }
0697 
0698     return 0;
0699 }
0700 
0701 DEFINE_SHOW_ATTRIBUTE(dbg_version);
0702 DEFINE_SHOW_ATTRIBUTE(dbg_sensors);
0703 
0704 static void tsens_debug_init(struct platform_device *pdev)
0705 {
0706     struct tsens_priv *priv = platform_get_drvdata(pdev);
0707     struct dentry *root, *file;
0708 
0709     root = debugfs_lookup("tsens", NULL);
0710     if (!root)
0711         priv->debug_root = debugfs_create_dir("tsens", NULL);
0712     else
0713         priv->debug_root = root;
0714 
0715     file = debugfs_lookup("version", priv->debug_root);
0716     if (!file)
0717         debugfs_create_file("version", 0444, priv->debug_root,
0718                     pdev, &dbg_version_fops);
0719 
0720     /* A directory for each instance of the TSENS IP */
0721     priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);
0722     debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);
0723 }
0724 #else
0725 static inline void tsens_debug_init(struct platform_device *pdev) {}
0726 #endif
0727 
0728 static const struct regmap_config tsens_config = {
0729     .name       = "tm",
0730     .reg_bits   = 32,
0731     .val_bits   = 32,
0732     .reg_stride = 4,
0733 };
0734 
0735 static const struct regmap_config tsens_srot_config = {
0736     .name       = "srot",
0737     .reg_bits   = 32,
0738     .val_bits   = 32,
0739     .reg_stride = 4,
0740 };
0741 
0742 int __init init_common(struct tsens_priv *priv)
0743 {
0744     void __iomem *tm_base, *srot_base;
0745     struct device *dev = priv->dev;
0746     u32 ver_minor;
0747     struct resource *res;
0748     u32 enabled;
0749     int ret, i, j;
0750     struct platform_device *op = of_find_device_by_node(priv->dev->of_node);
0751 
0752     if (!op)
0753         return -EINVAL;
0754 
0755     if (op->num_resources > 1) {
0756         /* DT with separate SROT and TM address space */
0757         priv->tm_offset = 0;
0758         res = platform_get_resource(op, IORESOURCE_MEM, 1);
0759         srot_base = devm_ioremap_resource(dev, res);
0760         if (IS_ERR(srot_base)) {
0761             ret = PTR_ERR(srot_base);
0762             goto err_put_device;
0763         }
0764 
0765         priv->srot_map = devm_regmap_init_mmio(dev, srot_base,
0766                                &tsens_srot_config);
0767         if (IS_ERR(priv->srot_map)) {
0768             ret = PTR_ERR(priv->srot_map);
0769             goto err_put_device;
0770         }
0771     } else {
0772         /* old DTs where SROT and TM were in a contiguous 2K block */
0773         priv->tm_offset = 0x1000;
0774     }
0775 
0776     if (tsens_version(priv) >= VER_0_1) {
0777         res = platform_get_resource(op, IORESOURCE_MEM, 0);
0778         tm_base = devm_ioremap_resource(dev, res);
0779         if (IS_ERR(tm_base)) {
0780             ret = PTR_ERR(tm_base);
0781             goto err_put_device;
0782         }
0783 
0784         priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);
0785     } else { /* VER_0 share the same gcc regs using a syscon */
0786         struct device *parent = priv->dev->parent;
0787 
0788         if (parent)
0789             priv->tm_map = syscon_node_to_regmap(parent->of_node);
0790     }
0791 
0792     if (IS_ERR_OR_NULL(priv->tm_map)) {
0793         if (!priv->tm_map)
0794             ret = -ENODEV;
0795         else
0796             ret = PTR_ERR(priv->tm_map);
0797         goto err_put_device;
0798     }
0799 
0800     /* VER_0 have only tm_map */
0801     if (!priv->srot_map)
0802         priv->srot_map = priv->tm_map;
0803 
0804     if (tsens_version(priv) > VER_0_1) {
0805         for (i = VER_MAJOR; i <= VER_STEP; i++) {
0806             priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,
0807                                   priv->fields[i]);
0808             if (IS_ERR(priv->rf[i])) {
0809                 ret = PTR_ERR(priv->rf[i]);
0810                 goto err_put_device;
0811             }
0812         }
0813         ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor);
0814         if (ret)
0815             goto err_put_device;
0816     }
0817 
0818     priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
0819                              priv->fields[TSENS_EN]);
0820     if (IS_ERR(priv->rf[TSENS_EN])) {
0821         ret = PTR_ERR(priv->rf[TSENS_EN]);
0822         goto err_put_device;
0823     }
0824     /* in VER_0 TSENS need to be explicitly enabled */
0825     if (tsens_version(priv) == VER_0)
0826         regmap_field_write(priv->rf[TSENS_EN], 1);
0827 
0828     ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
0829     if (ret)
0830         goto err_put_device;
0831     if (!enabled) {
0832         dev_err(dev, "%s: device not enabled\n", __func__);
0833         ret = -ENODEV;
0834         goto err_put_device;
0835     }
0836 
0837     priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
0838                               priv->fields[SENSOR_EN]);
0839     if (IS_ERR(priv->rf[SENSOR_EN])) {
0840         ret = PTR_ERR(priv->rf[SENSOR_EN]);
0841         goto err_put_device;
0842     }
0843     priv->rf[INT_EN] = devm_regmap_field_alloc(dev, priv->tm_map,
0844                            priv->fields[INT_EN]);
0845     if (IS_ERR(priv->rf[INT_EN])) {
0846         ret = PTR_ERR(priv->rf[INT_EN]);
0847         goto err_put_device;
0848     }
0849 
0850     priv->rf[TSENS_SW_RST] =
0851         devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[TSENS_SW_RST]);
0852     if (IS_ERR(priv->rf[TSENS_SW_RST])) {
0853         ret = PTR_ERR(priv->rf[TSENS_SW_RST]);
0854         goto err_put_device;
0855     }
0856 
0857     priv->rf[TRDY] = devm_regmap_field_alloc(dev, priv->tm_map, priv->fields[TRDY]);
0858     if (IS_ERR(priv->rf[TRDY])) {
0859         ret = PTR_ERR(priv->rf[TRDY]);
0860         goto err_put_device;
0861     }
0862 
0863     /* This loop might need changes if enum regfield_ids is reordered */
0864     for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {
0865         for (i = 0; i < priv->feat->max_sensors; i++) {
0866             int idx = j + i;
0867 
0868             priv->rf[idx] = devm_regmap_field_alloc(dev,
0869                                 priv->tm_map,
0870                                 priv->fields[idx]);
0871             if (IS_ERR(priv->rf[idx])) {
0872                 ret = PTR_ERR(priv->rf[idx]);
0873                 goto err_put_device;
0874             }
0875         }
0876     }
0877 
0878     if (priv->feat->crit_int || tsens_version(priv) < VER_0_1) {
0879         /* Loop might need changes if enum regfield_ids is reordered */
0880         for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) {
0881             for (i = 0; i < priv->feat->max_sensors; i++) {
0882                 int idx = j + i;
0883 
0884                 priv->rf[idx] =
0885                     devm_regmap_field_alloc(dev,
0886                                 priv->tm_map,
0887                                 priv->fields[idx]);
0888                 if (IS_ERR(priv->rf[idx])) {
0889                     ret = PTR_ERR(priv->rf[idx]);
0890                     goto err_put_device;
0891                 }
0892             }
0893         }
0894     }
0895 
0896     if (tsens_version(priv) > VER_1_X &&  ver_minor > 2) {
0897         /* Watchdog is present only on v2.3+ */
0898         priv->feat->has_watchdog = 1;
0899         for (i = WDOG_BARK_STATUS; i <= CC_MON_MASK; i++) {
0900             priv->rf[i] = devm_regmap_field_alloc(dev, priv->tm_map,
0901                                   priv->fields[i]);
0902             if (IS_ERR(priv->rf[i])) {
0903                 ret = PTR_ERR(priv->rf[i]);
0904                 goto err_put_device;
0905             }
0906         }
0907         /*
0908          * Watchdog is already enabled, unmask the bark.
0909          * Disable cycle completion monitoring
0910          */
0911         regmap_field_write(priv->rf[WDOG_BARK_MASK], 0);
0912         regmap_field_write(priv->rf[CC_MON_MASK], 1);
0913     }
0914 
0915     spin_lock_init(&priv->ul_lock);
0916 
0917     /* VER_0 interrupt doesn't need to be enabled */
0918     if (tsens_version(priv) >= VER_0_1)
0919         tsens_enable_irq(priv);
0920 
0921     tsens_debug_init(op);
0922 
0923 err_put_device:
0924     put_device(&op->dev);
0925     return ret;
0926 }
0927 
0928 static int tsens_get_temp(void *data, int *temp)
0929 {
0930     struct tsens_sensor *s = data;
0931     struct tsens_priv *priv = s->priv;
0932 
0933     return priv->ops->get_temp(s, temp);
0934 }
0935 
0936 static int  __maybe_unused tsens_suspend(struct device *dev)
0937 {
0938     struct tsens_priv *priv = dev_get_drvdata(dev);
0939 
0940     if (priv->ops && priv->ops->suspend)
0941         return priv->ops->suspend(priv);
0942 
0943     return 0;
0944 }
0945 
0946 static int __maybe_unused tsens_resume(struct device *dev)
0947 {
0948     struct tsens_priv *priv = dev_get_drvdata(dev);
0949 
0950     if (priv->ops && priv->ops->resume)
0951         return priv->ops->resume(priv);
0952 
0953     return 0;
0954 }
0955 
0956 static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
0957 
0958 static const struct of_device_id tsens_table[] = {
0959     {
0960         .compatible = "qcom,ipq8064-tsens",
0961         .data = &data_8960,
0962     }, {
0963         .compatible = "qcom,mdm9607-tsens",
0964         .data = &data_9607,
0965     }, {
0966         .compatible = "qcom,msm8916-tsens",
0967         .data = &data_8916,
0968     }, {
0969         .compatible = "qcom,msm8939-tsens",
0970         .data = &data_8939,
0971     }, {
0972         .compatible = "qcom,msm8960-tsens",
0973         .data = &data_8960,
0974     }, {
0975         .compatible = "qcom,msm8974-tsens",
0976         .data = &data_8974,
0977     }, {
0978         .compatible = "qcom,msm8976-tsens",
0979         .data = &data_8976,
0980     }, {
0981         .compatible = "qcom,msm8996-tsens",
0982         .data = &data_8996,
0983     }, {
0984         .compatible = "qcom,tsens-v1",
0985         .data = &data_tsens_v1,
0986     }, {
0987         .compatible = "qcom,tsens-v2",
0988         .data = &data_tsens_v2,
0989     },
0990     {}
0991 };
0992 MODULE_DEVICE_TABLE(of, tsens_table);
0993 
0994 static const struct thermal_zone_of_device_ops tsens_of_ops = {
0995     .get_temp = tsens_get_temp,
0996     .set_trips = tsens_set_trips,
0997 };
0998 
0999 static int tsens_register_irq(struct tsens_priv *priv, char *irqname,
1000                   irq_handler_t thread_fn)
1001 {
1002     struct platform_device *pdev;
1003     int ret, irq;
1004 
1005     pdev = of_find_device_by_node(priv->dev->of_node);
1006     if (!pdev)
1007         return -ENODEV;
1008 
1009     irq = platform_get_irq_byname(pdev, irqname);
1010     if (irq < 0) {
1011         ret = irq;
1012         /* For old DTs with no IRQ defined */
1013         if (irq == -ENXIO)
1014             ret = 0;
1015     } else {
1016         /* VER_0 interrupt is TRIGGER_RISING, VER_0_1 and up is ONESHOT */
1017         if (tsens_version(priv) == VER_0)
1018             ret = devm_request_threaded_irq(&pdev->dev, irq,
1019                             thread_fn, NULL,
1020                             IRQF_TRIGGER_RISING,
1021                             dev_name(&pdev->dev),
1022                             priv);
1023         else
1024             ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
1025                             thread_fn, IRQF_ONESHOT,
1026                             dev_name(&pdev->dev),
1027                             priv);
1028 
1029         if (ret)
1030             dev_err(&pdev->dev, "%s: failed to get irq\n",
1031                 __func__);
1032         else
1033             enable_irq_wake(irq);
1034     }
1035 
1036     put_device(&pdev->dev);
1037     return ret;
1038 }
1039 
1040 static int tsens_register(struct tsens_priv *priv)
1041 {
1042     int i, ret;
1043     struct thermal_zone_device *tzd;
1044 
1045     for (i = 0;  i < priv->num_sensors; i++) {
1046         priv->sensor[i].priv = priv;
1047         tzd = devm_thermal_zone_of_sensor_register(priv->dev, priv->sensor[i].hw_id,
1048                                &priv->sensor[i],
1049                                &tsens_of_ops);
1050         if (IS_ERR(tzd))
1051             continue;
1052         priv->sensor[i].tzd = tzd;
1053         if (priv->ops->enable)
1054             priv->ops->enable(priv, i);
1055 
1056         if (devm_thermal_add_hwmon_sysfs(tzd))
1057             dev_warn(priv->dev,
1058                  "Failed to add hwmon sysfs attributes\n");
1059     }
1060 
1061     /* VER_0 require to set MIN and MAX THRESH
1062      * These 2 regs are set using the:
1063      * - CRIT_THRESH_0 for MAX THRESH hardcoded to 120°C
1064      * - CRIT_THRESH_1 for MIN THRESH hardcoded to   0°C
1065      */
1066     if (tsens_version(priv) < VER_0_1) {
1067         regmap_field_write(priv->rf[CRIT_THRESH_0],
1068                    tsens_mC_to_hw(priv->sensor, 120000));
1069 
1070         regmap_field_write(priv->rf[CRIT_THRESH_1],
1071                    tsens_mC_to_hw(priv->sensor, 0));
1072     }
1073 
1074     ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
1075     if (ret < 0)
1076         return ret;
1077 
1078     if (priv->feat->crit_int)
1079         ret = tsens_register_irq(priv, "critical",
1080                      tsens_critical_irq_thread);
1081 
1082     return ret;
1083 }
1084 
1085 static int tsens_probe(struct platform_device *pdev)
1086 {
1087     int ret, i;
1088     struct device *dev;
1089     struct device_node *np;
1090     struct tsens_priv *priv;
1091     const struct tsens_plat_data *data;
1092     const struct of_device_id *id;
1093     u32 num_sensors;
1094 
1095     if (pdev->dev.of_node)
1096         dev = &pdev->dev;
1097     else
1098         dev = pdev->dev.parent;
1099 
1100     np = dev->of_node;
1101 
1102     id = of_match_node(tsens_table, np);
1103     if (id)
1104         data = id->data;
1105     else
1106         data = &data_8960;
1107 
1108     num_sensors = data->num_sensors;
1109 
1110     if (np)
1111         of_property_read_u32(np, "#qcom,sensors", &num_sensors);
1112 
1113     if (num_sensors <= 0) {
1114         dev_err(dev, "%s: invalid number of sensors\n", __func__);
1115         return -EINVAL;
1116     }
1117 
1118     priv = devm_kzalloc(dev,
1119                  struct_size(priv, sensor, num_sensors),
1120                  GFP_KERNEL);
1121     if (!priv)
1122         return -ENOMEM;
1123 
1124     priv->dev = dev;
1125     priv->num_sensors = num_sensors;
1126     priv->ops = data->ops;
1127     for (i = 0;  i < priv->num_sensors; i++) {
1128         if (data->hw_ids)
1129             priv->sensor[i].hw_id = data->hw_ids[i];
1130         else
1131             priv->sensor[i].hw_id = i;
1132     }
1133     priv->feat = data->feat;
1134     priv->fields = data->fields;
1135 
1136     platform_set_drvdata(pdev, priv);
1137 
1138     if (!priv->ops || !priv->ops->init || !priv->ops->get_temp)
1139         return -EINVAL;
1140 
1141     ret = priv->ops->init(priv);
1142     if (ret < 0) {
1143         dev_err(dev, "%s: init failed\n", __func__);
1144         return ret;
1145     }
1146 
1147     if (priv->ops->calibrate) {
1148         ret = priv->ops->calibrate(priv);
1149         if (ret < 0) {
1150             if (ret != -EPROBE_DEFER)
1151                 dev_err(dev, "%s: calibration failed\n", __func__);
1152             return ret;
1153         }
1154     }
1155 
1156     return tsens_register(priv);
1157 }
1158 
1159 static int tsens_remove(struct platform_device *pdev)
1160 {
1161     struct tsens_priv *priv = platform_get_drvdata(pdev);
1162 
1163     debugfs_remove_recursive(priv->debug_root);
1164     tsens_disable_irq(priv);
1165     if (priv->ops->disable)
1166         priv->ops->disable(priv);
1167 
1168     return 0;
1169 }
1170 
1171 static struct platform_driver tsens_driver = {
1172     .probe = tsens_probe,
1173     .remove = tsens_remove,
1174     .driver = {
1175         .name = "qcom-tsens",
1176         .pm = &tsens_pm_ops,
1177         .of_match_table = tsens_table,
1178     },
1179 };
1180 module_platform_driver(tsens_driver);
1181 
1182 MODULE_LICENSE("GPL v2");
1183 MODULE_DESCRIPTION("QCOM Temperature Sensor driver");
1184 MODULE_ALIAS("platform:qcom-tsens");