Skip to content

Commit

Permalink
Merge branch 'stmmac-wol'
Browse files Browse the repository at this point in the history
Vincent Palatin says:

====================
net: stmmac: dwmac-rk: fixes for Wake-on-Lan on RK3288

In order to support Wake-On-Lan when using the RK3288 integrated MAC
(with an external RGMII PHY), we need to avoid shutting down the regulator
of the external PHY when the MAC is suspended as it's currently done in the MAC
platform code.
As a first step, create independant callbacks for suspend/resume rather than
re-using exit/init callbacks. So the dwmac platform driver can behave differently
on suspend where it might skip shutting the PHY and at module unloading.
Then update the dwmac-rk driver to switch off the PHY regulator only if we are
not planning to wake up from the LAN.
Finally add the PMT interrupt to the MAC device tree configuration, so we can
wake up the core from it when the PHY has received the magic packet.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jun 16, 2016
2 parents 141ddef + d5bfbeb commit b4eccef
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 9 deletions.
5 changes: 3 additions & 2 deletions arch/arm/boot/dts/rk3288.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -539,8 +539,9 @@
gmac: ethernet@ff290000 {
compatible = "rockchip,rk3288-gmac";
reg = <0xff290000 0x10000>;
interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq", "eth_wake_irq";
rockchip,grf = <&grf>;
clocks = <&cru SCLK_MAC>,
<&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>,
Expand Down
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
8 changes: 6 additions & 2 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,9 @@ static int stmmac_pltfr_suspend(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);

ret = stmmac_suspend(dev);
if (priv->plat->exit)
if (priv->plat->suspend)
priv->plat->suspend(pdev, priv->plat->bsp_priv);
else if (priv->plat->exit)
priv->plat->exit(pdev, priv->plat->bsp_priv);

return ret;
Expand All @@ -430,7 +432,9 @@ static int stmmac_pltfr_resume(struct device *dev)
struct stmmac_priv *priv = netdev_priv(ndev);
struct platform_device *pdev = to_platform_device(dev);

if (priv->plat->init)
if (priv->plat->resume)
priv->plat->resume(pdev, priv->plat->bsp_priv);
else if (priv->plat->init)
priv->plat->init(pdev, priv->plat->bsp_priv);

return stmmac_resume(dev);
Expand Down
2 changes: 2 additions & 0 deletions include/linux/stmmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ struct plat_stmmacenet_data {
void (*bus_setup)(void __iomem *ioaddr);
int (*init)(struct platform_device *pdev, void *priv);
void (*exit)(struct platform_device *pdev, void *priv);
void (*suspend)(struct platform_device *pdev, void *priv);
void (*resume)(struct platform_device *pdev, void *priv);
void *bsp_priv;
struct stmmac_axi *axi;
int has_gmac4;
Expand Down

0 comments on commit b4eccef

Please sign in to comment.