From: Caesar Wang Date: Wed, 22 Jun 2016 10:13:57 +0000 (+0800) Subject: FIXUP: FROMLIST: thermal: rockchip: fixes the exception interrupts X-Git-Tag: firefly_0821_release~2199 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=firefly-linux-kernel-4.4.55.git;a=commitdiff_plain;h=2b3943b3e4b6283446b87358250523450fa9d307 FIXUP: FROMLIST: 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 Change-Id: I0ddbd0b2dd9c03e785e588f5f339f1eeed4e1c5c Reported-by: Rocky Hao Signed-off-by: Caesar Wang Cc: Zhang Rui Cc: Eduardo Valentin Cc: Heiko Stuebner Cc: linux-pm@vger.kernel.org (am from https://patchwork.kernel.org/patch/9192357/) --- diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index 66508100eb5d..f46ab8721bc2 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -401,13 +401,15 @@ static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table, int temp) { int high, low, mid; + u32 error = table.data_mask; low = 0; high = table.length - 1; mid = (high + low) / 2; + /* Return mask code data when the temp is over table range */ if (temp < table.id[low].temp || temp > table.id[high].temp) - return 0; + goto exit; while (low <= high) { if (temp == table.id[mid].temp) @@ -419,7 +421,11 @@ static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table, mid = (low + high) / 2; } - return 0; +exit: + pr_err("%s: Invalid conversion table: code=%d, temperature=%d\n", + __func__, error, temp); + + return error; } static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code, @@ -469,7 +475,8 @@ static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code, } break; default: - pr_err("Invalid the conversion table\n"); + pr_err("%s: Invalid the conversion table mode=%d\n", + __func__, table.mode); } /* @@ -649,7 +656,11 @@ static void rk_tsadcv2_alarm_temp(struct chip_tsadc_table table, { u32 alarm_value, int_en; + /* Make sure the value is valid */ alarm_value = rk_tsadcv2_temp_to_code(table, temp); + if (alarm_value == table.data_mask) + return; + writel_relaxed(alarm_value & table.data_mask, regs + TSADCV2_COMP_INT(chn)); @@ -663,7 +674,11 @@ static void rk_tsadcv2_tshut_temp(struct chip_tsadc_table table, { u32 tshut_value, val; + /* Make sure the value is valid */ tshut_value = rk_tsadcv2_temp_to_code(table, temp); + if (tshut_value == table.data_mask) + return; + writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn)); /* TSHUT will be valid */