net: phy: Add phy_modify_mmd() and phy_modify_mmd_changed() from Linux

Add phy_modify_mmd()/phy_modify_mmd_changed() from Linux 5.1.y as of commit
b8554d4f7288f ("net: phy: add register modifying helpers returning 1 on change")
This is used by the upcoming Marvell 10G PHY driver.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
This commit is contained in:
Marek Vasut 2023-03-19 18:08:07 +01:00
parent bf3dabb7de
commit 87b7502824
2 changed files with 58 additions and 0 deletions

View File

@ -1158,6 +1158,60 @@ int phy_clear_bits_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val
return 0;
}
/**
* phy_modify_mmd_changed - Function for modifying a register on MMD
* @phydev: the phy_device struct
* @devad: the MMD containing register to modify
* @regnum: register number to modify
* @mask: bit mask of bits to clear
* @set: new value of bits set in mask to write to @regnum
*
* NOTE: MUST NOT be called from interrupt context,
* because the bus read/write functions may wait for an interrupt
* to conclude the operation.
*
* Returns negative errno, 0 if there was no change, and 1 in case of change
*/
int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
u16 mask, u16 set)
{
int new, ret;
ret = phy_read_mmd(phydev, devad, regnum);
if (ret < 0)
return ret;
new = (ret & ~mask) | set;
if (new == ret)
return 0;
ret = phy_write_mmd(phydev, devad, regnum, new);
return ret < 0 ? ret : 1;
}
/**
* phy_modify_mmd - Convenience function for modifying a register on MMD
* @phydev: the phy_device struct
* @devad: the MMD containing register to modify
* @regnum: register number to modify
* @mask: bit mask of bits to clear
* @set: new value of bits set in mask to write to @regnum
*
* NOTE: MUST NOT be called from interrupt context,
* because the bus read/write functions may wait for an interrupt
* to conclude the operation.
*/
int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
u16 mask, u16 set)
{
int ret;
ret = phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
return ret < 0 ? ret : 0;
}
bool phy_interface_is_ncsi(void)
{
#ifdef CONFIG_PHY_NCSI

View File

@ -289,6 +289,10 @@ int phy_read_mmd(struct phy_device *phydev, int devad, int regnum);
int phy_write_mmd(struct phy_device *phydev, int devad, int regnum, u16 val);
int phy_set_bits_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val);
int phy_clear_bits_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val);
int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
u16 mask, u16 set);
int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
u16 mask, u16 set);
int phy_startup(struct phy_device *phydev);
int phy_config(struct phy_device *phydev);