[PATCH 2/2] can: flexcan: add transceiver capabilities

Dimitri Fedrau via B4 Relay posted 2 patches 12 months ago
There is a newer version of this series
[PATCH 2/2] can: flexcan: add transceiver capabilities
Posted by Dimitri Fedrau via B4 Relay 12 months ago
From: Dimitri Fedrau <dimitri.fedrau@liebherr.com>

Currently the flexcan driver does not support adding PHYs. Add the
capability to ensure that the PHY is in operational state when the link
is set to an "up" state.

Signed-off-by: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
---
 drivers/net/can/flexcan/flexcan-core.c | 25 +++++++++++++++++++------
 drivers/net/can/flexcan/flexcan.h      |  1 +
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
index ac1a860986df69a1dd64c25ff879490d5b21073b..a03dc8e3c80546a0e2fa9a85f0e0cc8159afa4f0 100644
--- a/drivers/net/can/flexcan/flexcan-core.c
+++ b/drivers/net/can/flexcan/flexcan-core.c
@@ -30,6 +30,7 @@
 #include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/phy/phy.h>
 
 #include "flexcan.h"
 
@@ -634,18 +635,22 @@ static void flexcan_clks_disable(const struct flexcan_priv *priv)
 
 static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
 {
-	if (!priv->reg_xceiver)
-		return 0;
+	if (priv->reg_xceiver)
+		return regulator_enable(priv->reg_xceiver);
+	else if (priv->xceiver)
+		return phy_power_on(priv->xceiver);
 
-	return regulator_enable(priv->reg_xceiver);
+	return 0;
 }
 
 static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv)
 {
-	if (!priv->reg_xceiver)
-		return 0;
+	if (priv->reg_xceiver)
+		return regulator_disable(priv->reg_xceiver);
+	else if (priv->xceiver)
+		return phy_power_off(priv->xceiver);
 
-	return regulator_disable(priv->reg_xceiver);
+	return 0;
 }
 
 static int flexcan_chip_enable(struct flexcan_priv *priv)
@@ -2061,6 +2066,7 @@ static int flexcan_probe(struct platform_device *pdev)
 	struct net_device *dev;
 	struct flexcan_priv *priv;
 	struct regulator *reg_xceiver;
+	struct phy *xceiver;
 	struct clk *clk_ipg = NULL, *clk_per = NULL;
 	struct flexcan_regs __iomem *regs;
 	struct flexcan_platform_data *pdata;
@@ -2076,6 +2082,12 @@ static int flexcan_probe(struct platform_device *pdev)
 	else if (IS_ERR(reg_xceiver))
 		return PTR_ERR(reg_xceiver);
 
