aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal/rockchip_thermal.c
diff options
context:
space:
mode:
authorCaesar Wang <wxt@rock-chips.com>2016-06-22 06:13:57 -0400
committerZhang Rui <rui.zhang@intel.com>2016-09-27 02:02:16 -0400
commit1f09ba82fa4bd405f5c656c48d53e076931b4a2d (patch)
tree58b495b04ad292595c732785cf4ca984e3bf6d6a /drivers/thermal/rockchip_thermal.c
parent466678790650a9dff6f107ca09a2f5e6480799e9 (diff)
thermal: rockchip: fixes the exception interrupts
The hardware-tracked trips will set the alarm interrupt value for registers. Then when the thermal zone has no trips to be set, That make the thermal trips callback a over range value. The root cause is the rk_tsadcv2_temp_to_code() function to handle the invalid temperature range is indeed incorrect, let's fix it on now. Otherwise, the thermal alarm interrupt will be triggered all the time on some SoCs. Fox example: localhost tmp # grep thermal /proc/interrupts; sleep 5; grep thermal /proc/interrupts 23: 994830 .. GICv3 129 Level rockchip_thermal 23: 1003423 .. GICv3 129 Level rockchip_thermal Reported-by: Rocky Hao <rocky.hao@rock-chips.com> Signed-off-by: Caesar Wang <wxt@rock-chips.com> Cc: Zhang Rui <rui.zhang@intel.com> Cc: Eduardo Valentin <edubezval@gmail.com> Cc: Heiko Stuebner <heiko@sntech.de> Cc: linux-pm@vger.kernel.org Signed-off-by: Eduardo Valentin <edubezval@gmail.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Diffstat (limited to 'drivers/thermal/rockchip_thermal.c')
-rw-r--r--drivers/thermal/rockchip_thermal.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 2d5ba97ade08..db5ecc5ed83a 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -401,13 +401,17 @@ static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table,
401 int temp) 401 int temp)
402{ 402{
403 int high, low, mid; 403 int high, low, mid;
404 u32 error = 0;
404 405
405 low = 0; 406 low = 0;
406 high = table.length - 1; 407 high = table.length - 1;
407 mid = (high + low) / 2; 408 mid = (high + low) / 2;
408 409
409 if (temp < table.id[low].temp || temp > table.id[high].temp) 410 /* Return mask code data when the temp is over table range */
410 return 0; 411 if (temp < table.id[low].temp || temp > table.id[high].temp) {
412 error = table.data_mask;
413 goto exit;
414 }
411 415
412 while (low <= high) { 416 while (low <= high) {
413 if (temp == table.id[mid].temp) 417 if (temp == table.id[mid].temp)
@@ -419,7 +423,9 @@ static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table,
419 mid = (low + high) / 2; 423 mid = (low + high) / 2;
420 } 424 }
421 425
422 return 0; 426exit:
427 pr_err("Invalid the conversion, error=%d\n", error);
428 return error;
423} 429}
424 430
425static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code, 431static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code,
@@ -651,7 +657,11 @@ static void rk_tsadcv2_alarm_temp(struct chip_tsadc_table table,
651{ 657{
652 u32 alarm_value, int_en; 658 u32 alarm_value, int_en;
653 659
660 /* Make sure the value is valid */
654 alarm_value = rk_tsadcv2_temp_to_code(table, temp); 661 alarm_value = rk_tsadcv2_temp_to_code(table, temp);
662 if (alarm_value == table.data_mask)
663 return;
664
655 writel_relaxed(alarm_value & table.data_mask, 665 writel_relaxed(alarm_value & table.data_mask,
656 regs + TSADCV2_COMP_INT(chn)); 666 regs + TSADCV2_COMP_INT(chn));
657 667
@@ -665,7 +675,11 @@ static void rk_tsadcv2_tshut_temp(struct chip_tsadc_table table,
665{ 675{
666 u32 tshut_value, val; 676 u32 tshut_value, val;
667 677
678 /* Make sure the value is valid */
668 tshut_value = rk_tsadcv2_temp_to_code(table, temp); 679 tshut_value = rk_tsadcv2_temp_to_code(table, temp);
680 if (tshut_value == table.data_mask)
681 return;
682
669 writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn)); 683 writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn));
670 684
671 /* TSHUT will be valid */ 685 /* TSHUT will be valid */