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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxx>
> Signed-off-by: Sricharan Ramabadhran <quic_srichara@xxxxxxxxxxx>
> Signed-off-by: George Moussalem <george.moussalem@xxxxxxxxxxx>
> ---
>  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
> 

-- 
With best wishes
Dmitry




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux