diff options
Diffstat (limited to 'drivers/net/phy/micrel.c')
-rw-r--r-- | drivers/net/phy/micrel.c | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 1882d9828c99..081df68d2ce1 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -439,6 +439,10 @@ static int ksz9021_config_init(struct phy_device *phydev) #define MII_KSZ9031RN_TX_DATA_PAD_SKEW 6 #define MII_KSZ9031RN_CLK_PAD_SKEW 8 +/* MMD Address 0x1C */ +#define MII_KSZ9031RN_EDPD 0x23 +#define MII_KSZ9031RN_EDPD_ENABLE BIT(0) + static int ksz9031_extended_write(struct phy_device *phydev, u8 mode, u32 dev_addr, u32 regnum, u16 val) { @@ -510,6 +514,18 @@ static int ksz9031_center_flp_timing(struct phy_device *phydev) return genphy_restart_aneg(phydev); } +/* Enable energy-detect power-down mode */ +static int ksz9031_enable_edpd(struct phy_device *phydev) +{ + int reg; + + reg = ksz9031_extended_read(phydev, OP_DATA, 0x1C, MII_KSZ9031RN_EDPD); + if (reg < 0) + return reg; + return ksz9031_extended_write(phydev, OP_DATA, 0x1C, MII_KSZ9031RN_EDPD, + reg | MII_KSZ9031RN_EDPD_ENABLE); +} + static int ksz9031_config_init(struct phy_device *phydev) { const struct device *dev = &phydev->mdio.dev; @@ -525,6 +541,11 @@ static int ksz9031_config_init(struct phy_device *phydev) }; static const char *control_skews[2] = {"txen-skew-ps", "rxdv-skew-ps"}; const struct device *dev_walker; + int result; + + result = ksz9031_enable_edpd(phydev); + if (result < 0) + return result; /* The Micrel driver has a deprecated option to place phy OF * properties in the MAC node. Walk up the tree of devices to @@ -677,17 +698,28 @@ static void kszphy_get_stats(struct phy_device *phydev, data[i] = kszphy_get_stat(phydev, i); } -static int kszphy_resume(struct phy_device *phydev) +static int kszphy_suspend(struct phy_device *phydev) { - int value; + /* Disable PHY Interrupts */ + if (phy_interrupt_is_valid(phydev)) { + phydev->interrupts = PHY_INTERRUPT_DISABLED; + if (phydev->drv->config_intr) + phydev->drv->config_intr(phydev); + } - mutex_lock(&phydev->lock); + return genphy_suspend(phydev); +} - value = phy_read(phydev, MII_BMCR); - phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); +static int kszphy_resume(struct phy_device *phydev) +{ + genphy_resume(phydev); - kszphy_config_intr(phydev); - mutex_unlock(&phydev->lock); + /* Enable PHY Interrupts */ + if (phy_interrupt_is_valid(phydev)) { + phydev->interrupts = PHY_INTERRUPT_ENABLED; + if (phydev->drv->config_intr) + phydev->drv->config_intr(phydev); + } return 0; } @@ -900,7 +932,7 @@ static struct phy_driver ksphy_driver[] = { .get_sset_count = kszphy_get_sset_count, .get_strings = kszphy_get_strings, .get_stats = kszphy_get_stats, - .suspend = genphy_suspend, + .suspend = kszphy_suspend, .resume = kszphy_resume, }, { .phy_id = PHY_ID_KSZ8061, @@ -953,7 +985,7 @@ static struct phy_driver ksphy_driver[] = { .get_strings = kszphy_get_strings, .get_stats = kszphy_get_stats, .suspend = genphy_suspend, - .resume = genphy_resume, + .resume = kszphy_resume, }, { .phy_id = PHY_ID_KSZ8873MLL, .phy_id_mask = MICREL_PHY_ID_MASK, |