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