diff mbox series

[v8,3/5] thermal: qcom: tsens: add support for tsens v1 without RPM

Message ID DS7PR19MB888322C58FC555299256E8D99DCD2@DS7PR19MB8883.namprd19.prod.outlook.com (mailing list archive)
State Superseded, archived
Headers show
Series Add support for IPQ5018 tsens | expand

Commit Message

George Moussalem Feb. 27, 2025, 10:56 a.m. UTC
Adding generic support for SoCs with tsens v1.0 IP with no RPM.
Due to lack of RPM, tsens has to be reset and enabled in the driver
init.

Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
---
 drivers/thermal/qcom/tsens-v1.c | 48 +++++++++++++++++++++++++++++++++
 drivers/thermal/qcom/tsens.c    | 24 ++++++++++-------
 drivers/thermal/qcom/tsens.h    |  1 +
 3 files changed, 64 insertions(+), 9 deletions(-)

Comments

Dmitry Baryshkov Feb. 27, 2025, 2:59 p.m. UTC | #1
On Thu, Feb 27, 2025 at 02:56:41PM +0400, George Moussalem wrote:
> Adding generic support for SoCs with tsens v1.0 IP with no RPM.
> Due to lack of RPM, tsens has to be reset and enabled in the driver
> init.
> 
> Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
> Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
> Signed-off-by: George Moussalem <george.moussalem@outlook.com>
> ---
>  drivers/thermal/qcom/tsens-v1.c | 48 +++++++++++++++++++++++++++++++++
>  drivers/thermal/qcom/tsens.c    | 24 ++++++++++-------
>  drivers/thermal/qcom/tsens.h    |  1 +
>  3 files changed, 64 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
> index 1a7874676f68..877b27274fd2 100644
> --- a/drivers/thermal/qcom/tsens-v1.c
> +++ b/drivers/thermal/qcom/tsens-v1.c
> @@ -79,6 +79,17 @@ static struct tsens_features tsens_v1_feat = {
>  	.trip_max_temp	= 120000,
>  };
>  
> +static struct tsens_features tsens_v1_no_rpm_feat = {
> +	.ver_major	= VER_1_X_NO_RPM,
> +	.crit_int	= 0,
> +	.combo_int	= 0,
> +	.adc		= 1,
> +	.srot_split	= 1,
> +	.max_sensors	= 11,
> +	.trip_min_temp	= -40000,
> +	.trip_max_temp	= 120000,
> +};
> +
>  static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
>  	/* ----- SROT ------ */
>  	/* VERSION */
> @@ -150,6 +161,43 @@ static int __init init_8956(struct tsens_priv *priv) {
>  	return init_common(priv);
>  }
>  
> +static int __init init_tsens_v1_no_rpm(struct tsens_priv *priv)
> +{
> +	int i, ret;
> +	u32 mask = 0;
> +
> +	ret = init_common(priv);
> +	if (ret < 0) {
> +		dev_err(priv->dev, "Init common failed %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = regmap_field_write(priv->rf[TSENS_SW_RST], 1);
> +	if (ret) {
> +		dev_err(priv->dev, "Reset failed\n");
> +		return ret;
> +	}
> +
> +	for (i = 0; i < priv->num_sensors; i++)
> +		mask |= BIT(priv->sensor[i].hw_id);
> +
> +	ret = regmap_field_update_bits(priv->rf[SENSOR_EN], mask, mask);
> +	if (ret) {
> +		dev_err(priv->dev, "Sensor Enable failed\n");
> +		return ret;
> +	}
> +
> +	ret = regmap_field_write(priv->rf[TSENS_EN], 1);
> +	if (ret) {
> +		dev_err(priv->dev, "Enable failed\n");
> +		return ret;
> +	}
> +
> +	ret = regmap_field_write(priv->rf[TSENS_SW_RST], 0);
> +
> +	return ret;
> +}
> +
>  static const struct tsens_ops ops_generic_v1 = {
>  	.init		= init_common,
>  	.calibrate	= calibrate_v1,
> diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
> index 1f5d4de017d9..f860ea86d130 100644
> --- a/drivers/thermal/qcom/tsens.c
> +++ b/drivers/thermal/qcom/tsens.c
> @@ -447,7 +447,7 @@ static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,
>  	dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,
>  		irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",
>  		enable ? "en" : "dis");
> -	if (tsens_version(priv) > VER_1_X)
> +	if (tsens_version(priv) > VER_1_X_NO_RPM)

I'd suggest to replace these checks with >= VER_2_X. This saves us from
all the troubles if there is another 1.x 'modification' later on.

>  		tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);
>  	else
>  		tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);
> @@ -499,7 +499,7 @@ static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
>  	ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear);
>  	if (ret)
>  		return ret;
> -	if (tsens_version(priv) > VER_1_X) {
> +	if (tsens_version(priv) > VER_1_X_NO_RPM) {
>  		ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask);
>  		if (ret)
>  			return ret;
> @@ -543,7 +543,7 @@ static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
>  
>  static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver)
>  {
> -	if (ver > VER_1_X)
> +	if (ver > VER_1_X_NO_RPM)
>  		return mask & (1 << hw_id);
>  
>  	/* v1, v0.1 don't have a irq mask register */
> @@ -733,7 +733,7 @@ static int tsens_set_trips(struct thermal_zone_device *tz, int low, int high)
>  static int tsens_enable_irq(struct tsens_priv *priv)
>  {
>  	int ret;
> -	int val = tsens_version(priv) > VER_1_X ? 7 : 1;
> +	int val = tsens_version(priv) > VER_1_X_NO_RPM ? 7 : 1;
>  
>  	ret = regmap_field_write(priv->rf[INT_EN], val);
>  	if (ret < 0)
> @@ -975,10 +975,16 @@ int __init init_common(struct tsens_priv *priv)
>  	ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
>  	if (ret)
>  		goto err_put_device;
> -	if (!enabled && (tsens_version(priv) != VER_2_X_NO_RPM)) {
> -		dev_err(dev, "%s: device not enabled\n", __func__);
> -		ret = -ENODEV;
> -		goto err_put_device;
> +	if (!enabled) {
> +		switch (tsens_version(priv)) {
> +		case VER_1_X_NO_RPM:
> +		case VER_2_X_NO_RPM:
> +			break;
> +		default:
> +			dev_err(dev, "%s: device not enabled\n", __func__);
> +			ret = -ENODEV;
> +			goto err_put_device;
> +		}
>  	}
>  
>  	priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
> @@ -1040,7 +1046,7 @@ int __init init_common(struct tsens_priv *priv)
>  		}
>  	}
>  
> -	if (tsens_version(priv) > VER_1_X &&  ver_minor > 2) {
> +	if (tsens_version(priv) > VER_1_X_NO_RPM &&  ver_minor > 2) {
>  		/* Watchdog is present only on v2.3+ */
>  		priv->feat->has_watchdog = 1;
>  		for (i = WDOG_BARK_STATUS; i <= CC_MON_MASK; i++) {
> diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
> index 336bc868fd7c..e3cb611426c4 100644
> --- a/drivers/thermal/qcom/tsens.h
> +++ b/drivers/thermal/qcom/tsens.h
> @@ -34,6 +34,7 @@ enum tsens_ver {
>  	VER_0 = 0,
>  	VER_0_1,
>  	VER_1_X,
> +	VER_1_X_NO_RPM,
>  	VER_2_X,
>  	VER_2_X_NO_RPM,
>  };
> -- 
> 2.48.1
>
George Moussalem Feb. 27, 2025, 5:25 p.m. UTC | #2
On 2/27/25 18:59, Dmitry Baryshkov wrote:

> On Thu, Feb 27, 2025 at 02:56:41PM +0400, George Moussalem wrote:
>> Adding generic support for SoCs with tsens v1.0 IP with no RPM.
>> Due to lack of RPM, tsens has to be reset and enabled in the driver
>> init.
>>
>> Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
>> Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
>> Signed-off-by: George Moussalem <george.moussalem@outlook.com>
>> ---
>>  drivers/thermal/qcom/tsens-v1.c | 48 +++++++++++++++++++++++++++++++++
>>  drivers/thermal/qcom/tsens.c    | 24 ++++++++++-------
>>  drivers/thermal/qcom/tsens.h    |  1 +
>>  3 files changed, 64 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
>> index 1a7874676f68..877b27274fd2 100644
>> --- a/drivers/thermal/qcom/tsens-v1.c
>> +++ b/drivers/thermal/qcom/tsens-v1.c
>> @@ -79,6 +79,17 @@ static struct tsens_features tsens_v1_feat = {
>>  	.trip_max_temp	= 120000,
>>  };
>>  
>> +static struct tsens_features tsens_v1_no_rpm_feat = {
>> +	.ver_major	= VER_1_X_NO_RPM,
>> +	.crit_int	= 0,
>> +	.combo_int	= 0,
>> +	.adc		= 1,
>> +	.srot_split	= 1,
>> +	.max_sensors	= 11,
>> +	.trip_min_temp	= -40000,
>> +	.trip_max_temp	= 120000,
>> +};
>> +
>>  static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
>>  	/* ----- SROT ------ */
>>  	/* VERSION */
>> @@ -150,6 +161,43 @@ static int __init init_8956(struct tsens_priv *priv) {
>>  	return init_common(priv);
>>  }
>>  
>> +static int __init init_tsens_v1_no_rpm(struct tsens_priv *priv)
>> +{
>> +	int i, ret;
>> +	u32 mask = 0;
>> +
>> +	ret = init_common(priv);
>> +	if (ret < 0) {
>> +		dev_err(priv->dev, "Init common failed %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	ret = regmap_field_write(priv->rf[TSENS_SW_RST], 1);
>> +	if (ret) {
>> +		dev_err(priv->dev, "Reset failed\n");
>> +		return ret;
>> +	}
>> +
>> +	for (i = 0; i < priv->num_sensors; i++)
>> +		mask |= BIT(priv->sensor[i].hw_id);
>> +
>> +	ret = regmap_field_update_bits(priv->rf[SENSOR_EN], mask, mask);
>> +	if (ret) {
>> +		dev_err(priv->dev, "Sensor Enable failed\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = regmap_field_write(priv->rf[TSENS_EN], 1);
>> +	if (ret) {
>> +		dev_err(priv->dev, "Enable failed\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = regmap_field_write(priv->rf[TSENS_SW_RST], 0);
>> +
>> +	return ret;
>> +}
>> +
>>  static const struct tsens_ops ops_generic_v1 = {
>>  	.init		= init_common,
>>  	.calibrate	= calibrate_v1,
>> diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
>> index 1f5d4de017d9..f860ea86d130 100644
>> --- a/drivers/thermal/qcom/tsens.c
>> +++ b/drivers/thermal/qcom/tsens.c
>> @@ -447,7 +447,7 @@ static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,
>>  	dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,
>>  		irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",
>>  		enable ? "en" : "dis");
>> -	if (tsens_version(priv) > VER_1_X)
>> +	if (tsens_version(priv) > VER_1_X_NO_RPM)
> I'd suggest to replace these checks with >= VER_2_X. This saves us from
> all the troubles if there is another 1.x 'modification' later on.

makes sense, will change to >= VER_2_X. Thanks for the feedback.

>
>>  		tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);
>>  	else
>>  		tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);
>> @@ -499,7 +499,7 @@ static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
>>  	ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear);
>>  	if (ret)
>>  		return ret;
>> -	if (tsens_version(priv) > VER_1_X) {
>> +	if (tsens_version(priv) > VER_1_X_NO_RPM) {
>>  		ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask);
>>  		if (ret)
>>  			return ret;
>> @@ -543,7 +543,7 @@ static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
>>  
>>  static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver)
>>  {
>> -	if (ver > VER_1_X)
>> +	if (ver > VER_1_X_NO_RPM)
>>  		return mask & (1 << hw_id);
>>  
>>  	/* v1, v0.1 don't have a irq mask register */
>> @@ -733,7 +733,7 @@ static int tsens_set_trips(struct thermal_zone_device *tz, int low, int high)
>>  static int tsens_enable_irq(struct tsens_priv *priv)
>>  {
>>  	int ret;
>> -	int val = tsens_version(priv) > VER_1_X ? 7 : 1;
>> +	int val = tsens_version(priv) > VER_1_X_NO_RPM ? 7 : 1;
>>  
>>  	ret = regmap_field_write(priv->rf[INT_EN], val);
>>  	if (ret < 0)
>> @@ -975,10 +975,16 @@ int __init init_common(struct tsens_priv *priv)
>>  	ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
>>  	if (ret)
>>  		goto err_put_device;
>> -	if (!enabled && (tsens_version(priv) != VER_2_X_NO_RPM)) {
>> -		dev_err(dev, "%s: device not enabled\n", __func__);
>> -		ret = -ENODEV;
>> -		goto err_put_device;
>> +	if (!enabled) {
>> +		switch (tsens_version(priv)) {
>> +		case VER_1_X_NO_RPM:
>> +		case VER_2_X_NO_RPM:
>> +			break;
>> +		default:
>> +			dev_err(dev, "%s: device not enabled\n", __func__);
>> +			ret = -ENODEV;
>> +			goto err_put_device;
>> +		}
>>  	}
>>  
>>  	priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
>> @@ -1040,7 +1046,7 @@ int __init init_common(struct tsens_priv *priv)
>>  		}
>>  	}
>>  
>> -	if (tsens_version(priv) > VER_1_X &&  ver_minor > 2) {
>> +	if (tsens_version(priv) > VER_1_X_NO_RPM &&  ver_minor > 2) {
>>  		/* Watchdog is present only on v2.3+ */
>>  		priv->feat->has_watchdog = 1;
>>  		for (i = WDOG_BARK_STATUS; i <= CC_MON_MASK; i++) {
>> diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
>> index 336bc868fd7c..e3cb611426c4 100644
>> --- a/drivers/thermal/qcom/tsens.h
>> +++ b/drivers/thermal/qcom/tsens.h
>> @@ -34,6 +34,7 @@ enum tsens_ver {
>>  	VER_0 = 0,
>>  	VER_0_1,
>>  	VER_1_X,
>> +	VER_1_X_NO_RPM,
>>  	VER_2_X,
>>  	VER_2_X_NO_RPM,
>>  };
>> -- 
>> 2.48.1
>>
Dmitry Baryshkov Feb. 27, 2025, 7:02 p.m. UTC | #3
On Thu, Feb 27, 2025 at 09:25:05PM +0400, George Moussalem wrote:
> 
> On 2/27/25 18:59, Dmitry Baryshkov wrote:
> 
> > On Thu, Feb 27, 2025 at 02:56:41PM +0400, George Moussalem wrote:
> >> Adding generic support for SoCs with tsens v1.0 IP with no RPM.
> >> Due to lack of RPM, tsens has to be reset and enabled in the driver
> >> init.
> >>
> >> Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
> >> Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
> >> Signed-off-by: George Moussalem <george.moussalem@outlook.com>
> >> ---
> >>  drivers/thermal/qcom/tsens-v1.c | 48 +++++++++++++++++++++++++++++++++
> >>  drivers/thermal/qcom/tsens.c    | 24 ++++++++++-------
> >>  drivers/thermal/qcom/tsens.h    |  1 +
> >>  3 files changed, 64 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
> >> index 1a7874676f68..877b27274fd2 100644
> >> --- a/drivers/thermal/qcom/tsens-v1.c
> >> +++ b/drivers/thermal/qcom/tsens-v1.c
> >> @@ -79,6 +79,17 @@ static struct tsens_features tsens_v1_feat = {
> >>  	.trip_max_temp	= 120000,
> >>  };
> >>  
> >> +static struct tsens_features tsens_v1_no_rpm_feat = {
> >> +	.ver_major	= VER_1_X_NO_RPM,
> >> +	.crit_int	= 0,
> >> +	.combo_int	= 0,
> >> +	.adc		= 1,
> >> +	.srot_split	= 1,
> >> +	.max_sensors	= 11,
> >> +	.trip_min_temp	= -40000,
> >> +	.trip_max_temp	= 120000,
> >> +};
> >> +
> >>  static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
> >>  	/* ----- SROT ------ */
> >>  	/* VERSION */
> >> @@ -150,6 +161,43 @@ static int __init init_8956(struct tsens_priv *priv) {
> >>  	return init_common(priv);
> >>  }
> >>  
> >> +static int __init init_tsens_v1_no_rpm(struct tsens_priv *priv)
> >> +{
> >> +	int i, ret;
> >> +	u32 mask = 0;
> >> +
> >> +	ret = init_common(priv);
> >> +	if (ret < 0) {
> >> +		dev_err(priv->dev, "Init common failed %d\n", ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	ret = regmap_field_write(priv->rf[TSENS_SW_RST], 1);
> >> +	if (ret) {
> >> +		dev_err(priv->dev, "Reset failed\n");
> >> +		return ret;
> >> +	}
> >> +
> >> +	for (i = 0; i < priv->num_sensors; i++)
> >> +		mask |= BIT(priv->sensor[i].hw_id);
> >> +
> >> +	ret = regmap_field_update_bits(priv->rf[SENSOR_EN], mask, mask);
> >> +	if (ret) {
> >> +		dev_err(priv->dev, "Sensor Enable failed\n");
> >> +		return ret;
> >> +	}
> >> +
> >> +	ret = regmap_field_write(priv->rf[TSENS_EN], 1);
> >> +	if (ret) {
> >> +		dev_err(priv->dev, "Enable failed\n");
> >> +		return ret;
> >> +	}
> >> +
> >> +	ret = regmap_field_write(priv->rf[TSENS_SW_RST], 0);
> >> +
> >> +	return ret;
> >> +}
> >> +
> >>  static const struct tsens_ops ops_generic_v1 = {
> >>  	.init		= init_common,
> >>  	.calibrate	= calibrate_v1,
> >> diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
> >> index 1f5d4de017d9..f860ea86d130 100644
> >> --- a/drivers/thermal/qcom/tsens.c
> >> +++ b/drivers/thermal/qcom/tsens.c
> >> @@ -447,7 +447,7 @@ static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,
> >>  	dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,
> >>  		irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",
> >>  		enable ? "en" : "dis");
> >> -	if (tsens_version(priv) > VER_1_X)
> >> +	if (tsens_version(priv) > VER_1_X_NO_RPM)
> > I'd suggest to replace these checks with >= VER_2_X. This saves us from
> > all the troubles if there is another 1.x 'modification' later on.
> 
> makes sense, will change to >= VER_2_X. Thanks for the feedback.

THanks! It also makes sense to split this into two patches then: one
which changes the condition all over the place and the other one which
adds VER_1_X_NO_RPM.

> 
> >
> >>  		tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);
> >>  	else
> >>  		tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);
George Moussalem Feb. 28, 2025, 4:16 a.m. UTC | #4
On 2/27/25 23:02, Dmitry Baryshkov wrote:
> On Thu, Feb 27, 2025 at 09:25:05PM +0400, George Moussalem wrote:
>> On 2/27/25 18:59, Dmitry Baryshkov wrote:
>>
>>> On Thu, Feb 27, 2025 at 02:56:41PM +0400, George Moussalem wrote:
>>>> Adding generic support for SoCs with tsens v1.0 IP with no RPM.
>>>> Due to lack of RPM, tsens has to be reset and enabled in the driver
>>>> init.
>>>>
>>>> Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
>>>> Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
>>>> Signed-off-by: George Moussalem <george.moussalem@outlook.com>
>>>> ---
>>>>  drivers/thermal/qcom/tsens-v1.c | 48 +++++++++++++++++++++++++++++++++
>>>>  drivers/thermal/qcom/tsens.c    | 24 ++++++++++-------
>>>>  drivers/thermal/qcom/tsens.h    |  1 +
>>>>  3 files changed, 64 insertions(+), 9 deletions(-)
>>>>
>>>> diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
>>>> index 1a7874676f68..877b27274fd2 100644
>>>> --- a/drivers/thermal/qcom/tsens-v1.c
>>>> +++ b/drivers/thermal/qcom/tsens-v1.c
>>>> @@ -79,6 +79,17 @@ static struct tsens_features tsens_v1_feat = {
>>>>  	.trip_max_temp	= 120000,
>>>>  };
>>>>  
>>>> +static struct tsens_features tsens_v1_no_rpm_feat = {
>>>> +	.ver_major	= VER_1_X_NO_RPM,
>>>> +	.crit_int	= 0,
>>>> +	.combo_int	= 0,
>>>> +	.adc		= 1,
>>>> +	.srot_split	= 1,
>>>> +	.max_sensors	= 11,
>>>> +	.trip_min_temp	= -40000,
>>>> +	.trip_max_temp	= 120000,
>>>> +};
>>>> +
>>>>  static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
>>>>  	/* ----- SROT ------ */
>>>>  	/* VERSION */
>>>> @@ -150,6 +161,43 @@ static int __init init_8956(struct tsens_priv *priv) {
>>>>  	return init_common(priv);
>>>>  }
>>>>  
>>>> +static int __init init_tsens_v1_no_rpm(struct tsens_priv *priv)
>>>> +{
>>>> +	int i, ret;
>>>> +	u32 mask = 0;
>>>> +
>>>> +	ret = init_common(priv);
>>>> +	if (ret < 0) {
>>>> +		dev_err(priv->dev, "Init common failed %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	ret = regmap_field_write(priv->rf[TSENS_SW_RST], 1);
>>>> +	if (ret) {
>>>> +		dev_err(priv->dev, "Reset failed\n");
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	for (i = 0; i < priv->num_sensors; i++)
>>>> +		mask |= BIT(priv->sensor[i].hw_id);
>>>> +
>>>> +	ret = regmap_field_update_bits(priv->rf[SENSOR_EN], mask, mask);
>>>> +	if (ret) {
>>>> +		dev_err(priv->dev, "Sensor Enable failed\n");
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	ret = regmap_field_write(priv->rf[TSENS_EN], 1);
>>>> +	if (ret) {
>>>> +		dev_err(priv->dev, "Enable failed\n");
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	ret = regmap_field_write(priv->rf[TSENS_SW_RST], 0);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>>  static const struct tsens_ops ops_generic_v1 = {
>>>>  	.init		= init_common,
>>>>  	.calibrate	= calibrate_v1,
>>>> diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
>>>> index 1f5d4de017d9..f860ea86d130 100644
>>>> --- a/drivers/thermal/qcom/tsens.c
>>>> +++ b/drivers/thermal/qcom/tsens.c
>>>> @@ -447,7 +447,7 @@ static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,
>>>>  	dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,
>>>>  		irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",
>>>>  		enable ? "en" : "dis");
>>>> -	if (tsens_version(priv) > VER_1_X)
>>>> +	if (tsens_version(priv) > VER_1_X_NO_RPM)
>>> I'd suggest to replace these checks with >= VER_2_X. This saves us from
>>> all the troubles if there is another 1.x 'modification' later on.
>> makes sense, will change to >= VER_2_X. Thanks for the feedback.
> THanks! It also makes sense to split this into two patches then: one
> which changes the condition all over the place and the other one which
> adds VER_1_X_NO_RPM.
Sounds good, will split into two. Will send v9 shortly..

Kind regards,
George
>>>>  		tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);
>>>>  	else
>>>>  		tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);
diff mbox series

Patch

diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
index 1a7874676f68..877b27274fd2 100644
--- a/drivers/thermal/qcom/tsens-v1.c
+++ b/drivers/thermal/qcom/tsens-v1.c
@@ -79,6 +79,17 @@  static struct tsens_features tsens_v1_feat = {
 	.trip_max_temp	= 120000,
 };
 
+static struct tsens_features tsens_v1_no_rpm_feat = {
+	.ver_major	= VER_1_X_NO_RPM,
+	.crit_int	= 0,
+	.combo_int	= 0,
+	.adc		= 1,
+	.srot_split	= 1,
+	.max_sensors	= 11,
+	.trip_min_temp	= -40000,
+	.trip_max_temp	= 120000,
+};
+
 static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
 	/* ----- SROT ------ */
 	/* VERSION */
@@ -150,6 +161,43 @@  static int __init init_8956(struct tsens_priv *priv) {
 	return init_common(priv);
 }
 
+static int __init init_tsens_v1_no_rpm(struct tsens_priv *priv)
+{
+	int i, ret;
+	u32 mask = 0;
+
+	ret = init_common(priv);
+	if (ret < 0) {
+		dev_err(priv->dev, "Init common failed %d\n", ret);
+		return ret;
+	}
+
+	ret = regmap_field_write(priv->rf[TSENS_SW_RST], 1);
+	if (ret) {
+		dev_err(priv->dev, "Reset failed\n");
+		return ret;
+	}
+
+	for (i = 0; i < priv->num_sensors; i++)
+		mask |= BIT(priv->sensor[i].hw_id);
+
+	ret = regmap_field_update_bits(priv->rf[SENSOR_EN], mask, mask);
+	if (ret) {
+		dev_err(priv->dev, "Sensor Enable failed\n");
+		return ret;
+	}
+
+	ret = regmap_field_write(priv->rf[TSENS_EN], 1);
+	if (ret) {
+		dev_err(priv->dev, "Enable failed\n");
+		return ret;
+	}
+
+	ret = regmap_field_write(priv->rf[TSENS_SW_RST], 0);
+
+	return ret;
+}
+
 static const struct tsens_ops ops_generic_v1 = {
 	.init		= init_common,
 	.calibrate	= calibrate_v1,
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 1f5d4de017d9..f860ea86d130 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -447,7 +447,7 @@  static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,
 	dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,
 		irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",
 		enable ? "en" : "dis");
-	if (tsens_version(priv) > VER_1_X)
+	if (tsens_version(priv) > VER_1_X_NO_RPM)
 		tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);
 	else
 		tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);
@@ -499,7 +499,7 @@  static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
 	ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear);
 	if (ret)
 		return ret;
-	if (tsens_version(priv) > VER_1_X) {
+	if (tsens_version(priv) > VER_1_X_NO_RPM) {
 		ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask);
 		if (ret)
 			return ret;
@@ -543,7 +543,7 @@  static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
 
 static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver)
 {
-	if (ver > VER_1_X)
+	if (ver > VER_1_X_NO_RPM)
 		return mask & (1 << hw_id);
 
 	/* v1, v0.1 don't have a irq mask register */
@@ -733,7 +733,7 @@  static int tsens_set_trips(struct thermal_zone_device *tz, int low, int high)
 static int tsens_enable_irq(struct tsens_priv *priv)
 {
 	int ret;
-	int val = tsens_version(priv) > VER_1_X ? 7 : 1;
+	int val = tsens_version(priv) > VER_1_X_NO_RPM ? 7 : 1;
 
 	ret = regmap_field_write(priv->rf[INT_EN], val);
 	if (ret < 0)
@@ -975,10 +975,16 @@  int __init init_common(struct tsens_priv *priv)
 	ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
 	if (ret)
 		goto err_put_device;
-	if (!enabled && (tsens_version(priv) != VER_2_X_NO_RPM)) {
-		dev_err(dev, "%s: device not enabled\n", __func__);
-		ret = -ENODEV;
-		goto err_put_device;
+	if (!enabled) {
+		switch (tsens_version(priv)) {
+		case VER_1_X_NO_RPM:
+		case VER_2_X_NO_RPM:
+			break;
+		default:
+			dev_err(dev, "%s: device not enabled\n", __func__);
+			ret = -ENODEV;
+			goto err_put_device;
+		}
 	}
 
 	priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
@@ -1040,7 +1046,7 @@  int __init init_common(struct tsens_priv *priv)
 		}
 	}
 
-	if (tsens_version(priv) > VER_1_X &&  ver_minor > 2) {
+	if (tsens_version(priv) > VER_1_X_NO_RPM &&  ver_minor > 2) {
 		/* Watchdog is present only on v2.3+ */
 		priv->feat->has_watchdog = 1;
 		for (i = WDOG_BARK_STATUS; i <= CC_MON_MASK; i++) {
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 336bc868fd7c..e3cb611426c4 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -34,6 +34,7 @@  enum tsens_ver {
 	VER_0 = 0,
 	VER_0_1,
 	VER_1_X,
+	VER_1_X_NO_RPM,
 	VER_2_X,
 	VER_2_X_NO_RPM,
 };