All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
To: Andrew Lunn <andrew@lunn.ch>
Cc: Joakim Zhang <qiangqing.zhang@nxp.com>,
	"David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] net: fec: defer probe if PHY on external MDIO bus is not available
Date: Wed, 20 Oct 2021 14:03:49 +0200	[thread overview]
Message-ID: <aae9573f89560a32da0786dc90cb7be0331acad4.camel@ew.tq-group.com> (raw)
In-Reply-To: <YW7SWKiUy8LfvSkl@lunn.ch>

On Tue, 2021-10-19 at 16:12 +0200, Andrew Lunn wrote:
> On Thu, Oct 14, 2021 at 01:30:43PM +0200, Matthias Schiffer wrote:
> > On some SoCs like i.MX6UL it is common to use the same MDIO bus for PHYs
> > on both Ethernet controllers. Currently device trees for such setups
> > have to make assumptions regarding the probe order of the controllers:
> > 
> > For example in imx6ul-14x14-evk.dtsi, the MDIO bus of fec2 is used for
> > the PHYs of both fec1 and fec2. The reason is that fec2 has a lower
> > address than fec1 and is thus loaded first, so the bus is already
> > available when fec1 is probed.
> > 
> > Besides being confusing, this limitation also makes it impossible to use
> > the same device tree for variants of the i.MX6UL with one Ethernet
> > controller (which have to use the MDIO of fec1, as fec2 does not exist)
> > and variants with two controllers (which have to use fec2 because of the
> > load order).
> > 
> > To fix this, defer the probe of the Ethernet controller when the PHY is
> > not on our own MDIO bus and not available.
> > 
> > Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
> > ---
> >  drivers/net/ethernet/freescale/fec_main.c | 23 ++++++++++++++++++++++-
> >  1 file changed, 22 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
> > index 47a6fc702ac7..dc070dd216e8 100644
> > --- a/drivers/net/ethernet/freescale/fec_main.c
> > +++ b/drivers/net/ethernet/freescale/fec_main.c
> > @@ -3820,7 +3820,28 @@ fec_probe(struct platform_device *pdev)
> >  		goto failed_stop_mode;
> >  
> >  	phy_node = of_parse_phandle(np, "phy-handle", 0);
> > -	if (!phy_node && of_phy_is_fixed_link(np)) {
> > +	if (phy_node) {
> > +		struct device_node *mdio_parent =
> > +			of_get_next_parent(of_get_parent(phy_node));
> > +
> > +		ret = 0;
> > +
> > +		/* Skip PHY availability check for our own MDIO bus to avoid
> > +		 * cyclic dependency
> > +		 */
> > +		if (mdio_parent != np) {
> > +			struct phy_device *phy = of_phy_find_device(phy_node);
> > +
> > +			if (phy)
> > +				put_device(&phy->mdio.dev);
> > +			else
> > +				ret = -EPROBE_DEFER;
> > +		}
> 
> I've not looked at the details yet, just back from vacation. But this
> seems wrong. I would of expected phylib to of returned -EPRODE_DEFER
> at some point, when asked for a PHY which does not exist yet. All the
> driver should need to do is make sure it returns the
> -EPRODE_DEFER.

This is what I expected as well, however there are a few complications:

- At the moment the first time the driver does anything with the PHY is
  in fec_enet_open(), not in fec_probe() - way too late to defer
  anything

- phylib doesn't know about EPROBE_DEFER, or error returns in general,
  everything just returns NULL. There is a fairly long chain of
  functions that just return NULL here (which might be okay, as they
  don't have a way to distinguish different errors anyways AFAICT):
  of_phy_find_device() -> fwnode_phy_find_device() ->
  fwnode_phy_find_device() -> fwnode_mdio_find_device() ->
  bus_find_device_by_fwnode() -> bus_find_device()

- Even if we implement the EPROBE_DEFER return somewhere in phylib,
  there needs to be special handling for the internal MDIO case, where
  the MDIO device is provided by the same driver that uses it. We can't
  wait with the check until we registered the MDIO bus, as it is not
  allowed to return EPROBE_DEFER after any devices have been
  registered. Splitting out the MDIO bus to be probed separately does
  not seem feasible, but I might be wrong?


So I have a few ideas, but I'm not sure which approach to pursue:

1. Make of_phy_find_device() return -EPROBE_DEFER (with or without
   touching more of the call chain). Doesn't seem too convincing to me,
   as it will just replace every case where of_phy_find_device()
   return NULL with -EPROBE_DEFER, making it more complicated to use
   for no gain.

2. Create a helper in phylib ("of_phy_device_available()") or something
   that encapsulates some of the code of this patch in a reuseable way,
   returning 0 or -EPROBE_DEFER.

 2a. Move just the code in "if (mdio_parent != np) {"
 2b. Also include the check for the MDIO parent for special handling of
     the internal MDIO. Not sure if this is approach is too specific
     to the node structure for a generic helper, or if the structure is
     common enough across different drivers.

3. Create a wrapper for of_parse_phandle() in phylib that does
   everything from 2b. 
  - Change the driver to hold a reference to a phy_device instead of
    its device_node
  - Might require further work for the fixed-link case
  - Will allow for an API similar to regulator_get[_optional]()
  - I have no idea how to solve the internal MDIO case with this
    approach nicely, as we don't be able to get a phy_device before the
    MDIO bus is registered


Matthias



> 
>        Andrew


  reply	other threads:[~2021-10-20 12:03 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-14 11:30 [PATCH] net: fec: defer probe if PHY on external MDIO bus is not available Matthias Schiffer
2021-10-18 10:20 ` Joakim Zhang
2021-10-18 10:32   ` Matthias Schiffer
2021-10-19 14:12 ` Andrew Lunn
2021-10-20 12:03   ` Matthias Schiffer [this message]
2021-10-20 18:50     ` Andrew Lunn
2021-10-21  7:08       ` (EXT) " Matthias Schiffer
2021-10-21 12:50         ` Andrew Lunn
2021-10-22  7:57           ` Matthias Schiffer
2021-10-22 12:56             ` Andrew Lunn
2021-10-26 11:54               ` Matthias Schiffer
2021-11-03 11:59                 ` Matthias Schiffer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aae9573f89560a32da0786dc90cb7be0331acad4.camel@ew.tq-group.com \
    --to=matthias.schiffer@ew.tq-group.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=qiangqing.zhang@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.