drivers: thermal: tsens: add timeout to get_temp_tsens_valid
Subsystems (3)
PATCH RESEND v3 1/1 drivers: thermal: tsens: add timeout to get_temp_tsens_valid
The function can loop and lock the system if for whatever reason the bit for the target sensor is NEVER valid. This is the case if a sensor is disabled by the factory and the valid bit is never reported as actually valid. Add a timeout check and exit if a timeout occurs. As this is a very rare condition, handle the timeout only if the first read fails. While at it also rework the function to improve readability and convert to poll_timeout generic macro.
--- drivers/thermal/qcom/tsens.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-)
drivers/thermal/qcom/tsens.c +14 -15
@@ -603,22 +603,21 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)int ret;/* VER_0 doesn't have VALID bit */ -if (tsens_version (priv) >=VER_0_1 ) { - ret =regmap_field_read (priv->rf[valid_idx], &valid); -if (ret) -return ret; -while (!valid) { -/* Valid bit is 0 for 6 AHB clock cycles. -* At 19.2MHz, 1 AHB clock is ~60ns. -* We should enter this loop very, very rarely. -*/ -ndelay (400 ); - ret =regmap_field_read (priv->rf[valid_idx], &valid); -if (ret) -return ret; - } - } +if (tsens_version (priv) ==VER_0 ) + goto get_temp; + +/* Valid bit is 0 for 6 AHB clock cycles. +* At 19.2MHz, 1 AHB clock is ~60ns. +* We should enter this loop very, very rarely. +* Wait 1 us since it's the min of poll_timeout macro. +* Old value was 400 ns. +*/ + ret =regmap_field_read_poll_timeout (priv->rf[valid_idx], valid, + valid,1 ,20 *USEC_PER_MSEC ); +if (ret) +return ret; +get_temp:/* Valid bit is set, OK to read the temperature */ *temp =tsens_hw_to_mC (s, temp_idx);
Signature · 1 line
2.32.0
Quoted 8 lines · Ansuel Smith
The function can loop and lock the system if for whatever reason the bit for the target sensor is NEVER valid. This is the case if a sensor is disabled by the factory and the valid bit is never reported as actually valid. Add a timeout check and exit if a timeout occurs. As this is a very rare condition, handle the timeout only if the first read fails. While at it also rework the function to improve readability and convert to
poll_timeoutgeneric macro.
Regards,
Bjorn
Quoted 49 lines
Signed-off-by Ansuel Smith <[email protected]>--- drivers/thermal/qcom/tsens.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-)drivers/thermal/qcom/tsens.c +14
-15@@ -603,22 +603,21 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)int ret;/* VER_0 doesn't have VALID bit */ -if (tsens_version (priv) >=VER_0_1 ) { - ret =regmap_field_read (priv->rf[valid_idx], &valid); -if (ret) -return ret; -while (!valid) { -/* Valid bit is 0 for 6 AHB clock cycles. -* At 19.2MHz, 1 AHB clock is ~60ns. -* We should enter this loop very, very rarely. -*/ -ndelay (400 ); - ret =regmap_field_read (priv->rf[valid_idx], &valid); -if (ret) -return ret; - } - } +if (tsens_version (priv) ==VER_0 ) + goto get_temp; + +/* Valid bit is 0 for 6 AHB clock cycles. +* At 19.2MHz, 1 AHB clock is ~60ns. +* We should enter this loop very, very rarely. +* Wait 1 us since it's the min of poll_timeout macro. +* Old value was 400 ns. +*/ + ret =regmap_field_read_poll_timeout (priv->rf[valid_idx], valid, + valid,1 ,20 *USEC_PER_MSEC ); +if (ret) +return ret; +get_temp:/* Valid bit is set, OK to read the temperature */ *temp =tsens_hw_to_mC (s, temp_idx);Signature · 1 line
2.32.0
[thermal: thermal/next] thermal/drivers/tsens: Add timeout to get_temp_tsens_valid
In reply to Ansuel SmithThe following commit has been merged into the thermal/next branch of thermal:
The following commit has been merged into the thermal/next branch of thermal:
Commit-ID: d012f9189fda0f3a1b303780ba0bbc7298d0d349 Gitweb: https://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux.git//d012f9189fda0f3a1b303780ba0bbc7298d0d349 Author: Ansuel Smith <[email protected]> AuthorDate: Thu, 07 Oct 2021 19:28:59 +02:00 Committer: Daniel Lezcano <[email protected]> CommitterDate: Sat, 16 Oct 2021 20:24:43 +02:00
thermal/drivers/tsens: Add timeout to get_temp_tsens_valid
The function can loop and lock the system if for whatever reason the bit for the target sensor is NEVER valid. This is the case if a sensor is disabled by the factory and the valid bit is never reported as actually valid. Add a timeout check and exit if a timeout occurs. As this is a very rare condition, handle the timeout only if the first read fails. While at it also rework the function to improve readability and convert to poll_timeout generic macro.
--- drivers/thermal/qcom/tsens.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-)
drivers/thermal/qcom/tsens.c +14 -15
@@ -603,22 +603,21 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)int ret;/* VER_0 doesn't have VALID bit */ -if (tsens_version (priv) >=VER_0_1 ) { - ret =regmap_field_read (priv->rf[valid_idx], &valid); -if (ret) -return ret; -while (!valid) { -/* Valid bit is 0 for 6 AHB clock cycles. -* At 19.2MHz, 1 AHB clock is ~60ns. -* We should enter this loop very, very rarely. -*/ -ndelay (400 ); - ret =regmap_field_read (priv->rf[valid_idx], &valid); -if (ret) -return ret; - } - } +if (tsens_version (priv) ==VER_0 ) + goto get_temp; + +/* Valid bit is 0 for 6 AHB clock cycles. +* At 19.2MHz, 1 AHB clock is ~60ns. +* We should enter this loop very, very rarely. +* Wait 1 us since it's the min of poll_timeout macro. +* Old value was 400 ns. +*/ + ret =regmap_field_read_poll_timeout (priv->rf[valid_idx], valid, + valid,1 ,20 *USEC_PER_MSEC ); +if (ret) +return ret; +get_temp:/* Valid bit is set, OK to read the temperature */ *temp =tsens_hw_to_mC (s, temp_idx);