aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal/exynos_thermal.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal/exynos_thermal.c')
-rw-r--r--drivers/thermal/exynos_thermal.c81
1 files changed, 46 insertions, 35 deletions
diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
index cd71e24194b1..f4dd68a25022 100644
--- a/drivers/thermal/exynos_thermal.c
+++ b/drivers/thermal/exynos_thermal.c
@@ -94,6 +94,7 @@
94#define SENSOR_NAME_LEN 16 94#define SENSOR_NAME_LEN 16
95#define MAX_TRIP_COUNT 8 95#define MAX_TRIP_COUNT 8
96#define MAX_COOLING_DEVICE 4 96#define MAX_COOLING_DEVICE 4
97#define MAX_THRESHOLD_LEVS 4
97 98
98#define ACTIVE_INTERVAL 500 99#define ACTIVE_INTERVAL 500
99#define IDLE_INTERVAL 10000 100#define IDLE_INTERVAL 10000
@@ -133,6 +134,7 @@ struct exynos_tmu_data {
133struct thermal_trip_point_conf { 134struct thermal_trip_point_conf {
134 int trip_val[MAX_TRIP_COUNT]; 135 int trip_val[MAX_TRIP_COUNT];
135 int trip_count; 136 int trip_count;
137 u8 trigger_falling;
136}; 138};
137 139
138struct thermal_cooling_conf { 140struct thermal_cooling_conf {
@@ -182,7 +184,8 @@ static int exynos_set_mode(struct thermal_zone_device *thermal,
182 184
183 mutex_lock(&th_zone->therm_dev->lock); 185 mutex_lock(&th_zone->therm_dev->lock);
184 186
185 if (mode == THERMAL_DEVICE_ENABLED) 187 if (mode == THERMAL_DEVICE_ENABLED &&
188 !th_zone->sensor_conf->trip_data.trigger_falling)
186 th_zone->therm_dev->polling_delay = IDLE_INTERVAL; 189 th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
187 else 190 else
188 th_zone->therm_dev->polling_delay = 0; 191 th_zone->therm_dev->polling_delay = 0;
@@ -428,7 +431,8 @@ static void exynos_report_trigger(void)
428 break; 431 break;
429 } 432 }
430 433
431 if (th_zone->mode == THERMAL_DEVICE_ENABLED) { 434 if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
435 !th_zone->sensor_conf->trip_data.trigger_falling) {
432 if (i > 0) 436 if (i > 0)
433 th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL; 437 th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
434 else 438 else
@@ -467,7 +471,8 @@ static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
467 471
468 th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name, 472 th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
469 EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0, 473 EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
470 IDLE_INTERVAL); 474 sensor_conf->trip_data.trigger_falling ?
475 0 : IDLE_INTERVAL);
471 476
472 if (IS_ERR(th_zone->therm_dev)) { 477 if (IS_ERR(th_zone->therm_dev)) {
473 pr_err("Failed to register thermal zone device\n"); 478 pr_err("Failed to register thermal zone device\n");
@@ -574,8 +579,9 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
574{ 579{
575 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 580 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
576 struct exynos_tmu_platform_data *pdata = data->pdata; 581 struct exynos_tmu_platform_data *pdata = data->pdata;
577 unsigned int status, trim_info, rising_threshold; 582 unsigned int status, trim_info;
578 int ret = 0, threshold_code; 583 unsigned int rising_threshold = 0, falling_threshold = 0;
584 int ret = 0, threshold_code, i, trigger_levs = 0;
579 585
580 mutex_lock(&data->lock); 586 mutex_lock(&data->lock);
581 clk_enable(data->clk); 587 clk_enable(data->clk);
@@ -600,6 +606,11 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
600 (data->temp_error2 != 0)) 606 (data->temp_error2 != 0))
601 data->temp_error1 = pdata->efuse_value; 607 data->temp_error1 = pdata->efuse_value;
602 608
609 /* Count trigger levels to be enabled */
610 for (i = 0; i < MAX_THRESHOLD_LEVS; i++)
611 if (pdata->trigger_levels[i])
612 trigger_levs++;
613
603 if (data->soc == SOC_ARCH_EXYNOS4210) { 614 if (data->soc == SOC_ARCH_EXYNOS4210) {
604 /* Write temperature code for threshold */ 615 /* Write temperature code for threshold */
605 threshold_code = temp_to_code(data, pdata->threshold); 616 threshold_code = temp_to_code(data, pdata->threshold);
@@ -609,44 +620,38 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
609 } 620 }
610 writeb(threshold_code, 621 writeb(threshold_code,
611 data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); 622 data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
612 623 for (i = 0; i < trigger_levs; i++)
613 writeb(pdata->trigger_levels[0], 624 writeb(pdata->trigger_levels[i],
614 data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0); 625 data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
615 writeb(pdata->trigger_levels[1],
616 data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL1);
617 writeb(pdata->trigger_levels[2],
618 data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL2);
619 writeb(pdata->trigger_levels[3],
620 data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL3);
621 626
622 writel(EXYNOS4210_TMU_INTCLEAR_VAL, 627 writel(EXYNOS4210_TMU_INTCLEAR_VAL,
623 data->base + EXYNOS_TMU_REG_INTCLEAR); 628 data->base + EXYNOS_TMU_REG_INTCLEAR);
624 } else if (data->soc == SOC_ARCH_EXYNOS) { 629 } else if (data->soc == SOC_ARCH_EXYNOS) {
625 /* Write temperature code for threshold */ 630 /* Write temperature code for rising and falling threshold */
626 threshold_code = temp_to_code(data, pdata->trigger_levels[0]); 631 for (i = 0; i < trigger_levs; i++) {
627 if (threshold_code < 0) { 632 threshold_code = temp_to_code(data,
628 ret = threshold_code; 633 pdata->trigger_levels[i]);
629 goto out; 634 if (threshold_code < 0) {
630 } 635 ret = threshold_code;
631 rising_threshold = threshold_code; 636 goto out;
632 threshold_code = temp_to_code(data, pdata->trigger_levels[1]); 637 }
633 if (threshold_code < 0) { 638 rising_threshold |= threshold_code << 8 * i;
634 ret = threshold_code; 639 if (pdata->threshold_falling) {
635 goto out; 640 threshold_code = temp_to_code(data,
636 } 641 pdata->trigger_levels[i] -
637 rising_threshold |= (threshold_code << 8); 642 pdata->threshold_falling);
638 threshold_code = temp_to_code(data, pdata->trigger_levels[2]); 643 if (threshold_code > 0)
639 if (threshold_code < 0) { 644 falling_threshold |=
640 ret = threshold_code; 645 threshold_code << 8 * i;
641 goto out; 646 }
642 } 647 }
643 rising_threshold |= (threshold_code << 16);
644 648
645 writel(rising_threshold, 649 writel(rising_threshold,
646 data->base + EXYNOS_THD_TEMP_RISE); 650 data->base + EXYNOS_THD_TEMP_RISE);
647 writel(0, data->base + EXYNOS_THD_TEMP_FALL); 651 writel(falling_threshold,
652 data->base + EXYNOS_THD_TEMP_FALL);
648 653
649 writel(EXYNOS_TMU_CLEAR_RISE_INT|EXYNOS_TMU_CLEAR_FALL_INT, 654 writel(EXYNOS_TMU_CLEAR_RISE_INT | EXYNOS_TMU_CLEAR_FALL_INT,
650 data->base + EXYNOS_TMU_REG_INTCLEAR); 655 data->base + EXYNOS_TMU_REG_INTCLEAR);
651 } 656 }
652out: 657out:
@@ -679,6 +684,8 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
679 pdata->trigger_level2_en << 8 | 684 pdata->trigger_level2_en << 8 |
680 pdata->trigger_level1_en << 4 | 685 pdata->trigger_level1_en << 4 |
681 pdata->trigger_level0_en; 686 pdata->trigger_level0_en;
687 if (pdata->threshold_falling)
688 interrupt_en |= interrupt_en << 16;
682 } else { 689 } else {
683 con |= EXYNOS_TMU_CORE_OFF; 690 con |= EXYNOS_TMU_CORE_OFF;
684 interrupt_en = 0; /* Disable all interrupts */ 691 interrupt_en = 0; /* Disable all interrupts */
@@ -716,7 +723,8 @@ static void exynos_tmu_work(struct work_struct *work)
716 mutex_lock(&data->lock); 723 mutex_lock(&data->lock);
717 clk_enable(data->clk); 724 clk_enable(data->clk);
718 if (data->soc == SOC_ARCH_EXYNOS) 725 if (data->soc == SOC_ARCH_EXYNOS)
719 writel(EXYNOS_TMU_CLEAR_RISE_INT, 726 writel(EXYNOS_TMU_CLEAR_RISE_INT |
727 EXYNOS_TMU_CLEAR_FALL_INT,
720 data->base + EXYNOS_TMU_REG_INTCLEAR); 728 data->base + EXYNOS_TMU_REG_INTCLEAR);
721 else 729 else
722 writel(EXYNOS4210_TMU_INTCLEAR_VAL, 730 writel(EXYNOS4210_TMU_INTCLEAR_VAL,
@@ -772,6 +780,7 @@ static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
772 780
773#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412) 781#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
774static struct exynos_tmu_platform_data const exynos_default_tmu_data = { 782static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
783 .threshold_falling = 10,
775 .trigger_levels[0] = 85, 784 .trigger_levels[0] = 85,
776 .trigger_levels[1] = 103, 785 .trigger_levels[1] = 103,
777 .trigger_levels[2] = 110, 786 .trigger_levels[2] = 110,
@@ -1015,6 +1024,8 @@ static int __devinit exynos_tmu_probe(struct platform_device *pdev)
1015 exynos_sensor_conf.trip_data.trip_val[i] = 1024 exynos_sensor_conf.trip_data.trip_val[i] =
1016 pdata->threshold + pdata->trigger_levels[i]; 1025 pdata->threshold + pdata->trigger_levels[i];
1017 1026
1027 exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling;
1028
1018 exynos_sensor_conf.cooling_data.freq_clip_count = 1029 exynos_sensor_conf.cooling_data.freq_clip_count =
1019 pdata->freq_tab_count; 1030 pdata->freq_tab_count;
1020 for (i = 0; i < pdata->freq_tab_count; i++) { 1031 for (i = 0; i < pdata->freq_tab_count; i++) {