diff options
Diffstat (limited to 'drivers/net/phy/phy_package.c')
-rw-r--r-- | drivers/net/phy/phy_package.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/net/phy/phy_package.c b/drivers/net/phy/phy_package.c index 873420e58f02..12c92d26ee0b 100644 --- a/drivers/net/phy/phy_package.c +++ b/drivers/net/phy/phy_package.c @@ -7,6 +7,7 @@ #include <linux/phy.h> #include "phylib.h" +#include "phylib-internal.h" struct device_node *phy_package_get_node(struct phy_device *phydev) { @@ -20,6 +21,66 @@ void *phy_package_get_priv(struct phy_device *phydev) } EXPORT_SYMBOL_GPL(phy_package_get_priv); +int phy_package_address(struct phy_device *phydev, unsigned int addr_offset) +{ + struct phy_package_shared *shared = phydev->shared; + u8 base_addr = shared->base_addr; + + if (addr_offset >= PHY_MAX_ADDR - base_addr) + return -EIO; + + /* we know that addr will be in the range 0..31 and thus the + * implicit cast to a signed int is not a problem. + */ + return base_addr + addr_offset; +} + +int __phy_package_read(struct phy_device *phydev, unsigned int addr_offset, + u32 regnum) +{ + int addr = phy_package_address(phydev, addr_offset); + + if (addr < 0) + return addr; + + return __mdiobus_read(phydev->mdio.bus, addr, regnum); +} +EXPORT_SYMBOL_GPL(__phy_package_read); + +int __phy_package_write(struct phy_device *phydev, unsigned int addr_offset, + u32 regnum, u16 val) +{ + int addr = phy_package_address(phydev, addr_offset); + + if (addr < 0) + return addr; + + return __mdiobus_write(phydev->mdio.bus, addr, regnum, val); +} +EXPORT_SYMBOL_GPL(__phy_package_write); + +static bool __phy_package_set_once(struct phy_device *phydev, unsigned int b) +{ + struct phy_package_shared *shared = phydev->shared; + + if (!shared) + return false; + + return !test_and_set_bit(b, &shared->flags); +} + +bool phy_package_init_once(struct phy_device *phydev) +{ + return __phy_package_set_once(phydev, 0); +} +EXPORT_SYMBOL_GPL(phy_package_init_once); + +bool phy_package_probe_once(struct phy_device *phydev) +{ + return __phy_package_set_once(phydev, 1); +} +EXPORT_SYMBOL_GPL(phy_package_probe_once); + /** * phy_package_join - join a common PHY group * @phydev: target phy_device struct |