diff mbox series

[net-next,3/3] net: phy: broadcom: Wire suspend/resume for BCM54810

Message ID 20200214233853.27217-4-f.fainelli@gmail.com
State Superseded
Delegated to: David Miller
Headers show
Series net: phy: Better support for BCM54810 | expand

Commit Message

Florian Fainelli Feb. 14, 2020, 11:38 p.m. UTC
The BCM54810 PHY can use the standard BMCR Power down suspend, but needs
a custom resume routine which first clear the Power down bit, and then
re-initializes the PHY. While in low-power mode, the PHY only accepts
writes to the BMCR register. The datasheet clearly says it:

Reads or writes to any MII register other than MII Control register
(address 00h) while the device is in the standby power-down mode may
cause unpredictable results.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/phy/broadcom.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Comments

Andrew Lunn Feb. 15, 2020, 4:12 p.m. UTC | #1
On Fri, Feb 14, 2020 at 03:38:53PM -0800, Florian Fainelli wrote:
> The BCM54810 PHY can use the standard BMCR Power down suspend, but needs
> a custom resume routine which first clear the Power down bit, and then
> re-initializes the PHY. While in low-power mode, the PHY only accepts
> writes to the BMCR register. The datasheet clearly says it:
> 
> Reads or writes to any MII register other than MII Control register
> (address 00h) while the device is in the standby power-down mode may
> cause unpredictable results.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew
diff mbox series

Patch

diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index b4eae84a9195..ab24692a92c6 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -313,6 +313,20 @@  static int bcm54xx_config_init(struct phy_device *phydev)
 	return 0;
 }
 
+static int bcm54xx_resume(struct phy_device *phydev)
+{
+	int ret;
+
+	/* Writes to register other than BMCR would be ignored
+	 * unless we clear the PDOWN bit first
+	 */
+	ret = genphy_resume(phydev);
+	if (ret < 0)
+		return ret;
+
+	return bcm54xx_config_init(phydev);
+}
+
 static int bcm5482_config_init(struct phy_device *phydev)
 {
 	int err, reg;
@@ -706,6 +720,8 @@  static struct phy_driver broadcom_drivers[] = {
 	.config_aneg    = bcm5481_config_aneg,
 	.ack_interrupt  = bcm_phy_ack_intr,
 	.config_intr    = bcm_phy_config_intr,
+	.suspend	= genphy_suspend,
+	.resume		= bcm54xx_resume,
 }, {
 	.phy_id		= PHY_ID_BCM5482,
 	.phy_id_mask	= 0xfffffff0,