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 */ 62enum 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 78struct thermal_soc_data { 79 u32 version; 80}; 81 82static struct thermal_soc_data thermal_imx6q_data = { 83 .version = TEMPMON_IMX6Q, 84}; 85 86static struct thermal_soc_data thermal_imx6sx_data = { 87 .version = TEMPMON_IMX6SX, 88}; 89 90struct 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 108static 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 120static 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 133static 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 208static 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 218static 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 254static 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 262static 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 270static 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 280static 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 300static 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 319static 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 335static 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 347static 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 443static 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 453static 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 465static 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}; 470MODULE_DEVICE_TABLE(of, of_imx_thermal_match); 471 472static 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 609static 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 626static 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 645static 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 660static SIMPLE_DEV_PM_OPS(imx_thermal_pm_ops, 661 imx_thermal_suspend, imx_thermal_resume); 662 663static 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}; 672module_platform_driver(imx_thermal); 673 674MODULE_AUTHOR("Freescale Semiconductor, Inc."); 675MODULE_DESCRIPTION("Thermal driver for Freescale i.MX SoCs"); 676MODULE_LICENSE("GPL v2"); 677MODULE_ALIAS("platform:imx-thermal"); 678