diff options
author | Jakub Kicinski <kuba@kernel.org> | 2020-09-05 22:09:16 +0200 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2020-09-05 22:10:03 +0200 |
commit | 35b237a51f4e04a3b07e6047bcf3b491997f0ef5 (patch) | |
tree | e107272160bde0bd8c34720b1c5ce600243d1191 | |
parent | Merge branch 'sfc-TXQ-refactor' (diff) | |
parent | net: dsa: bcm_sf2: Ensure that MDIO diversion is used (diff) | |
download | linux-35b237a51f4e04a3b07e6047bcf3b491997f0ef5.tar.xz linux-35b237a51f4e04a3b07e6047bcf3b491997f0ef5.zip |
Merge branch 'net-dsa-bcm_sf2-Ensure-MDIO-diversion-is-used'
Florian Fainelli says:
====================
net: dsa: bcm_sf2: Ensure MDIO diversion is used
Changes in v2:
- export of_update_property() to permit building bcm_sf2 as a module
- provided a better explanation of the problem being solved after
explaining it to Andrew during the v1 review
====================
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r-- | drivers/net/dsa/bcm_sf2.c | 31 | ||||
-rw-r--r-- | drivers/of/base.c | 1 | ||||
-rw-r--r-- | include/linux/of.h | 5 |
3 files changed, 35 insertions, 2 deletions
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index 7a74e4d73415..3263e8a0ae67 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -489,9 +489,11 @@ static void bcm_sf2_identify_ports(struct bcm_sf2_priv *priv, static int bcm_sf2_mdio_register(struct dsa_switch *ds) { struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); - struct device_node *dn; + struct device_node *dn, *child; + struct phy_device *phydev; + struct property *prop; static int index; - int err; + int err, reg; /* Find our integrated MDIO bus node */ dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio"); @@ -534,6 +536,31 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) priv->slave_mii_bus->parent = ds->dev->parent; priv->slave_mii_bus->phy_mask = ~priv->indir_phy_mask; + /* We need to make sure that of_phy_connect() will not work by + * removing the 'phandle' and 'linux,phandle' properties and + * unregister the existing PHY device that was already registered. + */ + for_each_available_child_of_node(dn, child) { + if (of_property_read_u32(child, "reg", ®) || + reg >= PHY_MAX_ADDR) + continue; + + if (!(priv->indir_phy_mask & BIT(reg))) + continue; + + prop = of_find_property(child, "phandle", NULL); + if (prop) + of_remove_property(child, prop); + + prop = of_find_property(child, "linux,phandle", NULL); + if (prop) + of_remove_property(child, prop); + + phydev = of_phy_find_device(child); + if (phydev) + phy_device_remove(phydev); + } + err = mdiobus_register(priv->slave_mii_bus); if (err && dn) of_node_put(dn); diff --git a/drivers/of/base.c b/drivers/of/base.c index ea44fea99813..161a23631472 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1869,6 +1869,7 @@ int of_remove_property(struct device_node *np, struct property *prop) return rc; } +EXPORT_SYMBOL_GPL(of_remove_property); int __of_update_property(struct device_node *np, struct property *newprop, struct property **oldpropp) diff --git a/include/linux/of.h b/include/linux/of.h index 5cf7ae0465d1..481ec0467285 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -929,6 +929,11 @@ static inline int of_machine_is_compatible(const char *compat) return 0; } +static inline int of_remove_property(struct device_node *np, struct property *prop) +{ + return 0; +} + static inline bool of_console_check(const struct device_node *dn, const char *name, int index) { return false; |