Commit b4eccef8 authored by David S. Miller's avatar David S. Miller

Merge branch 'stmmac-wol'

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 141ddefc d5bfbeb8
...@@ -539,8 +539,9 @@ tsadc: tsadc@ff280000 { ...@@ -539,8 +539,9 @@ tsadc: tsadc@ff280000 {
gmac: ethernet@ff290000 { gmac: ethernet@ff290000 {
compatible = "rockchip,rk3288-gmac"; compatible = "rockchip,rk3288-gmac";
reg = <0xff290000 0x10000>; reg = <0xff290000 0x10000>;
interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
interrupt-names = "macirq"; <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq", "eth_wake_irq";
rockchip,grf = <&grf>; rockchip,grf = <&grf>;
clocks = <&cru SCLK_MAC>, clocks = <&cru SCLK_MAC>,
<&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>, <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>,
......
...@@ -46,6 +46,7 @@ struct rk_priv_data { ...@@ -46,6 +46,7 @@ struct rk_priv_data {
struct platform_device *pdev; struct platform_device *pdev;
int phy_iface; int phy_iface;
struct regulator *regulator; struct regulator *regulator;
bool suspended;
const struct rk_gmac_ops *ops; const struct rk_gmac_ops *ops;
bool clk_enabled; bool clk_enabled;
...@@ -529,9 +530,8 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, ...@@ -529,9 +530,8 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
return bsp_priv; 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; int ret;
ret = phy_power_on(bsp_priv, true); ret = phy_power_on(bsp_priv, true);
...@@ -545,14 +545,50 @@ static int rk_gmac_init(struct platform_device *pdev, void *priv) ...@@ -545,14 +545,50 @@ static int rk_gmac_init(struct platform_device *pdev, void *priv)
return 0; 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); phy_power_on(gmac, false);
gmac_clk_enable(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) static void rk_fix_speed(void *priv, unsigned int speed)
{ {
struct rk_priv_data *bsp_priv = priv; struct rk_priv_data *bsp_priv = priv;
...@@ -591,6 +627,8 @@ static int rk_gmac_probe(struct platform_device *pdev) ...@@ -591,6 +627,8 @@ static int rk_gmac_probe(struct platform_device *pdev)
plat_dat->init = rk_gmac_init; plat_dat->init = rk_gmac_init;
plat_dat->exit = rk_gmac_exit; plat_dat->exit = rk_gmac_exit;
plat_dat->fix_mac_speed = rk_fix_speed; 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); plat_dat->bsp_priv = rk_gmac_setup(pdev, data);
if (IS_ERR(plat_dat->bsp_priv)) if (IS_ERR(plat_dat->bsp_priv))
......
...@@ -411,7 +411,9 @@ static int stmmac_pltfr_suspend(struct device *dev) ...@@ -411,7 +411,9 @@ static int stmmac_pltfr_suspend(struct device *dev)
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
ret = stmmac_suspend(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); priv->plat->exit(pdev, priv->plat->bsp_priv);
return ret; return ret;
...@@ -430,7 +432,9 @@ static int stmmac_pltfr_resume(struct device *dev) ...@@ -430,7 +432,9 @@ static int stmmac_pltfr_resume(struct device *dev)
struct stmmac_priv *priv = netdev_priv(ndev); struct stmmac_priv *priv = netdev_priv(ndev);
struct platform_device *pdev = to_platform_device(dev); 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); priv->plat->init(pdev, priv->plat->bsp_priv);
return stmmac_resume(dev); return stmmac_resume(dev);
......
...@@ -135,6 +135,8 @@ struct plat_stmmacenet_data { ...@@ -135,6 +135,8 @@ struct plat_stmmacenet_data {
void (*bus_setup)(void __iomem *ioaddr); void (*bus_setup)(void __iomem *ioaddr);
int (*init)(struct platform_device *pdev, void *priv); int (*init)(struct platform_device *pdev, void *priv);
void (*exit)(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; void *bsp_priv;
struct stmmac_axi *axi; struct stmmac_axi *axi;
int has_gmac4; int has_gmac4;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment