net: phy: add unlocked accessors
authorRussell King <rmk+kernel@armlinux.org.uk>
Tue, 2 Jan 2018 10:58:37 +0000 (10:58 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 3 Jan 2018 16:00:22 +0000 (11:00 -0500)
Add unlocked versions of the bus accessors, which allows access to the
bus with all the tracing. These accessors validate that the bus mutex
is held, which is a basic requirement for all mii bus accesses.

Also added is a read-modify-write unlocked accessor with the same
locking requirements.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/phy-core.c
include/linux/phy.h

index 2c985c6e2cdd89e475ee256583dc29d9ad41a0e5..028c098e9a003c7c84cc62b80ea16eed017bcab6 100644 (file)
@@ -323,3 +323,28 @@ int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
        return ret;
 }
 EXPORT_SYMBOL(phy_write_mmd);
+
+/**
+ * __phy_modify() - Convenience function for modifying a PHY register
+ * @phydev: a pointer to a &struct phy_device
+ * @regnum: register number
+ * @mask: bit mask of bits to clear
+ * @set: bit mask of bits to set
+ *
+ * Unlocked helper function which allows a PHY register to be modified as
+ * new register value = (old register value & mask) | set
+ */
+int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
+{
+       int ret, res;
+
+       ret = __phy_read(phydev, regnum);
+       if (ret >= 0) {
+               res = __phy_write(phydev, regnum, (ret & ~mask) | set);
+               if (res < 0)
+                       ret = res;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__phy_modify);
index a052e37684224d99b5874c08304b1cd9bbf32be1..0c5a28520c65160a0e3d450e0f76016624bedf80 100644 (file)
@@ -717,6 +717,18 @@ static inline int phy_read(struct phy_device *phydev, u32 regnum)
        return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, regnum);
 }
 
+/**
+ * __phy_read - convenience function for reading a given PHY register
+ * @phydev: the phy_device struct
+ * @regnum: register number to read
+ *
+ * The caller must have taken the MDIO bus lock.
+ */
+static inline int __phy_read(struct phy_device *phydev, u32 regnum)
+{
+       return __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, regnum);
+}
+
 /**
  * phy_write - Convenience function for writing a given PHY register
  * @phydev: the phy_device struct
@@ -732,6 +744,22 @@ static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val)
        return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
 }
 
+/**
+ * __phy_write - Convenience function for writing a given PHY register
+ * @phydev: the phy_device struct
+ * @regnum: register number to write
+ * @val: value to write to @regnum
+ *
+ * The caller must have taken the MDIO bus lock.
+ */
+static inline int __phy_write(struct phy_device *phydev, u32 regnum, u16 val)
+{
+       return __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum,
+                              val);
+}
+
+int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set);
+
 /**
  * phy_interrupt_is_valid - Convenience function for testing a given PHY irq
  * @phydev: the phy_device struct