1 /* 2 * exynos_tmu.c - Samsung EXYNOS TMU (Thermal Management Unit) 3 * 4 * Copyright (C) 2011 Samsung Electronics 5 * Donggeun Kim <dg77.kim@samsung.com> 6 * Amit Daniel Kachhap <amit.kachhap@linaro.org> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 23 24 #include <linux/clk.h> 25 #include <linux/io.h> 26 #include <linux/interrupt.h> 27 #include <linux/module.h> 28 #include <linux/of.h> 29 #include <linux/of_address.h> 30 #include <linux/of_irq.h> 31 #include <linux/platform_device.h> 32 #include <linux/regulator/consumer.h> 33 34 #include "exynos_thermal_common.h" 35 #include "exynos_tmu.h" 36 #include "exynos_tmu_data.h" 37 38 /** 39 * struct exynos_tmu_data : A structure to hold the private data of the TMU 40 driver 41 * @id: identifier of the one instance of the TMU controller. 42 * @pdata: pointer to the tmu platform/configuration data 43 * @base: base address of the single instance of the TMU controller. 44 * @base_common: base address of the common registers of the TMU controller. 45 * @irq: irq number of the TMU controller. 46 * @soc: id of the SOC type. 47 * @irq_work: pointer to the irq work structure. 48 * @lock: lock to implement synchronization. 49 * @clk: pointer to the clock structure. 50 * @temp_error1: fused value of the first point trim. 51 * @temp_error2: fused value of the second point trim. 52 * @regulator: pointer to the TMU regulator structure. 53 * @reg_conf: pointer to structure to register with core thermal. 54 */ 55 struct exynos_tmu_data { 56 int id; 57 struct exynos_tmu_platform_data *pdata; 58 void __iomem *base; 59 void __iomem *base_common; 60 int irq; 61 enum soc_type soc; 62 struct work_struct irq_work; 63 struct mutex lock; 64 struct clk *clk; 65 u8 temp_error1, temp_error2; 66 struct regulator *regulator; 67 struct thermal_sensor_conf *reg_conf; 68 }; 69 70 /* 71 * TMU treats temperature as a mapped temperature code. 72 * The temperature is converted differently depending on the calibration type. 73 */ 74 static int temp_to_code(struct exynos_tmu_data *data, u8 temp) 75 { 76 struct exynos_tmu_platform_data *pdata = data->pdata; 77 int temp_code; 78 79 if (pdata->cal_mode == HW_MODE) 80 return temp; 81 82 if (data->soc == SOC_ARCH_EXYNOS4210) 83 /* temp should range between 25 and 125 */ 84 if (temp < 25 || temp > 125) { 85 temp_code = -EINVAL; 86 goto out; 87 } 88 89 switch (pdata->cal_type) { 90 case TYPE_TWO_POINT_TRIMMING: 91 temp_code = (temp - pdata->first_point_trim) * 92 (data->temp_error2 - data->temp_error1) / 93 (pdata->second_point_trim - pdata->first_point_trim) + 94 data->temp_error1; 95 break; 96 case TYPE_ONE_POINT_TRIMMING: 97 temp_code = temp + data->temp_error1 - pdata->first_point_trim; 98 break; 99 default: 100 temp_code = temp + pdata->default_temp_offset; 101 break; 102 } 103 out: 104 return temp_code; 105 } 106 107 /* 108 * Calculate a temperature value from a temperature code. 109 * The unit of the temperature is degree Celsius. 110 */ 111 static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code) 112 { 113 struct exynos_tmu_platform_data *pdata = data->pdata; 114 int temp; 115 116 if (pdata->cal_mode == HW_MODE) 117 return temp_code; 118 119 if (data->soc == SOC_ARCH_EXYNOS4210) 120 /* temp_code should range between 75 and 175 */ 121 if (temp_code < 75 || temp_code > 175) { 122 temp = -ENODATA; 123 goto out; 124 } 125 126 switch (pdata->cal_type) { 127 case TYPE_TWO_POINT_TRIMMING: 128 temp = (temp_code - data->temp_error1) * 129 (pdata->second_point_trim - pdata->first_point_trim) / 130 (data->temp_error2 - data->temp_error1) + 131 pdata->first_point_trim; 132 break; 133 case TYPE_ONE_POINT_TRIMMING: 134 temp = temp_code - data->temp_error1 + pdata->first_point_trim; 135 break; 136 default: 137 temp = temp_code - pdata->default_temp_offset; 138 break; 139 } 140 out: 141 return temp; 142 } 143 144 static int exynos_tmu_initialize(struct platform_device *pdev) 145 { 146 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 147 struct exynos_tmu_platform_data *pdata = data->pdata; 148 const struct exynos_tmu_registers *reg = pdata->registers; 149 unsigned int status, trim_info = 0, con; 150 unsigned int rising_threshold = 0, falling_threshold = 0; 151 int ret = 0, threshold_code, i, trigger_levs = 0; 152 153 mutex_lock(&data->lock); 154 clk_enable(data->clk); 155 156 if (TMU_SUPPORTS(pdata, READY_STATUS)) { 157 status = readb(data->base + reg->tmu_status); 158 if (!status) { 159 ret = -EBUSY; 160 goto out; 161 } 162 } 163 164 if (TMU_SUPPORTS(pdata, TRIM_RELOAD)) 165 __raw_writel(1, data->base + reg->triminfo_ctrl); 166 167 if (pdata->cal_mode == HW_MODE) 168 goto skip_calib_data; 169 170 /* Save trimming info in order to perform calibration */ 171 if (data->soc == SOC_ARCH_EXYNOS5440) { 172 /* 173 * For exynos5440 soc triminfo value is swapped between TMU0 and 174 * TMU2, so the below logic is needed. 175 */ 176 switch (data->id) { 177 case 0: 178 trim_info = readl(data->base + 179 EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data); 180 break; 181 case 1: 182 trim_info = readl(data->base + reg->triminfo_data); 183 break; 184 case 2: 185 trim_info = readl(data->base - 186 EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data); 187 } 188 } else { 189 trim_info = readl(data->base + reg->triminfo_data); 190 } 191 data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; 192 data->temp_error2 = ((trim_info >> reg->triminfo_85_shift) & 193 EXYNOS_TMU_TEMP_MASK); 194 195 if (!data->temp_error1 || 196 (pdata->min_efuse_value > data->temp_error1) || 197 (data->temp_error1 > pdata->max_efuse_value)) 198 data->temp_error1 = pdata->efuse_value & EXYNOS_TMU_TEMP_MASK; 199 200 if (!data->temp_error2) 201 data->temp_error2 = 202 (pdata->efuse_value >> reg->triminfo_85_shift) & 203 EXYNOS_TMU_TEMP_MASK; 204 205 skip_calib_data: 206 if (pdata->max_trigger_level > MAX_THRESHOLD_LEVS) { 207 dev_err(&pdev->dev, "Invalid max trigger level\n"); 208 goto out; 209 } 210 211 for (i = 0; i < pdata->max_trigger_level; i++) { 212 if (!pdata->trigger_levels[i]) 213 continue; 214 215 if ((pdata->trigger_type[i] == HW_TRIP) && 216 (!pdata->trigger_levels[pdata->max_trigger_level - 1])) { 217 dev_err(&pdev->dev, "Invalid hw trigger level\n"); 218 ret = -EINVAL; 219 goto out; 220 } 221 222 /* Count trigger levels except the HW trip*/ 223 if (!(pdata->trigger_type[i] == HW_TRIP)) 224 trigger_levs++; 225 } 226 227 if (data->soc == SOC_ARCH_EXYNOS4210) { 228 /* Write temperature code for threshold */ 229 threshold_code = temp_to_code(data, pdata->threshold); 230 if (threshold_code < 0) { 231 ret = threshold_code; 232 goto out; 233 } 234 writeb(threshold_code, 235 data->base + reg->threshold_temp); 236 for (i = 0; i < trigger_levs; i++) 237 writeb(pdata->trigger_levels[i], data->base + 238 reg->threshold_th0 + i * sizeof(reg->threshold_th0)); 239 240 writel(reg->inten_rise_mask, data->base + reg->tmu_intclear); 241 } else { 242 /* Write temperature code for rising and falling threshold */ 243 for (i = 0; 244 i < trigger_levs && i < EXYNOS_MAX_TRIGGER_PER_REG; i++) { 245 threshold_code = temp_to_code(data, 246 pdata->trigger_levels[i]); 247 if (threshold_code < 0) { 248 ret = threshold_code; 249 goto out; 250 } 251 rising_threshold |= threshold_code << 8 * i; 252 if (pdata->threshold_falling) { 253 threshold_code = temp_to_code(data, 254 pdata->trigger_levels[i] - 255 pdata->threshold_falling); 256 if (threshold_code > 0) 257 falling_threshold |= 258 threshold_code << 8 * i; 259 } 260 } 261 262 writel(rising_threshold, 263 data->base + reg->threshold_th0); 264 writel(falling_threshold, 265 data->base + reg->threshold_th1); 266 267 writel((reg->inten_rise_mask << reg->inten_rise_shift) | 268 (reg->inten_fall_mask << reg->inten_fall_shift), 269 data->base + reg->tmu_intclear); 270 271 /* if last threshold limit is also present */ 272 i = pdata->max_trigger_level - 1; 273 if (pdata->trigger_levels[i] && 274 (pdata->trigger_type[i] == HW_TRIP)) { 275 threshold_code = temp_to_code(data, 276 pdata->trigger_levels[i]); 277 if (threshold_code < 0) { 278 ret = threshold_code; 279 goto out; 280 } 281 if (i == EXYNOS_MAX_TRIGGER_PER_REG - 1) { 282 /* 1-4 level to be assigned in th0 reg */ 283 rising_threshold |= threshold_code << 8 * i; 284 writel(rising_threshold, 285 data->base + reg->threshold_th0); 286 } else if (i == EXYNOS_MAX_TRIGGER_PER_REG) { 287 /* 5th level to be assigned in th2 reg */ 288 rising_threshold = 289 threshold_code << reg->threshold_th3_l0_shift; 290 writel(rising_threshold, 291 data->base + reg->threshold_th2); 292 } 293 con = readl(data->base + reg->tmu_ctrl); 294 con |= (1 << reg->therm_trip_en_shift); 295 writel(con, data->base + reg->tmu_ctrl); 296 } 297 } 298 /*Clear the PMIN in the common TMU register*/ 299 if (reg->tmu_pmin && !data->id) 300 writel(0, data->base_common + reg->tmu_pmin); 301 out: 302 clk_disable(data->clk); 303 mutex_unlock(&data->lock); 304 305 return ret; 306 } 307 308 static void exynos_tmu_control(struct platform_device *pdev, bool on) 309 { 310 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 311 struct exynos_tmu_platform_data *pdata = data->pdata; 312 const struct exynos_tmu_registers *reg = pdata->registers; 313 unsigned int con, interrupt_en, cal_val; 314 315 mutex_lock(&data->lock); 316 clk_enable(data->clk); 317 318 con = readl(data->base + reg->tmu_ctrl); 319 320 if (pdata->reference_voltage) { 321 con &= ~(reg->buf_vref_sel_mask << reg->buf_vref_sel_shift); 322 con |= pdata->reference_voltage << reg->buf_vref_sel_shift; 323 } 324 325 if (pdata->gain) { 326 con &= ~(reg->buf_slope_sel_mask << reg->buf_slope_sel_shift); 327 con |= (pdata->gain << reg->buf_slope_sel_shift); 328 } 329 330 if (pdata->noise_cancel_mode) { 331 con &= ~(reg->therm_trip_mode_mask << 332 reg->therm_trip_mode_shift); 333 con |= (pdata->noise_cancel_mode << reg->therm_trip_mode_shift); 334 } 335 336 if (pdata->cal_mode == HW_MODE) { 337 con &= ~(reg->calib_mode_mask << reg->calib_mode_shift); 338 cal_val = 0; 339 switch (pdata->cal_type) { 340 case TYPE_TWO_POINT_TRIMMING: 341 cal_val = 3; 342 break; 343 case TYPE_ONE_POINT_TRIMMING_85: 344 cal_val = 2; 345 break; 346 case TYPE_ONE_POINT_TRIMMING_25: 347 cal_val = 1; 348 break; 349 case TYPE_NONE: 350 break; 351 default: 352 dev_err(&pdev->dev, "Invalid calibration type, using none\n"); 353 } 354 con |= cal_val << reg->calib_mode_shift; 355 } 356 357 if (on) { 358 con |= (1 << reg->core_en_shift); 359 interrupt_en = 360 pdata->trigger_enable[3] << reg->inten_rise3_shift | 361 pdata->trigger_enable[2] << reg->inten_rise2_shift | 362 pdata->trigger_enable[1] << reg->inten_rise1_shift | 363 pdata->trigger_enable[0] << reg->inten_rise0_shift; 364 if (TMU_SUPPORTS(pdata, FALLING_TRIP)) 365 interrupt_en |= 366 interrupt_en << reg->inten_fall0_shift; 367 } else { 368 con &= ~(1 << reg->core_en_shift); 369 interrupt_en = 0; /* Disable all interrupts */ 370 } 371 writel(interrupt_en, data->base + reg->tmu_inten); 372 writel(con, data->base + reg->tmu_ctrl); 373 374 clk_disable(data->clk); 375 mutex_unlock(&data->lock); 376 } 377 378 static int exynos_tmu_read(struct exynos_tmu_data *data) 379 { 380 struct exynos_tmu_platform_data *pdata = data->pdata; 381 const struct exynos_tmu_registers *reg = pdata->registers; 382 u8 temp_code; 383 int temp; 384 385 mutex_lock(&data->lock); 386 clk_enable(data->clk); 387 388 temp_code = readb(data->base + reg->tmu_cur_temp); 389 temp = code_to_temp(data, temp_code); 390 391 clk_disable(data->clk); 392 mutex_unlock(&data->lock); 393 394 return temp; 395 } 396 397 #ifdef CONFIG_THERMAL_EMULATION 398 static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) 399 { 400 struct exynos_tmu_data *data = drv_data; 401 struct exynos_tmu_platform_data *pdata = data->pdata; 402 const struct exynos_tmu_registers *reg = pdata->registers; 403 unsigned int val; 404 int ret = -EINVAL; 405 406 if (!TMU_SUPPORTS(pdata, EMULATION)) 407 goto out; 408 409 if (temp && temp < MCELSIUS) 410 goto out; 411 412 mutex_lock(&data->lock); 413 clk_enable(data->clk); 414 415 val = readl(data->base + reg->emul_con); 416 417 if (temp) { 418 temp /= MCELSIUS; 419 420 if (TMU_SUPPORTS(pdata, EMUL_TIME)) { 421 val &= ~(EXYNOS_EMUL_TIME_MASK << reg->emul_time_shift); 422 val |= (EXYNOS_EMUL_TIME << reg->emul_time_shift); 423 } 424 val &= ~(EXYNOS_EMUL_DATA_MASK << reg->emul_temp_shift); 425 val |= (temp_to_code(data, temp) << reg->emul_temp_shift) | 426 EXYNOS_EMUL_ENABLE; 427 } else { 428 val &= ~EXYNOS_EMUL_ENABLE; 429 } 430 431 writel(val, data->base + reg->emul_con); 432 433 clk_disable(data->clk); 434 mutex_unlock(&data->lock); 435 return 0; 436 out: 437 return ret; 438 } 439 #else 440 static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) 441 { return -EINVAL; } 442 #endif/*CONFIG_THERMAL_EMULATION*/ 443 444 static void exynos_tmu_work(struct work_struct *work) 445 { 446 struct exynos_tmu_data *data = container_of(work, 447 struct exynos_tmu_data, irq_work); 448 struct exynos_tmu_platform_data *pdata = data->pdata; 449 const struct exynos_tmu_registers *reg = pdata->registers; 450 unsigned int val_irq, val_type; 451 452 /* Find which sensor generated this interrupt */ 453 if (reg->tmu_irqstatus) { 454 val_type = readl(data->base_common + reg->tmu_irqstatus); 455 if (!((val_type >> data->id) & 0x1)) 456 goto out; 457 } 458 459 exynos_report_trigger(data->reg_conf); 460 mutex_lock(&data->lock); 461 clk_enable(data->clk); 462 463 /* TODO: take action based on particular interrupt */ 464 val_irq = readl(data->base + reg->tmu_intstat); 465 /* clear the interrupts */ 466 writel(val_irq, data->base + reg->tmu_intclear); 467 468 clk_disable(data->clk); 469 mutex_unlock(&data->lock); 470 out: 471 enable_irq(data->irq); 472 } 473 474 static irqreturn_t exynos_tmu_irq(int irq, void *id) 475 { 476 struct exynos_tmu_data *data = id; 477 478 disable_irq_nosync(irq); 479 schedule_work(&data->irq_work); 480 481 return IRQ_HANDLED; 482 } 483 484 #ifdef CONFIG_OF 485 static const struct of_device_id exynos_tmu_match[] = { 486 { 487 .compatible = "samsung,exynos4210-tmu", 488 .data = (void *)EXYNOS4210_TMU_DRV_DATA, 489 }, 490 { 491 .compatible = "samsung,exynos4412-tmu", 492 .data = (void *)EXYNOS5250_TMU_DRV_DATA, 493 }, 494 { 495 .compatible = "samsung,exynos5250-tmu", 496 .data = (void *)EXYNOS5250_TMU_DRV_DATA, 497 }, 498 { 499 .compatible = "samsung,exynos5440-tmu", 500 .data = (void *)EXYNOS5440_TMU_DRV_DATA, 501 }, 502 {}, 503 }; 504 MODULE_DEVICE_TABLE(of, exynos_tmu_match); 505 #endif 506 507 static inline struct exynos_tmu_platform_data *exynos_get_driver_data( 508 struct platform_device *pdev, int id) 509 { 510 #ifdef CONFIG_OF 511 struct exynos_tmu_init_data *data_table; 512 struct exynos_tmu_platform_data *tmu_data; 513 if (pdev->dev.of_node) { 514 const struct of_device_id *match; 515 match = of_match_node(exynos_tmu_match, pdev->dev.of_node); 516 if (!match) 517 return NULL; 518 data_table = (struct exynos_tmu_init_data *) match->data; 519 if (!data_table || id >= data_table->tmu_count) 520 return NULL; 521 tmu_data = data_table->tmu_data; 522 return (struct exynos_tmu_platform_data *) (tmu_data + id); 523 } 524 #endif 525 return NULL; 526 } 527 528 static int exynos_map_dt_data(struct platform_device *pdev) 529 { 530 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 531 struct exynos_tmu_platform_data *pdata; 532 struct resource res; 533 int ret; 534 535 if (!data) 536 return -ENODEV; 537 538 /* 539 * Try enabling the regulator if found 540 * TODO: Add regulator as an SOC feature, so that regulator enable 541 * is a compulsory call. 542 */ 543 data->regulator = devm_regulator_get(&pdev->dev, "vtmu"); 544 if (!IS_ERR(data->regulator)) { 545 ret = regulator_enable(data->regulator); 546 if (ret) { 547 dev_err(&pdev->dev, "failed to enable vtmu\n"); 548 return ret; 549 } 550 } else { 551 dev_info(&pdev->dev, "Regulator node (vtmu) not found\n"); 552 } 553 554 data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl"); 555 if (data->id < 0) 556 data->id = 0; 557 558 data->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); 559 if (data->irq <= 0) { 560 dev_err(&pdev->dev, "failed to get IRQ\n"); 561 return -ENODEV; 562 } 563 564 if (of_address_to_resource(pdev->dev.of_node, 0, &res)) { 565 dev_err(&pdev->dev, "failed to get Resource 0\n"); 566 return -ENODEV; 567 } 568 569 data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res)); 570 if (!data->base) { 571 dev_err(&pdev->dev, "Failed to ioremap memory\n"); 572 return -EADDRNOTAVAIL; 573 } 574 575 pdata = exynos_get_driver_data(pdev, data->id); 576 if (!pdata) { 577 dev_err(&pdev->dev, "No platform init data supplied.\n"); 578 return -ENODEV; 579 } 580 data->pdata = pdata; 581 /* 582 * Check if the TMU shares some registers and then try to map the 583 * memory of common registers. 584 */ 585 if (!TMU_SUPPORTS(pdata, SHARED_MEMORY)) 586 return 0; 587 588 if (of_address_to_resource(pdev->dev.of_node, 1, &res)) { 589 dev_err(&pdev->dev, "failed to get Resource 1\n"); 590 return -ENODEV; 591 } 592 593 data->base_common = devm_ioremap(&pdev->dev, res.start, 594 resource_size(&res)); 595 if (!data->base) { 596 dev_err(&pdev->dev, "Failed to ioremap memory\n"); 597 return -ENOMEM; 598 } 599 600 return 0; 601 } 602 603 static int exynos_tmu_probe(struct platform_device *pdev) 604 { 605 struct exynos_tmu_data *data; 606 struct exynos_tmu_platform_data *pdata; 607 struct thermal_sensor_conf *sensor_conf; 608 int ret, i; 609 610 data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data), 611 GFP_KERNEL); 612 if (!data) { 613 dev_err(&pdev->dev, "Failed to allocate driver structure\n"); 614 return -ENOMEM; 615 } 616 617 platform_set_drvdata(pdev, data); 618 mutex_init(&data->lock); 619 620 ret = exynos_map_dt_data(pdev); 621 if (ret) 622 return ret; 623 624 pdata = data->pdata; 625 626 INIT_WORK(&data->irq_work, exynos_tmu_work); 627 628 data->clk = devm_clk_get(&pdev->dev, "tmu_apbif"); 629 if (IS_ERR(data->clk)) { 630 dev_err(&pdev->dev, "Failed to get clock\n"); 631 return PTR_ERR(data->clk); 632 } 633 634 ret = clk_prepare(data->clk); 635 if (ret) 636 return ret; 637 638 if (pdata->type == SOC_ARCH_EXYNOS || 639 pdata->type == SOC_ARCH_EXYNOS4210 || 640 pdata->type == SOC_ARCH_EXYNOS5440) 641 data->soc = pdata->type; 642 else { 643 ret = -EINVAL; 644 dev_err(&pdev->dev, "Platform not supported\n"); 645 goto err_clk; 646 } 647 648 ret = exynos_tmu_initialize(pdev); 649 if (ret) { 650 dev_err(&pdev->dev, "Failed to initialize TMU\n"); 651 goto err_clk; 652 } 653 654 exynos_tmu_control(pdev, true); 655 656 /* Allocate a structure to register with the exynos core thermal */ 657 sensor_conf = devm_kzalloc(&pdev->dev, 658 sizeof(struct thermal_sensor_conf), GFP_KERNEL); 659 if (!sensor_conf) { 660 dev_err(&pdev->dev, "Failed to allocate registration struct\n"); 661 ret = -ENOMEM; 662 goto err_clk; 663 } 664 sprintf(sensor_conf->name, "therm_zone%d", data->id); 665 sensor_conf->read_temperature = (int (*)(void *))exynos_tmu_read; 666 sensor_conf->write_emul_temp = 667 (int (*)(void *, unsigned long))exynos_tmu_set_emulation; 668 sensor_conf->driver_data = data; 669 sensor_conf->trip_data.trip_count = pdata->trigger_enable[0] + 670 pdata->trigger_enable[1] + pdata->trigger_enable[2]+ 671 pdata->trigger_enable[3]; 672 673 for (i = 0; i < sensor_conf->trip_data.trip_count; i++) { 674 sensor_conf->trip_data.trip_val[i] = 675 pdata->threshold + pdata->trigger_levels[i]; 676 sensor_conf->trip_data.trip_type[i] = 677 pdata->trigger_type[i]; 678 } 679 680 sensor_conf->trip_data.trigger_falling = pdata->threshold_falling; 681 682 sensor_conf->cooling_data.freq_clip_count = pdata->freq_tab_count; 683 for (i = 0; i < pdata->freq_tab_count; i++) { 684 sensor_conf->cooling_data.freq_data[i].freq_clip_max = 685 pdata->freq_tab[i].freq_clip_max; 686 sensor_conf->cooling_data.freq_data[i].temp_level = 687 pdata->freq_tab[i].temp_level; 688 } 689 sensor_conf->dev = &pdev->dev; 690 /* Register the sensor with thermal management interface */ 691 ret = exynos_register_thermal(sensor_conf); 692 if (ret) { 693 dev_err(&pdev->dev, "Failed to register thermal interface\n"); 694 goto err_clk; 695 } 696 data->reg_conf = sensor_conf; 697 698 ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq, 699 IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data); 700 if (ret) { 701 dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq); 702 goto err_clk; 703 } 704 705 return 0; 706 err_clk: 707 clk_unprepare(data->clk); 708 return ret; 709 } 710 711 static int exynos_tmu_remove(struct platform_device *pdev) 712 { 713 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 714 715 exynos_tmu_control(pdev, false); 716 717 exynos_unregister_thermal(data->reg_conf); 718 719 clk_unprepare(data->clk); 720 721 if (!IS_ERR(data->regulator)) 722 regulator_disable(data->regulator); 723 724 return 0; 725 } 726 727 #ifdef CONFIG_PM_SLEEP 728 static int exynos_tmu_suspend(struct device *dev) 729 { 730 exynos_tmu_control(to_platform_device(dev), false); 731 732 return 0; 733 } 734 735 static int exynos_tmu_resume(struct device *dev) 736 { 737 struct platform_device *pdev = to_platform_device(dev); 738 739 exynos_tmu_initialize(pdev); 740 exynos_tmu_control(pdev, true); 741 742 return 0; 743 } 744 745 static SIMPLE_DEV_PM_OPS(exynos_tmu_pm, 746 exynos_tmu_suspend, exynos_tmu_resume); 747 #define EXYNOS_TMU_PM (&exynos_tmu_pm) 748 #else 749 #define EXYNOS_TMU_PM NULL 750 #endif 751 752 static struct platform_driver exynos_tmu_driver = { 753 .driver = { 754 .name = "exynos-tmu", 755 .owner = THIS_MODULE, 756 .pm = EXYNOS_TMU_PM, 757 .of_match_table = of_match_ptr(exynos_tmu_match), 758 }, 759 .probe = exynos_tmu_probe, 760 .remove = exynos_tmu_remove, 761 }; 762 763 module_platform_driver(exynos_tmu_driver); 764 765 MODULE_DESCRIPTION("EXYNOS TMU Driver"); 766 MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); 767 MODULE_LICENSE("GPL"); 768 MODULE_ALIAS("platform:exynos-tmu"); 769