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