Re: MDIO over I2C driver driver probe dependency issue

2 messages, 2 authors, 2021-01-08 · open the first message on its own page

Re: MDIO over I2C driver driver probe dependency issue

From: Florian Fainelli <f.fainelli@gmail.com>
Date: 2021-01-08 03:06:17


On 1/7/2021 6:22 PM, Brian Silverman wrote:
I've written a very small generic MDIO driver that uses the existing
mdio-i2c.c library in drivers/net/phy.  The driver allows
communication to the PHY's MDIO interface as using I2C, as supported by
PHYs like the BCM54616S.  This is working on my hardware.  

The one issue I have is that I2C is not up and available (i.e. probed)
at the time that the MDIO interface comes up.  To fix this, I've changed
the device order in drivers/Makefile to put "obj-y += i2c/"
before "obj-y += net/".

While that works, I prefer not to have to keep that difference from
mainline Linux.  Also, I don't understand why i2c drivers occur
arbitrarily late in the Makefile - surely there are other devices
drivers that need i2c to be enabled when they are probed?

Is there a way to do this that doesn't change probe order?  Or is there
a way to change probe order without patching mainline Linux?
Linux supports probe deferral so when a consumer of a resource finds
that said resource's provider is not available, it should return
-EPROBE_DEFER which puts the driver's probe routine onto a list of
driver's probe function to retry at a later time.

In your case the GEM Ethernet driver should get an -EPROBE_DEFER while
the Ethernet PHY device tree node is looked up via
phylink_of_phy_connect() because the mdio-i2c-gen i2c client has not had
a chance to register the MDIO bus yet. Have you figured out the call
path that does not work for you?

Which version of the kernel are you using? What I am referring to is
assuming mainline, but maybe this is not your case?

---

For reference, here's the driver (excluding headers and footers):

static int mdio_i2c_gen_probe(struct i2c_client *client,
    const struct i2c_device_id *id)
{
struct mii_bus *bus;

bus = mdio_i2c_alloc(&client->dev, client->adapter);
if (IS_ERR(bus)){
return PTR_ERR(bus);
}
bus->name = "Generic MDIO bus over I2C";
bus->parent = &client->dev;

return of_mdiobus_register(bus, client->dev.of_node);
}

static int mdio_i2c_gen_remove(struct i2c_client *client)
{
return 0;
}

static const struct of_device_id mdio_i2c_gen_of_match[] = {
{ .compatible = "mdio-i2c-gen", },
{ }
};
MODULE_DEVICE_TABLE(of, mdio_i2c_gen_of_match);

static struct i2c_driver mdio_i2c_gen_driver = {
.driver = {
.name= "mdio-i2c-gen",
.of_match_table = of_match_ptr(mdio_i2c_gen_of_match),
},
.probe= mdio_i2c_gen_probe,
.remove= mdio_i2c_gen_remove,
};

module_i2c_driver(mdio_i2c_gen_driver);


---

And here's a device-tree snippet:

&gem3 {
    status = "okay";
    phy-handle =  <&phy0>;
};

&i2c0 {
    mdio@40 {
        compatible = "mdio-i2c-gen";
        reg = <0x40>;
        #address-cells = <1>;
        #size-cells = <0>;

        phy0: phy@0 {
            reg = <0>;
        };
    };
};

-- 
Florian

Re: MDIO over I2C driver driver probe dependency issue

From: Andrew Lunn <andrew@lunn.ch>
Date: 2021-01-08 13:43:30

On Thu, Jan 07, 2021 at 07:05:21PM -0800, Florian Fainelli wrote:

On 1/7/2021 6:22 PM, Brian Silverman wrote:
quoted
I've written a very small generic MDIO driver that uses the existing
mdio-i2c.c library in drivers/net/phy.  The driver allows
communication to the PHY's MDIO interface as using I2C, as supported by
PHYs like the BCM54616S.  This is working on my hardware.  

The one issue I have is that I2C is not up and available (i.e. probed)
at the time that the MDIO interface comes up.  To fix this, I've changed
the device order in drivers/Makefile to put "obj-y += i2c/"
before "obj-y += net/".

While that works, I prefer not to have to keep that difference from
mainline Linux.  Also, I don't understand why i2c drivers occur
arbitrarily late in the Makefile - surely there are other devices
drivers that need i2c to be enabled when they are probed?

Is there a way to do this that doesn't change probe order?  Or is there
a way to change probe order without patching mainline Linux?
Linux supports probe deferral so when a consumer of a resource finds
that said resource's provider is not available, it should return
-EPROBE_DEFER which puts the driver's probe routine onto a list of
driver's probe function to retry at a later time.

In your case the GEM Ethernet driver should get an -EPROBE_DEFER while
the Ethernet PHY device tree node is looked up via
phylink_of_phy_connect() because the mdio-i2c-gen i2c client has not had
a chance to register the MDIO bus yet. Have you figured out the call
path that does not work for you?
Just adding to this. The way the current mdio-i2c code is used, we
have already talked to the SFP to get its EEPROM contents. So we know
I2C works at the time the mdio-i2c bus is instantiated.

You are using the code slightly differently which might be why the
code is not correctly handling EPROBE_DEFER where it should. Patches
to add this are likely to be accepted.

   Andrew
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help