Commit d0f9d64a0b8fb3399ca8dd0d54f4d305492c9217

Authored by Anson Huang
Committed by Zhang Rui
1 parent dd354b84d4

Thermal: imx: correct critical trip temperature setting

On latest i.MX6 SOC with thermal calibration data of 0x5A100000,
the critical trip temperature will be an invalid value and
cause system auto shutdown as below log:

thermal thermal_zone0: critical temperature reached(42 C),shutting down

So, with universal formula for thermal sensor, only room
temperature point is calibrated, which means the calibration
data read from fuse only has valid data of bit [31:20], others
are all 0, the critical trip point temperature can NOT depend
on the hot point calibration data, here we set it to 20 C higher
than default passive temperature.

Signed-off-by: Anson Huang <b20788@freescale.com>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Showing 1 changed file with 7 additions and 11 deletions Inline Diff

drivers/thermal/imx_thermal.c
1 /* 1 /*
2 * Copyright 2013 Freescale Semiconductor, Inc. 2 * Copyright 2013 Freescale Semiconductor, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 * 7 *
8 */ 8 */
9 9
10 #include <linux/clk.h> 10 #include <linux/clk.h>
11 #include <linux/cpu_cooling.h> 11 #include <linux/cpu_cooling.h>
12 #include <linux/cpufreq.h> 12 #include <linux/cpufreq.h>
13 #include <linux/delay.h> 13 #include <linux/delay.h>
14 #include <linux/device.h> 14 #include <linux/device.h>
15 #include <linux/init.h> 15 #include <linux/init.h>
16 #include <linux/interrupt.h> 16 #include <linux/interrupt.h>
17 #include <linux/io.h> 17 #include <linux/io.h>
18 #include <linux/kernel.h> 18 #include <linux/kernel.h>
19 #include <linux/mfd/syscon.h> 19 #include <linux/mfd/syscon.h>
20 #include <linux/module.h> 20 #include <linux/module.h>
21 #include <linux/of.h> 21 #include <linux/of.h>
22 #include <linux/platform_device.h> 22 #include <linux/platform_device.h>
23 #include <linux/regmap.h> 23 #include <linux/regmap.h>
24 #include <linux/slab.h> 24 #include <linux/slab.h>
25 #include <linux/thermal.h> 25 #include <linux/thermal.h>
26 #include <linux/types.h> 26 #include <linux/types.h>
27 27
28 #define REG_SET 0x4 28 #define REG_SET 0x4
29 #define REG_CLR 0x8 29 #define REG_CLR 0x8
30 #define REG_TOG 0xc 30 #define REG_TOG 0xc
31 31
32 #define MISC0 0x0150 32 #define MISC0 0x0150
33 #define MISC0_REFTOP_SELBIASOFF (1 << 3) 33 #define MISC0_REFTOP_SELBIASOFF (1 << 3)
34 34
35 #define TEMPSENSE0 0x0180 35 #define TEMPSENSE0 0x0180
36 #define TEMPSENSE0_ALARM_VALUE_SHIFT 20 36 #define TEMPSENSE0_ALARM_VALUE_SHIFT 20
37 #define TEMPSENSE0_ALARM_VALUE_MASK (0xfff << TEMPSENSE0_ALARM_VALUE_SHIFT) 37 #define TEMPSENSE0_ALARM_VALUE_MASK (0xfff << TEMPSENSE0_ALARM_VALUE_SHIFT)
38 #define TEMPSENSE0_TEMP_CNT_SHIFT 8 38 #define TEMPSENSE0_TEMP_CNT_SHIFT 8
39 #define TEMPSENSE0_TEMP_CNT_MASK (0xfff << TEMPSENSE0_TEMP_CNT_SHIFT) 39 #define TEMPSENSE0_TEMP_CNT_MASK (0xfff << TEMPSENSE0_TEMP_CNT_SHIFT)
40 #define TEMPSENSE0_FINISHED (1 << 2) 40 #define TEMPSENSE0_FINISHED (1 << 2)
41 #define TEMPSENSE0_MEASURE_TEMP (1 << 1) 41 #define TEMPSENSE0_MEASURE_TEMP (1 << 1)
42 #define TEMPSENSE0_POWER_DOWN (1 << 0) 42 #define TEMPSENSE0_POWER_DOWN (1 << 0)
43 43
44 #define TEMPSENSE1 0x0190 44 #define TEMPSENSE1 0x0190
45 #define TEMPSENSE1_MEASURE_FREQ 0xffff 45 #define TEMPSENSE1_MEASURE_FREQ 0xffff
46 46
47 #define OCOTP_ANA1 0x04e0 47 #define OCOTP_ANA1 0x04e0
48 48
49 /* The driver supports 1 passive trip point and 1 critical trip point */ 49 /* The driver supports 1 passive trip point and 1 critical trip point */
50 enum imx_thermal_trip { 50 enum imx_thermal_trip {
51 IMX_TRIP_PASSIVE, 51 IMX_TRIP_PASSIVE,
52 IMX_TRIP_CRITICAL, 52 IMX_TRIP_CRITICAL,
53 IMX_TRIP_NUM, 53 IMX_TRIP_NUM,
54 }; 54 };
55 55
56 /* 56 /*
57 * It defines the temperature in millicelsius for passive trip point 57 * It defines the temperature in millicelsius for passive trip point
58 * that will trigger cooling action when crossed. 58 * that will trigger cooling action when crossed.
59 */ 59 */
60 #define IMX_TEMP_PASSIVE 85000 60 #define IMX_TEMP_PASSIVE 85000
61 61
62 #define IMX_POLLING_DELAY 2000 /* millisecond */ 62 #define IMX_POLLING_DELAY 2000 /* millisecond */
63 #define IMX_PASSIVE_DELAY 1000 63 #define IMX_PASSIVE_DELAY 1000
64 64
65 #define FACTOR0 10000000 65 #define FACTOR0 10000000
66 #define FACTOR1 15976 66 #define FACTOR1 15976
67 #define FACTOR2 4297157 67 #define FACTOR2 4297157
68 68
69 struct imx_thermal_data { 69 struct imx_thermal_data {
70 struct thermal_zone_device *tz; 70 struct thermal_zone_device *tz;
71 struct thermal_cooling_device *cdev; 71 struct thermal_cooling_device *cdev;
72 enum thermal_device_mode mode; 72 enum thermal_device_mode mode;
73 struct regmap *tempmon; 73 struct regmap *tempmon;
74 u32 c1, c2; /* See formula in imx_get_sensor_data() */ 74 u32 c1, c2; /* See formula in imx_get_sensor_data() */
75 unsigned long temp_passive; 75 unsigned long temp_passive;
76 unsigned long temp_critical; 76 unsigned long temp_critical;
77 unsigned long alarm_temp; 77 unsigned long alarm_temp;
78 unsigned long last_temp; 78 unsigned long last_temp;
79 bool irq_enabled; 79 bool irq_enabled;
80 int irq; 80 int irq;
81 struct clk *thermal_clk; 81 struct clk *thermal_clk;
82 }; 82 };
83 83
84 static void imx_set_alarm_temp(struct imx_thermal_data *data, 84 static void imx_set_alarm_temp(struct imx_thermal_data *data,
85 signed long alarm_temp) 85 signed long alarm_temp)
86 { 86 {
87 struct regmap *map = data->tempmon; 87 struct regmap *map = data->tempmon;
88 int alarm_value; 88 int alarm_value;
89 89
90 data->alarm_temp = alarm_temp; 90 data->alarm_temp = alarm_temp;
91 alarm_value = (data->c2 - alarm_temp) / data->c1; 91 alarm_value = (data->c2 - alarm_temp) / data->c1;
92 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK); 92 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK);
93 regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value << 93 regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value <<
94 TEMPSENSE0_ALARM_VALUE_SHIFT); 94 TEMPSENSE0_ALARM_VALUE_SHIFT);
95 } 95 }
96 96
97 static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp) 97 static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp)
98 { 98 {
99 struct imx_thermal_data *data = tz->devdata; 99 struct imx_thermal_data *data = tz->devdata;
100 struct regmap *map = data->tempmon; 100 struct regmap *map = data->tempmon;
101 unsigned int n_meas; 101 unsigned int n_meas;
102 bool wait; 102 bool wait;
103 u32 val; 103 u32 val;
104 104
105 if (data->mode == THERMAL_DEVICE_ENABLED) { 105 if (data->mode == THERMAL_DEVICE_ENABLED) {
106 /* Check if a measurement is currently in progress */ 106 /* Check if a measurement is currently in progress */
107 regmap_read(map, TEMPSENSE0, &val); 107 regmap_read(map, TEMPSENSE0, &val);
108 wait = !(val & TEMPSENSE0_FINISHED); 108 wait = !(val & TEMPSENSE0_FINISHED);
109 } else { 109 } else {
110 /* 110 /*
111 * Every time we measure the temperature, we will power on the 111 * Every time we measure the temperature, we will power on the
112 * temperature sensor, enable measurements, take a reading, 112 * temperature sensor, enable measurements, take a reading,
113 * disable measurements, power off the temperature sensor. 113 * disable measurements, power off the temperature sensor.
114 */ 114 */
115 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); 115 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
116 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); 116 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
117 117
118 wait = true; 118 wait = true;
119 } 119 }
120 120
121 /* 121 /*
122 * According to the temp sensor designers, it may require up to ~17us 122 * According to the temp sensor designers, it may require up to ~17us
123 * to complete a measurement. 123 * to complete a measurement.
124 */ 124 */
125 if (wait) 125 if (wait)
126 usleep_range(20, 50); 126 usleep_range(20, 50);
127 127
128 regmap_read(map, TEMPSENSE0, &val); 128 regmap_read(map, TEMPSENSE0, &val);
129 129
130 if (data->mode != THERMAL_DEVICE_ENABLED) { 130 if (data->mode != THERMAL_DEVICE_ENABLED) {
131 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP); 131 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
132 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); 132 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
133 } 133 }
134 134
135 if ((val & TEMPSENSE0_FINISHED) == 0) { 135 if ((val & TEMPSENSE0_FINISHED) == 0) {
136 dev_dbg(&tz->device, "temp measurement never finished\n"); 136 dev_dbg(&tz->device, "temp measurement never finished\n");
137 return -EAGAIN; 137 return -EAGAIN;
138 } 138 }
139 139
140 n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT; 140 n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT;
141 141
142 /* See imx_get_sensor_data() for formula derivation */ 142 /* See imx_get_sensor_data() for formula derivation */
143 *temp = data->c2 - n_meas * data->c1; 143 *temp = data->c2 - n_meas * data->c1;
144 144
145 /* Update alarm value to next higher trip point */ 145 /* Update alarm value to next higher trip point */
146 if (data->alarm_temp == data->temp_passive && *temp >= data->temp_passive) 146 if (data->alarm_temp == data->temp_passive && *temp >= data->temp_passive)
147 imx_set_alarm_temp(data, data->temp_critical); 147 imx_set_alarm_temp(data, data->temp_critical);
148 if (data->alarm_temp == data->temp_critical && *temp < data->temp_passive) { 148 if (data->alarm_temp == data->temp_critical && *temp < data->temp_passive) {
149 imx_set_alarm_temp(data, data->temp_passive); 149 imx_set_alarm_temp(data, data->temp_passive);
150 dev_dbg(&tz->device, "thermal alarm off: T < %lu\n", 150 dev_dbg(&tz->device, "thermal alarm off: T < %lu\n",
151 data->alarm_temp / 1000); 151 data->alarm_temp / 1000);
152 } 152 }
153 153
154 if (*temp != data->last_temp) { 154 if (*temp != data->last_temp) {
155 dev_dbg(&tz->device, "millicelsius: %ld\n", *temp); 155 dev_dbg(&tz->device, "millicelsius: %ld\n", *temp);
156 data->last_temp = *temp; 156 data->last_temp = *temp;
157 } 157 }
158 158
159 /* Reenable alarm IRQ if temperature below alarm temperature */ 159 /* Reenable alarm IRQ if temperature below alarm temperature */
160 if (!data->irq_enabled && *temp < data->alarm_temp) { 160 if (!data->irq_enabled && *temp < data->alarm_temp) {
161 data->irq_enabled = true; 161 data->irq_enabled = true;
162 enable_irq(data->irq); 162 enable_irq(data->irq);
163 } 163 }
164 164
165 return 0; 165 return 0;
166 } 166 }
167 167
168 static int imx_get_mode(struct thermal_zone_device *tz, 168 static int imx_get_mode(struct thermal_zone_device *tz,
169 enum thermal_device_mode *mode) 169 enum thermal_device_mode *mode)
170 { 170 {
171 struct imx_thermal_data *data = tz->devdata; 171 struct imx_thermal_data *data = tz->devdata;
172 172
173 *mode = data->mode; 173 *mode = data->mode;
174 174
175 return 0; 175 return 0;
176 } 176 }
177 177
178 static int imx_set_mode(struct thermal_zone_device *tz, 178 static int imx_set_mode(struct thermal_zone_device *tz,
179 enum thermal_device_mode mode) 179 enum thermal_device_mode mode)
180 { 180 {
181 struct imx_thermal_data *data = tz->devdata; 181 struct imx_thermal_data *data = tz->devdata;
182 struct regmap *map = data->tempmon; 182 struct regmap *map = data->tempmon;
183 183
184 if (mode == THERMAL_DEVICE_ENABLED) { 184 if (mode == THERMAL_DEVICE_ENABLED) {
185 tz->polling_delay = IMX_POLLING_DELAY; 185 tz->polling_delay = IMX_POLLING_DELAY;
186 tz->passive_delay = IMX_PASSIVE_DELAY; 186 tz->passive_delay = IMX_PASSIVE_DELAY;
187 187
188 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); 188 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
189 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); 189 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
190 190
191 if (!data->irq_enabled) { 191 if (!data->irq_enabled) {
192 data->irq_enabled = true; 192 data->irq_enabled = true;
193 enable_irq(data->irq); 193 enable_irq(data->irq);
194 } 194 }
195 } else { 195 } else {
196 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP); 196 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
197 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); 197 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
198 198
199 tz->polling_delay = 0; 199 tz->polling_delay = 0;
200 tz->passive_delay = 0; 200 tz->passive_delay = 0;
201 201
202 if (data->irq_enabled) { 202 if (data->irq_enabled) {
203 disable_irq(data->irq); 203 disable_irq(data->irq);
204 data->irq_enabled = false; 204 data->irq_enabled = false;
205 } 205 }
206 } 206 }
207 207
208 data->mode = mode; 208 data->mode = mode;
209 thermal_zone_device_update(tz); 209 thermal_zone_device_update(tz);
210 210
211 return 0; 211 return 0;
212 } 212 }
213 213
214 static int imx_get_trip_type(struct thermal_zone_device *tz, int trip, 214 static int imx_get_trip_type(struct thermal_zone_device *tz, int trip,
215 enum thermal_trip_type *type) 215 enum thermal_trip_type *type)
216 { 216 {
217 *type = (trip == IMX_TRIP_PASSIVE) ? THERMAL_TRIP_PASSIVE : 217 *type = (trip == IMX_TRIP_PASSIVE) ? THERMAL_TRIP_PASSIVE :
218 THERMAL_TRIP_CRITICAL; 218 THERMAL_TRIP_CRITICAL;
219 return 0; 219 return 0;
220 } 220 }
221 221
222 static int imx_get_crit_temp(struct thermal_zone_device *tz, 222 static int imx_get_crit_temp(struct thermal_zone_device *tz,
223 unsigned long *temp) 223 unsigned long *temp)
224 { 224 {
225 struct imx_thermal_data *data = tz->devdata; 225 struct imx_thermal_data *data = tz->devdata;
226 226
227 *temp = data->temp_critical; 227 *temp = data->temp_critical;
228 return 0; 228 return 0;
229 } 229 }
230 230
231 static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip, 231 static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip,
232 unsigned long *temp) 232 unsigned long *temp)
233 { 233 {
234 struct imx_thermal_data *data = tz->devdata; 234 struct imx_thermal_data *data = tz->devdata;
235 235
236 *temp = (trip == IMX_TRIP_PASSIVE) ? data->temp_passive : 236 *temp = (trip == IMX_TRIP_PASSIVE) ? data->temp_passive :
237 data->temp_critical; 237 data->temp_critical;
238 return 0; 238 return 0;
239 } 239 }
240 240
241 static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip, 241 static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
242 unsigned long temp) 242 unsigned long temp)
243 { 243 {
244 struct imx_thermal_data *data = tz->devdata; 244 struct imx_thermal_data *data = tz->devdata;
245 245
246 if (trip == IMX_TRIP_CRITICAL) 246 if (trip == IMX_TRIP_CRITICAL)
247 return -EPERM; 247 return -EPERM;
248 248
249 if (temp > IMX_TEMP_PASSIVE) 249 if (temp > IMX_TEMP_PASSIVE)
250 return -EINVAL; 250 return -EINVAL;
251 251
252 data->temp_passive = temp; 252 data->temp_passive = temp;
253 253
254 imx_set_alarm_temp(data, temp); 254 imx_set_alarm_temp(data, temp);
255 255
256 return 0; 256 return 0;
257 } 257 }
258 258
259 static int imx_bind(struct thermal_zone_device *tz, 259 static int imx_bind(struct thermal_zone_device *tz,
260 struct thermal_cooling_device *cdev) 260 struct thermal_cooling_device *cdev)
261 { 261 {
262 int ret; 262 int ret;
263 263
264 ret = thermal_zone_bind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev, 264 ret = thermal_zone_bind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev,
265 THERMAL_NO_LIMIT, 265 THERMAL_NO_LIMIT,
266 THERMAL_NO_LIMIT); 266 THERMAL_NO_LIMIT);
267 if (ret) { 267 if (ret) {
268 dev_err(&tz->device, 268 dev_err(&tz->device,
269 "binding zone %s with cdev %s failed:%d\n", 269 "binding zone %s with cdev %s failed:%d\n",
270 tz->type, cdev->type, ret); 270 tz->type, cdev->type, ret);
271 return ret; 271 return ret;
272 } 272 }
273 273
274 return 0; 274 return 0;
275 } 275 }
276 276
277 static int imx_unbind(struct thermal_zone_device *tz, 277 static int imx_unbind(struct thermal_zone_device *tz,
278 struct thermal_cooling_device *cdev) 278 struct thermal_cooling_device *cdev)
279 { 279 {
280 int ret; 280 int ret;
281 281
282 ret = thermal_zone_unbind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev); 282 ret = thermal_zone_unbind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev);
283 if (ret) { 283 if (ret) {
284 dev_err(&tz->device, 284 dev_err(&tz->device,
285 "unbinding zone %s with cdev %s failed:%d\n", 285 "unbinding zone %s with cdev %s failed:%d\n",
286 tz->type, cdev->type, ret); 286 tz->type, cdev->type, ret);
287 return ret; 287 return ret;
288 } 288 }
289 289
290 return 0; 290 return 0;
291 } 291 }
292 292
293 static struct thermal_zone_device_ops imx_tz_ops = { 293 static struct thermal_zone_device_ops imx_tz_ops = {
294 .bind = imx_bind, 294 .bind = imx_bind,
295 .unbind = imx_unbind, 295 .unbind = imx_unbind,
296 .get_temp = imx_get_temp, 296 .get_temp = imx_get_temp,
297 .get_mode = imx_get_mode, 297 .get_mode = imx_get_mode,
298 .set_mode = imx_set_mode, 298 .set_mode = imx_set_mode,
299 .get_trip_type = imx_get_trip_type, 299 .get_trip_type = imx_get_trip_type,
300 .get_trip_temp = imx_get_trip_temp, 300 .get_trip_temp = imx_get_trip_temp,
301 .get_crit_temp = imx_get_crit_temp, 301 .get_crit_temp = imx_get_crit_temp,
302 .set_trip_temp = imx_set_trip_temp, 302 .set_trip_temp = imx_set_trip_temp,
303 }; 303 };
304 304
305 static int imx_get_sensor_data(struct platform_device *pdev) 305 static int imx_get_sensor_data(struct platform_device *pdev)
306 { 306 {
307 struct imx_thermal_data *data = platform_get_drvdata(pdev); 307 struct imx_thermal_data *data = platform_get_drvdata(pdev);
308 struct regmap *map; 308 struct regmap *map;
309 int t1, t2, n1, n2; 309 int t1, n1;
310 int ret; 310 int ret;
311 u32 val; 311 u32 val;
312 u64 temp64; 312 u64 temp64;
313 313
314 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 314 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
315 "fsl,tempmon-data"); 315 "fsl,tempmon-data");
316 if (IS_ERR(map)) { 316 if (IS_ERR(map)) {
317 ret = PTR_ERR(map); 317 ret = PTR_ERR(map);
318 dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret); 318 dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret);
319 return ret; 319 return ret;
320 } 320 }
321 321
322 ret = regmap_read(map, OCOTP_ANA1, &val); 322 ret = regmap_read(map, OCOTP_ANA1, &val);
323 if (ret) { 323 if (ret) {
324 dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret); 324 dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
325 return ret; 325 return ret;
326 } 326 }
327 327
328 if (val == 0 || val == ~0) { 328 if (val == 0 || val == ~0) {
329 dev_err(&pdev->dev, "invalid sensor calibration data\n"); 329 dev_err(&pdev->dev, "invalid sensor calibration data\n");
330 return -EINVAL; 330 return -EINVAL;
331 } 331 }
332 332
333 /* 333 /*
334 * Sensor data layout: 334 * Sensor data layout:
335 * [31:20] - sensor value @ 25C 335 * [31:20] - sensor value @ 25C
336 * [19:8] - sensor value of hot
337 * [7:0] - hot temperature value
338 * Use universal formula now and only need sensor value @ 25C 336 * Use universal formula now and only need sensor value @ 25C
339 * slope = 0.4297157 - (0.0015976 * 25C fuse) 337 * slope = 0.4297157 - (0.0015976 * 25C fuse)
340 */ 338 */
341 n1 = val >> 20; 339 n1 = val >> 20;
342 n2 = (val & 0xfff00) >> 8;
343 t2 = val & 0xff;
344 t1 = 25; /* t1 always 25C */ 340 t1 = 25; /* t1 always 25C */
345 341
346 /* 342 /*
347 * Derived from linear interpolation: 343 * Derived from linear interpolation:
348 * slope = 0.4297157 - (0.0015976 * 25C fuse) 344 * slope = 0.4297157 - (0.0015976 * 25C fuse)
349 * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0 345 * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0
350 * (Nmeas - n1) / (Tmeas - t1) = slope 346 * (Nmeas - n1) / (Tmeas - t1) = slope
351 * We want to reduce this down to the minimum computation necessary 347 * We want to reduce this down to the minimum computation necessary
352 * for each temperature read. Also, we want Tmeas in millicelsius 348 * for each temperature read. Also, we want Tmeas in millicelsius
353 * and we don't want to lose precision from integer division. So... 349 * and we don't want to lose precision from integer division. So...
354 * Tmeas = (Nmeas - n1) / slope + t1 350 * Tmeas = (Nmeas - n1) / slope + t1
355 * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1 351 * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1
356 * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1 352 * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1
357 * Let constant c1 = (-1000 / slope) 353 * Let constant c1 = (-1000 / slope)
358 * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1 354 * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1
359 * Let constant c2 = n1 *c1 + 1000 * t1 355 * Let constant c2 = n1 *c1 + 1000 * t1
360 * milli_Tmeas = c2 - Nmeas * c1 356 * milli_Tmeas = c2 - Nmeas * c1
361 */ 357 */
362 temp64 = FACTOR0; 358 temp64 = FACTOR0;
363 temp64 *= 1000; 359 temp64 *= 1000;
364 do_div(temp64, FACTOR1 * n1 - FACTOR2); 360 do_div(temp64, FACTOR1 * n1 - FACTOR2);
365 data->c1 = temp64; 361 data->c1 = temp64;
366 data->c2 = n1 * data->c1 + 1000 * t1; 362 data->c2 = n1 * data->c1 + 1000 * t1;
367 363
368 /* 364 /*
369 * Set the default passive cooling trip point to 20 °C below the 365 * Set the default passive cooling trip point,
370 * maximum die temperature. Can be changed from userspace. 366 * can be changed from userspace.
371 */ 367 */
372 data->temp_passive = 1000 * (t2 - 20); 368 data->temp_passive = IMX_TEMP_PASSIVE;
373 369
374 /* 370 /*
375 * The maximum die temperature is t2, let's give 5 °C cushion 371 * The maximum die temperature set to 20 C higher than
376 * for noise and possible temperature rise between measurements. 372 * IMX_TEMP_PASSIVE.
377 */ 373 */
378 data->temp_critical = 1000 * (t2 - 5); 374 data->temp_critical = 1000 * 20 + data->temp_passive;
379 375
380 return 0; 376 return 0;
381 } 377 }
382 378
383 static irqreturn_t imx_thermal_alarm_irq(int irq, void *dev) 379 static irqreturn_t imx_thermal_alarm_irq(int irq, void *dev)
384 { 380 {
385 struct imx_thermal_data *data = dev; 381 struct imx_thermal_data *data = dev;
386 382
387 disable_irq_nosync(irq); 383 disable_irq_nosync(irq);
388 data->irq_enabled = false; 384 data->irq_enabled = false;
389 385
390 return IRQ_WAKE_THREAD; 386 return IRQ_WAKE_THREAD;
391 } 387 }
392 388
393 static irqreturn_t imx_thermal_alarm_irq_thread(int irq, void *dev) 389 static irqreturn_t imx_thermal_alarm_irq_thread(int irq, void *dev)
394 { 390 {
395 struct imx_thermal_data *data = dev; 391 struct imx_thermal_data *data = dev;
396 392
397 dev_dbg(&data->tz->device, "THERMAL ALARM: T > %lu\n", 393 dev_dbg(&data->tz->device, "THERMAL ALARM: T > %lu\n",
398 data->alarm_temp / 1000); 394 data->alarm_temp / 1000);
399 395
400 thermal_zone_device_update(data->tz); 396 thermal_zone_device_update(data->tz);
401 397
402 return IRQ_HANDLED; 398 return IRQ_HANDLED;
403 } 399 }
404 400
405 static int imx_thermal_probe(struct platform_device *pdev) 401 static int imx_thermal_probe(struct platform_device *pdev)
406 { 402 {
407 struct imx_thermal_data *data; 403 struct imx_thermal_data *data;
408 struct cpumask clip_cpus; 404 struct cpumask clip_cpus;
409 struct regmap *map; 405 struct regmap *map;
410 int measure_freq; 406 int measure_freq;
411 int ret; 407 int ret;
412 408
413 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 409 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
414 if (!data) 410 if (!data)
415 return -ENOMEM; 411 return -ENOMEM;
416 412
417 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon"); 413 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon");
418 if (IS_ERR(map)) { 414 if (IS_ERR(map)) {
419 ret = PTR_ERR(map); 415 ret = PTR_ERR(map);
420 dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret); 416 dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret);
421 return ret; 417 return ret;
422 } 418 }
423 data->tempmon = map; 419 data->tempmon = map;
424 420
425 data->irq = platform_get_irq(pdev, 0); 421 data->irq = platform_get_irq(pdev, 0);
426 if (data->irq < 0) 422 if (data->irq < 0)
427 return data->irq; 423 return data->irq;
428 424
429 ret = devm_request_threaded_irq(&pdev->dev, data->irq, 425 ret = devm_request_threaded_irq(&pdev->dev, data->irq,
430 imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread, 426 imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
431 0, "imx_thermal", data); 427 0, "imx_thermal", data);
432 if (ret < 0) { 428 if (ret < 0) {
433 dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret); 429 dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
434 return ret; 430 return ret;
435 } 431 }
436 432
437 platform_set_drvdata(pdev, data); 433 platform_set_drvdata(pdev, data);
438 434
439 ret = imx_get_sensor_data(pdev); 435 ret = imx_get_sensor_data(pdev);
440 if (ret) { 436 if (ret) {
441 dev_err(&pdev->dev, "failed to get sensor data\n"); 437 dev_err(&pdev->dev, "failed to get sensor data\n");
442 return ret; 438 return ret;
443 } 439 }
444 440
445 /* Make sure sensor is in known good state for measurements */ 441 /* Make sure sensor is in known good state for measurements */
446 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); 442 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
447 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP); 443 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
448 regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ); 444 regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
449 regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF); 445 regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF);
450 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); 446 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
451 447
452 cpumask_set_cpu(0, &clip_cpus); 448 cpumask_set_cpu(0, &clip_cpus);
453 data->cdev = cpufreq_cooling_register(&clip_cpus); 449 data->cdev = cpufreq_cooling_register(&clip_cpus);
454 if (IS_ERR(data->cdev)) { 450 if (IS_ERR(data->cdev)) {
455 ret = PTR_ERR(data->cdev); 451 ret = PTR_ERR(data->cdev);
456 dev_err(&pdev->dev, 452 dev_err(&pdev->dev,
457 "failed to register cpufreq cooling device: %d\n", ret); 453 "failed to register cpufreq cooling device: %d\n", ret);
458 return ret; 454 return ret;
459 } 455 }
460 456
461 data->tz = thermal_zone_device_register("imx_thermal_zone", 457 data->tz = thermal_zone_device_register("imx_thermal_zone",
462 IMX_TRIP_NUM, 458 IMX_TRIP_NUM,
463 BIT(IMX_TRIP_PASSIVE), data, 459 BIT(IMX_TRIP_PASSIVE), data,
464 &imx_tz_ops, NULL, 460 &imx_tz_ops, NULL,
465 IMX_PASSIVE_DELAY, 461 IMX_PASSIVE_DELAY,
466 IMX_POLLING_DELAY); 462 IMX_POLLING_DELAY);
467 if (IS_ERR(data->tz)) { 463 if (IS_ERR(data->tz)) {
468 ret = PTR_ERR(data->tz); 464 ret = PTR_ERR(data->tz);
469 dev_err(&pdev->dev, 465 dev_err(&pdev->dev,
470 "failed to register thermal zone device %d\n", ret); 466 "failed to register thermal zone device %d\n", ret);
471 cpufreq_cooling_unregister(data->cdev); 467 cpufreq_cooling_unregister(data->cdev);
472 return ret; 468 return ret;
473 } 469 }
474 470
475 data->thermal_clk = devm_clk_get(&pdev->dev, NULL); 471 data->thermal_clk = devm_clk_get(&pdev->dev, NULL);
476 if (IS_ERR(data->thermal_clk)) { 472 if (IS_ERR(data->thermal_clk)) {
477 dev_warn(&pdev->dev, "failed to get thermal clk!\n"); 473 dev_warn(&pdev->dev, "failed to get thermal clk!\n");
478 } else { 474 } else {
479 /* 475 /*
480 * Thermal sensor needs clk on to get correct value, normally 476 * Thermal sensor needs clk on to get correct value, normally
481 * we should enable its clk before taking measurement and disable 477 * we should enable its clk before taking measurement and disable
482 * clk after measurement is done, but if alarm function is enabled, 478 * clk after measurement is done, but if alarm function is enabled,
483 * hardware will auto measure the temperature periodically, so we 479 * hardware will auto measure the temperature periodically, so we
484 * need to keep the clk always on for alarm function. 480 * need to keep the clk always on for alarm function.
485 */ 481 */
486 ret = clk_prepare_enable(data->thermal_clk); 482 ret = clk_prepare_enable(data->thermal_clk);
487 if (ret) 483 if (ret)
488 dev_warn(&pdev->dev, "failed to enable thermal clk: %d\n", ret); 484 dev_warn(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
489 } 485 }
490 486
491 /* Enable measurements at ~ 10 Hz */ 487 /* Enable measurements at ~ 10 Hz */
492 regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ); 488 regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
493 measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */ 489 measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
494 regmap_write(map, TEMPSENSE1 + REG_SET, measure_freq); 490 regmap_write(map, TEMPSENSE1 + REG_SET, measure_freq);
495 imx_set_alarm_temp(data, data->temp_passive); 491 imx_set_alarm_temp(data, data->temp_passive);
496 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); 492 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
497 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); 493 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
498 494
499 data->irq_enabled = true; 495 data->irq_enabled = true;
500 data->mode = THERMAL_DEVICE_ENABLED; 496 data->mode = THERMAL_DEVICE_ENABLED;
501 497
502 return 0; 498 return 0;
503 } 499 }
504 500
505 static int imx_thermal_remove(struct platform_device *pdev) 501 static int imx_thermal_remove(struct platform_device *pdev)
506 { 502 {
507 struct imx_thermal_data *data = platform_get_drvdata(pdev); 503 struct imx_thermal_data *data = platform_get_drvdata(pdev);
508 struct regmap *map = data->tempmon; 504 struct regmap *map = data->tempmon;
509 505
510 /* Disable measurements */ 506 /* Disable measurements */
511 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); 507 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
512 if (!IS_ERR(data->thermal_clk)) 508 if (!IS_ERR(data->thermal_clk))
513 clk_disable_unprepare(data->thermal_clk); 509 clk_disable_unprepare(data->thermal_clk);
514 510
515 thermal_zone_device_unregister(data->tz); 511 thermal_zone_device_unregister(data->tz);
516 cpufreq_cooling_unregister(data->cdev); 512 cpufreq_cooling_unregister(data->cdev);
517 513
518 return 0; 514 return 0;
519 } 515 }
520 516
521 #ifdef CONFIG_PM_SLEEP 517 #ifdef CONFIG_PM_SLEEP
522 static int imx_thermal_suspend(struct device *dev) 518 static int imx_thermal_suspend(struct device *dev)
523 { 519 {
524 struct imx_thermal_data *data = dev_get_drvdata(dev); 520 struct imx_thermal_data *data = dev_get_drvdata(dev);
525 struct regmap *map = data->tempmon; 521 struct regmap *map = data->tempmon;
526 522
527 /* 523 /*
528 * Need to disable thermal sensor, otherwise, when thermal core 524 * Need to disable thermal sensor, otherwise, when thermal core
529 * try to get temperature before thermal sensor resume, a wrong 525 * try to get temperature before thermal sensor resume, a wrong
530 * temperature will be read as the thermal sensor is powered 526 * temperature will be read as the thermal sensor is powered
531 * down. 527 * down.
532 */ 528 */
533 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP); 529 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
534 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); 530 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
535 data->mode = THERMAL_DEVICE_DISABLED; 531 data->mode = THERMAL_DEVICE_DISABLED;
536 532
537 return 0; 533 return 0;
538 } 534 }
539 535
540 static int imx_thermal_resume(struct device *dev) 536 static int imx_thermal_resume(struct device *dev)
541 { 537 {
542 struct imx_thermal_data *data = dev_get_drvdata(dev); 538 struct imx_thermal_data *data = dev_get_drvdata(dev);
543 struct regmap *map = data->tempmon; 539 struct regmap *map = data->tempmon;
544 540
545 /* Enabled thermal sensor after resume */ 541 /* Enabled thermal sensor after resume */
546 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); 542 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
547 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); 543 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
548 data->mode = THERMAL_DEVICE_ENABLED; 544 data->mode = THERMAL_DEVICE_ENABLED;
549 545
550 return 0; 546 return 0;
551 } 547 }
552 #endif 548 #endif
553 549
554 static SIMPLE_DEV_PM_OPS(imx_thermal_pm_ops, 550 static SIMPLE_DEV_PM_OPS(imx_thermal_pm_ops,
555 imx_thermal_suspend, imx_thermal_resume); 551 imx_thermal_suspend, imx_thermal_resume);
556 552
557 static const struct of_device_id of_imx_thermal_match[] = { 553 static const struct of_device_id of_imx_thermal_match[] = {
558 { .compatible = "fsl,imx6q-tempmon", }, 554 { .compatible = "fsl,imx6q-tempmon", },
559 { /* end */ } 555 { /* end */ }
560 }; 556 };
561 MODULE_DEVICE_TABLE(of, of_imx_thermal_match); 557 MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
562 558
563 static struct platform_driver imx_thermal = { 559 static struct platform_driver imx_thermal = {
564 .driver = { 560 .driver = {
565 .name = "imx_thermal", 561 .name = "imx_thermal",
566 .owner = THIS_MODULE, 562 .owner = THIS_MODULE,
567 .pm = &imx_thermal_pm_ops, 563 .pm = &imx_thermal_pm_ops,
568 .of_match_table = of_imx_thermal_match, 564 .of_match_table = of_imx_thermal_match,
569 }, 565 },
570 .probe = imx_thermal_probe, 566 .probe = imx_thermal_probe,
571 .remove = imx_thermal_remove, 567 .remove = imx_thermal_remove,
572 }; 568 };
573 module_platform_driver(imx_thermal); 569 module_platform_driver(imx_thermal);
574 570
575 MODULE_AUTHOR("Freescale Semiconductor, Inc."); 571 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
576 MODULE_DESCRIPTION("Thermal driver for Freescale i.MX SoCs"); 572 MODULE_DESCRIPTION("Thermal driver for Freescale i.MX SoCs");
577 MODULE_LICENSE("GPL v2"); 573 MODULE_LICENSE("GPL v2");
578 MODULE_ALIAS("platform:imx-thermal"); 574 MODULE_ALIAS("platform:imx-thermal");
579 575