net: phy: broadcom: add bcm_phy_modify_exp()
authorMichael Walle <michael@walle.cc>
Wed, 13 May 2020 16:35:22 +0000 (18:35 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 13 May 2020 19:52:38 +0000 (12:52 -0700)
Add the convenience function to do a read-modify-write. This has the
additional benefit of saving one write to the selection register.

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/bcm-phy-lib.c
drivers/net/phy/bcm-phy-lib.h

index a390812714eda1d3a7d5488ec4cdc3d956d07484..41c728fbcfb264d70d28684809f66a760e85a9f1 100644 (file)
@@ -67,6 +67,38 @@ int bcm_phy_read_exp(struct phy_device *phydev, u16 reg)
 }
 EXPORT_SYMBOL_GPL(bcm_phy_read_exp);
 
+int __bcm_phy_modify_exp(struct phy_device *phydev, u16 reg, u16 mask, u16 set)
+{
+       int new, ret;
+
+       ret = __phy_write(phydev, MII_BCM54XX_EXP_SEL, reg);
+       if (ret < 0)
+               return ret;
+
+       ret = __phy_read(phydev, MII_BCM54XX_EXP_DATA);
+       if (ret < 0)
+               return ret;
+
+       new = (ret & ~mask) | set;
+       if (new == ret)
+               return 0;
+
+       return __phy_write(phydev, MII_BCM54XX_EXP_DATA, new);
+}
+EXPORT_SYMBOL_GPL(__bcm_phy_modify_exp);
+
+int bcm_phy_modify_exp(struct phy_device *phydev, u16 reg, u16 mask, u16 set)
+{
+       int ret;
+
+       phy_lock_mdio_bus(phydev);
+       ret = __bcm_phy_modify_exp(phydev, reg, mask, set);
+       phy_unlock_mdio_bus(phydev);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(bcm_phy_modify_exp);
+
 int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum)
 {
        /* The register must be written to both the Shadow Register Select and
index 0eb5333cda39dc2cc682c8cd777cab71c328cbe9..b35d880220b9f2e66de6038a9105bb170e449ba4 100644 (file)
 
 int __bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val);
 int __bcm_phy_read_exp(struct phy_device *phydev, u16 reg);
+int __bcm_phy_modify_exp(struct phy_device *phydev, u16 reg, u16 mask, u16 set);
 int bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val);
 int bcm_phy_read_exp(struct phy_device *phydev, u16 reg);
+int bcm_phy_modify_exp(struct phy_device *phydev, u16 reg, u16 mask, u16 set);
 
 static inline int bcm_phy_write_exp_sel(struct phy_device *phydev,
                                        u16 reg, u16 val)