+	xceiver = devm_phy_optional_get(&pdev->dev, NULL);
+	if (IS_ERR(xceiver)) {
+		dev_err(&pdev->dev, "failed to get phy\n");
+		return PTR_ERR(xceiver);
+	}
+
 	if (pdev->dev.of_node) {
 		of_property_read_u32(pdev->dev.of_node,
 				     "clock-frequency", &clock_freq);
@@ -2173,6 +2185,7 @@ static int flexcan_probe(struct platform_device *pdev)
 	priv->clk_per = clk_per;
 	priv->clk_src = clk_src;
 	priv->reg_xceiver = reg_xceiver;
+	priv->xceiver = xceiver;
 
 	if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3) {
 		priv->irq_boff = platform_get_irq(pdev, 1);
diff --git a/drivers/net/can/flexcan/flexcan.h b/drivers/net/can/flexcan/flexcan.h
index 4933d8c7439e62b5d6fcc445d88c2b5ccbfa13bb..56be40875eee24aee9297c4bc7c2fc4380e682ff 100644
--- a/drivers/net/can/flexcan/flexcan.h
+++ b/drivers/net/can/flexcan/flexcan.h
@@ -103,6 +103,7 @@ struct flexcan_priv {
 	struct clk *clk_per;
 	struct flexcan_devtype_data devtype_data;
 	struct regulator *reg_xceiver;
+	struct phy *xceiver;
 	struct flexcan_stop_mode stm;
 
 	int irq_boff;

-- 
2.39.5
Re: [PATCH 2/2] can: flexcan: add transceiver capabilities
Posted by Marc Kleine-Budde 11 months, 3 weeks ago
On 11.02.2025 14:12:34, Dimitri Fedrau via B4 Relay wrote:
> From: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
> 
> Currently the flexcan driver does not support adding PHYs. Add the
> capability to ensure that the PHY is in operational state when the link
> is set to an "up" state.
> 
> Signed-off-by: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
> ---
>  drivers/net/can/flexcan/flexcan-core.c | 25 +++++++++++++++++++------
>  drivers/net/can/flexcan/flexcan.h      |  1 +
>  2 files changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
> index ac1a860986df69a1dd64c25ff879490d5b21073b..a03dc8e3c80546a0e2fa9a85f0e0cc8159afa4f0 100644
> --- a/drivers/net/can/flexcan/flexcan-core.c
> +++ b/drivers/net/can/flexcan/flexcan-core.c
> @@ -30,6 +30,7 @@
>  #include <linux/property.h>
>  #include <linux/regmap.h>
>  #include <linux/regulator/consumer.h>
> +#include <linux/phy/phy.h>
>  
>  #include "flexcan.h"
>  
> @@ -634,18 +635,22 @@ static void flexcan_clks_disable(const struct flexcan_priv *priv)
>  
>  static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
>  {
> -	if (!priv->reg_xceiver)
> -		return 0;
> +	if (priv->reg_xceiver)
> +		return regulator_enable(priv->reg_xceiver);
> +	else if (priv->xceiver)
> +		return phy_power_on(priv->xceiver);
>  
> -	return regulator_enable(priv->reg_xceiver);
> +	return 0;
>  }
>  
>  static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv)
>  {
> -	if (!priv->reg_xceiver)
> -		return 0;
> +	if (priv->reg_xceiver)
> +		return regulator_disable(priv->reg_xceiver);
> +	else if (priv->xceiver)
> +		return phy_power_off(priv->xceiver);
>  
> -	return regulator_disable(priv->reg_xceiver);
> +	return 0;
>  }
>  
>  static int flexcan_chip_enable(struct flexcan_priv *priv)
> @@ -2061,6 +2066,7 @@ static int flexcan_probe(struct platform_device *pdev)
>  	struct net_device *dev;
>  	struct flexcan_priv *priv;
>  	struct regulator *reg_xceiver;
> +	struct phy *xceiver;
>  	struct clk *clk_ipg = NULL, *clk_per = NULL;
>  	struct flexcan_regs __iomem *regs;
>  	struct flexcan_platform_data *pdata;
> @@ -2076,6 +2082,12 @@ static int flexcan_probe(struct platform_device *pdev)
>  	else if (IS_ERR(reg_xceiver))
>  		return PTR_ERR(reg_xceiver);
>  
> +	xceiver = devm_phy_optional_get(&pdev->dev, NULL);
> +	if (IS_ERR(xceiver)) {
> +		dev_err(&pdev->dev, "failed to get phy\n");
> +		return PTR_ERR(xceiver);
> +	}
> +
>  	if (pdev->dev.of_node) {
>  		of_property_read_u32(pdev->dev.of_node,
>  				     "clock-frequency", &clock_freq);
> @@ -2173,6 +2185,7 @@ static int flexcan_probe(struct platform_device *pdev)
>  	priv->clk_per = clk_per;
>  	priv->clk_src = clk_src;
>  	priv->reg_xceiver = reg_xceiver;
> +	priv->xceiver = xceiver;
>  
>  	if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3) {
>  		priv->irq_boff = platform_get_irq(pdev, 1);

please also add
	if (xceiver)
		priv->can.bitrate_max = xceiver->attrs.max_link_rate;


> diff --git a/drivers/net/can/flexcan/flexcan.h b/drivers/net/can/flexcan/flexcan.h
> index 4933d8c7439e62b5d6fcc445d88c2b5ccbfa13bb..56be40875eee24aee9297c4bc7c2fc4380e682ff 100644
> --- a/drivers/net/can/flexcan/flexcan.h
> +++ b/drivers/net/can/flexcan/flexcan.h
> @@ -103,6 +103,7 @@ struct flexcan_priv {
>  	struct clk *clk_per;
>  	struct flexcan_devtype_data devtype_data;
>  	struct regulator *reg_xceiver;
> +	struct phy *xceiver;

All other drivers name this variable "transceiver", does it make sense
to use this name here, too?

>  	struct flexcan_stop_mode stm;
>  
>  	int irq_boff;

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |
Re: [PATCH 2/2] can: flexcan: add transceiver capabilities
Posted by Dimitri Fedrau 11 months, 3 weeks ago
Hi Marc,

Am Wed, Feb 19, 2025 at 10:41:24AM +0100 schrieb Marc Kleine-Budde:
> On 11.02.2025 14:12:34, Dimitri Fedrau via B4 Relay wrote:
> > From: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
> > 
[...]
> > +
> >  	if (pdev->dev.of_node) {
> >  		of_property_read_u32(pdev->dev.of_node,
> >  				     "clock-frequency", &clock_freq);
> > @@ -2173,6 +2185,7 @@ static int flexcan_probe(struct platform_device *pdev)
> >  	priv->clk_per = clk_per;
> >  	priv->clk_src = clk_src;
> >  	priv->reg_xceiver = reg_xceiver;
> > +	priv->xceiver = xceiver;
> >  
> >  	if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3) {
> >  		priv->irq_boff = platform_get_irq(pdev, 1);
> 
> please also add
> 	if (xceiver)
> 		priv->can.bitrate_max = xceiver->attrs.max_link_rate;
> 
> 

Yes, will add it.

> > diff --git a/drivers/net/can/flexcan/flexcan.h b/drivers/net/can/flexcan/flexcan.h
> > index 4933d8c7439e62b5d6fcc445d88c2b5ccbfa13bb..56be40875eee24aee9297c4bc7c2fc4380e682ff 100644
> > --- a/drivers/net/can/flexcan/flexcan.h
> > +++ b/drivers/net/can/flexcan/flexcan.h
> > @@ -103,6 +103,7 @@ struct flexcan_priv {
> >  	struct clk *clk_per;
> >  	struct flexcan_devtype_data devtype_data;
> >  	struct regulator *reg_xceiver;
> > +	struct phy *xceiver;
> 
> All other drivers name this variable "transceiver", does it make sense
> to use this name here, too?
> 
I have no preference on this, but my intention was to name it xceiver
according to reg_xceiver, so people familiar with the code would know
what it is about. I can change it to transceiver, what do you think ?

Best regards,
Dimitri Fedrau
Re: [PATCH 2/2] can: flexcan: add transceiver capabilities
Posted by Marc Kleine-Budde 11 months, 3 weeks ago
On 19.02.2025 11:39:55, Dimitri Fedrau wrote:
> > > diff --git a/drivers/net/can/flexcan/flexcan.h b/drivers/net/can/flexcan/flexcan.h
> > > index 4933d8c7439e62b5d6fcc445d88c2b5ccbfa13bb..56be40875eee24aee9297c4bc7c2fc4380e682ff 100644
> > > --- a/drivers/net/can/flexcan/flexcan.h
> > > +++ b/drivers/net/can/flexcan/flexcan.h
> > > @@ -103,6 +103,7 @@ struct flexcan_priv {
> > >  	struct clk *clk_per;
> > >  	struct flexcan_devtype_data devtype_data;
> > >  	struct regulator *reg_xceiver;
> > > +	struct phy *xceiver;
> > 
> > All other drivers name this variable "transceiver", does it make sense
> > to use this name here, too?
> > 
> I have no preference on this, but my intention was to name it xceiver
> according to reg_xceiver, so people familiar with the code would know
> what it is about. I can change it to transceiver, what do you think ?

Please use transceiver.

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |