When running suspend/resume test on nxp ls1028 platform, there is below warning trace Call trace: mdio_bus_phy_resume+0xa8/0x128 dpm_run_callback+0x4c/0x184 device_resume+0x9c/0x1f0 dpm_resume+0x114/0x340 dpm_resume_end+0x24/0x3c suspend_devices_and_enter+0x1e0/0x810 pm_suspend+0x288/0x330 ...... el0t_64_sync+0x1a0/0x1a4 ---[ end trace e8da30565a047649 ]--- Because there is a commit 47ac7b2f6a1f("net: phy: Warn about incorrect mdio_bus_phy_resume() state") to check phy state when entering resume phase. This is only a surface phenomenon, the root cause is that enetc driver can not co-operation with common phy code properly. According to commit fba863b81604("net: phy: make PHY PM ops a no-op if MAC driver manages PHY PM "). enetc also can manages PHY PM by itself. So, add suspend/resume function to manage both mac and phy PM.
Signed-off-by: Meng Li <meng...@windriver.com> --- .../net/ethernet/freescale/enetc/enetc_pf.c | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index c4560222318d..538a4dba42d3 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -8,6 +8,7 @@ #include <linux/of_platform.h> #include <linux/of_mdio.h> #include <linux/of_net.h> +#include <linux/of.h> #include <linux/pcs-lynx.h> #include "enetc_ierb.h" #include "enetc_pf.h" @@ -1243,6 +1244,8 @@ static int enetc_pf_probe(struct pci_dev *pdev, struct enetc_si *si; struct enetc_pf *pf; int err; + struct fwnode_handle *phy_fwnode; + struct phy_device *phy_dev; err = enetc_pf_register_with_ierb(pdev); if (err == -EPROBE_DEFER) @@ -1349,6 +1352,11 @@ static int enetc_pf_probe(struct pci_dev *pdev, enetc_tsn_pf_init(ndev, pdev); + phy_fwnode = fwnode_get_phy_node(of_fwnode_handle(priv->dev->of_node)); + phy_dev = fwnode_phy_find_device(phy_fwnode); + if (phy_dev) + phy_dev->mac_managed_pm = 1; + return 0; err_reg_netdev: @@ -1405,6 +1413,62 @@ static void enetc_pf_remove(struct pci_dev *pdev) enetc_pci_remove(pdev); } +static int enetc_pf_resume(struct device *dev) +{ + struct enetc_si *si = dev_get_drvdata(dev); + struct net_device *netdev = si->ndev; + struct enetc_ndev_priv *priv = netdev_priv(netdev); + struct fwnode_handle *phy_fwnode; + struct phy_device *phy_dev; + + if (!netdev) + return 0; + + rtnl_lock(); + + if (!netif_running(netdev)) { + rtnl_unlock(); + return 0; + } + + phy_fwnode = fwnode_get_phy_node(of_fwnode_handle(priv->dev->of_node)); + phy_dev = fwnode_phy_find_device(phy_fwnode); + if (phy_dev) + phy_init_hw(phy_dev); + enetc_start(netdev); + + rtnl_unlock(); + + return 0; +} + +static int enetc_pf_suspend(struct device *dev) +{ + struct enetc_si *si = dev_get_drvdata(dev); + struct net_device *netdev = si->ndev; + + if (!netdev) + return 0; + + rtnl_lock(); + + if (!netif_running(netdev)) { + rtnl_unlock(); + return 0; + } + + enetc_stop(netdev); + + rtnl_unlock(); + + return 0; +} + +static const struct dev_pm_ops enetc_pf_pm_ops = { + .suspend = enetc_pf_suspend, + .resume = enetc_pf_resume, +}; + static const struct pci_device_id enetc_pf_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PF) }, { 0, } /* End of table. */ @@ -1419,6 +1483,9 @@ static struct pci_driver enetc_pf_driver = { #ifdef CONFIG_PCI_IOV .sriov_configure = enetc_sriov_configure, #endif + .driver = { + .pm = &enetc_pf_pm_ops, + }, }; module_pci_driver(enetc_pf_driver); -- 2.36.1
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#12442): https://lists.yoctoproject.org/g/linux-yocto/message/12442 Mute This Topic: https://lists.yoctoproject.org/mt/98555946/21656 Group Owner: linux-yocto+ow...@lists.yoctoproject.org Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-