Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2014 - 2018, NVIDIA CORPORATION.  All rights reserved.
0004  *
0005  * Author:
0006  *  Mikko Perttunen <mperttunen@nvidia.com>
0007  *
0008  * This software is licensed under the terms of the GNU General Public
0009  * License version 2, as published by the Free Software Foundation, and
0010  * may be copied, distributed, and modified under those terms.
0011  *
0012  * This program is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015  * GNU General Public License for more details.
0016  *
0017  */
0018 
0019 #include <linux/debugfs.h>
0020 #include <linux/bitops.h>
0021 #include <linux/clk.h>
0022 #include <linux/delay.h>
0023 #include <linux/err.h>
0024 #include <linux/interrupt.h>
0025 #include <linux/io.h>
0026 #include <linux/irq.h>
0027 #include <linux/irqdomain.h>
0028 #include <linux/module.h>
0029 #include <linux/of.h>
0030 #include <linux/platform_device.h>
0031 #include <linux/reset.h>
0032 #include <linux/thermal.h>
0033 
0034 #include <dt-bindings/thermal/tegra124-soctherm.h>
0035 
0036 #include "../thermal_core.h"
0037 #include "soctherm.h"
0038 
0039 #define SENSOR_CONFIG0              0
0040 #define SENSOR_CONFIG0_STOP         BIT(0)
0041 #define SENSOR_CONFIG0_CPTR_OVER        BIT(2)
0042 #define SENSOR_CONFIG0_OVER         BIT(3)
0043 #define SENSOR_CONFIG0_TCALC_OVER       BIT(4)
0044 #define SENSOR_CONFIG0_TALL_MASK        (0xfffff << 8)
0045 #define SENSOR_CONFIG0_TALL_SHIFT       8
0046 
0047 #define SENSOR_CONFIG1              4
0048 #define SENSOR_CONFIG1_TSAMPLE_MASK     0x3ff
0049 #define SENSOR_CONFIG1_TSAMPLE_SHIFT        0
0050 #define SENSOR_CONFIG1_TIDDQ_EN_MASK        (0x3f << 15)
0051 #define SENSOR_CONFIG1_TIDDQ_EN_SHIFT       15
0052 #define SENSOR_CONFIG1_TEN_COUNT_MASK       (0x3f << 24)
0053 #define SENSOR_CONFIG1_TEN_COUNT_SHIFT      24
0054 #define SENSOR_CONFIG1_TEMP_ENABLE      BIT(31)
0055 
0056 /*
0057  * SENSOR_CONFIG2 is defined in soctherm.h
0058  * because, it will be used by tegra_soctherm_fuse.c
0059  */
0060 
0061 #define SENSOR_STATUS0              0xc
0062 #define SENSOR_STATUS0_VALID_MASK       BIT(31)
0063 #define SENSOR_STATUS0_CAPTURE_MASK     0xffff
0064 
0065 #define SENSOR_STATUS1              0x10
0066 #define SENSOR_STATUS1_TEMP_VALID_MASK      BIT(31)
0067 #define SENSOR_STATUS1_TEMP_MASK        0xffff
0068 
0069 #define READBACK_VALUE_MASK         0xff00
0070 #define READBACK_VALUE_SHIFT            8
0071 #define READBACK_ADD_HALF           BIT(7)
0072 #define READBACK_NEGATE             BIT(0)
0073 
0074 /*
0075  * THERMCTL_LEVEL0_GROUP_CPU is defined in soctherm.h
0076  * because it will be used by tegraxxx_soctherm.c
0077  */
0078 #define THERMCTL_LVL0_CPU0_EN_MASK      BIT(8)
0079 #define THERMCTL_LVL0_CPU0_CPU_THROT_MASK   (0x3 << 5)
0080 #define THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT  0x1
0081 #define THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY  0x2
0082 #define THERMCTL_LVL0_CPU0_GPU_THROT_MASK   (0x3 << 3)
0083 #define THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT  0x1
0084 #define THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY  0x2
0085 #define THERMCTL_LVL0_CPU0_MEM_THROT_MASK   BIT(2)
0086 #define THERMCTL_LVL0_CPU0_STATUS_MASK      0x3
0087 
0088 #define THERMCTL_LVL0_UP_STATS          0x10
0089 #define THERMCTL_LVL0_DN_STATS          0x14
0090 
0091 #define THERMCTL_INTR_STATUS            0x84
0092 
0093 #define TH_INTR_MD0_MASK            BIT(25)
0094 #define TH_INTR_MU0_MASK            BIT(24)
0095 #define TH_INTR_GD0_MASK            BIT(17)
0096 #define TH_INTR_GU0_MASK            BIT(16)
0097 #define TH_INTR_CD0_MASK            BIT(9)
0098 #define TH_INTR_CU0_MASK            BIT(8)
0099 #define TH_INTR_PD0_MASK            BIT(1)
0100 #define TH_INTR_PU0_MASK            BIT(0)
0101 #define TH_INTR_IGNORE_MASK         0xFCFCFCFC
0102 
0103 #define THERMCTL_STATS_CTL          0x94
0104 #define STATS_CTL_CLR_DN            0x8
0105 #define STATS_CTL_EN_DN             0x4
0106 #define STATS_CTL_CLR_UP            0x2
0107 #define STATS_CTL_EN_UP             0x1
0108 
0109 #define OC1_CFG                 0x310
0110 #define OC1_CFG_LONG_LATENCY_MASK       BIT(6)
0111 #define OC1_CFG_HW_RESTORE_MASK         BIT(5)
0112 #define OC1_CFG_PWR_GOOD_MASK_MASK      BIT(4)
0113 #define OC1_CFG_THROTTLE_MODE_MASK      (0x3 << 2)
0114 #define OC1_CFG_ALARM_POLARITY_MASK     BIT(1)
0115 #define OC1_CFG_EN_THROTTLE_MASK        BIT(0)
0116 
0117 #define OC1_CNT_THRESHOLD           0x314
0118 #define OC1_THROTTLE_PERIOD         0x318
0119 #define OC1_ALARM_COUNT             0x31c
0120 #define OC1_FILTER              0x320
0121 #define OC1_STATS               0x3a8
0122 
0123 #define OC_INTR_STATUS              0x39c
0124 #define OC_INTR_ENABLE              0x3a0
0125 #define OC_INTR_DISABLE             0x3a4
0126 #define OC_STATS_CTL                0x3c4
0127 #define OC_STATS_CTL_CLR_ALL            0x2
0128 #define OC_STATS_CTL_EN_ALL         0x1
0129 
0130 #define OC_INTR_OC1_MASK            BIT(0)
0131 #define OC_INTR_OC2_MASK            BIT(1)
0132 #define OC_INTR_OC3_MASK            BIT(2)
0133 #define OC_INTR_OC4_MASK            BIT(3)
0134 #define OC_INTR_OC5_MASK            BIT(4)
0135 
0136 #define THROT_GLOBAL_CFG            0x400
0137 #define THROT_GLOBAL_ENB_MASK           BIT(0)
0138 
0139 #define CPU_PSKIP_STATUS            0x418
0140 #define XPU_PSKIP_STATUS_M_MASK         (0xff << 12)
0141 #define XPU_PSKIP_STATUS_N_MASK         (0xff << 4)
0142 #define XPU_PSKIP_STATUS_SW_OVERRIDE_MASK   BIT(1)
0143 #define XPU_PSKIP_STATUS_ENABLED_MASK       BIT(0)
0144 
0145 #define THROT_PRIORITY_LOCK         0x424
0146 #define THROT_PRIORITY_LOCK_PRIORITY_MASK   0xff
0147 
0148 #define THROT_STATUS                0x428
0149 #define THROT_STATUS_BREACH_MASK        BIT(12)
0150 #define THROT_STATUS_STATE_MASK         (0xff << 4)
0151 #define THROT_STATUS_ENABLED_MASK       BIT(0)
0152 
0153 #define THROT_PSKIP_CTRL_LITE_CPU       0x430
0154 #define THROT_PSKIP_CTRL_ENABLE_MASK            BIT(31)
0155 #define THROT_PSKIP_CTRL_DIVIDEND_MASK          (0xff << 8)
0156 #define THROT_PSKIP_CTRL_DIVISOR_MASK           0xff
0157 #define THROT_PSKIP_CTRL_VECT_GPU_MASK          (0x7 << 16)
0158 #define THROT_PSKIP_CTRL_VECT_CPU_MASK          (0x7 << 8)
0159 #define THROT_PSKIP_CTRL_VECT2_CPU_MASK         0x7
0160 
0161 #define THROT_VECT_NONE             0x0 /* 3'b000 */
0162 #define THROT_VECT_LOW              0x1 /* 3'b001 */
0163 #define THROT_VECT_MED              0x3 /* 3'b011 */
0164 #define THROT_VECT_HIGH             0x7 /* 3'b111 */
0165 
0166 #define THROT_PSKIP_RAMP_LITE_CPU       0x434
0167 #define THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK   BIT(31)
0168 #define THROT_PSKIP_RAMP_DURATION_MASK      (0xffff << 8)
0169 #define THROT_PSKIP_RAMP_STEP_MASK      0xff
0170 
0171 #define THROT_PRIORITY_LITE         0x444
0172 #define THROT_PRIORITY_LITE_PRIO_MASK       0xff
0173 
0174 #define THROT_DELAY_LITE            0x448
0175 #define THROT_DELAY_LITE_DELAY_MASK     0xff
0176 
0177 /* car register offsets needed for enabling HW throttling */
0178 #define CAR_SUPER_CCLKG_DIVIDER         0x36c
0179 #define CDIVG_USE_THERM_CONTROLS_MASK       BIT(30)
0180 
0181 /* ccroc register offsets needed for enabling HW throttling for Tegra132 */
0182 #define CCROC_SUPER_CCLKG_DIVIDER       0x024
0183 
0184 #define CCROC_GLOBAL_CFG            0x148
0185 
0186 #define CCROC_THROT_PSKIP_RAMP_CPU      0x150
0187 #define CCROC_THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK BIT(31)
0188 #define CCROC_THROT_PSKIP_RAMP_DURATION_MASK    (0xffff << 8)
0189 #define CCROC_THROT_PSKIP_RAMP_STEP_MASK    0xff
0190 
0191 #define CCROC_THROT_PSKIP_CTRL_CPU      0x154
0192 #define CCROC_THROT_PSKIP_CTRL_ENB_MASK     BIT(31)
0193 #define CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK    (0xff << 8)
0194 #define CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK 0xff
0195 
0196 /* get val from register(r) mask bits(m) */
0197 #define REG_GET_MASK(r, m)  (((r) & (m)) >> (ffs(m) - 1))
0198 /* set val(v) to mask bits(m) of register(r) */
0199 #define REG_SET_MASK(r, m, v)   (((r) & ~(m)) | \
0200                  (((v) & (m >> (ffs(m) - 1))) << (ffs(m) - 1)))
0201 
0202 /* get dividend from the depth */
0203 #define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1)
0204 
0205 /* gk20a nv_therm interface N:3 Mapping. Levels defined in tegra124-soctherm.h
0206  * level    vector
0207  * NONE     3'b000
0208  * LOW      3'b001
0209  * MED      3'b011
0210  * HIGH     3'b111
0211  */
0212 #define THROT_LEVEL_TO_DEPTH(level) ((0x1 << (level)) - 1)
0213 
0214 /* get THROT_PSKIP_xxx offset per LIGHT/HEAVY throt and CPU/GPU dev */
0215 #define THROT_OFFSET            0x30
0216 #define THROT_PSKIP_CTRL(throt, dev)    (THROT_PSKIP_CTRL_LITE_CPU + \
0217                     (THROT_OFFSET * throt) + (8 * dev))
0218 #define THROT_PSKIP_RAMP(throt, dev)    (THROT_PSKIP_RAMP_LITE_CPU + \
0219                     (THROT_OFFSET * throt) + (8 * dev))
0220 
0221 /* get THROT_xxx_CTRL offset per LIGHT/HEAVY throt */
0222 #define THROT_PRIORITY_CTRL(throt)  (THROT_PRIORITY_LITE + \
0223                     (THROT_OFFSET * throt))
0224 #define THROT_DELAY_CTRL(throt)     (THROT_DELAY_LITE + \
0225                     (THROT_OFFSET * throt))
0226 
0227 #define ALARM_OFFSET            0x14
0228 #define ALARM_CFG(throt)        (OC1_CFG + \
0229                     (ALARM_OFFSET * (throt - THROTTLE_OC1)))
0230 
0231 #define ALARM_CNT_THRESHOLD(throt)  (OC1_CNT_THRESHOLD + \
0232                     (ALARM_OFFSET * (throt - THROTTLE_OC1)))
0233 
0234 #define ALARM_THROTTLE_PERIOD(throt)    (OC1_THROTTLE_PERIOD + \
0235                     (ALARM_OFFSET * (throt - THROTTLE_OC1)))
0236 
0237 #define ALARM_ALARM_COUNT(throt)    (OC1_ALARM_COUNT + \
0238                     (ALARM_OFFSET * (throt - THROTTLE_OC1)))
0239 
0240 #define ALARM_FILTER(throt)     (OC1_FILTER + \
0241                     (ALARM_OFFSET * (throt - THROTTLE_OC1)))
0242 
0243 #define ALARM_STATS(throt)      (OC1_STATS + \
0244                     (4 * (throt - THROTTLE_OC1)))
0245 
0246 /* get CCROC_THROT_PSKIP_xxx offset per HIGH/MED/LOW vect*/
0247 #define CCROC_THROT_OFFSET          0x0c
0248 #define CCROC_THROT_PSKIP_CTRL_CPU_REG(vect)    (CCROC_THROT_PSKIP_CTRL_CPU + \
0249                         (CCROC_THROT_OFFSET * vect))
0250 #define CCROC_THROT_PSKIP_RAMP_CPU_REG(vect)    (CCROC_THROT_PSKIP_RAMP_CPU + \
0251                         (CCROC_THROT_OFFSET * vect))
0252 
0253 /* get THERMCTL_LEVELx offset per CPU/GPU/MEM/TSENSE rg and LEVEL0~3 lv */
0254 #define THERMCTL_LVL_REGS_SIZE      0x20
0255 #define THERMCTL_LVL_REG(rg, lv)    ((rg) + ((lv) * THERMCTL_LVL_REGS_SIZE))
0256 
0257 #define OC_THROTTLE_MODE_DISABLED   0
0258 #define OC_THROTTLE_MODE_BRIEF      2
0259 
0260 static const int min_low_temp = -127000;
0261 static const int max_high_temp = 127000;
0262 
0263 enum soctherm_throttle_id {
0264     THROTTLE_LIGHT = 0,
0265     THROTTLE_HEAVY,
0266     THROTTLE_OC1,
0267     THROTTLE_OC2,
0268     THROTTLE_OC3,
0269     THROTTLE_OC4,
0270     THROTTLE_OC5, /* OC5 is reserved */
0271     THROTTLE_SIZE,
0272 };
0273 
0274 enum soctherm_oc_irq_id {
0275     TEGRA_SOC_OC_IRQ_1,
0276     TEGRA_SOC_OC_IRQ_2,
0277     TEGRA_SOC_OC_IRQ_3,
0278     TEGRA_SOC_OC_IRQ_4,
0279     TEGRA_SOC_OC_IRQ_5,
0280     TEGRA_SOC_OC_IRQ_MAX,
0281 };
0282 
0283 enum soctherm_throttle_dev_id {
0284     THROTTLE_DEV_CPU = 0,
0285     THROTTLE_DEV_GPU,
0286     THROTTLE_DEV_SIZE,
0287 };
0288 
0289 static const char *const throt_names[] = {
0290     [THROTTLE_LIGHT] = "light",
0291     [THROTTLE_HEAVY] = "heavy",
0292     [THROTTLE_OC1]   = "oc1",
0293     [THROTTLE_OC2]   = "oc2",
0294     [THROTTLE_OC3]   = "oc3",
0295     [THROTTLE_OC4]   = "oc4",
0296     [THROTTLE_OC5]   = "oc5",
0297 };
0298 
0299 struct tegra_soctherm;
0300 struct tegra_thermctl_zone {
0301     void __iomem *reg;
0302     struct device *dev;
0303     struct tegra_soctherm *ts;
0304     struct thermal_zone_device *tz;
0305     const struct tegra_tsensor_group *sg;
0306 };
0307 
0308 struct soctherm_oc_cfg {
0309     u32 active_low;
0310     u32 throt_period;
0311     u32 alarm_cnt_thresh;
0312     u32 alarm_filter;
0313     u32 mode;
0314     bool intr_en;
0315 };
0316 
0317 struct soctherm_throt_cfg {
0318     const char *name;
0319     unsigned int id;
0320     u8 priority;
0321     u8 cpu_throt_level;
0322     u32 cpu_throt_depth;
0323     u32 gpu_throt_level;
0324     struct soctherm_oc_cfg oc_cfg;
0325     struct thermal_cooling_device *cdev;
0326     bool init;
0327 };
0328 
0329 struct tegra_soctherm {
0330     struct reset_control *reset;
0331     struct clk *clock_tsensor;
0332     struct clk *clock_soctherm;
0333     void __iomem *regs;
0334     void __iomem *clk_regs;
0335     void __iomem *ccroc_regs;
0336 
0337     int thermal_irq;
0338     int edp_irq;
0339 
0340     u32 *calib;
0341     struct thermal_zone_device **thermctl_tzs;
0342     struct tegra_soctherm_soc *soc;
0343 
0344     struct soctherm_throt_cfg throt_cfgs[THROTTLE_SIZE];
0345 
0346     struct dentry *debugfs_dir;
0347 
0348     struct mutex thermctl_lock;
0349 };
0350 
0351 struct soctherm_oc_irq_chip_data {
0352     struct mutex        irq_lock; /* serialize OC IRQs */
0353     struct irq_chip     irq_chip;
0354     struct irq_domain   *domain;
0355     int         irq_enable;
0356 };
0357 
0358 static struct soctherm_oc_irq_chip_data soc_irq_cdata;
0359 
0360 /**
0361  * ccroc_writel() - writes a value to a CCROC register
0362  * @ts: pointer to a struct tegra_soctherm
0363  * @value: the value to write
0364  * @reg: the register offset
0365  *
0366  * Writes @v to @reg.  No return value.
0367  */
0368 static inline void ccroc_writel(struct tegra_soctherm *ts, u32 value, u32 reg)
0369 {
0370     writel(value, (ts->ccroc_regs + reg));
0371 }
0372 
0373 /**
0374  * ccroc_readl() - reads specified register from CCROC IP block
0375  * @ts: pointer to a struct tegra_soctherm
0376  * @reg: register address to be read
0377  *
0378  * Return: the value of the register
0379  */
0380 static inline u32 ccroc_readl(struct tegra_soctherm *ts, u32 reg)
0381 {
0382     return readl(ts->ccroc_regs + reg);
0383 }
0384 
0385 static void enable_tsensor(struct tegra_soctherm *tegra, unsigned int i)
0386 {
0387     const struct tegra_tsensor *sensor = &tegra->soc->tsensors[i];
0388     void __iomem *base = tegra->regs + sensor->base;
0389     unsigned int val;
0390 
0391     val = sensor->config->tall << SENSOR_CONFIG0_TALL_SHIFT;
0392     writel(val, base + SENSOR_CONFIG0);
0393 
0394     val  = (sensor->config->tsample - 1) << SENSOR_CONFIG1_TSAMPLE_SHIFT;
0395     val |= sensor->config->tiddq_en << SENSOR_CONFIG1_TIDDQ_EN_SHIFT;
0396     val |= sensor->config->ten_count << SENSOR_CONFIG1_TEN_COUNT_SHIFT;
0397     val |= SENSOR_CONFIG1_TEMP_ENABLE;
0398     writel(val, base + SENSOR_CONFIG1);
0399 
0400     writel(tegra->calib[i], base + SENSOR_CONFIG2);
0401 }
0402 
0403 /*
0404  * Translate from soctherm readback format to millicelsius.
0405  * The soctherm readback format in bits is as follows:
0406  *   TTTTTTTT H______N
0407  * where T's contain the temperature in Celsius,
0408  * H denotes an addition of 0.5 Celsius and N denotes negation
0409  * of the final value.
0410  */
0411 static int translate_temp(u16 val)
0412 {
0413     int t;
0414 
0415     t = ((val & READBACK_VALUE_MASK) >> READBACK_VALUE_SHIFT) * 1000;
0416     if (val & READBACK_ADD_HALF)
0417         t += 500;
0418     if (val & READBACK_NEGATE)
0419         t *= -1;
0420 
0421     return t;
0422 }
0423 
0424 static int tegra_thermctl_get_temp(void *data, int *out_temp)
0425 {
0426     struct tegra_thermctl_zone *zone = data;
0427     u32 val;
0428 
0429     val = readl(zone->reg);
0430     val = REG_GET_MASK(val, zone->sg->sensor_temp_mask);
0431     *out_temp = translate_temp(val);
0432 
0433     return 0;
0434 }
0435 
0436 /**
0437  * enforce_temp_range() - check and enforce temperature range [min, max]
0438  * @dev: struct device * of the SOC_THERM instance
0439  * @trip_temp: the trip temperature to check
0440  *
0441  * Checks and enforces the permitted temperature range that SOC_THERM
0442  * HW can support This is
0443  * done while taking care of precision.
0444  *
0445  * Return: The precision adjusted capped temperature in millicelsius.
0446  */
0447 static int enforce_temp_range(struct device *dev, int trip_temp)
0448 {
0449     int temp;
0450 
0451     temp = clamp_val(trip_temp, min_low_temp, max_high_temp);
0452     if (temp != trip_temp)
0453         dev_dbg(dev, "soctherm: trip temperature %d forced to %d\n",
0454             trip_temp, temp);
0455     return temp;
0456 }
0457 
0458 /**
0459  * thermtrip_program() - Configures the hardware to shut down the
0460  * system if a given sensor group reaches a given temperature
0461  * @dev: ptr to the struct device for the SOC_THERM IP block
0462  * @sg: pointer to the sensor group to set the thermtrip temperature for
0463  * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
0464  *
0465  * Sets the thermal trip threshold of the given sensor group to be the
0466  * @trip_temp.  If this threshold is crossed, the hardware will shut
0467  * down.
0468  *
0469  * Note that, although @trip_temp is specified in millicelsius, the
0470  * hardware is programmed in degrees Celsius.
0471  *
0472  * Return: 0 upon success, or %-EINVAL upon failure.
0473  */
0474 static int thermtrip_program(struct device *dev,
0475                  const struct tegra_tsensor_group *sg,
0476                  int trip_temp)
0477 {
0478     struct tegra_soctherm *ts = dev_get_drvdata(dev);
0479     int temp;
0480     u32 r;
0481 
0482     if (!sg || !sg->thermtrip_threshold_mask)
0483         return -EINVAL;
0484 
0485     temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
0486 
0487     r = readl(ts->regs + THERMCTL_THERMTRIP_CTL);
0488     r = REG_SET_MASK(r, sg->thermtrip_threshold_mask, temp);
0489     r = REG_SET_MASK(r, sg->thermtrip_enable_mask, 1);
0490     r = REG_SET_MASK(r, sg->thermtrip_any_en_mask, 0);
0491     writel(r, ts->regs + THERMCTL_THERMTRIP_CTL);
0492 
0493     return 0;
0494 }
0495 
0496 /**
0497  * throttrip_program() - Configures the hardware to throttle the
0498  * pulse if a given sensor group reaches a given temperature
0499  * @dev: ptr to the struct device for the SOC_THERM IP block
0500  * @sg: pointer to the sensor group to set the thermtrip temperature for
0501  * @stc: pointer to the throttle need to be triggered
0502  * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
0503  *
0504  * Sets the thermal trip threshold and throttle event of the given sensor
0505  * group. If this threshold is crossed, the hardware will trigger the
0506  * throttle.
0507  *
0508  * Note that, although @trip_temp is specified in millicelsius, the
0509  * hardware is programmed in degrees Celsius.
0510  *
0511  * Return: 0 upon success, or %-EINVAL upon failure.
0512  */
0513 static int throttrip_program(struct device *dev,
0514                  const struct tegra_tsensor_group *sg,
0515                  struct soctherm_throt_cfg *stc,
0516                  int trip_temp)
0517 {
0518     struct tegra_soctherm *ts = dev_get_drvdata(dev);
0519     int temp, cpu_throt, gpu_throt;
0520     unsigned int throt;
0521     u32 r, reg_off;
0522 
0523     if (!sg || !stc || !stc->init)
0524         return -EINVAL;
0525 
0526     temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
0527 
0528     /* Hardcode LIGHT on LEVEL1 and HEAVY on LEVEL2 */
0529     throt = stc->id;
0530     reg_off = THERMCTL_LVL_REG(sg->thermctl_lvl0_offset, throt + 1);
0531 
0532     if (throt == THROTTLE_LIGHT) {
0533         cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT;
0534         gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT;
0535     } else {
0536         cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY;
0537         gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY;
0538         if (throt != THROTTLE_HEAVY)
0539             dev_warn(dev,
0540                  "invalid throt id %d - assuming HEAVY",
0541                  throt);
0542     }
0543 
0544     r = readl(ts->regs + reg_off);
0545     r = REG_SET_MASK(r, sg->thermctl_lvl0_up_thresh_mask, temp);
0546     r = REG_SET_MASK(r, sg->thermctl_lvl0_dn_thresh_mask, temp);
0547     r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_CPU_THROT_MASK, cpu_throt);
0548     r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_GPU_THROT_MASK, gpu_throt);
0549     r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 1);
0550     writel(r, ts->regs + reg_off);
0551 
0552     return 0;
0553 }
0554 
0555 static struct soctherm_throt_cfg *
0556 find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name)
0557 {
0558     unsigned int i;
0559 
0560     for (i = 0; ts->throt_cfgs[i].name; i++)
0561         if (!strcmp(ts->throt_cfgs[i].name, name))
0562             return &ts->throt_cfgs[i];
0563 
0564     return NULL;
0565 }
0566 
0567 static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id)
0568 {
0569     int i, temp = min_low_temp;
0570     struct tsensor_group_thermtrips *tt = ts->soc->thermtrips;
0571 
0572     if (id >= TEGRA124_SOCTHERM_SENSOR_NUM)
0573         return temp;
0574 
0575     if (tt) {
0576         for (i = 0; i < ts->soc->num_ttgs; i++) {
0577             if (tt[i].id == id)
0578                 return tt[i].temp;
0579         }
0580     }
0581 
0582     return temp;
0583 }
0584 
0585 static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
0586 {
0587     struct tegra_thermctl_zone *zone = data;
0588     struct thermal_zone_device *tz = zone->tz;
0589     struct tegra_soctherm *ts = zone->ts;
0590     const struct tegra_tsensor_group *sg = zone->sg;
0591     struct device *dev = zone->dev;
0592     enum thermal_trip_type type;
0593     int ret;
0594 
0595     if (!tz)
0596         return -EINVAL;
0597 
0598     ret = tz->ops->get_trip_type(tz, trip, &type);
0599     if (ret)
0600         return ret;
0601 
0602     if (type == THERMAL_TRIP_CRITICAL) {
0603         /*
0604          * If thermtrips property is set in DT,
0605          * doesn't need to program critical type trip to HW,
0606          * if not, program critical trip to HW.
0607          */
0608         if (min_low_temp == tsensor_group_thermtrip_get(ts, sg->id))
0609             return thermtrip_program(dev, sg, temp);
0610         else
0611             return 0;
0612 
0613     } else if (type == THERMAL_TRIP_HOT) {
0614         int i;
0615 
0616         for (i = 0; i < THROTTLE_SIZE; i++) {
0617             struct thermal_cooling_device *cdev;
0618             struct soctherm_throt_cfg *stc;
0619 
0620             if (!ts->throt_cfgs[i].init)
0621                 continue;
0622 
0623             cdev = ts->throt_cfgs[i].cdev;
0624             if (get_thermal_instance(tz, cdev, trip))
0625                 stc = find_throttle_cfg_by_name(ts, cdev->type);
0626             else
0627                 continue;
0628 
0629             return throttrip_program(dev, sg, stc, temp);
0630         }
0631     }
0632 
0633     return 0;
0634 }
0635 
0636 static void thermal_irq_enable(struct tegra_thermctl_zone *zn)
0637 {
0638     u32 r;
0639 
0640     /* multiple zones could be handling and setting trips at once */
0641     mutex_lock(&zn->ts->thermctl_lock);
0642     r = readl(zn->ts->regs + THERMCTL_INTR_ENABLE);
0643     r = REG_SET_MASK(r, zn->sg->thermctl_isr_mask, TH_INTR_UP_DN_EN);
0644     writel(r, zn->ts->regs + THERMCTL_INTR_ENABLE);
0645     mutex_unlock(&zn->ts->thermctl_lock);
0646 }
0647 
0648 static void thermal_irq_disable(struct tegra_thermctl_zone *zn)
0649 {
0650     u32 r;
0651 
0652     /* multiple zones could be handling and setting trips at once */
0653     mutex_lock(&zn->ts->thermctl_lock);
0654     r = readl(zn->ts->regs + THERMCTL_INTR_DISABLE);
0655     r = REG_SET_MASK(r, zn->sg->thermctl_isr_mask, 0);
0656     writel(r, zn->ts->regs + THERMCTL_INTR_DISABLE);
0657     mutex_unlock(&zn->ts->thermctl_lock);
0658 }
0659 
0660 static int tegra_thermctl_set_trips(void *data, int lo, int hi)
0661 {
0662     struct tegra_thermctl_zone *zone = data;
0663     u32 r;
0664 
0665     thermal_irq_disable(zone);
0666 
0667     r = readl(zone->ts->regs + zone->sg->thermctl_lvl0_offset);
0668     r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 0);
0669     writel(r, zone->ts->regs + zone->sg->thermctl_lvl0_offset);
0670 
0671     lo = enforce_temp_range(zone->dev, lo) / zone->ts->soc->thresh_grain;
0672     hi = enforce_temp_range(zone->dev, hi) / zone->ts->soc->thresh_grain;
0673     dev_dbg(zone->dev, "%s hi:%d, lo:%d\n", __func__, hi, lo);
0674 
0675     r = REG_SET_MASK(r, zone->sg->thermctl_lvl0_up_thresh_mask, hi);
0676     r = REG_SET_MASK(r, zone->sg->thermctl_lvl0_dn_thresh_mask, lo);
0677     r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 1);
0678     writel(r, zone->ts->regs + zone->sg->thermctl_lvl0_offset);
0679 
0680     thermal_irq_enable(zone);
0681 
0682     return 0;
0683 }
0684 
0685 static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
0686     .get_temp = tegra_thermctl_get_temp,
0687     .set_trip_temp = tegra_thermctl_set_trip_temp,
0688     .set_trips = tegra_thermctl_set_trips,
0689 };
0690 
0691 static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
0692 {
0693     int ntrips, i, ret;
0694     enum thermal_trip_type type;
0695 
0696     ntrips = of_thermal_get_ntrips(tz);
0697     if (ntrips <= 0)
0698         return -EINVAL;
0699 
0700     for (i = 0; i < ntrips; i++) {
0701         ret = tz->ops->get_trip_type(tz, i, &type);
0702         if (ret)
0703             return -EINVAL;
0704         if (type == THERMAL_TRIP_HOT) {
0705             ret = tz->ops->get_trip_temp(tz, i, temp);
0706             if (!ret)
0707                 *trip = i;
0708 
0709             return ret;
0710         }
0711     }
0712 
0713     return -EINVAL;
0714 }
0715 
0716 /**
0717  * tegra_soctherm_set_hwtrips() - set HW trip point from DT data
0718  * @dev: struct device * of the SOC_THERM instance
0719  * @sg: pointer to the sensor group to set the thermtrip temperature for
0720  * @tz: struct thermal_zone_device *
0721  *
0722  * Configure the SOC_THERM HW trip points, setting "THERMTRIP"
0723  * "THROTTLE" trip points , using "thermtrips", "critical" or "hot"
0724  * type trip_temp
0725  * from thermal zone.
0726  * After they have been configured, THERMTRIP or THROTTLE will take
0727  * action when the configured SoC thermal sensor group reaches a
0728  * certain temperature.
0729  *
0730  * Return: 0 upon success, or a negative error code on failure.
0731  * "Success" does not mean that trips was enabled; it could also
0732  * mean that no node was found in DT.
0733  * THERMTRIP has been enabled successfully when a message similar to
0734  * this one appears on the serial console:
0735  * "thermtrip: will shut down when sensor group XXX reaches YYYYYY mC"
0736  * THROTTLE has been enabled successfully when a message similar to
0737  * this one appears on the serial console:
0738  * ""throttrip: will throttle when sensor group XXX reaches YYYYYY mC"
0739  */
0740 static int tegra_soctherm_set_hwtrips(struct device *dev,
0741                       const struct tegra_tsensor_group *sg,
0742                       struct thermal_zone_device *tz)
0743 {
0744     struct tegra_soctherm *ts = dev_get_drvdata(dev);
0745     struct soctherm_throt_cfg *stc;
0746     int i, trip, temperature, ret;
0747 
0748     /* Get thermtrips. If missing, try to get critical trips. */
0749     temperature = tsensor_group_thermtrip_get(ts, sg->id);
0750     if (min_low_temp == temperature)
0751         if (tz->ops->get_crit_temp(tz, &temperature))
0752             temperature = max_high_temp;
0753 
0754     ret = thermtrip_program(dev, sg, temperature);
0755     if (ret) {
0756         dev_err(dev, "thermtrip: %s: error during enable\n", sg->name);
0757         return ret;
0758     }
0759 
0760     dev_info(dev, "thermtrip: will shut down when %s reaches %d mC\n",
0761          sg->name, temperature);
0762 
0763     ret = get_hot_temp(tz, &trip, &temperature);
0764     if (ret) {
0765         dev_info(dev, "throttrip: %s: missing hot temperature\n",
0766              sg->name);
0767         return 0;
0768     }
0769 
0770     for (i = 0; i < THROTTLE_OC1; i++) {
0771         struct thermal_cooling_device *cdev;
0772 
0773         if (!ts->throt_cfgs[i].init)
0774             continue;
0775 
0776         cdev = ts->throt_cfgs[i].cdev;
0777         if (get_thermal_instance(tz, cdev, trip))
0778             stc = find_throttle_cfg_by_name(ts, cdev->type);
0779         else
0780             continue;
0781 
0782         ret = throttrip_program(dev, sg, stc, temperature);
0783         if (ret) {
0784             dev_err(dev, "throttrip: %s: error during enable\n",
0785                 sg->name);
0786             return ret;
0787         }
0788 
0789         dev_info(dev,
0790              "throttrip: will throttle when %s reaches %d mC\n",
0791              sg->name, temperature);
0792         break;
0793     }
0794 
0795     if (i == THROTTLE_SIZE)
0796         dev_info(dev, "throttrip: %s: missing throttle cdev\n",
0797              sg->name);
0798 
0799     return 0;
0800 }
0801 
0802 static irqreturn_t soctherm_thermal_isr(int irq, void *dev_id)
0803 {
0804     struct tegra_soctherm *ts = dev_id;
0805     u32 r;
0806 
0807     /* Case for no lock:
0808      * Although interrupts are enabled in set_trips, there is still no need
0809      * to lock here because the interrupts are disabled before programming
0810      * new trip points. Hence there cant be a interrupt on the same sensor.
0811      * An interrupt can however occur on a sensor while trips are being
0812      * programmed on a different one. This beign a LEVEL interrupt won't
0813      * cause a new interrupt but this is taken care of by the re-reading of
0814      * the STATUS register in the thread function.
0815      */
0816     r = readl(ts->regs + THERMCTL_INTR_STATUS);
0817     writel(r, ts->regs + THERMCTL_INTR_DISABLE);
0818 
0819     return IRQ_WAKE_THREAD;
0820 }
0821 
0822 /**
0823  * soctherm_thermal_isr_thread() - Handles a thermal interrupt request
0824  * @irq:       The interrupt number being requested; not used
0825  * @dev_id:    Opaque pointer to tegra_soctherm;
0826  *
0827  * Clears the interrupt status register if there are expected
0828  * interrupt bits set.
0829  * The interrupt(s) are then handled by updating the corresponding
0830  * thermal zones.
0831  *
0832  * An error is logged if any unexpected interrupt bits are set.
0833  *
0834  * Disabled interrupts are re-enabled.
0835  *
0836  * Return: %IRQ_HANDLED. Interrupt was handled and no further processing
0837  * is needed.
0838  */
0839 static irqreturn_t soctherm_thermal_isr_thread(int irq, void *dev_id)
0840 {
0841     struct tegra_soctherm *ts = dev_id;
0842     struct thermal_zone_device *tz;
0843     u32 st, ex = 0, cp = 0, gp = 0, pl = 0, me = 0;
0844 
0845     st = readl(ts->regs + THERMCTL_INTR_STATUS);
0846 
0847     /* deliberately clear expected interrupts handled in SW */
0848     cp |= st & TH_INTR_CD0_MASK;
0849     cp |= st & TH_INTR_CU0_MASK;
0850 
0851     gp |= st & TH_INTR_GD0_MASK;
0852     gp |= st & TH_INTR_GU0_MASK;
0853 
0854     pl |= st & TH_INTR_PD0_MASK;
0855     pl |= st & TH_INTR_PU0_MASK;
0856 
0857     me |= st & TH_INTR_MD0_MASK;
0858     me |= st & TH_INTR_MU0_MASK;
0859 
0860     ex |= cp | gp | pl | me;
0861     if (ex) {
0862         writel(ex, ts->regs + THERMCTL_INTR_STATUS);
0863         st &= ~ex;
0864 
0865         if (cp) {
0866             tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_CPU];
0867             thermal_zone_device_update(tz,
0868                            THERMAL_EVENT_UNSPECIFIED);
0869         }
0870 
0871         if (gp) {
0872             tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_GPU];
0873             thermal_zone_device_update(tz,
0874                            THERMAL_EVENT_UNSPECIFIED);
0875         }
0876 
0877         if (pl) {
0878             tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_PLLX];
0879             thermal_zone_device_update(tz,
0880                            THERMAL_EVENT_UNSPECIFIED);
0881         }
0882 
0883         if (me) {
0884             tz = ts->thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_MEM];
0885             thermal_zone_device_update(tz,
0886                            THERMAL_EVENT_UNSPECIFIED);
0887         }
0888     }
0889 
0890     /* deliberately ignore expected interrupts NOT handled in SW */
0891     ex |= TH_INTR_IGNORE_MASK;
0892     st &= ~ex;
0893 
0894     if (st) {
0895         /* Whine about any other unexpected INTR bits still set */
0896         pr_err("soctherm: Ignored unexpected INTRs 0x%08x\n", st);
0897         writel(st, ts->regs + THERMCTL_INTR_STATUS);
0898     }
0899 
0900     return IRQ_HANDLED;
0901 }
0902 
0903 /**
0904  * soctherm_oc_intr_enable() - Enables the soctherm over-current interrupt
0905  * @ts:     pointer to a struct tegra_soctherm
0906  * @alarm:      The soctherm throttle id
0907  * @enable:     Flag indicating enable the soctherm over-current
0908  *          interrupt or disable it
0909  *
0910  * Enables a specific over-current pins @alarm to raise an interrupt if the flag
0911  * is set and the alarm corresponds to OC1, OC2, OC3, or OC4.
0912  */
0913 static void soctherm_oc_intr_enable(struct tegra_soctherm *ts,
0914                     enum soctherm_throttle_id alarm,
0915                     bool enable)
0916 {
0917     u32 r;
0918 
0919     if (!enable)
0920         return;
0921 
0922     r = readl(ts->regs + OC_INTR_ENABLE);
0923     switch (alarm) {
0924     case THROTTLE_OC1:
0925         r = REG_SET_MASK(r, OC_INTR_OC1_MASK, 1);
0926         break;
0927     case THROTTLE_OC2:
0928         r = REG_SET_MASK(r, OC_INTR_OC2_MASK, 1);
0929         break;
0930     case THROTTLE_OC3:
0931         r = REG_SET_MASK(r, OC_INTR_OC3_MASK, 1);
0932         break;
0933     case THROTTLE_OC4:
0934         r = REG_SET_MASK(r, OC_INTR_OC4_MASK, 1);
0935         break;
0936     default:
0937         r = 0;
0938         break;
0939     }
0940     writel(r, ts->regs + OC_INTR_ENABLE);
0941 }
0942 
0943 /**
0944  * soctherm_handle_alarm() - Handles soctherm alarms
0945  * @alarm:      The soctherm throttle id
0946  *
0947  * "Handles" over-current alarms (OC1, OC2, OC3, and OC4) by printing
0948  * a warning or informative message.
0949  *
0950  * Return: -EINVAL for @alarm = THROTTLE_OC3, otherwise 0 (success).
0951  */
0952 static int soctherm_handle_alarm(enum soctherm_throttle_id alarm)
0953 {
0954     int rv = -EINVAL;
0955 
0956     switch (alarm) {
0957     case THROTTLE_OC1:
0958         pr_debug("soctherm: Successfully handled OC1 alarm\n");
0959         rv = 0;
0960         break;
0961 
0962     case THROTTLE_OC2:
0963         pr_debug("soctherm: Successfully handled OC2 alarm\n");
0964         rv = 0;
0965         break;
0966 
0967     case THROTTLE_OC3:
0968         pr_debug("soctherm: Successfully handled OC3 alarm\n");
0969         rv = 0;
0970         break;
0971 
0972     case THROTTLE_OC4:
0973         pr_debug("soctherm: Successfully handled OC4 alarm\n");
0974         rv = 0;
0975         break;
0976 
0977     default:
0978         break;
0979     }
0980 
0981     if (rv)
0982         pr_err("soctherm: ERROR in handling %s alarm\n",
0983                throt_names[alarm]);
0984 
0985     return rv;
0986 }
0987 
0988 /**
0989  * soctherm_edp_isr_thread() - log an over-current interrupt request
0990  * @irq:    OC irq number. Currently not being used. See description
0991  * @arg:    a void pointer for callback, currently not being used
0992  *
0993  * Over-current events are handled in hardware. This function is called to log
0994  * and handle any OC events that happened. Additionally, it checks every
0995  * over-current interrupt registers for registers are set but
0996  * was not expected (i.e. any discrepancy in interrupt status) by the function,
0997  * the discrepancy will logged.
0998  *
0999  * Return: %IRQ_HANDLED
1000  */
1001 static irqreturn_t soctherm_edp_isr_thread(int irq, void *arg)
1002 {
1003     struct tegra_soctherm *ts = arg;
1004     u32 st, ex, oc1, oc2, oc3, oc4;
1005 
1006     st = readl(ts->regs + OC_INTR_STATUS);
1007 
1008     /* deliberately clear expected interrupts handled in SW */
1009     oc1 = st & OC_INTR_OC1_MASK;
1010     oc2 = st & OC_INTR_OC2_MASK;
1011     oc3 = st & OC_INTR_OC3_MASK;
1012     oc4 = st & OC_INTR_OC4_MASK;
1013     ex = oc1 | oc2 | oc3 | oc4;
1014 
1015     pr_err("soctherm: OC ALARM 0x%08x\n", ex);
1016     if (ex) {
1017         writel(st, ts->regs + OC_INTR_STATUS);
1018         st &= ~ex;
1019 
1020         if (oc1 && !soctherm_handle_alarm(THROTTLE_OC1))
1021             soctherm_oc_intr_enable(ts, THROTTLE_OC1, true);
1022 
1023         if (oc2 && !soctherm_handle_alarm(THROTTLE_OC2))
1024             soctherm_oc_intr_enable(ts, THROTTLE_OC2, true);
1025 
1026         if (oc3 && !soctherm_handle_alarm(THROTTLE_OC3))
1027             soctherm_oc_intr_enable(ts, THROTTLE_OC3, true);
1028 
1029         if (oc4 && !soctherm_handle_alarm(THROTTLE_OC4))
1030             soctherm_oc_intr_enable(ts, THROTTLE_OC4, true);
1031 
1032         if (oc1 && soc_irq_cdata.irq_enable & BIT(0))
1033             handle_nested_irq(
1034                 irq_find_mapping(soc_irq_cdata.domain, 0));
1035 
1036         if (oc2 && soc_irq_cdata.irq_enable & BIT(1))
1037             handle_nested_irq(
1038                 irq_find_mapping(soc_irq_cdata.domain, 1));
1039 
1040         if (oc3 && soc_irq_cdata.irq_enable & BIT(2))
1041             handle_nested_irq(
1042                 irq_find_mapping(soc_irq_cdata.domain, 2));
1043 
1044         if (oc4 && soc_irq_cdata.irq_enable & BIT(3))
1045             handle_nested_irq(
1046                 irq_find_mapping(soc_irq_cdata.domain, 3));
1047     }
1048 
1049     if (st) {
1050         pr_err("soctherm: Ignored unexpected OC ALARM 0x%08x\n", st);
1051         writel(st, ts->regs + OC_INTR_STATUS);
1052     }
1053 
1054     return IRQ_HANDLED;
1055 }
1056 
1057 /**
1058  * soctherm_edp_isr() - Disables any active interrupts
1059  * @irq:    The interrupt request number
1060  * @arg:    Opaque pointer to an argument
1061  *
1062  * Writes to the OC_INTR_DISABLE register the over current interrupt status,
1063  * masking any asserted interrupts. Doing this prevents the same interrupts
1064  * from triggering this isr repeatedly. The thread woken by this isr will
1065  * handle asserted interrupts and subsequently unmask/re-enable them.
1066  *
1067  * The OC_INTR_DISABLE register indicates which OC interrupts
1068  * have been disabled.
1069  *
1070  * Return: %IRQ_WAKE_THREAD, handler requests to wake the handler thread
1071  */
1072 static irqreturn_t soctherm_edp_isr(int irq, void *arg)
1073 {
1074     struct tegra_soctherm *ts = arg;
1075     u32 r;
1076 
1077     if (!ts)
1078         return IRQ_NONE;
1079 
1080     r = readl(ts->regs + OC_INTR_STATUS);
1081     writel(r, ts->regs + OC_INTR_DISABLE);
1082 
1083     return IRQ_WAKE_THREAD;
1084 }
1085 
1086 /**
1087  * soctherm_oc_irq_lock() - locks the over-current interrupt request
1088  * @data:   Interrupt request data
1089  *
1090  * Looks up the chip data from @data and locks the mutex associated with
1091  * a particular over-current interrupt request.
1092  */
1093 static void soctherm_oc_irq_lock(struct irq_data *data)
1094 {
1095     struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
1096 
1097     mutex_lock(&d->irq_lock);
1098 }
1099 
1100 /**
1101  * soctherm_oc_irq_sync_unlock() - Unlocks the OC interrupt request
1102  * @data:       Interrupt request data
1103  *
1104  * Looks up the interrupt request data @data and unlocks the mutex associated
1105  * with a particular over-current interrupt request.
1106  */
1107 static void soctherm_oc_irq_sync_unlock(struct irq_data *data)
1108 {
1109     struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
1110 
1111     mutex_unlock(&d->irq_lock);
1112 }
1113 
1114 /**
1115  * soctherm_oc_irq_enable() - Enables the SOC_THERM over-current interrupt queue
1116  * @data:       irq_data structure of the chip
1117  *
1118  * Sets the irq_enable bit of SOC_THERM allowing SOC_THERM
1119  * to respond to over-current interrupts.
1120  *
1121  */
1122 static void soctherm_oc_irq_enable(struct irq_data *data)
1123 {
1124     struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
1125 
1126     d->irq_enable |= BIT(data->hwirq);
1127 }
1128 
1129 /**
1130  * soctherm_oc_irq_disable() - Disables overcurrent interrupt requests
1131  * @data:   The interrupt request information
1132  *
1133  * Clears the interrupt request enable bit of the overcurrent
1134  * interrupt request chip data.
1135  *
1136  * Return: Nothing is returned (void)
1137  */
1138 static void soctherm_oc_irq_disable(struct irq_data *data)
1139 {
1140     struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
1141 
1142     d->irq_enable &= ~BIT(data->hwirq);
1143 }
1144 
1145 static int soctherm_oc_irq_set_type(struct irq_data *data, unsigned int type)
1146 {
1147     return 0;
1148 }
1149 
1150 /**
1151  * soctherm_oc_irq_map() - SOC_THERM interrupt request domain mapper
1152  * @h:      Interrupt request domain
1153  * @virq:   Virtual interrupt request number
1154  * @hw:     Hardware interrupt request number
1155  *
1156  * Mapping callback function for SOC_THERM's irq_domain. When a SOC_THERM
1157  * interrupt request is called, the irq_domain takes the request's virtual
1158  * request number (much like a virtual memory address) and maps it to a
1159  * physical hardware request number.
1160  *
1161  * When a mapping doesn't already exist for a virtual request number, the
1162  * irq_domain calls this function to associate the virtual request number with
1163  * a hardware request number.
1164  *
1165  * Return: 0
1166  */
1167 static int soctherm_oc_irq_map(struct irq_domain *h, unsigned int virq,
1168         irq_hw_number_t hw)
1169 {
1170     struct soctherm_oc_irq_chip_data *data = h->host_data;
1171 
1172     irq_set_chip_data(virq, data);
1173     irq_set_chip(virq, &data->irq_chip);
1174     irq_set_nested_thread(virq, 1);
1175     return 0;
1176 }
1177 
1178 /**
1179  * soctherm_irq_domain_xlate_twocell() - xlate for soctherm interrupts
1180  * @d:      Interrupt request domain
1181  * @ctrlr:      Controller device tree node
1182  * @intspec:    Array of u32s from DTs "interrupt" property
1183  * @intsize:    Number of values inside the intspec array
1184  * @out_hwirq:  HW IRQ value associated with this interrupt
1185  * @out_type:   The IRQ SENSE type for this interrupt.
1186  *
1187  * This Device Tree IRQ specifier translation function will translate a
1188  * specific "interrupt" as defined by 2 DT values where the cell values map
1189  * the hwirq number + 1 and linux irq flags. Since the output is the hwirq
1190  * number, this function will subtract 1 from the value listed in DT.
1191  *
1192  * Return: 0
1193  */
1194 static int soctherm_irq_domain_xlate_twocell(struct irq_domain *d,
1195     struct device_node *ctrlr, const u32 *intspec, unsigned int intsize,
1196     irq_hw_number_t *out_hwirq, unsigned int *out_type)
1197 {
1198     if (WARN_ON(intsize < 2))
1199         return -EINVAL;
1200 
1201     /*
1202      * The HW value is 1 index less than the DT IRQ values.
1203      * i.e. OC4 goes to HW index 3.
1204      */
1205     *out_hwirq = intspec[0] - 1;
1206     *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
1207     return 0;
1208 }
1209 
1210 static const struct irq_domain_ops soctherm_oc_domain_ops = {
1211     .map    = soctherm_oc_irq_map,
1212     .xlate  = soctherm_irq_domain_xlate_twocell,
1213 };
1214 
1215 /**
1216  * soctherm_oc_int_init() - Initial enabling of the over
1217  * current interrupts
1218  * @np: The devicetree node for soctherm
1219  * @num_irqs:   The number of new interrupt requests
1220  *
1221  * Sets the over current interrupt request chip data
1222  *
1223  * Return: 0 on success or if overcurrent interrupts are not enabled,
1224  * -ENOMEM (out of memory), or irq_base if the function failed to
1225  * allocate the irqs
1226  */
1227 static int soctherm_oc_int_init(struct device_node *np, int num_irqs)
1228 {
1229     if (!num_irqs) {
1230         pr_info("%s(): OC interrupts are not enabled\n", __func__);
1231         return 0;
1232     }
1233 
1234     mutex_init(&soc_irq_cdata.irq_lock);
1235     soc_irq_cdata.irq_enable = 0;
1236 
1237     soc_irq_cdata.irq_chip.name = "soc_therm_oc";
1238     soc_irq_cdata.irq_chip.irq_bus_lock = soctherm_oc_irq_lock;
1239     soc_irq_cdata.irq_chip.irq_bus_sync_unlock =
1240         soctherm_oc_irq_sync_unlock;
1241     soc_irq_cdata.irq_chip.irq_disable = soctherm_oc_irq_disable;
1242     soc_irq_cdata.irq_chip.irq_enable = soctherm_oc_irq_enable;
1243     soc_irq_cdata.irq_chip.irq_set_type = soctherm_oc_irq_set_type;
1244     soc_irq_cdata.irq_chip.irq_set_wake = NULL;
1245 
1246     soc_irq_cdata.domain = irq_domain_add_linear(np, num_irqs,
1247                              &soctherm_oc_domain_ops,
1248                              &soc_irq_cdata);
1249 
1250     if (!soc_irq_cdata.domain) {
1251         pr_err("%s: Failed to create IRQ domain\n", __func__);
1252         return -ENOMEM;
1253     }
1254 
1255     pr_debug("%s(): OC interrupts enabled successful\n", __func__);
1256     return 0;
1257 }
1258 
1259 #ifdef CONFIG_DEBUG_FS
1260 static int regs_show(struct seq_file *s, void *data)
1261 {
1262     struct platform_device *pdev = s->private;
1263     struct tegra_soctherm *ts = platform_get_drvdata(pdev);
1264     const struct tegra_tsensor *tsensors = ts->soc->tsensors;
1265     const struct tegra_tsensor_group **ttgs = ts->soc->ttgs;
1266     u32 r, state;
1267     int i, level;
1268 
1269     seq_puts(s, "-----TSENSE (convert HW)-----\n");
1270 
1271     for (i = 0; i < ts->soc->num_tsensors; i++) {
1272         r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG1);
1273         state = REG_GET_MASK(r, SENSOR_CONFIG1_TEMP_ENABLE);
1274 
1275         seq_printf(s, "%s: ", tsensors[i].name);
1276         seq_printf(s, "En(%d) ", state);
1277 
1278         if (!state) {
1279             seq_puts(s, "\n");
1280             continue;
1281         }
1282 
1283         state = REG_GET_MASK(r, SENSOR_CONFIG1_TIDDQ_EN_MASK);
1284         seq_printf(s, "tiddq(%d) ", state);
1285         state = REG_GET_MASK(r, SENSOR_CONFIG1_TEN_COUNT_MASK);
1286         seq_printf(s, "ten_count(%d) ", state);
1287         state = REG_GET_MASK(r, SENSOR_CONFIG1_TSAMPLE_MASK);
1288         seq_printf(s, "tsample(%d) ", state + 1);
1289 
1290         r = readl(ts->regs + tsensors[i].base + SENSOR_STATUS1);
1291         state = REG_GET_MASK(r, SENSOR_STATUS1_TEMP_VALID_MASK);
1292         seq_printf(s, "Temp(%d/", state);
1293         state = REG_GET_MASK(r, SENSOR_STATUS1_TEMP_MASK);
1294         seq_printf(s, "%d) ", translate_temp(state));
1295 
1296         r = readl(ts->regs + tsensors[i].base + SENSOR_STATUS0);
1297         state = REG_GET_MASK(r, SENSOR_STATUS0_VALID_MASK);
1298         seq_printf(s, "Capture(%d/", state);
1299         state = REG_GET_MASK(r, SENSOR_STATUS0_CAPTURE_MASK);
1300         seq_printf(s, "%d) ", state);
1301 
1302         r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG0);
1303         state = REG_GET_MASK(r, SENSOR_CONFIG0_STOP);
1304         seq_printf(s, "Stop(%d) ", state);
1305         state = REG_GET_MASK(r, SENSOR_CONFIG0_TALL_MASK);
1306         seq_printf(s, "Tall(%d) ", state);
1307         state = REG_GET_MASK(r, SENSOR_CONFIG0_TCALC_OVER);
1308         seq_printf(s, "Over(%d/", state);
1309         state = REG_GET_MASK(r, SENSOR_CONFIG0_OVER);
1310         seq_printf(s, "%d/", state);
1311         state = REG_GET_MASK(r, SENSOR_CONFIG0_CPTR_OVER);
1312         seq_printf(s, "%d) ", state);
1313 
1314         r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG2);
1315         state = REG_GET_MASK(r, SENSOR_CONFIG2_THERMA_MASK);
1316         seq_printf(s, "Therm_A/B(%d/", state);
1317         state = REG_GET_MASK(r, SENSOR_CONFIG2_THERMB_MASK);
1318         seq_printf(s, "%d)\n", (s16)state);
1319     }
1320 
1321     r = readl(ts->regs + SENSOR_PDIV);
1322     seq_printf(s, "PDIV: 0x%x\n", r);
1323 
1324     r = readl(ts->regs + SENSOR_HOTSPOT_OFF);
1325     seq_printf(s, "HOTSPOT: 0x%x\n", r);
1326 
1327     seq_puts(s, "\n");
1328     seq_puts(s, "-----SOC_THERM-----\n");
1329 
1330     r = readl(ts->regs + SENSOR_TEMP1);
1331     state = REG_GET_MASK(r, SENSOR_TEMP1_CPU_TEMP_MASK);
1332     seq_printf(s, "Temperatures: CPU(%d) ", translate_temp(state));
1333     state = REG_GET_MASK(r, SENSOR_TEMP1_GPU_TEMP_MASK);
1334     seq_printf(s, " GPU(%d) ", translate_temp(state));
1335     r = readl(ts->regs + SENSOR_TEMP2);
1336     state = REG_GET_MASK(r, SENSOR_TEMP2_PLLX_TEMP_MASK);
1337     seq_printf(s, " PLLX(%d) ", translate_temp(state));
1338     state = REG_GET_MASK(r, SENSOR_TEMP2_MEM_TEMP_MASK);
1339     seq_printf(s, " MEM(%d)\n", translate_temp(state));
1340 
1341     for (i = 0; i < ts->soc->num_ttgs; i++) {
1342         seq_printf(s, "%s:\n", ttgs[i]->name);
1343         for (level = 0; level < 4; level++) {
1344             s32 v;
1345             u32 mask;
1346             u16 off = ttgs[i]->thermctl_lvl0_offset;
1347 
1348             r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
1349 
1350             mask = ttgs[i]->thermctl_lvl0_up_thresh_mask;
1351             state = REG_GET_MASK(r, mask);
1352             v = sign_extend32(state, ts->soc->bptt - 1);
1353             v *= ts->soc->thresh_grain;
1354             seq_printf(s, "   %d: Up/Dn(%d /", level, v);
1355 
1356             mask = ttgs[i]->thermctl_lvl0_dn_thresh_mask;
1357             state = REG_GET_MASK(r, mask);
1358             v = sign_extend32(state, ts->soc->bptt - 1);
1359             v *= ts->soc->thresh_grain;
1360             seq_printf(s, "%d ) ", v);
1361 
1362             mask = THERMCTL_LVL0_CPU0_EN_MASK;
1363             state = REG_GET_MASK(r, mask);
1364             seq_printf(s, "En(%d) ", state);
1365 
1366             mask = THERMCTL_LVL0_CPU0_CPU_THROT_MASK;
1367             state = REG_GET_MASK(r, mask);
1368             seq_puts(s, "CPU Throt");
1369             if (!state)
1370                 seq_printf(s, "(%s) ", "none");
1371             else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT)
1372                 seq_printf(s, "(%s) ", "L");
1373             else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY)
1374                 seq_printf(s, "(%s) ", "H");
1375             else
1376                 seq_printf(s, "(%s) ", "H+L");
1377 
1378             mask = THERMCTL_LVL0_CPU0_GPU_THROT_MASK;
1379             state = REG_GET_MASK(r, mask);
1380             seq_puts(s, "GPU Throt");
1381             if (!state)
1382                 seq_printf(s, "(%s) ", "none");
1383             else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT)
1384                 seq_printf(s, "(%s) ", "L");
1385             else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY)
1386                 seq_printf(s, "(%s) ", "H");
1387             else
1388                 seq_printf(s, "(%s) ", "H+L");
1389 
1390             mask = THERMCTL_LVL0_CPU0_STATUS_MASK;
1391             state = REG_GET_MASK(r, mask);
1392             seq_printf(s, "Status(%s)\n",
1393                    state == 0 ? "LO" :
1394                    state == 1 ? "In" :
1395                    state == 2 ? "Res" : "HI");
1396         }
1397     }
1398 
1399     r = readl(ts->regs + THERMCTL_STATS_CTL);
1400     seq_printf(s, "STATS: Up(%s) Dn(%s)\n",
1401            r & STATS_CTL_EN_UP ? "En" : "--",
1402            r & STATS_CTL_EN_DN ? "En" : "--");
1403 
1404     for (level = 0; level < 4; level++) {
1405         u16 off;
1406 
1407         off = THERMCTL_LVL0_UP_STATS;
1408         r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
1409         seq_printf(s, "  Level_%d Up(%d) ", level, r);
1410 
1411         off = THERMCTL_LVL0_DN_STATS;
1412         r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
1413         seq_printf(s, "Dn(%d)\n", r);
1414     }
1415 
1416     r = readl(ts->regs + THERMCTL_THERMTRIP_CTL);
1417     state = REG_GET_MASK(r, ttgs[0]->thermtrip_any_en_mask);
1418     seq_printf(s, "Thermtrip Any En(%d)\n", state);
1419     for (i = 0; i < ts->soc->num_ttgs; i++) {
1420         state = REG_GET_MASK(r, ttgs[i]->thermtrip_enable_mask);
1421         seq_printf(s, "     %s En(%d) ", ttgs[i]->name, state);
1422         state = REG_GET_MASK(r, ttgs[i]->thermtrip_threshold_mask);
1423         state *= ts->soc->thresh_grain;
1424         seq_printf(s, "Thresh(%d)\n", state);
1425     }
1426 
1427     r = readl(ts->regs + THROT_GLOBAL_CFG);
1428     seq_puts(s, "\n");
1429     seq_printf(s, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r);
1430 
1431     seq_puts(s, "---------------------------------------------------\n");
1432     r = readl(ts->regs + THROT_STATUS);
1433     state = REG_GET_MASK(r, THROT_STATUS_BREACH_MASK);
1434     seq_printf(s, "THROT STATUS: breach(%d) ", state);
1435     state = REG_GET_MASK(r, THROT_STATUS_STATE_MASK);
1436     seq_printf(s, "state(%d) ", state);
1437     state = REG_GET_MASK(r, THROT_STATUS_ENABLED_MASK);
1438     seq_printf(s, "enabled(%d)\n", state);
1439 
1440     r = readl(ts->regs + CPU_PSKIP_STATUS);
1441     if (ts->soc->use_ccroc) {
1442         state = REG_GET_MASK(r, XPU_PSKIP_STATUS_ENABLED_MASK);
1443         seq_printf(s, "CPU PSKIP STATUS: enabled(%d)\n", state);
1444     } else {
1445         state = REG_GET_MASK(r, XPU_PSKIP_STATUS_M_MASK);
1446         seq_printf(s, "CPU PSKIP STATUS: M(%d) ", state);
1447         state = REG_GET_MASK(r, XPU_PSKIP_STATUS_N_MASK);
1448         seq_printf(s, "N(%d) ", state);
1449         state = REG_GET_MASK(r, XPU_PSKIP_STATUS_ENABLED_MASK);
1450         seq_printf(s, "enabled(%d)\n", state);
1451     }
1452 
1453     return 0;
1454 }
1455 
1456 DEFINE_SHOW_ATTRIBUTE(regs);
1457 
1458 static void soctherm_debug_init(struct platform_device *pdev)
1459 {
1460     struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
1461     struct dentry *root;
1462 
1463     root = debugfs_create_dir("soctherm", NULL);
1464 
1465     tegra->debugfs_dir = root;
1466 
1467     debugfs_create_file("reg_contents", 0644, root, pdev, &regs_fops);
1468 }
1469 #else
1470 static inline void soctherm_debug_init(struct platform_device *pdev) {}
1471 #endif
1472 
1473 static int soctherm_clk_enable(struct platform_device *pdev, bool enable)
1474 {
1475     struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
1476     int err;
1477 
1478     if (!tegra->clock_soctherm || !tegra->clock_tsensor)
1479         return -EINVAL;
1480 
1481     reset_control_assert(tegra->reset);
1482 
1483     if (enable) {
1484         err = clk_prepare_enable(tegra->clock_soctherm);
1485         if (err) {
1486             reset_control_deassert(tegra->reset);
1487             return err;
1488         }
1489 
1490         err = clk_prepare_enable(tegra->clock_tsensor);
1491         if (err) {
1492             clk_disable_unprepare(tegra->clock_soctherm);
1493             reset_control_deassert(tegra->reset);
1494             return err;
1495         }
1496     } else {
1497         clk_disable_unprepare(tegra->clock_tsensor);
1498         clk_disable_unprepare(tegra->clock_soctherm);
1499     }
1500 
1501     reset_control_deassert(tegra->reset);
1502 
1503     return 0;
1504 }
1505 
1506 static int throt_get_cdev_max_state(struct thermal_cooling_device *cdev,
1507                     unsigned long *max_state)
1508 {
1509     *max_state = 1;
1510     return 0;
1511 }
1512 
1513 static int throt_get_cdev_cur_state(struct thermal_cooling_device *cdev,
1514                     unsigned long *cur_state)
1515 {
1516     struct tegra_soctherm *ts = cdev->devdata;
1517     u32 r;
1518 
1519     r = readl(ts->regs + THROT_STATUS);
1520     if (REG_GET_MASK(r, THROT_STATUS_STATE_MASK))
1521         *cur_state = 1;
1522     else
1523         *cur_state = 0;
1524 
1525     return 0;
1526 }
1527 
1528 static int throt_set_cdev_state(struct thermal_cooling_device *cdev,
1529                 unsigned long cur_state)
1530 {
1531     return 0;
1532 }
1533 
1534 static const struct thermal_cooling_device_ops throt_cooling_ops = {
1535     .get_max_state = throt_get_cdev_max_state,
1536     .get_cur_state = throt_get_cdev_cur_state,
1537     .set_cur_state = throt_set_cdev_state,
1538 };
1539 
1540 static int soctherm_thermtrips_parse(struct platform_device *pdev)
1541 {
1542     struct device *dev = &pdev->dev;
1543     struct tegra_soctherm *ts = dev_get_drvdata(dev);
1544     struct tsensor_group_thermtrips *tt = ts->soc->thermtrips;
1545     const int max_num_prop = ts->soc->num_ttgs * 2;
1546     u32 *tlb;
1547     int i, j, n, ret;
1548 
1549     if (!tt)
1550         return -ENOMEM;
1551 
1552     n = of_property_count_u32_elems(dev->of_node, "nvidia,thermtrips");
1553     if (n <= 0) {
1554         dev_info(dev,
1555              "missing thermtrips, will use critical trips as shut down temp\n");
1556         return n;
1557     }
1558 
1559     n = min(max_num_prop, n);
1560 
1561     tlb = devm_kcalloc(&pdev->dev, max_num_prop, sizeof(u32), GFP_KERNEL);
1562     if (!tlb)
1563         return -ENOMEM;
1564     ret = of_property_read_u32_array(dev->of_node, "nvidia,thermtrips",
1565                      tlb, n);
1566     if (ret) {
1567         dev_err(dev, "invalid num ele: thermtrips:%d\n", ret);
1568         return ret;
1569     }
1570 
1571     i = 0;
1572     for (j = 0; j < n; j = j + 2) {
1573         if (tlb[j] >= TEGRA124_SOCTHERM_SENSOR_NUM)
1574             continue;
1575 
1576         tt[i].id = tlb[j];
1577         tt[i].temp = tlb[j + 1];
1578         i++;
1579     }
1580 
1581     return 0;
1582 }
1583 
1584 static void soctherm_oc_cfg_parse(struct device *dev,
1585                 struct device_node *np_oc,
1586                 struct soctherm_throt_cfg *stc)
1587 {
1588     u32 val;
1589 
1590     if (of_property_read_bool(np_oc, "nvidia,polarity-active-low"))
1591         stc->oc_cfg.active_low = 1;
1592     else
1593         stc->oc_cfg.active_low = 0;
1594 
1595     if (!of_property_read_u32(np_oc, "nvidia,count-threshold", &val)) {
1596         stc->oc_cfg.intr_en = 1;
1597         stc->oc_cfg.alarm_cnt_thresh = val;
1598     }
1599 
1600     if (!of_property_read_u32(np_oc, "nvidia,throttle-period-us", &val))
1601         stc->oc_cfg.throt_period = val;
1602 
1603     if (!of_property_read_u32(np_oc, "nvidia,alarm-filter", &val))
1604         stc->oc_cfg.alarm_filter = val;
1605 
1606     /* BRIEF throttling by default, do not support STICKY */
1607     stc->oc_cfg.mode = OC_THROTTLE_MODE_BRIEF;
1608 }
1609 
1610 static int soctherm_throt_cfg_parse(struct device *dev,
1611                     struct device_node *np,
1612                     struct soctherm_throt_cfg *stc)
1613 {
1614     struct tegra_soctherm *ts = dev_get_drvdata(dev);
1615     int ret;
1616     u32 val;
1617 
1618     ret = of_property_read_u32(np, "nvidia,priority", &val);
1619     if (ret) {
1620         dev_err(dev, "throttle-cfg: %s: invalid priority\n", stc->name);
1621         return -EINVAL;
1622     }
1623     stc->priority = val;
1624 
1625     ret = of_property_read_u32(np, ts->soc->use_ccroc ?
1626                    "nvidia,cpu-throt-level" :
1627                    "nvidia,cpu-throt-percent", &val);
1628     if (!ret) {
1629         if (ts->soc->use_ccroc &&
1630             val <= TEGRA_SOCTHERM_THROT_LEVEL_HIGH)
1631             stc->cpu_throt_level = val;
1632         else if (!ts->soc->use_ccroc && val <= 100)
1633             stc->cpu_throt_depth = val;
1634         else
1635             goto err;
1636     } else {
1637         goto err;
1638     }
1639 
1640     ret = of_property_read_u32(np, "nvidia,gpu-throt-level", &val);
1641     if (!ret && val <= TEGRA_SOCTHERM_THROT_LEVEL_HIGH)
1642         stc->gpu_throt_level = val;
1643     else
1644         goto err;
1645 
1646     return 0;
1647 
1648 err:
1649     dev_err(dev, "throttle-cfg: %s: no throt prop or invalid prop\n",
1650         stc->name);
1651     return -EINVAL;
1652 }
1653 
1654 /**
1655  * soctherm_init_hw_throt_cdev() - Parse the HW throttle configurations
1656  * and register them as cooling devices.
1657  * @pdev: Pointer to platform_device struct
1658  */
1659 static void soctherm_init_hw_throt_cdev(struct platform_device *pdev)
1660 {
1661     struct device *dev = &pdev->dev;
1662     struct tegra_soctherm *ts = dev_get_drvdata(dev);
1663     struct device_node *np_stc, *np_stcc;
1664     const char *name;
1665     int i;
1666 
1667     for (i = 0; i < THROTTLE_SIZE; i++) {
1668         ts->throt_cfgs[i].name = throt_names[i];
1669         ts->throt_cfgs[i].id = i;
1670         ts->throt_cfgs[i].init = false;
1671     }
1672 
1673     np_stc = of_get_child_by_name(dev->of_node, "throttle-cfgs");
1674     if (!np_stc) {
1675         dev_info(dev,
1676              "throttle-cfg: no throttle-cfgs - not enabling\n");
1677         return;
1678     }
1679 
1680     for_each_child_of_node(np_stc, np_stcc) {
1681         struct soctherm_throt_cfg *stc;
1682         struct thermal_cooling_device *tcd;
1683         int err;
1684 
1685         name = np_stcc->name;
1686         stc = find_throttle_cfg_by_name(ts, name);
1687         if (!stc) {
1688             dev_err(dev,
1689                 "throttle-cfg: could not find %s\n", name);
1690             continue;
1691         }
1692 
1693         if (stc->init) {
1694             dev_err(dev, "throttle-cfg: %s: redefined!\n", name);
1695             of_node_put(np_stcc);
1696             break;
1697         }
1698 
1699         err = soctherm_throt_cfg_parse(dev, np_stcc, stc);
1700         if (err)
1701             continue;
1702 
1703         if (stc->id >= THROTTLE_OC1) {
1704             soctherm_oc_cfg_parse(dev, np_stcc, stc);
1705             stc->init = true;
1706         } else {
1707 
1708             tcd = thermal_of_cooling_device_register(np_stcc,
1709                              (char *)name, ts,
1710                              &throt_cooling_ops);
1711             if (IS_ERR_OR_NULL(tcd)) {
1712                 dev_err(dev,
1713                     "throttle-cfg: %s: failed to register cooling device\n",
1714                     name);
1715                 continue;
1716             }
1717             stc->cdev = tcd;
1718             stc->init = true;
1719         }
1720 
1721     }
1722 
1723     of_node_put(np_stc);
1724 }
1725 
1726 /**
1727  * throttlectl_cpu_level_cfg() - programs CCROC NV_THERM level config
1728  * @ts: pointer to a struct tegra_soctherm
1729  * @level: describing the level LOW/MED/HIGH of throttling
1730  *
1731  * It's necessary to set up the CPU-local CCROC NV_THERM instance with
1732  * the M/N values desired for each level. This function does this.
1733  *
1734  * This function pre-programs the CCROC NV_THERM levels in terms of
1735  * pre-configured "Low", "Medium" or "Heavy" throttle levels which are
1736  * mapped to THROT_LEVEL_LOW, THROT_LEVEL_MED and THROT_LEVEL_HVY.
1737  */
1738 static void throttlectl_cpu_level_cfg(struct tegra_soctherm *ts, int level)
1739 {
1740     u8 depth, dividend;
1741     u32 r;
1742 
1743     switch (level) {
1744     case TEGRA_SOCTHERM_THROT_LEVEL_LOW:
1745         depth = 50;
1746         break;
1747     case TEGRA_SOCTHERM_THROT_LEVEL_MED:
1748         depth = 75;
1749         break;
1750     case TEGRA_SOCTHERM_THROT_LEVEL_HIGH:
1751         depth = 80;
1752         break;
1753     case TEGRA_SOCTHERM_THROT_LEVEL_NONE:
1754         return;
1755     default:
1756         return;
1757     }
1758 
1759     dividend = THROT_DEPTH_DIVIDEND(depth);
1760 
1761     /* setup PSKIP in ccroc nv_therm registers */
1762     r = ccroc_readl(ts, CCROC_THROT_PSKIP_RAMP_CPU_REG(level));
1763     r = REG_SET_MASK(r, CCROC_THROT_PSKIP_RAMP_DURATION_MASK, 0xff);
1764     r = REG_SET_MASK(r, CCROC_THROT_PSKIP_RAMP_STEP_MASK, 0xf);
1765     ccroc_writel(ts, r, CCROC_THROT_PSKIP_RAMP_CPU_REG(level));
1766 
1767     r = ccroc_readl(ts, CCROC_THROT_PSKIP_CTRL_CPU_REG(level));
1768     r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_ENB_MASK, 1);
1769     r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK, dividend);
1770     r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK, 0xff);
1771     ccroc_writel(ts, r, CCROC_THROT_PSKIP_CTRL_CPU_REG(level));
1772 }
1773 
1774 /**
1775  * throttlectl_cpu_level_select() - program CPU pulse skipper config
1776  * @ts: pointer to a struct tegra_soctherm
1777  * @throt: the LIGHT/HEAVY of throttle event id
1778  *
1779  * Pulse skippers are used to throttle clock frequencies.  This
1780  * function programs the pulse skippers based on @throt and platform
1781  * data.  This function is used on SoCs which have CPU-local pulse
1782  * skipper control, such as T13x. It programs soctherm's interface to
1783  * Denver:CCROC NV_THERM in terms of Low, Medium and HIGH throttling
1784  * vectors. PSKIP_BYPASS mode is set as required per HW spec.
1785  */
1786 static void throttlectl_cpu_level_select(struct tegra_soctherm *ts,
1787                      enum soctherm_throttle_id throt)
1788 {
1789     u32 r, throt_vect;
1790 
1791     /* Denver:CCROC NV_THERM interface N:3 Mapping */
1792     switch (ts->throt_cfgs[throt].cpu_throt_level) {
1793     case TEGRA_SOCTHERM_THROT_LEVEL_LOW:
1794         throt_vect = THROT_VECT_LOW;
1795         break;
1796     case TEGRA_SOCTHERM_THROT_LEVEL_MED:
1797         throt_vect = THROT_VECT_MED;
1798         break;
1799     case TEGRA_SOCTHERM_THROT_LEVEL_HIGH:
1800         throt_vect = THROT_VECT_HIGH;
1801         break;
1802     default:
1803         throt_vect = THROT_VECT_NONE;
1804         break;
1805     }
1806 
1807     r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
1808     r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
1809     r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT_CPU_MASK, throt_vect);
1810     r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT2_CPU_MASK, throt_vect);
1811     writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
1812 
1813     /* bypass sequencer in soc_therm as it is programmed in ccroc */
1814     r = REG_SET_MASK(0, THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK, 1);
1815     writel(r, ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
1816 }
1817 
1818 /**
1819  * throttlectl_cpu_mn() - program CPU pulse skipper configuration
1820  * @ts: pointer to a struct tegra_soctherm
1821  * @throt: the LIGHT/HEAVY of throttle event id
1822  *
1823  * Pulse skippers are used to throttle clock frequencies.  This
1824  * function programs the pulse skippers based on @throt and platform
1825  * data.  This function is used for CPUs that have "remote" pulse
1826  * skipper control, e.g., the CPU pulse skipper is controlled by the
1827  * SOC_THERM IP block.  (SOC_THERM is located outside the CPU
1828  * complex.)
1829  */
1830 static void throttlectl_cpu_mn(struct tegra_soctherm *ts,
1831                    enum soctherm_throttle_id throt)
1832 {
1833     u32 r;
1834     int depth;
1835     u8 dividend;
1836 
1837     depth = ts->throt_cfgs[throt].cpu_throt_depth;
1838     dividend = THROT_DEPTH_DIVIDEND(depth);
1839 
1840     r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
1841     r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
1842     r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVIDEND_MASK, dividend);
1843     r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVISOR_MASK, 0xff);
1844     writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
1845 
1846     r = readl(ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
1847     r = REG_SET_MASK(r, THROT_PSKIP_RAMP_DURATION_MASK, 0xff);
1848     r = REG_SET_MASK(r, THROT_PSKIP_RAMP_STEP_MASK, 0xf);
1849     writel(r, ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
1850 }
1851 
1852 /**
1853  * throttlectl_gpu_level_select() - selects throttling level for GPU
1854  * @ts: pointer to a struct tegra_soctherm
1855  * @throt: the LIGHT/HEAVY of throttle event id
1856  *
1857  * This function programs soctherm's interface to GK20a NV_THERM to select
1858  * pre-configured "Low", "Medium" or "Heavy" throttle levels.
1859  *
1860  * Return: boolean true if HW was programmed
1861  */
1862 static void throttlectl_gpu_level_select(struct tegra_soctherm *ts,
1863                      enum soctherm_throttle_id throt)
1864 {
1865     u32 r, level, throt_vect;
1866 
1867     level = ts->throt_cfgs[throt].gpu_throt_level;
1868     throt_vect = THROT_LEVEL_TO_DEPTH(level);
1869     r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
1870     r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
1871     r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT_GPU_MASK, throt_vect);
1872     writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
1873 }
1874 
1875 static int soctherm_oc_cfg_program(struct tegra_soctherm *ts,
1876                       enum soctherm_throttle_id throt)
1877 {
1878     u32 r;
1879     struct soctherm_oc_cfg *oc = &ts->throt_cfgs[throt].oc_cfg;
1880 
1881     if (oc->mode == OC_THROTTLE_MODE_DISABLED)
1882         return -EINVAL;
1883 
1884     r = REG_SET_MASK(0, OC1_CFG_HW_RESTORE_MASK, 1);
1885     r = REG_SET_MASK(r, OC1_CFG_THROTTLE_MODE_MASK, oc->mode);
1886     r = REG_SET_MASK(r, OC1_CFG_ALARM_POLARITY_MASK, oc->active_low);
1887     r = REG_SET_MASK(r, OC1_CFG_EN_THROTTLE_MASK, 1);
1888     writel(r, ts->regs + ALARM_CFG(throt));
1889     writel(oc->throt_period, ts->regs + ALARM_THROTTLE_PERIOD(throt));
1890     writel(oc->alarm_cnt_thresh, ts->regs + ALARM_CNT_THRESHOLD(throt));
1891     writel(oc->alarm_filter, ts->regs + ALARM_FILTER(throt));
1892     soctherm_oc_intr_enable(ts, throt, oc->intr_en);
1893 
1894     return 0;
1895 }
1896 
1897 /**
1898  * soctherm_throttle_program() - programs pulse skippers' configuration
1899  * @ts: pointer to a struct tegra_soctherm
1900  * @throt: the LIGHT/HEAVY of the throttle event id.
1901  *
1902  * Pulse skippers are used to throttle clock frequencies.
1903  * This function programs the pulse skippers.
1904  */
1905 static void soctherm_throttle_program(struct tegra_soctherm *ts,
1906                       enum soctherm_throttle_id throt)
1907 {
1908     u32 r;
1909     struct soctherm_throt_cfg stc = ts->throt_cfgs[throt];
1910 
1911     if (!stc.init)
1912         return;
1913 
1914     if ((throt >= THROTTLE_OC1) && (soctherm_oc_cfg_program(ts, throt)))
1915         return;
1916 
1917     /* Setup PSKIP parameters */
1918     if (ts->soc->use_ccroc)
1919         throttlectl_cpu_level_select(ts, throt);
1920     else
1921         throttlectl_cpu_mn(ts, throt);
1922 
1923     throttlectl_gpu_level_select(ts, throt);
1924 
1925     r = REG_SET_MASK(0, THROT_PRIORITY_LITE_PRIO_MASK, stc.priority);
1926     writel(r, ts->regs + THROT_PRIORITY_CTRL(throt));
1927 
1928     r = REG_SET_MASK(0, THROT_DELAY_LITE_DELAY_MASK, 0);
1929     writel(r, ts->regs + THROT_DELAY_CTRL(throt));
1930 
1931     r = readl(ts->regs + THROT_PRIORITY_LOCK);
1932     r = REG_GET_MASK(r, THROT_PRIORITY_LOCK_PRIORITY_MASK);
1933     if (r >= stc.priority)
1934         return;
1935     r = REG_SET_MASK(0, THROT_PRIORITY_LOCK_PRIORITY_MASK,
1936              stc.priority);
1937     writel(r, ts->regs + THROT_PRIORITY_LOCK);
1938 }
1939 
1940 static void tegra_soctherm_throttle(struct device *dev)
1941 {
1942     struct tegra_soctherm *ts = dev_get_drvdata(dev);
1943     u32 v;
1944     int i;
1945 
1946     /* configure LOW, MED and HIGH levels for CCROC NV_THERM */
1947     if (ts->soc->use_ccroc) {
1948         throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_LOW);
1949         throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_MED);
1950         throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_HIGH);
1951     }
1952 
1953     /* Thermal HW throttle programming */
1954     for (i = 0; i < THROTTLE_SIZE; i++)
1955         soctherm_throttle_program(ts, i);
1956 
1957     v = REG_SET_MASK(0, THROT_GLOBAL_ENB_MASK, 1);
1958     if (ts->soc->use_ccroc) {
1959         ccroc_writel(ts, v, CCROC_GLOBAL_CFG);
1960 
1961         v = ccroc_readl(ts, CCROC_SUPER_CCLKG_DIVIDER);
1962         v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
1963         ccroc_writel(ts, v, CCROC_SUPER_CCLKG_DIVIDER);
1964     } else {
1965         writel(v, ts->regs + THROT_GLOBAL_CFG);
1966 
1967         v = readl(ts->clk_regs + CAR_SUPER_CCLKG_DIVIDER);
1968         v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
1969         writel(v, ts->clk_regs + CAR_SUPER_CCLKG_DIVIDER);
1970     }
1971 
1972     /* initialize stats collection */
1973     v = STATS_CTL_CLR_DN | STATS_CTL_EN_DN |
1974         STATS_CTL_CLR_UP | STATS_CTL_EN_UP;
1975     writel(v, ts->regs + THERMCTL_STATS_CTL);
1976 }
1977 
1978 static int soctherm_interrupts_init(struct platform_device *pdev,
1979                     struct tegra_soctherm *tegra)
1980 {
1981     struct device_node *np = pdev->dev.of_node;
1982     int ret;
1983 
1984     ret = soctherm_oc_int_init(np, TEGRA_SOC_OC_IRQ_MAX);
1985     if (ret < 0) {
1986         dev_err(&pdev->dev, "soctherm_oc_int_init failed\n");
1987         return ret;
1988     }
1989 
1990     tegra->thermal_irq = platform_get_irq(pdev, 0);
1991     if (tegra->thermal_irq < 0) {
1992         dev_dbg(&pdev->dev, "get 'thermal_irq' failed.\n");
1993         return 0;
1994     }
1995 
1996     tegra->edp_irq = platform_get_irq(pdev, 1);
1997     if (tegra->edp_irq < 0) {
1998         dev_dbg(&pdev->dev, "get 'edp_irq' failed.\n");
1999         return 0;
2000     }
2001 
2002     ret = devm_request_threaded_irq(&pdev->dev,
2003                     tegra->thermal_irq,
2004                     soctherm_thermal_isr,
2005                     soctherm_thermal_isr_thread,
2006                     IRQF_ONESHOT,
2007                     dev_name(&pdev->dev),
2008                     tegra);
2009     if (ret < 0) {
2010         dev_err(&pdev->dev, "request_irq 'thermal_irq' failed.\n");
2011         return ret;
2012     }
2013 
2014     ret = devm_request_threaded_irq(&pdev->dev,
2015                     tegra->edp_irq,
2016                     soctherm_edp_isr,
2017                     soctherm_edp_isr_thread,
2018                     IRQF_ONESHOT,
2019                     "soctherm_edp",
2020                     tegra);
2021     if (ret < 0) {
2022         dev_err(&pdev->dev, "request_irq 'edp_irq' failed.\n");
2023         return ret;
2024     }
2025 
2026     return 0;
2027 }
2028 
2029 static void soctherm_init(struct platform_device *pdev)
2030 {
2031     struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
2032     const struct tegra_tsensor_group **ttgs = tegra->soc->ttgs;
2033     int i;
2034     u32 pdiv, hotspot;
2035 
2036     /* Initialize raw sensors */
2037     for (i = 0; i < tegra->soc->num_tsensors; ++i)
2038         enable_tsensor(tegra, i);
2039 
2040     /* program pdiv and hotspot offsets per THERM */
2041     pdiv = readl(tegra->regs + SENSOR_PDIV);
2042     hotspot = readl(tegra->regs + SENSOR_HOTSPOT_OFF);
2043     for (i = 0; i < tegra->soc->num_ttgs; ++i) {
2044         pdiv = REG_SET_MASK(pdiv, ttgs[i]->pdiv_mask,
2045                     ttgs[i]->pdiv);
2046         /* hotspot offset from PLLX, doesn't need to configure PLLX */
2047         if (ttgs[i]->id == TEGRA124_SOCTHERM_SENSOR_PLLX)
2048             continue;
2049         hotspot =  REG_SET_MASK(hotspot,
2050                     ttgs[i]->pllx_hotspot_mask,
2051                     ttgs[i]->pllx_hotspot_diff);
2052     }
2053     writel(pdiv, tegra->regs + SENSOR_PDIV);
2054     writel(hotspot, tegra->regs + SENSOR_HOTSPOT_OFF);
2055 
2056     /* Configure hw throttle */
2057     tegra_soctherm_throttle(&pdev->dev);
2058 }
2059 
2060 static const struct of_device_id tegra_soctherm_of_match[] = {
2061 #ifdef CONFIG_ARCH_TEGRA_124_SOC
2062     {
2063         .compatible = "nvidia,tegra124-soctherm",
2064         .data = &tegra124_soctherm,
2065     },
2066 #endif
2067 #ifdef CONFIG_ARCH_TEGRA_132_SOC
2068     {
2069         .compatible = "nvidia,tegra132-soctherm",
2070         .data = &tegra132_soctherm,
2071     },
2072 #endif
2073 #ifdef CONFIG_ARCH_TEGRA_210_SOC
2074     {
2075         .compatible = "nvidia,tegra210-soctherm",
2076         .data = &tegra210_soctherm,
2077     },
2078 #endif
2079     { },
2080 };
2081 MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match);
2082 
2083 static int tegra_soctherm_probe(struct platform_device *pdev)
2084 {
2085     const struct of_device_id *match;
2086     struct tegra_soctherm *tegra;
2087     struct thermal_zone_device *z;
2088     struct tsensor_shared_calib shared_calib;
2089     struct tegra_soctherm_soc *soc;
2090     unsigned int i;
2091     int err;
2092 
2093     match = of_match_node(tegra_soctherm_of_match, pdev->dev.of_node);
2094     if (!match)
2095         return -ENODEV;
2096 
2097     soc = (struct tegra_soctherm_soc *)match->data;
2098     if (soc->num_ttgs > TEGRA124_SOCTHERM_SENSOR_NUM)
2099         return -EINVAL;
2100 
2101     tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
2102     if (!tegra)
2103         return -ENOMEM;
2104 
2105     mutex_init(&tegra->thermctl_lock);
2106     dev_set_drvdata(&pdev->dev, tegra);
2107 
2108     tegra->soc = soc;
2109 
2110     tegra->regs = devm_platform_ioremap_resource_byname(pdev, "soctherm-reg");
2111     if (IS_ERR(tegra->regs)) {
2112         dev_err(&pdev->dev, "can't get soctherm registers");
2113         return PTR_ERR(tegra->regs);
2114     }
2115 
2116     if (!tegra->soc->use_ccroc) {
2117         tegra->clk_regs = devm_platform_ioremap_resource_byname(pdev, "car-reg");
2118         if (IS_ERR(tegra->clk_regs)) {
2119             dev_err(&pdev->dev, "can't get car clk registers");
2120             return PTR_ERR(tegra->clk_regs);
2121         }
2122     } else {
2123         tegra->ccroc_regs = devm_platform_ioremap_resource_byname(pdev, "ccroc-reg");
2124         if (IS_ERR(tegra->ccroc_regs)) {
2125             dev_err(&pdev->dev, "can't get ccroc registers");
2126             return PTR_ERR(tegra->ccroc_regs);
2127         }
2128     }
2129 
2130     tegra->reset = devm_reset_control_get(&pdev->dev, "soctherm");
2131     if (IS_ERR(tegra->reset)) {
2132         dev_err(&pdev->dev, "can't get soctherm reset\n");
2133         return PTR_ERR(tegra->reset);
2134     }
2135 
2136     tegra->clock_tsensor = devm_clk_get(&pdev->dev, "tsensor");
2137     if (IS_ERR(tegra->clock_tsensor)) {
2138         dev_err(&pdev->dev, "can't get tsensor clock\n");
2139         return PTR_ERR(tegra->clock_tsensor);
2140     }
2141 
2142     tegra->clock_soctherm = devm_clk_get(&pdev->dev, "soctherm");
2143     if (IS_ERR(tegra->clock_soctherm)) {
2144         dev_err(&pdev->dev, "can't get soctherm clock\n");
2145         return PTR_ERR(tegra->clock_soctherm);
2146     }
2147 
2148     tegra->calib = devm_kcalloc(&pdev->dev,
2149                     soc->num_tsensors, sizeof(u32),
2150                     GFP_KERNEL);
2151     if (!tegra->calib)
2152         return -ENOMEM;
2153 
2154     /* calculate shared calibration data */
2155     err = tegra_calc_shared_calib(soc->tfuse, &shared_calib);
2156     if (err)
2157         return err;
2158 
2159     /* calculate tsensor calibration data */
2160     for (i = 0; i < soc->num_tsensors; ++i) {
2161         err = tegra_calc_tsensor_calib(&soc->tsensors[i],
2162                            &shared_calib,
2163                            &tegra->calib[i]);
2164         if (err)
2165             return err;
2166     }
2167 
2168     tegra->thermctl_tzs = devm_kcalloc(&pdev->dev,
2169                        soc->num_ttgs, sizeof(z),
2170                        GFP_KERNEL);
2171     if (!tegra->thermctl_tzs)
2172         return -ENOMEM;
2173 
2174     err = soctherm_clk_enable(pdev, true);
2175     if (err)
2176         return err;
2177 
2178     soctherm_thermtrips_parse(pdev);
2179 
2180     soctherm_init_hw_throt_cdev(pdev);
2181 
2182     soctherm_init(pdev);
2183 
2184     for (i = 0; i < soc->num_ttgs; ++i) {
2185         struct tegra_thermctl_zone *zone =
2186             devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL);
2187         if (!zone) {
2188             err = -ENOMEM;
2189             goto disable_clocks;
2190         }
2191 
2192         zone->reg = tegra->regs + soc->ttgs[i]->sensor_temp_offset;
2193         zone->dev = &pdev->dev;
2194         zone->sg = soc->ttgs[i];
2195         zone->ts = tegra;
2196 
2197         z = devm_thermal_zone_of_sensor_register(&pdev->dev,
2198                              soc->ttgs[i]->id, zone,
2199                              &tegra_of_thermal_ops);
2200         if (IS_ERR(z)) {
2201             err = PTR_ERR(z);
2202             dev_err(&pdev->dev, "failed to register sensor: %d\n",
2203                 err);
2204             goto disable_clocks;
2205         }
2206 
2207         zone->tz = z;
2208         tegra->thermctl_tzs[soc->ttgs[i]->id] = z;
2209 
2210         /* Configure hw trip points */
2211         err = tegra_soctherm_set_hwtrips(&pdev->dev, soc->ttgs[i], z);
2212         if (err)
2213             goto disable_clocks;
2214     }
2215 
2216     err = soctherm_interrupts_init(pdev, tegra);
2217 
2218     soctherm_debug_init(pdev);
2219 
2220     return 0;
2221 
2222 disable_clocks:
2223     soctherm_clk_enable(pdev, false);
2224 
2225     return err;
2226 }
2227 
2228 static int tegra_soctherm_remove(struct platform_device *pdev)
2229 {
2230     struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
2231 
2232     debugfs_remove_recursive(tegra->debugfs_dir);
2233 
2234     soctherm_clk_enable(pdev, false);
2235 
2236     return 0;
2237 }
2238 
2239 static int __maybe_unused soctherm_suspend(struct device *dev)
2240 {
2241     struct platform_device *pdev = to_platform_device(dev);
2242 
2243     soctherm_clk_enable(pdev, false);
2244 
2245     return 0;
2246 }
2247 
2248 static int __maybe_unused soctherm_resume(struct device *dev)
2249 {
2250     struct platform_device *pdev = to_platform_device(dev);
2251     struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
2252     struct tegra_soctherm_soc *soc = tegra->soc;
2253     int err, i;
2254 
2255     err = soctherm_clk_enable(pdev, true);
2256     if (err) {
2257         dev_err(&pdev->dev,
2258             "Resume failed: enable clocks failed\n");
2259         return err;
2260     }
2261 
2262     soctherm_init(pdev);
2263 
2264     for (i = 0; i < soc->num_ttgs; ++i) {
2265         struct thermal_zone_device *tz;
2266 
2267         tz = tegra->thermctl_tzs[soc->ttgs[i]->id];
2268         err = tegra_soctherm_set_hwtrips(dev, soc->ttgs[i], tz);
2269         if (err) {
2270             dev_err(&pdev->dev,
2271                 "Resume failed: set hwtrips failed\n");
2272             return err;
2273         }
2274     }
2275 
2276     return 0;
2277 }
2278 
2279 static SIMPLE_DEV_PM_OPS(tegra_soctherm_pm, soctherm_suspend, soctherm_resume);
2280 
2281 static struct platform_driver tegra_soctherm_driver = {
2282     .probe = tegra_soctherm_probe,
2283     .remove = tegra_soctherm_remove,
2284     .driver = {
2285         .name = "tegra_soctherm",
2286         .pm = &tegra_soctherm_pm,
2287         .of_match_table = tegra_soctherm_of_match,
2288     },
2289 };
2290 module_platform_driver(tegra_soctherm_driver);
2291 
2292 MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
2293 MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver");
2294 MODULE_LICENSE("GPL v2");