Skip to content

Commit

Permalink
net: stmmac: dwmac-rk: keep the PHY up for WoL
Browse files Browse the repository at this point in the history
When suspending the machine, do not shutdown the external PHY by cutting
its regulator in the mac platform driver suspend code if Wake-on-Lan is enabled,
else it cannot wake us up.
In order to do this, split the suspend/resume callbacks from the
init/exit callbacks, so we can condition the power-down on the lack of
need to wake-up from the LAN but do it unconditionally when unloading the
module.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Vincent Palatin authored and David S. Miller committed Jun 16, 2016
1 parent cecbc55 commit 229666c
Showing 1 changed file with 43 additions and 5 deletions.
48 changes: 43 additions & 5 deletions drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct rk_priv_data {
struct platform_device *pdev;
int phy_iface;
struct regulator *regulator;
bool suspended;
const struct rk_gmac_ops *ops;

bool clk_enabled;
Expand Down Expand Up @@ -529,9 +530,8 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
return bsp_priv;
}

static int rk_gmac_init(struct platform_device *pdev, void *priv)
static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
{
struct rk_priv_data *bsp_priv = priv;
int ret;

ret = phy_power_on(bsp_priv, true);
Expand All @@ -545,14 +545,50 @@ static int rk_gmac_init(struct platform_device *pdev, void *priv)
return 0;
}

static void rk_gmac_exit(struct platform_device *pdev, void *priv)
static void rk_gmac_powerdown(struct rk_priv_data *gmac)
{
struct rk_priv_data *gmac = priv;

phy_power_on(gmac, false);
gmac_clk_enable(gmac, false);
}

static int rk_gmac_init(struct platform_device *pdev, void *priv)
{
struct rk_priv_data *bsp_priv = priv;

return rk_gmac_powerup(bsp_priv);
}

static void rk_gmac_exit(struct platform_device *pdev, void *priv)
{
struct rk_priv_data *bsp_priv = priv;

rk_gmac_powerdown(bsp_priv);
}

static void rk_gmac_suspend(struct platform_device *pdev, void *priv)
{
struct rk_priv_data *bsp_priv = priv;

/* Keep the PHY up if we use Wake-on-Lan. */
if (device_may_wakeup(&pdev->dev))
return;

rk_gmac_powerdown(bsp_priv);
bsp_priv->suspended = true;
}

static void rk_gmac_resume(struct platform_device *pdev, void *priv)
{
struct rk_priv_data *bsp_priv = priv;

/* The PHY was up for Wake-on-Lan. */
if (!bsp_priv->suspended)
return;

rk_gmac_powerup(bsp_priv);
bsp_priv->suspended = false;
}

static void rk_fix_speed(void *priv, unsigned int speed)
{
struct rk_priv_data *bsp_priv = priv;
Expand Down Expand Up @@ -591,6 +627,8 @@ static int rk_gmac_probe(struct platform_device *pdev)
plat_dat->init = rk_gmac_init;
plat_dat->exit = rk_gmac_exit;
plat_dat->fix_mac_speed = rk_fix_speed;
plat_dat->suspend = rk_gmac_suspend;
plat_dat->resume = rk_gmac_resume;

plat_dat->bsp_priv = rk_gmac_setup(pdev, data);
if (IS_ERR(plat_dat->bsp_priv))
Expand Down

0 comments on commit 229666c

Please sign in to comment.