Commit 17bf1693 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'bcmgenet-fix-aborted-suspend'



Doug Berger says:

====================
net: bcmgenet: fix aborted suspend

It is not enough to return an error code from the driver suspend
routine. The driver must also restore the device functionality.

This commit corrects the issue introduced by commit 0db55093
("net: bcmgenet: return correct value 'ret' from bcmgenet_power_down")
by calling the driver resume function if the suspend function returns
an error.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8a962c4a c5a54bbc
Loading
Loading
Loading
Loading
+33 −30
Original line number Diff line number Diff line
@@ -3612,36 +3612,6 @@ static int bcmgenet_remove(struct platform_device *pdev)
}

#ifdef CONFIG_PM_SLEEP
static int bcmgenet_suspend(struct device *d)
{
	struct net_device *dev = dev_get_drvdata(d);
	struct bcmgenet_priv *priv = netdev_priv(dev);
	int ret = 0;

	if (!netif_running(dev))
		return 0;

	netif_device_detach(dev);

	bcmgenet_netif_stop(dev);

	if (!device_may_wakeup(d))
		phy_suspend(dev->phydev);

	/* Prepare the device for Wake-on-LAN and switch to the slow clock */
	if (device_may_wakeup(d) && priv->wolopts) {
		ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC);
		clk_prepare_enable(priv->clk_wol);
	} else if (priv->internal_phy) {
		ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE);
	}

	/* Turn off the clocks */
	clk_disable_unprepare(priv->clk);

	return ret;
}

static int bcmgenet_resume(struct device *d)
{
	struct net_device *dev = dev_get_drvdata(d);
@@ -3719,6 +3689,39 @@ out_clk_disable:
	clk_disable_unprepare(priv->clk);
	return ret;
}

static int bcmgenet_suspend(struct device *d)
{
	struct net_device *dev = dev_get_drvdata(d);
	struct bcmgenet_priv *priv = netdev_priv(dev);
	int ret = 0;

	if (!netif_running(dev))
		return 0;

	netif_device_detach(dev);

	bcmgenet_netif_stop(dev);

	if (!device_may_wakeup(d))
		phy_suspend(dev->phydev);

	/* Prepare the device for Wake-on-LAN and switch to the slow clock */
	if (device_may_wakeup(d) && priv->wolopts) {
		ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC);
		clk_prepare_enable(priv->clk_wol);
	} else if (priv->internal_phy) {
		ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE);
	}

	/* Turn off the clocks */
	clk_disable_unprepare(priv->clk);

	if (ret)
		bcmgenet_resume(d);

	return ret;
}
#endif /* CONFIG_PM_SLEEP */

static SIMPLE_DEV_PM_OPS(bcmgenet_pm_ops, bcmgenet_suspend, bcmgenet_resume);
+6 −0
Original line number Diff line number Diff line
@@ -186,9 +186,15 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
	}

	reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
	if (!(reg & MPD_EN))
		return;	/* already powered up so skip the rest */
	reg &= ~MPD_EN;
	bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);

	reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL);
	reg &= ~(RBUF_HFB_EN | RBUF_ACPI_EN);
	bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL);

	/* Disable CRC Forward */
	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
	reg &= ~CMD_CRC_FWD;