mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-12 08:45:11 +08:00
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
b4eccef8f3
@ -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>,
|
||||
|
@ -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;
|
||||
@ -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);
|
||||
@ -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;
|
||||
@ -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))
|
||||
|
@ -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;
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user