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