Re: [PATCH 1/2] thermal: qcom: tsens: atomic temperature read with hardware-guided retries
From: Daniel Lezcano
Date: Tue May 05 2026 - 03:43:58 EST
On 5/5/26 08:11, Priyansh Jain wrote:
[ ... ]
Thanks for pointing this out — yes, this approach looks better.+ .valid_bit = BIT(14),
+ .last_temp_mask = 0x3FF,
This is GENMASK(9, 0)
+ .last_temp_resolution = 9,
Please comply with the SSOT, in the init function compute the mask with:
->last_temp_mask = GENMASK(9, 0);
and remove the initialization here
If I understand correctly, you’re suggesting that the mask should simply be defined in the init function as follows:
priv->feat->last_temp_mask = GENMASK(priv->feat->last_temp_resolution, 0);
?
Yes, that's correct
I did not introduce this new function; it was already present and I only moved it from the bottom of the file to the top since it was being used in tsens_read_temp().};
static struct tsens_features ipq8074_feat = {
@@ -125,8 +128,7 @@ static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
[WDOG_BARK_COUNT] = REG_FIELD(TM_WDOG_LOG_OFF, 0, 7),
/* Sn_STATUS */
- REG_FIELD_FOR_EACH_SENSOR16(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 11),
- REG_FIELD_FOR_EACH_SENSOR16(VALID, TM_Sn_STATUS_OFF, 21, 21),
+ REG_FIELD_FOR_EACH_SENSOR16(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 21),
/* xxx_STATUS bits: 1 == threshold violated */
REG_FIELD_FOR_EACH_SENSOR16(MIN_STATUS, TM_Sn_STATUS_OFF, 16, 16),
REG_FIELD_FOR_EACH_SENSOR16(LOWER_STATUS, TM_Sn_STATUS_OFF, 17, 17),
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index a2422ebee816..15392a17ef41 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -315,10 +315,66 @@ static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
return degc;
}
+static inline enum tsens_ver tsens_version(struct tsens_priv *priv)
+{
+ return priv->feat->ver_major;
+}
I agree putting accessor functions is a good practice but here as it results in duplicating the function, the benefit is discutable.
However, this change is no longer required as I am removing the use of tsens_version() in tsens_read_temp(). As discussed earlier with Konrad, it makes more sense to check for valid‑bit support rather than relying on the TSENS version check in tsens_read_temp().
Ah yes, makes sense
[ ... ]
This approach has some misalignment with the HW recommendations.+ }
+
+ if (temp_val[0] == temp_val[1])
+ *temp = temp_val[1];
+ else if (temp_val[1] == temp_val[2])
+ *temp = temp_val[2];
+ else
+ return -EAGAIN;
We have a, b and c.
if a == b, then return b
else b == c, then return c
else return -EAGAIN
It is like we have two consecutives successful read. IMO that could be simplified to:
int prev = INTMAX;
/*
* An explanation ...
*/
for (i = 0; i < max_retry; i++) {
int value, valid;
ret = regmap_field_read(priv->rf[field], &status);
if (ret)
return ret;
value = FIELD_GET(priv->feat->last_temp_mask, status);
valid = FIELD_GET(priv->feat->valid_bit, status)
if (valid)
return value;
if (value == prev)
return value;
prev = value;
}
return -EAGAIN;
(Not tested)
As per the HW guidelines, 3 back‑to‑back reads must be performed until a valid read is observed.
b or c should be returned only if none of the three reads(a,b,c) report the valid bit not set.
Right I missed the point the HW recommendations is to read 3 times in any case. Maybe replace if (value == prev) continue; ?