cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

imx_thermal.c (25333B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// Copyright 2013 Freescale Semiconductor, Inc.
      4
      5#include <linux/clk.h>
      6#include <linux/cpufreq.h>
      7#include <linux/cpu_cooling.h>
      8#include <linux/delay.h>
      9#include <linux/interrupt.h>
     10#include <linux/io.h>
     11#include <linux/mfd/syscon.h>
     12#include <linux/module.h>
     13#include <linux/of.h>
     14#include <linux/of_device.h>
     15#include <linux/regmap.h>
     16#include <linux/thermal.h>
     17#include <linux/nvmem-consumer.h>
     18#include <linux/pm_runtime.h>
     19
     20#define REG_SET		0x4
     21#define REG_CLR		0x8
     22#define REG_TOG		0xc
     23
     24/* i.MX6 specific */
     25#define IMX6_MISC0				0x0150
     26#define IMX6_MISC0_REFTOP_SELBIASOFF		(1 << 3)
     27#define IMX6_MISC1				0x0160
     28#define IMX6_MISC1_IRQ_TEMPHIGH			(1 << 29)
     29/* Below LOW and PANIC bits are only for TEMPMON_IMX6SX */
     30#define IMX6_MISC1_IRQ_TEMPLOW			(1 << 28)
     31#define IMX6_MISC1_IRQ_TEMPPANIC		(1 << 27)
     32
     33#define IMX6_TEMPSENSE0				0x0180
     34#define IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT	20
     35#define IMX6_TEMPSENSE0_ALARM_VALUE_MASK	(0xfff << 20)
     36#define IMX6_TEMPSENSE0_TEMP_CNT_SHIFT		8
     37#define IMX6_TEMPSENSE0_TEMP_CNT_MASK		(0xfff << 8)
     38#define IMX6_TEMPSENSE0_FINISHED		(1 << 2)
     39#define IMX6_TEMPSENSE0_MEASURE_TEMP		(1 << 1)
     40#define IMX6_TEMPSENSE0_POWER_DOWN		(1 << 0)
     41
     42#define IMX6_TEMPSENSE1				0x0190
     43#define IMX6_TEMPSENSE1_MEASURE_FREQ		0xffff
     44#define IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT	0
     45
     46#define OCOTP_MEM0			0x0480
     47#define OCOTP_ANA1			0x04e0
     48
     49/* Below TEMPSENSE2 is only for TEMPMON_IMX6SX */
     50#define IMX6_TEMPSENSE2				0x0290
     51#define IMX6_TEMPSENSE2_LOW_VALUE_SHIFT		0
     52#define IMX6_TEMPSENSE2_LOW_VALUE_MASK		0xfff
     53#define IMX6_TEMPSENSE2_PANIC_VALUE_SHIFT	16
     54#define IMX6_TEMPSENSE2_PANIC_VALUE_MASK	0xfff0000
     55
     56/* i.MX7 specific */
     57#define IMX7_ANADIG_DIGPROG			0x800
     58#define IMX7_TEMPSENSE0				0x300
     59#define IMX7_TEMPSENSE0_PANIC_ALARM_SHIFT	18
     60#define IMX7_TEMPSENSE0_PANIC_ALARM_MASK	(0x1ff << 18)
     61#define IMX7_TEMPSENSE0_HIGH_ALARM_SHIFT	9
     62#define IMX7_TEMPSENSE0_HIGH_ALARM_MASK		(0x1ff << 9)
     63#define IMX7_TEMPSENSE0_LOW_ALARM_SHIFT		0
     64#define IMX7_TEMPSENSE0_LOW_ALARM_MASK		0x1ff
     65
     66#define IMX7_TEMPSENSE1				0x310
     67#define IMX7_TEMPSENSE1_MEASURE_FREQ_SHIFT	16
     68#define IMX7_TEMPSENSE1_MEASURE_FREQ_MASK	(0xffff << 16)
     69#define IMX7_TEMPSENSE1_FINISHED		(1 << 11)
     70#define IMX7_TEMPSENSE1_MEASURE_TEMP		(1 << 10)
     71#define IMX7_TEMPSENSE1_POWER_DOWN		(1 << 9)
     72#define IMX7_TEMPSENSE1_TEMP_VALUE_SHIFT	0
     73#define IMX7_TEMPSENSE1_TEMP_VALUE_MASK		0x1ff
     74
     75/* The driver supports 1 passive trip point and 1 critical trip point */
     76enum imx_thermal_trip {
     77	IMX_TRIP_PASSIVE,
     78	IMX_TRIP_CRITICAL,
     79	IMX_TRIP_NUM,
     80};
     81
     82#define IMX_POLLING_DELAY		2000 /* millisecond */
     83#define IMX_PASSIVE_DELAY		1000
     84
     85#define TEMPMON_IMX6Q			1
     86#define TEMPMON_IMX6SX			2
     87#define TEMPMON_IMX7D			3
     88
     89struct thermal_soc_data {
     90	u32 version;
     91
     92	u32 sensor_ctrl;
     93	u32 power_down_mask;
     94	u32 measure_temp_mask;
     95
     96	u32 measure_freq_ctrl;
     97	u32 measure_freq_mask;
     98	u32 measure_freq_shift;
     99
    100	u32 temp_data;
    101	u32 temp_value_mask;
    102	u32 temp_value_shift;
    103	u32 temp_valid_mask;
    104
    105	u32 panic_alarm_ctrl;
    106	u32 panic_alarm_mask;
    107	u32 panic_alarm_shift;
    108
    109	u32 high_alarm_ctrl;
    110	u32 high_alarm_mask;
    111	u32 high_alarm_shift;
    112
    113	u32 low_alarm_ctrl;
    114	u32 low_alarm_mask;
    115	u32 low_alarm_shift;
    116};
    117
    118static struct thermal_soc_data thermal_imx6q_data = {
    119	.version = TEMPMON_IMX6Q,
    120
    121	.sensor_ctrl = IMX6_TEMPSENSE0,
    122	.power_down_mask = IMX6_TEMPSENSE0_POWER_DOWN,
    123	.measure_temp_mask = IMX6_TEMPSENSE0_MEASURE_TEMP,
    124
    125	.measure_freq_ctrl = IMX6_TEMPSENSE1,
    126	.measure_freq_shift = IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT,
    127	.measure_freq_mask = IMX6_TEMPSENSE1_MEASURE_FREQ,
    128
    129	.temp_data = IMX6_TEMPSENSE0,
    130	.temp_value_mask = IMX6_TEMPSENSE0_TEMP_CNT_MASK,
    131	.temp_value_shift = IMX6_TEMPSENSE0_TEMP_CNT_SHIFT,
    132	.temp_valid_mask = IMX6_TEMPSENSE0_FINISHED,
    133
    134	.high_alarm_ctrl = IMX6_TEMPSENSE0,
    135	.high_alarm_mask = IMX6_TEMPSENSE0_ALARM_VALUE_MASK,
    136	.high_alarm_shift = IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT,
    137};
    138
    139static struct thermal_soc_data thermal_imx6sx_data = {
    140	.version = TEMPMON_IMX6SX,
    141
    142	.sensor_ctrl = IMX6_TEMPSENSE0,
    143	.power_down_mask = IMX6_TEMPSENSE0_POWER_DOWN,
    144	.measure_temp_mask = IMX6_TEMPSENSE0_MEASURE_TEMP,
    145
    146	.measure_freq_ctrl = IMX6_TEMPSENSE1,
    147	.measure_freq_shift = IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT,
    148	.measure_freq_mask = IMX6_TEMPSENSE1_MEASURE_FREQ,
    149
    150	.temp_data = IMX6_TEMPSENSE0,
    151	.temp_value_mask = IMX6_TEMPSENSE0_TEMP_CNT_MASK,
    152	.temp_value_shift = IMX6_TEMPSENSE0_TEMP_CNT_SHIFT,
    153	.temp_valid_mask = IMX6_TEMPSENSE0_FINISHED,
    154
    155	.high_alarm_ctrl = IMX6_TEMPSENSE0,
    156	.high_alarm_mask = IMX6_TEMPSENSE0_ALARM_VALUE_MASK,
    157	.high_alarm_shift = IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT,
    158
    159	.panic_alarm_ctrl = IMX6_TEMPSENSE2,
    160	.panic_alarm_mask = IMX6_TEMPSENSE2_PANIC_VALUE_MASK,
    161	.panic_alarm_shift = IMX6_TEMPSENSE2_PANIC_VALUE_SHIFT,
    162
    163	.low_alarm_ctrl = IMX6_TEMPSENSE2,
    164	.low_alarm_mask = IMX6_TEMPSENSE2_LOW_VALUE_MASK,
    165	.low_alarm_shift = IMX6_TEMPSENSE2_LOW_VALUE_SHIFT,
    166};
    167
    168static struct thermal_soc_data thermal_imx7d_data = {
    169	.version = TEMPMON_IMX7D,
    170
    171	.sensor_ctrl = IMX7_TEMPSENSE1,
    172	.power_down_mask = IMX7_TEMPSENSE1_POWER_DOWN,
    173	.measure_temp_mask = IMX7_TEMPSENSE1_MEASURE_TEMP,
    174
    175	.measure_freq_ctrl = IMX7_TEMPSENSE1,
    176	.measure_freq_shift = IMX7_TEMPSENSE1_MEASURE_FREQ_SHIFT,
    177	.measure_freq_mask = IMX7_TEMPSENSE1_MEASURE_FREQ_MASK,
    178
    179	.temp_data = IMX7_TEMPSENSE1,
    180	.temp_value_mask = IMX7_TEMPSENSE1_TEMP_VALUE_MASK,
    181	.temp_value_shift = IMX7_TEMPSENSE1_TEMP_VALUE_SHIFT,
    182	.temp_valid_mask = IMX7_TEMPSENSE1_FINISHED,
    183
    184	.panic_alarm_ctrl = IMX7_TEMPSENSE1,
    185	.panic_alarm_mask = IMX7_TEMPSENSE0_PANIC_ALARM_MASK,
    186	.panic_alarm_shift = IMX7_TEMPSENSE0_PANIC_ALARM_SHIFT,
    187
    188	.high_alarm_ctrl = IMX7_TEMPSENSE0,
    189	.high_alarm_mask = IMX7_TEMPSENSE0_HIGH_ALARM_MASK,
    190	.high_alarm_shift = IMX7_TEMPSENSE0_HIGH_ALARM_SHIFT,
    191
    192	.low_alarm_ctrl = IMX7_TEMPSENSE0,
    193	.low_alarm_mask = IMX7_TEMPSENSE0_LOW_ALARM_MASK,
    194	.low_alarm_shift = IMX7_TEMPSENSE0_LOW_ALARM_SHIFT,
    195};
    196
    197struct imx_thermal_data {
    198	struct device *dev;
    199	struct cpufreq_policy *policy;
    200	struct thermal_zone_device *tz;
    201	struct thermal_cooling_device *cdev;
    202	struct regmap *tempmon;
    203	u32 c1, c2; /* See formula in imx_init_calib() */
    204	int temp_passive;
    205	int temp_critical;
    206	int temp_max;
    207	int alarm_temp;
    208	int last_temp;
    209	bool irq_enabled;
    210	int irq;
    211	struct clk *thermal_clk;
    212	const struct thermal_soc_data *socdata;
    213	const char *temp_grade;
    214};
    215
    216static void imx_set_panic_temp(struct imx_thermal_data *data,
    217			       int panic_temp)
    218{
    219	const struct thermal_soc_data *soc_data = data->socdata;
    220	struct regmap *map = data->tempmon;
    221	int critical_value;
    222
    223	critical_value = (data->c2 - panic_temp) / data->c1;
    224
    225	regmap_write(map, soc_data->panic_alarm_ctrl + REG_CLR,
    226		     soc_data->panic_alarm_mask);
    227	regmap_write(map, soc_data->panic_alarm_ctrl + REG_SET,
    228		     critical_value << soc_data->panic_alarm_shift);
    229}
    230
    231static void imx_set_alarm_temp(struct imx_thermal_data *data,
    232			       int alarm_temp)
    233{
    234	struct regmap *map = data->tempmon;
    235	const struct thermal_soc_data *soc_data = data->socdata;
    236	int alarm_value;
    237
    238	data->alarm_temp = alarm_temp;
    239
    240	if (data->socdata->version == TEMPMON_IMX7D)
    241		alarm_value = alarm_temp / 1000 + data->c1 - 25;
    242	else
    243		alarm_value = (data->c2 - alarm_temp) / data->c1;
    244
    245	regmap_write(map, soc_data->high_alarm_ctrl + REG_CLR,
    246		     soc_data->high_alarm_mask);
    247	regmap_write(map, soc_data->high_alarm_ctrl + REG_SET,
    248		     alarm_value << soc_data->high_alarm_shift);
    249}
    250
    251static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
    252{
    253	struct imx_thermal_data *data = tz->devdata;
    254	const struct thermal_soc_data *soc_data = data->socdata;
    255	struct regmap *map = data->tempmon;
    256	unsigned int n_meas;
    257	u32 val;
    258	int ret;
    259
    260	ret = pm_runtime_resume_and_get(data->dev);
    261	if (ret < 0)
    262		return ret;
    263
    264	regmap_read(map, soc_data->temp_data, &val);
    265
    266	if ((val & soc_data->temp_valid_mask) == 0) {
    267		dev_dbg(&tz->device, "temp measurement never finished\n");
    268		return -EAGAIN;
    269	}
    270
    271	n_meas = (val & soc_data->temp_value_mask)
    272		>> soc_data->temp_value_shift;
    273
    274	/* See imx_init_calib() for formula derivation */
    275	if (data->socdata->version == TEMPMON_IMX7D)
    276		*temp = (n_meas - data->c1 + 25) * 1000;
    277	else
    278		*temp = data->c2 - n_meas * data->c1;
    279
    280	/* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
    281	if (data->socdata->version == TEMPMON_IMX6Q) {
    282		if (data->alarm_temp == data->temp_passive &&
    283			*temp >= data->temp_passive)
    284			imx_set_alarm_temp(data, data->temp_critical);
    285		if (data->alarm_temp == data->temp_critical &&
    286			*temp < data->temp_passive) {
    287			imx_set_alarm_temp(data, data->temp_passive);
    288			dev_dbg(&tz->device, "thermal alarm off: T < %d\n",
    289				data->alarm_temp / 1000);
    290		}
    291	}
    292
    293	if (*temp != data->last_temp) {
    294		dev_dbg(&tz->device, "millicelsius: %d\n", *temp);
    295		data->last_temp = *temp;
    296	}
    297
    298	/* Reenable alarm IRQ if temperature below alarm temperature */
    299	if (!data->irq_enabled && *temp < data->alarm_temp) {
    300		data->irq_enabled = true;
    301		enable_irq(data->irq);
    302	}
    303
    304	pm_runtime_put(data->dev);
    305
    306	return 0;
    307}
    308
    309static int imx_change_mode(struct thermal_zone_device *tz,
    310			   enum thermal_device_mode mode)
    311{
    312	struct imx_thermal_data *data = tz->devdata;
    313
    314	if (mode == THERMAL_DEVICE_ENABLED) {
    315		pm_runtime_get(data->dev);
    316
    317		if (!data->irq_enabled) {
    318			data->irq_enabled = true;
    319			enable_irq(data->irq);
    320		}
    321	} else {
    322		pm_runtime_put(data->dev);
    323
    324		if (data->irq_enabled) {
    325			disable_irq(data->irq);
    326			data->irq_enabled = false;
    327		}
    328	}
    329
    330	return 0;
    331}
    332
    333static int imx_get_trip_type(struct thermal_zone_device *tz, int trip,
    334			     enum thermal_trip_type *type)
    335{
    336	*type = (trip == IMX_TRIP_PASSIVE) ? THERMAL_TRIP_PASSIVE :
    337					     THERMAL_TRIP_CRITICAL;
    338	return 0;
    339}
    340
    341static int imx_get_crit_temp(struct thermal_zone_device *tz, int *temp)
    342{
    343	struct imx_thermal_data *data = tz->devdata;
    344
    345	*temp = data->temp_critical;
    346	return 0;
    347}
    348
    349static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip,
    350			     int *temp)
    351{
    352	struct imx_thermal_data *data = tz->devdata;
    353
    354	*temp = (trip == IMX_TRIP_PASSIVE) ? data->temp_passive :
    355					     data->temp_critical;
    356	return 0;
    357}
    358
    359static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
    360			     int temp)
    361{
    362	struct imx_thermal_data *data = tz->devdata;
    363	int ret;
    364
    365	ret = pm_runtime_resume_and_get(data->dev);
    366	if (ret < 0)
    367		return ret;
    368
    369	/* do not allow changing critical threshold */
    370	if (trip == IMX_TRIP_CRITICAL)
    371		return -EPERM;
    372
    373	/* do not allow passive to be set higher than critical */
    374	if (temp < 0 || temp > data->temp_critical)
    375		return -EINVAL;
    376
    377	data->temp_passive = temp;
    378
    379	imx_set_alarm_temp(data, temp);
    380
    381	pm_runtime_put(data->dev);
    382
    383	return 0;
    384}
    385
    386static int imx_bind(struct thermal_zone_device *tz,
    387		    struct thermal_cooling_device *cdev)
    388{
    389	int ret;
    390
    391	ret = thermal_zone_bind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev,
    392					       THERMAL_NO_LIMIT,
    393					       THERMAL_NO_LIMIT,
    394					       THERMAL_WEIGHT_DEFAULT);
    395	if (ret) {
    396		dev_err(&tz->device,
    397			"binding zone %s with cdev %s failed:%d\n",
    398			tz->type, cdev->type, ret);
    399		return ret;
    400	}
    401
    402	return 0;
    403}
    404
    405static int imx_unbind(struct thermal_zone_device *tz,
    406		      struct thermal_cooling_device *cdev)
    407{
    408	int ret;
    409
    410	ret = thermal_zone_unbind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev);
    411	if (ret) {
    412		dev_err(&tz->device,
    413			"unbinding zone %s with cdev %s failed:%d\n",
    414			tz->type, cdev->type, ret);
    415		return ret;
    416	}
    417
    418	return 0;
    419}
    420
    421static struct thermal_zone_device_ops imx_tz_ops = {
    422	.bind = imx_bind,
    423	.unbind = imx_unbind,
    424	.get_temp = imx_get_temp,
    425	.change_mode = imx_change_mode,
    426	.get_trip_type = imx_get_trip_type,
    427	.get_trip_temp = imx_get_trip_temp,
    428	.get_crit_temp = imx_get_crit_temp,
    429	.set_trip_temp = imx_set_trip_temp,
    430};
    431
    432static int imx_init_calib(struct platform_device *pdev, u32 ocotp_ana1)
    433{
    434	struct imx_thermal_data *data = platform_get_drvdata(pdev);
    435	int n1;
    436	u64 temp64;
    437
    438	if (ocotp_ana1 == 0 || ocotp_ana1 == ~0) {
    439		dev_err(&pdev->dev, "invalid sensor calibration data\n");
    440		return -EINVAL;
    441	}
    442
    443	/*
    444	 * On i.MX7D, we only use the calibration data at 25C to get the temp,
    445	 * Tmeas = ( Nmeas - n1) + 25; n1 is the fuse value for 25C.
    446	 */
    447	if (data->socdata->version == TEMPMON_IMX7D) {
    448		data->c1 = (ocotp_ana1 >> 9) & 0x1ff;
    449		return 0;
    450	}
    451
    452	/*
    453	 * The sensor is calibrated at 25 °C (aka T1) and the value measured
    454	 * (aka N1) at this temperature is provided in bits [31:20] in the
    455	 * i.MX's OCOTP value ANA1.
    456	 * To find the actual temperature T, the following formula has to be used
    457	 * when reading value n from the sensor:
    458	 *
    459	 * T = T1 + (N - N1) / (0.4148468 - 0.0015423 * N1) °C + 3.580661 °C
    460	 *   = [T1' - N1 / (0.4148468 - 0.0015423 * N1) °C] + N / (0.4148468 - 0.0015423 * N1) °C
    461	 *   = [T1' + N1 / (0.0015423 * N1 - 0.4148468) °C] - N / (0.0015423 * N1 - 0.4148468) °C
    462	 *   = c2 - c1 * N
    463	 *
    464	 * with
    465	 *
    466	 *  T1' = 28.580661 °C
    467	 *   c1 = 1 / (0.0015423 * N1 - 0.4297157) °C
    468	 *   c2 = T1' + N1 / (0.0015423 * N1 - 0.4148468) °C
    469	 *      = T1' + N1 * c1
    470	 */
    471	n1 = ocotp_ana1 >> 20;
    472
    473	temp64 = 10000000; /* use 10^7 as fixed point constant for values in formula */
    474	temp64 *= 1000; /* to get result in °mC */
    475	do_div(temp64, 15423 * n1 - 4148468);
    476	data->c1 = temp64;
    477	data->c2 = n1 * data->c1 + 28581;
    478
    479	return 0;
    480}
    481
    482static void imx_init_temp_grade(struct platform_device *pdev, u32 ocotp_mem0)
    483{
    484	struct imx_thermal_data *data = platform_get_drvdata(pdev);
    485
    486	/* The maximum die temp is specified by the Temperature Grade */
    487	switch ((ocotp_mem0 >> 6) & 0x3) {
    488	case 0: /* Commercial (0 to 95 °C) */
    489		data->temp_grade = "Commercial";
    490		data->temp_max = 95000;
    491		break;
    492	case 1: /* Extended Commercial (-20 °C to 105 °C) */
    493		data->temp_grade = "Extended Commercial";
    494		data->temp_max = 105000;
    495		break;
    496	case 2: /* Industrial (-40 °C to 105 °C) */
    497		data->temp_grade = "Industrial";
    498		data->temp_max = 105000;
    499		break;
    500	case 3: /* Automotive (-40 °C to 125 °C) */
    501		data->temp_grade = "Automotive";
    502		data->temp_max = 125000;
    503		break;
    504	}
    505
    506	/*
    507	 * Set the critical trip point at 5 °C under max
    508	 * Set the passive trip point at 10 °C under max (changeable via sysfs)
    509	 */
    510	data->temp_critical = data->temp_max - (1000 * 5);
    511	data->temp_passive = data->temp_max - (1000 * 10);
    512}
    513
    514static int imx_init_from_tempmon_data(struct platform_device *pdev)
    515{
    516	struct regmap *map;
    517	int ret;
    518	u32 val;
    519
    520	map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
    521					      "fsl,tempmon-data");
    522	if (IS_ERR(map)) {
    523		ret = PTR_ERR(map);
    524		dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret);
    525		return ret;
    526	}
    527
    528	ret = regmap_read(map, OCOTP_ANA1, &val);
    529	if (ret) {
    530		dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
    531		return ret;
    532	}
    533	ret = imx_init_calib(pdev, val);
    534	if (ret)
    535		return ret;
    536
    537	ret = regmap_read(map, OCOTP_MEM0, &val);
    538	if (ret) {
    539		dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
    540		return ret;
    541	}
    542	imx_init_temp_grade(pdev, val);
    543
    544	return 0;
    545}
    546
    547static int imx_init_from_nvmem_cells(struct platform_device *pdev)
    548{
    549	int ret;
    550	u32 val;
    551
    552	ret = nvmem_cell_read_u32(&pdev->dev, "calib", &val);
    553	if (ret)
    554		return ret;
    555
    556	ret = imx_init_calib(pdev, val);
    557	if (ret)
    558		return ret;
    559
    560	ret = nvmem_cell_read_u32(&pdev->dev, "temp_grade", &val);
    561	if (ret)
    562		return ret;
    563	imx_init_temp_grade(pdev, val);
    564
    565	return 0;
    566}
    567
    568static irqreturn_t imx_thermal_alarm_irq(int irq, void *dev)
    569{
    570	struct imx_thermal_data *data = dev;
    571
    572	disable_irq_nosync(irq);
    573	data->irq_enabled = false;
    574
    575	return IRQ_WAKE_THREAD;
    576}
    577
    578static irqreturn_t imx_thermal_alarm_irq_thread(int irq, void *dev)
    579{
    580	struct imx_thermal_data *data = dev;
    581
    582	dev_dbg(&data->tz->device, "THERMAL ALARM: T > %d\n",
    583		data->alarm_temp / 1000);
    584
    585	thermal_zone_device_update(data->tz, THERMAL_EVENT_UNSPECIFIED);
    586
    587	return IRQ_HANDLED;
    588}
    589
    590static const struct of_device_id of_imx_thermal_match[] = {
    591	{ .compatible = "fsl,imx6q-tempmon", .data = &thermal_imx6q_data, },
    592	{ .compatible = "fsl,imx6sx-tempmon", .data = &thermal_imx6sx_data, },
    593	{ .compatible = "fsl,imx7d-tempmon", .data = &thermal_imx7d_data, },
    594	{ /* end */ }
    595};
    596MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
    597
    598#ifdef CONFIG_CPU_FREQ
    599/*
    600 * Create cooling device in case no #cooling-cells property is available in
    601 * CPU node
    602 */
    603static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
    604{
    605	struct device_node *np;
    606	int ret = 0;
    607
    608	data->policy = cpufreq_cpu_get(0);
    609	if (!data->policy) {
    610		pr_debug("%s: CPUFreq policy not found\n", __func__);
    611		return -EPROBE_DEFER;
    612	}
    613
    614	np = of_get_cpu_node(data->policy->cpu, NULL);
    615
    616	if (!np || !of_find_property(np, "#cooling-cells", NULL)) {
    617		data->cdev = cpufreq_cooling_register(data->policy);
    618		if (IS_ERR(data->cdev)) {
    619			ret = PTR_ERR(data->cdev);
    620			cpufreq_cpu_put(data->policy);
    621		}
    622	}
    623
    624	of_node_put(np);
    625
    626	return ret;
    627}
    628
    629static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data)
    630{
    631	cpufreq_cooling_unregister(data->cdev);
    632	cpufreq_cpu_put(data->policy);
    633}
    634
    635#else
    636
    637static inline int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
    638{
    639	return 0;
    640}
    641
    642static inline void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data)
    643{
    644}
    645#endif
    646
    647static int imx_thermal_probe(struct platform_device *pdev)
    648{
    649	struct imx_thermal_data *data;
    650	struct regmap *map;
    651	int measure_freq;
    652	int ret;
    653
    654	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
    655	if (!data)
    656		return -ENOMEM;
    657
    658	data->dev = &pdev->dev;
    659
    660	map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon");
    661	if (IS_ERR(map)) {
    662		ret = PTR_ERR(map);
    663		dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret);
    664		return ret;
    665	}
    666	data->tempmon = map;
    667
    668	data->socdata = of_device_get_match_data(&pdev->dev);
    669	if (!data->socdata) {
    670		dev_err(&pdev->dev, "no device match found\n");
    671		return -ENODEV;
    672	}
    673
    674	/* make sure the IRQ flag is clear before enabling irq on i.MX6SX */
    675	if (data->socdata->version == TEMPMON_IMX6SX) {
    676		regmap_write(map, IMX6_MISC1 + REG_CLR,
    677			IMX6_MISC1_IRQ_TEMPHIGH | IMX6_MISC1_IRQ_TEMPLOW
    678			| IMX6_MISC1_IRQ_TEMPPANIC);
    679		/*
    680		 * reset value of LOW ALARM is incorrect, set it to lowest
    681		 * value to avoid false trigger of low alarm.
    682		 */
    683		regmap_write(map, data->socdata->low_alarm_ctrl + REG_SET,
    684			     data->socdata->low_alarm_mask);
    685	}
    686
    687	data->irq = platform_get_irq(pdev, 0);
    688	if (data->irq < 0)
    689		return data->irq;
    690
    691	platform_set_drvdata(pdev, data);
    692
    693	if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) {
    694		ret = imx_init_from_nvmem_cells(pdev);
    695		if (ret)
    696			return dev_err_probe(&pdev->dev, ret,
    697					     "failed to init from nvmem\n");
    698	} else {
    699		ret = imx_init_from_tempmon_data(pdev);
    700		if (ret) {
    701			dev_err(&pdev->dev, "failed to init from fsl,tempmon-data\n");
    702			return ret;
    703		}
    704	}
    705
    706	/* Make sure sensor is in known good state for measurements */
    707	regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
    708		     data->socdata->power_down_mask);
    709	regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
    710		     data->socdata->measure_temp_mask);
    711	regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
    712		     data->socdata->measure_freq_mask);
    713	if (data->socdata->version != TEMPMON_IMX7D)
    714		regmap_write(map, IMX6_MISC0 + REG_SET,
    715			IMX6_MISC0_REFTOP_SELBIASOFF);
    716	regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
    717		     data->socdata->power_down_mask);
    718
    719	ret = imx_thermal_register_legacy_cooling(data);
    720	if (ret)
    721		return dev_err_probe(&pdev->dev, ret,
    722				     "failed to register cpufreq cooling device\n");
    723
    724	data->thermal_clk = devm_clk_get(&pdev->dev, NULL);
    725	if (IS_ERR(data->thermal_clk)) {
    726		ret = PTR_ERR(data->thermal_clk);
    727		if (ret != -EPROBE_DEFER)
    728			dev_err(&pdev->dev,
    729				"failed to get thermal clk: %d\n", ret);
    730		goto legacy_cleanup;
    731	}
    732
    733	/*
    734	 * Thermal sensor needs clk on to get correct value, normally
    735	 * we should enable its clk before taking measurement and disable
    736	 * clk after measurement is done, but if alarm function is enabled,
    737	 * hardware will auto measure the temperature periodically, so we
    738	 * need to keep the clk always on for alarm function.
    739	 */
    740	ret = clk_prepare_enable(data->thermal_clk);
    741	if (ret) {
    742		dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
    743		goto legacy_cleanup;
    744	}
    745
    746	data->tz = thermal_zone_device_register("imx_thermal_zone",
    747						IMX_TRIP_NUM,
    748						BIT(IMX_TRIP_PASSIVE), data,
    749						&imx_tz_ops, NULL,
    750						IMX_PASSIVE_DELAY,
    751						IMX_POLLING_DELAY);
    752	if (IS_ERR(data->tz)) {
    753		ret = PTR_ERR(data->tz);
    754		dev_err(&pdev->dev,
    755			"failed to register thermal zone device %d\n", ret);
    756		goto clk_disable;
    757	}
    758
    759	dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC"
    760		 " critical:%dC passive:%dC\n", data->temp_grade,
    761		 data->temp_max / 1000, data->temp_critical / 1000,
    762		 data->temp_passive / 1000);
    763
    764	/* Enable measurements at ~ 10 Hz */
    765	regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
    766		     data->socdata->measure_freq_mask);
    767	measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
    768	regmap_write(map, data->socdata->measure_freq_ctrl + REG_SET,
    769		     measure_freq << data->socdata->measure_freq_shift);
    770	imx_set_alarm_temp(data, data->temp_passive);
    771
    772	if (data->socdata->version == TEMPMON_IMX6SX)
    773		imx_set_panic_temp(data, data->temp_critical);
    774
    775	regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
    776		     data->socdata->power_down_mask);
    777	regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
    778		     data->socdata->measure_temp_mask);
    779	/* After power up, we need a delay before first access can be done. */
    780	usleep_range(20, 50);
    781
    782	/* the core was configured and enabled just before */
    783	pm_runtime_set_active(&pdev->dev);
    784	pm_runtime_enable(data->dev);
    785
    786	ret = pm_runtime_resume_and_get(data->dev);
    787	if (ret < 0)
    788		goto disable_runtime_pm;
    789
    790	data->irq_enabled = true;
    791	ret = thermal_zone_device_enable(data->tz);
    792	if (ret)
    793		goto thermal_zone_unregister;
    794
    795	ret = devm_request_threaded_irq(&pdev->dev, data->irq,
    796			imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
    797			0, "imx_thermal", data);
    798	if (ret < 0) {
    799		dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
    800		goto thermal_zone_unregister;
    801	}
    802
    803	pm_runtime_put(data->dev);
    804
    805	return 0;
    806
    807thermal_zone_unregister:
    808	thermal_zone_device_unregister(data->tz);
    809disable_runtime_pm:
    810	pm_runtime_put_noidle(data->dev);
    811	pm_runtime_disable(data->dev);
    812clk_disable:
    813	clk_disable_unprepare(data->thermal_clk);
    814legacy_cleanup:
    815	imx_thermal_unregister_legacy_cooling(data);
    816
    817	return ret;
    818}
    819
    820static int imx_thermal_remove(struct platform_device *pdev)
    821{
    822	struct imx_thermal_data *data = platform_get_drvdata(pdev);
    823
    824	pm_runtime_put_noidle(data->dev);
    825	pm_runtime_disable(data->dev);
    826
    827	thermal_zone_device_unregister(data->tz);
    828	imx_thermal_unregister_legacy_cooling(data);
    829
    830	return 0;
    831}
    832
    833static int __maybe_unused imx_thermal_suspend(struct device *dev)
    834{
    835	struct imx_thermal_data *data = dev_get_drvdata(dev);
    836	int ret;
    837
    838	/*
    839	 * Need to disable thermal sensor, otherwise, when thermal core
    840	 * try to get temperature before thermal sensor resume, a wrong
    841	 * temperature will be read as the thermal sensor is powered
    842	 * down. This is done in change_mode() operation called from
    843	 * thermal_zone_device_disable()
    844	 */
    845	ret = thermal_zone_device_disable(data->tz);
    846	if (ret)
    847		return ret;
    848
    849	return pm_runtime_force_suspend(data->dev);
    850}
    851
    852static int __maybe_unused imx_thermal_resume(struct device *dev)
    853{
    854	struct imx_thermal_data *data = dev_get_drvdata(dev);
    855	int ret;
    856
    857	ret = pm_runtime_force_resume(data->dev);
    858	if (ret)
    859		return ret;
    860	/* Enabled thermal sensor after resume */
    861	return thermal_zone_device_enable(data->tz);
    862}
    863
    864static int __maybe_unused imx_thermal_runtime_suspend(struct device *dev)
    865{
    866	struct imx_thermal_data *data = dev_get_drvdata(dev);
    867	const struct thermal_soc_data *socdata = data->socdata;
    868	struct regmap *map = data->tempmon;
    869	int ret;
    870
    871	ret = regmap_write(map, socdata->sensor_ctrl + REG_CLR,
    872			   socdata->measure_temp_mask);
    873	if (ret)
    874		return ret;
    875
    876	ret = regmap_write(map, socdata->sensor_ctrl + REG_SET,
    877			   socdata->power_down_mask);
    878	if (ret)
    879		return ret;
    880
    881	clk_disable_unprepare(data->thermal_clk);
    882
    883	return 0;
    884}
    885
    886static int __maybe_unused imx_thermal_runtime_resume(struct device *dev)
    887{
    888	struct imx_thermal_data *data = dev_get_drvdata(dev);
    889	const struct thermal_soc_data *socdata = data->socdata;
    890	struct regmap *map = data->tempmon;
    891	int ret;
    892
    893	ret = clk_prepare_enable(data->thermal_clk);
    894	if (ret)
    895		return ret;
    896
    897	ret = regmap_write(map, socdata->sensor_ctrl + REG_CLR,
    898			   socdata->power_down_mask);
    899	if (ret)
    900		return ret;
    901
    902	ret = regmap_write(map, socdata->sensor_ctrl + REG_SET,
    903			   socdata->measure_temp_mask);
    904	if (ret)
    905		return ret;
    906
    907	/*
    908	 * According to the temp sensor designers, it may require up to ~17us
    909	 * to complete a measurement.
    910	 */
    911	usleep_range(20, 50);
    912
    913	return 0;
    914}
    915
    916static const struct dev_pm_ops imx_thermal_pm_ops = {
    917	SET_SYSTEM_SLEEP_PM_OPS(imx_thermal_suspend, imx_thermal_resume)
    918	SET_RUNTIME_PM_OPS(imx_thermal_runtime_suspend,
    919			   imx_thermal_runtime_resume, NULL)
    920};
    921
    922static struct platform_driver imx_thermal = {
    923	.driver = {
    924		.name	= "imx_thermal",
    925		.pm	= &imx_thermal_pm_ops,
    926		.of_match_table = of_imx_thermal_match,
    927	},
    928	.probe		= imx_thermal_probe,
    929	.remove		= imx_thermal_remove,
    930};
    931module_platform_driver(imx_thermal);
    932
    933MODULE_AUTHOR("Freescale Semiconductor, Inc.");
    934MODULE_DESCRIPTION("Thermal driver for Freescale i.MX SoCs");
    935MODULE_LICENSE("GPL v2");
    936MODULE_ALIAS("platform:imx-thermal");