[PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function

Christian Marangi posted 5 patches 1 month, 1 week ago
[PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function
Posted by Christian Marangi 1 month, 1 week ago
In preparation for support of Airoha AN7583, generalize the probe
function to address for the 2 SoC differece.

Implement a match_data struct where it's possible to define a more
specific probe and post_probe function and specific thermal ops and
pllrg protect value.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++--------
 1 file changed, 75 insertions(+), 27 deletions(-)

diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
index 01ed49a4887e..864a01fd8fd8 100644
--- a/drivers/thermal/airoha_thermal.c
+++ b/drivers/thermal/airoha_thermal.c
@@ -198,12 +198,23 @@ struct airoha_thermal_priv {
 	struct regmap *chip_scu;
 	struct resource scu_adc_res;
 
+	u32 pllrg_protect;
+
 	struct thermal_zone_device *tz;
 	int init_temp;
 	int default_slope;
 	int default_offset;
 };
 
+struct airoha_thermal_soc_data {
+	u32 pllrg_protect;
+
+	const struct thermal_zone_device_ops *thdev_ops;
+	int (*probe)(struct platform_device *pdev,
+		     struct airoha_thermal_priv *priv);
+	int (*post_probe)(struct platform_device *pdev);
+};
+
 static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
 {
 	u32 val;
@@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
 	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
 
 	/* Give access to thermal regs */
-	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
+	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
+		     priv->pllrg_protect);
 	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
 	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
 
@@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
 }
 
-static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
+static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
 {
 	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
 	int min_value, max_value, avg_value, value;
@@ -253,7 +265,7 @@ static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
 	return 0;
 }
 
-static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
+static int en7581_thermal_set_trips(struct thermal_zone_device *tz, int low,
 				    int high)
 {
 	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
@@ -290,12 +302,12 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
 	return 0;
 }
 
-static const struct thermal_zone_device_ops thdev_ops = {
-	.get_temp = airoha_thermal_get_temp,
-	.set_trips = airoha_thermal_set_trips,
+static const struct thermal_zone_device_ops en7581_thdev_ops = {
+	.get_temp = en7581_thermal_get_temp,
+	.set_trips = en7581_thermal_set_trips,
 };
 
-static irqreturn_t airoha_thermal_irq(int irq, void *data)
+static irqreturn_t en7581_thermal_irq(int irq, void *data)
 {
 	struct airoha_thermal_priv *priv = data;
 	enum thermal_notify_event event;
@@ -326,7 +338,7 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static void airoha_thermal_setup_adc_val(struct device *dev,
+static void en7581_thermal_setup_adc_val(struct device *dev,
 					 struct airoha_thermal_priv *priv)
 {
 	u32 efuse_calib_info, cpu_sensor;
@@ -356,7 +368,7 @@ static void airoha_thermal_setup_adc_val(struct device *dev,
 	}
 }
 
-static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
+static void en7581_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 {
 	/* Set measure mode */
 	regmap_write(priv->map, EN7581_TEMPMSRCTL0,
@@ -411,30 +423,26 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 		     FIELD_PREP(EN7581_ADC_POLL_INTVL, 146));
 }
 
-static const struct regmap_config airoha_thermal_regmap_config = {
+static const struct regmap_config en7581_thermal_regmap_config = {
 	.reg_bits		= 32,
 	.reg_stride		= 4,
 	.val_bits		= 32,
 };
 
-static int airoha_thermal_probe(struct platform_device *pdev)
+static int en7581_thermal_probe(struct platform_device *pdev,
+				struct airoha_thermal_priv *priv)
 {
-	struct airoha_thermal_priv *priv;
 	struct device_node *chip_scu_np;
 	struct device *dev = &pdev->dev;
 	void __iomem *base;
 	int irq, ret;
 
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
 	priv->map = devm_regmap_init_mmio(dev, base,
-					  &airoha_thermal_regmap_config);
+					  &en7581_thermal_regmap_config);
 	if (IS_ERR(priv->map))
 		return PTR_ERR(priv->map);
 
@@ -454,18 +462,55 @@ static int airoha_thermal_probe(struct platform_device *pdev)
 		return irq;
 
 	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
-					airoha_thermal_irq, IRQF_ONESHOT,
+					en7581_thermal_irq, IRQF_ONESHOT,
 					pdev->name, priv);
 	if (ret) {
 		dev_err(dev, "Can't get interrupt working.\n");
 		return ret;
 	}
 
-	airoha_thermal_setup_monitor(priv);
-	airoha_thermal_setup_adc_val(dev, priv);
+	en7581_thermal_setup_monitor(priv);
+	en7581_thermal_setup_adc_val(dev, priv);
+
+	return 0;
+}
+
+static int en7581_thermal_post_probe(struct platform_device *pdev)
+{
+	struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
+
+	/* Enable LOW and HIGH interrupt (if supported) */
+	regmap_write(priv->map, EN7581_TEMPMONINT,
+		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
+
+	return 0;
+}
+
+static int airoha_thermal_probe(struct platform_device *pdev)
+{
+	const struct airoha_thermal_soc_data *soc_data;
+	struct airoha_thermal_priv *priv;
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	soc_data = device_get_match_data(dev);
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->pllrg_protect = soc_data->pllrg_protect;
+
+	if (!soc_data->probe)
+		return -EINVAL;
+
+	ret = soc_data->probe(pdev, priv);
+	if (ret)
+		return ret;
 
 	/* register of thermal sensor and get info from DT */
-	priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops);
+	priv->tz = devm_thermal_of_zone_register(dev, 0, priv,
+						 soc_data->thdev_ops);
 	if (IS_ERR(priv->tz)) {
 		dev_err(dev, "register thermal zone sensor failed\n");
 		return PTR_ERR(priv->tz);
@@ -473,15 +518,18 @@ static int airoha_thermal_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, priv);
 
-	/* Enable LOW and HIGH interrupt */
-	regmap_write(priv->map, EN7581_TEMPMONINT,
-		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
-
-	return 0;
+	return soc_data->post_probe ? soc_data->post_probe(pdev) : 0;
 }
 
+static const struct airoha_thermal_soc_data en7581_data = {
+	.pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
+	.thdev_ops = &en7581_thdev_ops,
+	.probe = &en7581_thermal_probe,
+	.post_probe = &en7581_thermal_post_probe,
+};
+
 static const struct of_device_id airoha_thermal_match[] = {
-	{ .compatible = "airoha,en7581-thermal" },
+	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, airoha_thermal_match);
-- 
2.51.0
Re: [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function
Posted by Daniel Lezcano 2 weeks, 5 days ago
On 11/6/25 23:59, Christian Marangi wrote:
> In preparation for support of Airoha AN7583, generalize the probe
> function to address for the 2 SoC differece.
> 
> Implement a match_data struct where it's possible to define a more
> specific probe and post_probe function and specific thermal ops and
> pllrg protect value.
> 
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
>   drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++--------
>   1 file changed, 75 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
> index 01ed49a4887e..864a01fd8fd8 100644
> --- a/drivers/thermal/airoha_thermal.c
> +++ b/drivers/thermal/airoha_thermal.c
> @@ -198,12 +198,23 @@ struct airoha_thermal_priv {
>   	struct regmap *chip_scu;
>   	struct resource scu_adc_res;
>   
> +	u32 pllrg_protect;
> +
>   	struct thermal_zone_device *tz;
>   	int init_temp;
>   	int default_slope;
>   	int default_offset;
>   };
>   
> +struct airoha_thermal_soc_data {
> +	u32 pllrg_protect;
> +
> +	const struct thermal_zone_device_ops *thdev_ops;
> +	int (*probe)(struct platform_device *pdev,
> +		     struct airoha_thermal_priv *priv);
> +	int (*post_probe)(struct platform_device *pdev);
> +};
> +
>   static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
>   {
>   	u32 val;
> @@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
>   	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
>   
>   	/* Give access to thermal regs */
> -	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
> +	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
> +		     priv->pllrg_protect);
>   	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
>   	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
>   
> @@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
>   	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
>   }
>   
> -static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
> +static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
>   {
>   	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
>   	int min_value, max_value, avg_value, value;
> @@ -253,7 +265,7 @@ static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
>   	return 0;
>   }
>   
> -static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
> +static int en7581_thermal_set_trips(struct thermal_zone_device *tz, int low,
>   				    int high)
>   {
>   	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
> @@ -290,12 +302,12 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
>   	return 0;
>   }
>   
> -static const struct thermal_zone_device_ops thdev_ops = {
> -	.get_temp = airoha_thermal_get_temp,
> -	.set_trips = airoha_thermal_set_trips,
> +static const struct thermal_zone_device_ops en7581_thdev_ops = {
> +	.get_temp = en7581_thermal_get_temp,
> +	.set_trips = en7581_thermal_set_trips,
>   };
>   
> -static irqreturn_t airoha_thermal_irq(int irq, void *data)
> +static irqreturn_t en7581_thermal_irq(int irq, void *data)
>   {
>   	struct airoha_thermal_priv *priv = data;
>   	enum thermal_notify_event event;
> @@ -326,7 +338,7 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
>   	return IRQ_HANDLED;
>   }
>   
> -static void airoha_thermal_setup_adc_val(struct device *dev,
> +static void en7581_thermal_setup_adc_val(struct device *dev,
>   					 struct airoha_thermal_priv *priv)
>   {
>   	u32 efuse_calib_info, cpu_sensor;
> @@ -356,7 +368,7 @@ static void airoha_thermal_setup_adc_val(struct device *dev,
>   	}
>   }
>   
> -static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
> +static void en7581_thermal_setup_monitor(struct airoha_thermal_priv *priv)
>   {
>   	/* Set measure mode */
>   	regmap_write(priv->map, EN7581_TEMPMSRCTL0,
> @@ -411,30 +423,26 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
>   		     FIELD_PREP(EN7581_ADC_POLL_INTVL, 146));
>   }
>   
> -static const struct regmap_config airoha_thermal_regmap_config = {
> +static const struct regmap_config en7581_thermal_regmap_config = {
>   	.reg_bits		= 32,
>   	.reg_stride		= 4,
>   	.val_bits		= 32,
>   };
>   
> -static int airoha_thermal_probe(struct platform_device *pdev)
> +static int en7581_thermal_probe(struct platform_device *pdev,
> +				struct airoha_thermal_priv *priv)
>   {
> -	struct airoha_thermal_priv *priv;
>   	struct device_node *chip_scu_np;
>   	struct device *dev = &pdev->dev;
>   	void __iomem *base;
>   	int irq, ret;
>   
> -	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> -	if (!priv)
> -		return -ENOMEM;
> -
>   	base = devm_platform_ioremap_resource(pdev, 0);
>   	if (IS_ERR(base))
>   		return PTR_ERR(base);
>   
>   	priv->map = devm_regmap_init_mmio(dev, base,
> -					  &airoha_thermal_regmap_config);
> +					  &en7581_thermal_regmap_config);
>   	if (IS_ERR(priv->map))
>   		return PTR_ERR(priv->map);
>   
> @@ -454,18 +462,55 @@ static int airoha_thermal_probe(struct platform_device *pdev)
>   		return irq;
>   
>   	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
> -					airoha_thermal_irq, IRQF_ONESHOT,
> +					en7581_thermal_irq, IRQF_ONESHOT,
>   					pdev->name, priv);
>   	if (ret) {
>   		dev_err(dev, "Can't get interrupt working.\n");
>   		return ret;
>   	}
>   
> -	airoha_thermal_setup_monitor(priv);
> -	airoha_thermal_setup_adc_val(dev, priv);
> +	en7581_thermal_setup_monitor(priv);
> +	en7581_thermal_setup_adc_val(dev, priv);
> +
> +	return 0;
> +}
> +
> +static int en7581_thermal_post_probe(struct platform_device *pdev)
> +{
> +	struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
> +
> +	/* Enable LOW and HIGH interrupt (if supported) */
> +	regmap_write(priv->map, EN7581_TEMPMONINT,
> +		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
> +
> +	return 0;
> +}
> +
> +static int airoha_thermal_probe(struct platform_device *pdev)
> +{
> +	const struct airoha_thermal_soc_data *soc_data;
> +	struct airoha_thermal_priv *priv;
> +	struct device *dev = &pdev->dev;
> +	int ret;
> +
> +	soc_data = device_get_match_data(dev);
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->pllrg_protect = soc_data->pllrg_protect;
> +
> +	if (!soc_data->probe)
> +		return -EINVAL;
> +
> +	ret = soc_data->probe(pdev, priv);
> +	if (ret)
> +		return ret;
>   
>   	/* register of thermal sensor and get info from DT */
> -	priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops);
> +	priv->tz = devm_thermal_of_zone_register(dev, 0, priv,
> +						 soc_data->thdev_ops);

I suggest to move devm_thermal_of_zone_register() in the platform 
specific probe function, directly pass the corresponding ops.

That will allow to get rid of the post_probe() and the thdev_ops field 
in the airoha_thermal_soc_data structure.

	devm_thermal_of_zone_register(dev, 0, priv, &en7581_thdev_ops);


>   	if (IS_ERR(priv->tz)) {
>   		dev_err(dev, "register thermal zone sensor failed\n");
>   		return PTR_ERR(priv->tz);
> @@ -473,15 +518,18 @@ static int airoha_thermal_probe(struct platform_device *pdev)
>   
>   	platform_set_drvdata(pdev, priv);
>   
> -	/* Enable LOW and HIGH interrupt */
> -	regmap_write(priv->map, EN7581_TEMPMONINT,
> -		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
> -
> -	return 0;
> +	return soc_data->post_probe ? soc_data->post_probe(pdev) : 0;
>   }
>   
> +static const struct airoha_thermal_soc_data en7581_data = {
> +	.pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
> +	.thdev_ops = &en7581_thdev_ops,
> +	.probe = &en7581_thermal_probe,
> +	.post_probe = &en7581_thermal_post_probe,
> +};
> +
>   static const struct of_device_id airoha_thermal_match[] = {
> -	{ .compatible = "airoha,en7581-thermal" },
> +	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
>   	{},
>   };
>   MODULE_DEVICE_TABLE(of, airoha_thermal_match);


-- 
<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
Re: [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function
Posted by Daniel Lezcano 2 weeks, 5 days ago
On 11/6/25 23:59, Christian Marangi wrote:
> In preparation for support of Airoha AN7583, generalize the probe
> function to address for the 2 SoC differece.
> 
> Implement a match_data struct where it's possible to define a more
> specific probe and post_probe function and specific thermal ops and
> pllrg protect value.
> 
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
>   drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++--------
>   1 file changed, 75 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
> index 01ed49a4887e..864a01fd8fd8 100644
> --- a/drivers/thermal/airoha_thermal.c
> +++ b/drivers/thermal/airoha_thermal.c
> @@ -198,12 +198,23 @@ struct airoha_thermal_priv {
>   	struct regmap *chip_scu;
>   	struct resource scu_adc_res;
>   
> +	u32 pllrg_protect;
> +
>   	struct thermal_zone_device *tz;
>   	int init_temp;
>   	int default_slope;
>   	int default_offset;
>   };
>   
> +struct airoha_thermal_soc_data {
> +	u32 pllrg_protect;
> +
> +	const struct thermal_zone_device_ops *thdev_ops;
> +	int (*probe)(struct platform_device *pdev,
> +		     struct airoha_thermal_priv *priv);
> +	int (*post_probe)(struct platform_device *pdev);

What the post-probe provides compared to calling the corresponding code 
in the probe function ?

> +};
> +
>   static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
>   {
>   	u32 val;
> @@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
>   	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
>   
>   	/* Give access to thermal regs */
> -	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
> +	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
> +		     priv->pllrg_protect);
>   	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
>   	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
>   
> @@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
>   	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
>   }
>   
> -static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
> +static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)

Please provide a separate patch before where s/airoha/en7581/

[ ... ]
> +static int en7581_thermal_post_probe(struct platform_device *pdev)
> +{
> +	struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
> +
> +	/* Enable LOW and HIGH interrupt (if supported) */

Why "(if supported)" ?

> +	regmap_write(priv->map, EN7581_TEMPMONINT,
> +		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
> +
> +	return 0;
> +}
> +
> +static int airoha_thermal_probe(struct platform_device *pdev)
> +{
> +	const struct airoha_thermal_soc_data *soc_data;
> +	struct airoha_thermal_priv *priv;
> +	struct device *dev = &pdev->dev;
> +	int ret;
> +
> +	soc_data = device_get_match_data(dev);
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->pllrg_protect = soc_data->pllrg_protect;
> +
> +	if (!soc_data->probe)
> +		return -EINVAL;

Shall the driver check its own code ?
> +	ret = soc_data->probe(pdev, priv);
> +	if (ret)

[ ... ]
> +static const struct airoha_thermal_soc_data en7581_data = {
> +	.pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
> +	.thdev_ops = &en7581_thdev_ops,
> +	.probe = &en7581_thermal_probe,
> +	.post_probe = &en7581_thermal_post_probe,
	.probe = en7581_thermal_probe,
	.post_probe = en7581_thermal_post_probe,

> +};
> +
>   static const struct of_device_id airoha_thermal_match[] = {
> -	{ .compatible = "airoha,en7581-thermal" },
> +	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
>   	{},
>   };
>   MODULE_DEVICE_TABLE(of, airoha_thermal_match);


-- 
<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
Re: [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function
Posted by Christian Marangi 2 weeks, 5 days ago
On Tue, Nov 25, 2025 at 06:16:29PM +0100, Daniel Lezcano wrote:
> On 11/6/25 23:59, Christian Marangi wrote:
> > In preparation for support of Airoha AN7583, generalize the probe
> > function to address for the 2 SoC differece.
> > 
> > Implement a match_data struct where it's possible to define a more
> > specific probe and post_probe function and specific thermal ops and
> > pllrg protect value.
> > 
> > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > ---
> >   drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++--------
> >   1 file changed, 75 insertions(+), 27 deletions(-)
> > 
> > diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
> > index 01ed49a4887e..864a01fd8fd8 100644
> > --- a/drivers/thermal/airoha_thermal.c
> > +++ b/drivers/thermal/airoha_thermal.c
> > @@ -198,12 +198,23 @@ struct airoha_thermal_priv {
> >   	struct regmap *chip_scu;
> >   	struct resource scu_adc_res;
> > +	u32 pllrg_protect;
> > +
> >   	struct thermal_zone_device *tz;
> >   	int init_temp;
> >   	int default_slope;
> >   	int default_offset;
> >   };
> > +struct airoha_thermal_soc_data {
> > +	u32 pllrg_protect;
> > +
> > +	const struct thermal_zone_device_ops *thdev_ops;
> > +	int (*probe)(struct platform_device *pdev,
> > +		     struct airoha_thermal_priv *priv);
> > +	int (*post_probe)(struct platform_device *pdev);
> 
> What the post-probe provides compared to calling the corresponding code in
> the probe function ?
>

Hi Daniel,

the usage would be to do those operation that should be done AFTER the
thermal zone are registered. In this specific case, to enable the
interrupt.

(they can't be enabled before as they will fire up immediately due to
wrong configuration of trip point)

I can also limit enabling the interrupt to AN7581 by checking the
compatible. I probably went too much with the modular approach.

> > +};
> > +
> >   static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
> >   {
> >   	u32 val;
> > @@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
> >   	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
> >   	/* Give access to thermal regs */
> > -	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
> > +	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
> > +		     priv->pllrg_protect);
> >   	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
> >   	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
> > @@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
> >   	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
> >   }
> > -static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
> > +static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
> 
> Please provide a separate patch before where s/airoha/en7581/
> 

Ok no problem.

> [ ... ]
> > +static int en7581_thermal_post_probe(struct platform_device *pdev)
> > +{
> > +	struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
> > +
> > +	/* Enable LOW and HIGH interrupt (if supported) */
> 
> Why "(if supported)" ?
> 

Airoha AN7583 won't support this. But I understand this is confusing
since this function is specific to AN7581.

> > +	regmap_write(priv->map, EN7581_TEMPMONINT,
> > +		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
> > +
> > +	return 0;
> > +}
> > +
> > +static int airoha_thermal_probe(struct platform_device *pdev)
> > +{
> > +	const struct airoha_thermal_soc_data *soc_data;
> > +	struct airoha_thermal_priv *priv;
> > +	struct device *dev = &pdev->dev;
> > +	int ret;
> > +
> > +	soc_data = device_get_match_data(dev);
> > +
> > +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	priv->pllrg_protect = soc_data->pllrg_protect;
> > +
> > +	if (!soc_data->probe)
> > +		return -EINVAL;
> 
> Shall the driver check its own code ?
> > +	ret = soc_data->probe(pdev, priv);
> > +	if (ret)
> 

Well it's expected to be always present so I guess I can drop this.

> [ ... ]
> > +static const struct airoha_thermal_soc_data en7581_data = {
> > +	.pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
> > +	.thdev_ops = &en7581_thdev_ops,
> > +	.probe = &en7581_thermal_probe,
> > +	.post_probe = &en7581_thermal_post_probe,
> 	.probe = en7581_thermal_probe,
> 	.post_probe = en7581_thermal_post_probe,
> 
> > +};
> > +
> >   static const struct of_device_id airoha_thermal_match[] = {
> > -	{ .compatible = "airoha,en7581-thermal" },
> > +	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
> >   	{},
> >   };
> >   MODULE_DEVICE_TABLE(of, airoha_thermal_match);
> 
> 
> -- 
> <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

-- 
	Ansuel