Introduce lvts_platform_ops struct to support SoC-specific versions of
lvts_raw_to_temp() and lvts_temp_to_raw() conversion functions.
This is in preparation for supporting SoCs like MT8196/MT6991, which
require a different lvts_temp_to_raw() implementation.
Reviewed-by: Fei Shao <fshao@chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Laura Nao <laura.nao@collabora.com>
---
drivers/thermal/mediatek/lvts_thermal.c | 27 ++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
index 4ef549386add..df1c0f059ad0 100644
--- a/drivers/thermal/mediatek/lvts_thermal.c
+++ b/drivers/thermal/mediatek/lvts_thermal.c
@@ -125,8 +125,14 @@ struct lvts_ctrl_data {
continue; \
else
+struct lvts_platform_ops {
+ int (*lvts_raw_to_temp)(u32 raw_temp, int temp_factor);
+ u32 (*lvts_temp_to_raw)(int temperature, int temp_factor);
+};
+
struct lvts_data {
const struct lvts_ctrl_data *lvts_ctrl;
+ const struct lvts_platform_ops *ops;
const u32 *conn_cmd;
const u32 *init_cmd;
int num_cal_offsets;
@@ -300,6 +306,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,
sensors[lvts_sensor->id]);
const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
+ const struct lvts_platform_ops *ops = lvts_data->ops;
void __iomem *msr = lvts_sensor->msr;
u32 value;
int rc;
@@ -332,7 +339,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
if (rc)
return -EAGAIN;
- *temp = lvts_raw_to_temp(value & 0xFFFF, lvts_data->temp_factor);
+ *temp = ops->lvts_raw_to_temp(value & 0xFFFF, lvts_data->temp_factor);
return 0;
}
@@ -400,10 +407,11 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,
sensors[lvts_sensor->id]);
const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
+ const struct lvts_platform_ops *ops = lvts_data->ops;
void __iomem *base = lvts_sensor->base;
- u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD,
+ u32 raw_low = ops->lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD,
lvts_data->temp_factor);
- u32 raw_high = lvts_temp_to_raw(high, lvts_data->temp_factor);
+ u32 raw_high = ops->lvts_temp_to_raw(high, lvts_data->temp_factor);
bool should_update_thresh;
lvts_sensor->low_thresh = low;
@@ -1763,6 +1771,11 @@ static const struct lvts_ctrl_data mt8195_lvts_ap_data_ctrl[] = {
}
};
+static const struct lvts_platform_ops lvts_platform_ops_v1 = {
+ .lvts_raw_to_temp = lvts_raw_to_temp,
+ .lvts_temp_to_raw = lvts_temp_to_raw,
+};
+
static const struct lvts_data mt7988_lvts_ap_data = {
.lvts_ctrl = mt7988_lvts_ap_data_ctrl,
.conn_cmd = mt7988_conn_cmds,
@@ -1774,6 +1787,7 @@ static const struct lvts_data mt7988_lvts_ap_data = {
.temp_offset = LVTS_COEFF_B_MT7988,
.gt_calib_bit_offset = 24,
.num_cal_offsets = 3,
+ .ops = &lvts_platform_ops_v1,
};
static const struct lvts_data mt8186_lvts_data = {
@@ -1788,6 +1802,7 @@ static const struct lvts_data mt8186_lvts_data = {
.gt_calib_bit_offset = 24,
.def_calibration = 19000,
.num_cal_offsets = 3,
+ .ops = &lvts_platform_ops_v1,
};
static const struct lvts_data mt8188_lvts_mcu_data = {
@@ -1802,6 +1817,7 @@ static const struct lvts_data mt8188_lvts_mcu_data = {
.gt_calib_bit_offset = 20,
.def_calibration = 35000,
.num_cal_offsets = 3,
+ .ops = &lvts_platform_ops_v1,
};
static const struct lvts_data mt8188_lvts_ap_data = {
@@ -1816,6 +1832,7 @@ static const struct lvts_data mt8188_lvts_ap_data = {
.gt_calib_bit_offset = 20,
.def_calibration = 35000,
.num_cal_offsets = 3,
+ .ops = &lvts_platform_ops_v1,
};
static const struct lvts_data mt8192_lvts_mcu_data = {
@@ -1830,6 +1847,7 @@ static const struct lvts_data mt8192_lvts_mcu_data = {
.gt_calib_bit_offset = 24,
.def_calibration = 35000,
.num_cal_offsets = 3,
+ .ops = &lvts_platform_ops_v1,
};
static const struct lvts_data mt8192_lvts_ap_data = {
@@ -1844,6 +1862,7 @@ static const struct lvts_data mt8192_lvts_ap_data = {
.gt_calib_bit_offset = 24,
.def_calibration = 35000,
.num_cal_offsets = 3,
+ .ops = &lvts_platform_ops_v1,
};
static const struct lvts_data mt8195_lvts_mcu_data = {
@@ -1858,6 +1877,7 @@ static const struct lvts_data mt8195_lvts_mcu_data = {
.gt_calib_bit_offset = 24,
.def_calibration = 35000,
.num_cal_offsets = 3,
+ .ops = &lvts_platform_ops_v1,
};
static const struct lvts_data mt8195_lvts_ap_data = {
@@ -1872,6 +1892,7 @@ static const struct lvts_data mt8195_lvts_ap_data = {
.gt_calib_bit_offset = 24,
.def_calibration = 35000,
.num_cal_offsets = 3,
+ .ops = &lvts_platform_ops_v1,
};
static const struct of_device_id lvts_of_match[] = {
--
2.39.5
On 10/16/25 16:21, Laura Nao wrote:
> Introduce lvts_platform_ops struct to support SoC-specific versions of
> lvts_raw_to_temp() and lvts_temp_to_raw() conversion functions.
>
> This is in preparation for supporting SoCs like MT8196/MT6991, which
> require a different lvts_temp_to_raw() implementation.
>
> Reviewed-by: Fei Shao <fshao@chromium.org>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Signed-off-by: Laura Nao <laura.nao@collabora.com>
> ---
> drivers/thermal/mediatek/lvts_thermal.c | 27 ++++++++++++++++++++++---
> 1 file changed, 24 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
> index 4ef549386add..df1c0f059ad0 100644
> --- a/drivers/thermal/mediatek/lvts_thermal.c
> +++ b/drivers/thermal/mediatek/lvts_thermal.c
> @@ -125,8 +125,14 @@ struct lvts_ctrl_data {
> continue; \
> else
>
> +struct lvts_platform_ops {
> + int (*lvts_raw_to_temp)(u32 raw_temp, int temp_factor);
> + u32 (*lvts_temp_to_raw)(int temperature, int temp_factor);
> +};
> +
> struct lvts_data {
> const struct lvts_ctrl_data *lvts_ctrl;
> + const struct lvts_platform_ops *ops;
> const u32 *conn_cmd;
> const u32 *init_cmd;
> int num_cal_offsets;
> @@ -300,6 +306,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
> struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,
> sensors[lvts_sensor->id]);
> const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
> + const struct lvts_platform_ops *ops = lvts_data->ops;
> void __iomem *msr = lvts_sensor->msr;
> u32 value;
> int rc;
> @@ -332,7 +339,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
> if (rc)
> return -EAGAIN;
>
> - *temp = lvts_raw_to_temp(value & 0xFFFF, lvts_data->temp_factor);
> + *temp = ops->lvts_raw_to_temp(value & 0xFFFF, lvts_data->temp_factor);
Don't do this in each functions. It does not help for the readability.
May be something like:
int lvts_raw_to_temp(u32 raw_temp, const struct lvts_ctrl_data)
{
return data->ops->lvts_temp_to_raw(raw_temp, data->temp_factor);
}
or
int lvts_raw_to_temp(u32 raw_temp, const struct lvts_ctrl_data)
{
int temperature;
if (data->ops->lvts_temp_to_raw)
return data->ops->lvts_temp_to_raw(raw_temp, data->temp_factor);
temperature = ((s64)(raw_temp & 0xFFFF) * temp_factor) >> 14;
temperature += golden_temp_offset;
return temperature;
}
... and get rid of all the lvts_platform_ops_v1
(btw _v1 is confusing, it suggests there multiple versions of the same SoC)
[ ... ]
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
Hi Daniel,
On 11/10/25 14:06, Daniel Lezcano wrote:
> On 10/16/25 16:21, Laura Nao wrote:
>> Introduce lvts_platform_ops struct to support SoC-specific versions of
>> lvts_raw_to_temp() and lvts_temp_to_raw() conversion functions.
>>
>> This is in preparation for supporting SoCs like MT8196/MT6991, which
>> require a different lvts_temp_to_raw() implementation.
>>
>> Reviewed-by: Fei Shao <fshao@chromium.org>
>> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> Signed-off-by: Laura Nao <laura.nao@collabora.com>
>> ---
>> drivers/thermal/mediatek/lvts_thermal.c | 27 ++++++++++++++++++++++---
>> 1 file changed, 24 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
>> index 4ef549386add..df1c0f059ad0 100644
>> --- a/drivers/thermal/mediatek/lvts_thermal.c
>> +++ b/drivers/thermal/mediatek/lvts_thermal.c
>> @@ -125,8 +125,14 @@ struct lvts_ctrl_data {
>> continue; \
>> else
>> +struct lvts_platform_ops {
>> + int (*lvts_raw_to_temp)(u32 raw_temp, int temp_factor);
>> + u32 (*lvts_temp_to_raw)(int temperature, int temp_factor);
>> +};
>> +
>> struct lvts_data {
>> const struct lvts_ctrl_data *lvts_ctrl;
>> + const struct lvts_platform_ops *ops;
>> const u32 *conn_cmd;
>> const u32 *init_cmd;
>> int num_cal_offsets;
>> @@ -300,6 +306,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
>> struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,
>> sensors[lvts_sensor->id]);
>> const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
>> + const struct lvts_platform_ops *ops = lvts_data->ops;
>> void __iomem *msr = lvts_sensor->msr;
>> u32 value;
>> int rc;
>> @@ -332,7 +339,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
>> if (rc)
>> return -EAGAIN;
>> - *temp = lvts_raw_to_temp(value & 0xFFFF, lvts_data->temp_factor);
>> + *temp = ops->lvts_raw_to_temp(value & 0xFFFF, lvts_data->temp_factor);
>
> Don't do this in each functions. It does not help for the readability.
>
> May be something like:
>
> int lvts_raw_to_temp(u32 raw_temp, const struct lvts_ctrl_data)
> {
> return data->ops->lvts_temp_to_raw(raw_temp, data->temp_factor);
> }
>
> or
>
> int lvts_raw_to_temp(u32 raw_temp, const struct lvts_ctrl_data)
> {
> int temperature;
>
> if (data->ops->lvts_temp_to_raw)
> return data->ops->lvts_temp_to_raw(raw_temp, data->temp_factor);
>
> temperature = ((s64)(raw_temp & 0xFFFF) * temp_factor) >> 14;
> temperature += golden_temp_offset;
>
> return temperature;
> }
>
> ... and get rid of all the lvts_platform_ops_v1
>
> (btw _v1 is confusing, it suggests there multiple versions of the same SoC)
>
Right, the first option looks more efficient. Since temp_offset is
already part of lvts_data, the function would look like:
int lvts_raw_to_temp(u32 raw_temp, const struct lvts_data *lvts_data)
{
return lvts_data->ops->lvts_raw_to_temp(raw_temp, lvts_data->temp_factor);
}
and the same pattern applies for temp_to_raw().
This change will require renaming the existing
lvts_raw_to_temp()/lvts_temp_to_raw()/lvts_temp_to_raw_v2()
implementations. I agree the current _v1 and _v2 suffixes aren’t very
descriptive. Since lvts_temp_to_raw_v2() version is only used by MT8196,
it could be renamed to lvts_temp_to_raw_mt8196(), with the corresponding
platform ops defined as lvts_platform_ops_mt8196. The base
lvts_raw_to_temp()/lvts_temp_to_raw() are shared across the other SoCs,
so they could be renamed after the first supported platform (mt7988) and
reused for all SoCs that share the same logic.
I'll send out a v4 with the proposed changes.
Thanks,
Laura
> [ ... ]
>
© 2016 - 2026 Red Hat, Inc.