mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
eth: restart eth0 when resume [1/1]
PD#SWPL-114869 Problem: phy not work atfer resume sometimes Solution: restart ethernet after resume Verify: QA_verify with oppen Change-Id: I88bac8f0c24f0e2890b24a1508e05e74ed667b5c Signed-off-by: Zhuo Wang <zhuo.wang@amlogic.com>
This commit is contained in:
@@ -420,6 +420,7 @@ static void set_wol_notify_bl30(u32 enable_bl30)
|
||||
scpi_set_ethernet_wol(enable_bl30);
|
||||
}
|
||||
#endif
|
||||
unsigned int internal_phy;
|
||||
static int aml_custom_setting(struct platform_device *pdev, struct meson8b_dwmac *dwmac)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
@@ -433,6 +434,9 @@ static int aml_custom_setting(struct platform_device *pdev, struct meson8b_dwmac
|
||||
writel(mc_val, dwmac->regs + PRG_ETH0);
|
||||
}
|
||||
|
||||
if (of_property_read_u32(np, "internal_phy", &internal_phy) != 0)
|
||||
pr_info("use default internal_phy as 0\n");
|
||||
|
||||
ndev->wol_enabled = true;
|
||||
return 0;
|
||||
}
|
||||
@@ -594,8 +598,10 @@ static void meson8b_dwmac_shutdown(struct platform_device *pdev)
|
||||
|
||||
pr_info("aml_eth_shutdown\n");
|
||||
ret = stmmac_suspend(priv->device);
|
||||
if (dwmac->data->suspend)
|
||||
ret = dwmac->data->suspend(dwmac);
|
||||
if (internal_phy != 2) {
|
||||
if (dwmac->data->suspend)
|
||||
ret = dwmac->data->suspend(dwmac);
|
||||
}
|
||||
}
|
||||
|
||||
static int dwmac_suspend(struct meson8b_dwmac *dwmac)
|
||||
@@ -620,6 +626,7 @@ static void dwmac_resume(struct meson8b_dwmac *dwmac)
|
||||
}
|
||||
|
||||
int backup_adv;
|
||||
int without_reset;
|
||||
static int meson8b_suspend(struct device *dev)
|
||||
{
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
@@ -629,8 +636,8 @@ static int meson8b_suspend(struct device *dev)
|
||||
|
||||
int ret;
|
||||
|
||||
/*open wol*/
|
||||
if (wol_switch_from_user) {
|
||||
/*open wol, shutdown phy when not link*/
|
||||
if ((wol_switch_from_user) && phydev->link) {
|
||||
set_wol_notify_bl31(true);
|
||||
set_wol_notify_bl30(true);
|
||||
device_init_wakeup(dev, true);
|
||||
@@ -643,14 +650,18 @@ static int meson8b_suspend(struct device *dev)
|
||||
genphy_restart_aneg(phydev);
|
||||
msleep(3000);
|
||||
ret = stmmac_suspend(dev);
|
||||
without_reset = 1;
|
||||
} else {
|
||||
set_wol_notify_bl31(false);
|
||||
set_wol_notify_bl30(false);
|
||||
device_init_wakeup(dev, false);
|
||||
|
||||
ret = stmmac_suspend(dev);
|
||||
if (dwmac->data->suspend)
|
||||
ret = dwmac->data->suspend(dwmac);
|
||||
if (internal_phy != 2) {
|
||||
if (dwmac->data->suspend)
|
||||
ret = dwmac->data->suspend(dwmac);
|
||||
}
|
||||
without_reset = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -666,7 +677,7 @@ static int meson8b_resume(struct device *dev)
|
||||
|
||||
priv->wolopts = 0;
|
||||
|
||||
if (wol_switch_from_user) {
|
||||
if ((wol_switch_from_user) && (without_reset)) {
|
||||
ret = stmmac_resume(dev);
|
||||
|
||||
if (get_resume_method() == ETH_PHY_WAKEUP) {
|
||||
@@ -683,9 +694,13 @@ static int meson8b_resume(struct device *dev)
|
||||
mii_lpa_to_linkmode_lpa_t(phydev->advertising, backup_adv);
|
||||
genphy_restart_aneg(phydev);
|
||||
} else {
|
||||
if (dwmac->data->resume)
|
||||
dwmac->data->resume(dwmac);
|
||||
if (internal_phy != 2) {
|
||||
if (dwmac->data->resume)
|
||||
dwmac->data->resume(dwmac);
|
||||
}
|
||||
ret = stmmac_resume(dev);
|
||||
pr_info("wzh %s\n", __func__);
|
||||
stmmac_global_err(priv);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -395,4 +395,7 @@ static inline int stmmac_selftest_get_count(struct stmmac_priv *priv)
|
||||
}
|
||||
#endif /* CONFIG_STMMAC_SELFTESTS */
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_ETH_PRIVE)
|
||||
void stmmac_global_err(struct stmmac_priv *priv);
|
||||
#endif
|
||||
#endif /* __STMMAC_H__ */
|
||||
|
||||
@@ -276,6 +276,15 @@ static void stmmac_service_event_schedule(struct stmmac_priv *priv)
|
||||
queue_work(priv->wq, &priv->service_task);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_ETH_PRIVE)
|
||||
void stmmac_global_err(struct stmmac_priv *priv)
|
||||
{
|
||||
netif_carrier_off(priv->dev);
|
||||
set_bit(STMMAC_RESET_REQUESTED, &priv->state);
|
||||
stmmac_service_event_schedule(priv);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(stmmac_global_err);
|
||||
#else
|
||||
static void stmmac_global_err(struct stmmac_priv *priv)
|
||||
{
|
||||
netif_carrier_off(priv->dev);
|
||||
@@ -283,6 +292,7 @@ static void stmmac_global_err(struct stmmac_priv *priv)
|
||||
stmmac_service_event_schedule(priv);
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* stmmac_clk_csr_set - dynamically set the MDC clock
|
||||
* @priv: driver private structure
|
||||
|
||||
@@ -984,7 +984,8 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
|
||||
struct phy_device *phydev = phy_dat;
|
||||
struct phy_driver *drv = phydev->drv;
|
||||
irqreturn_t ret;
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_ETH_PRIVE)
|
||||
#else
|
||||
/* Wakeup interrupts may occur during a system sleep transition.
|
||||
* Postpone handling until the PHY has resumed.
|
||||
*/
|
||||
@@ -1006,7 +1007,7 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
|
||||
disable_irq_nosync(irq);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#endif
|
||||
mutex_lock(&phydev->lock);
|
||||
ret = drv->handle_interrupt(phydev);
|
||||
mutex_unlock(&phydev->lock);
|
||||
|
||||
Reference in New Issue
Block a user