]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 19 Nov 2021 13:29:10 +0000 (14:29 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 19 Nov 2021 13:29:10 +0000 (14:29 +0100)
added patches:
net-stmmac-add-clocks-management-for-gmac-driver.patch
net-stmmac-dwmac-rk-fix-unbalanced-pm_runtime_enable-warnings.patch
net-stmmac-fix-issue-where-clk-is-being-unprepared-twice.patch
net-stmmac-fix-missing-unlock-on-error-in-stmmac_suspend.patch
net-stmmac-fix-system-hang-if-change-mac-address-after-interface-ifdown.patch
net-stmmac-platform-fix-build-error-with-config_pm_sleep.patch

queue-5.10/net-stmmac-add-clocks-management-for-gmac-driver.patch [new file with mode: 0644]
queue-5.10/net-stmmac-dwmac-rk-fix-unbalanced-pm_runtime_enable-warnings.patch [new file with mode: 0644]
queue-5.10/net-stmmac-fix-issue-where-clk-is-being-unprepared-twice.patch [new file with mode: 0644]
queue-5.10/net-stmmac-fix-missing-unlock-on-error-in-stmmac_suspend.patch [new file with mode: 0644]
queue-5.10/net-stmmac-fix-system-hang-if-change-mac-address-after-interface-ifdown.patch [new file with mode: 0644]
queue-5.10/net-stmmac-platform-fix-build-error-with-config_pm_sleep.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/net-stmmac-add-clocks-management-for-gmac-driver.patch b/queue-5.10/net-stmmac-add-clocks-management-for-gmac-driver.patch
new file mode 100644 (file)
index 0000000..6f78095
--- /dev/null
@@ -0,0 +1,533 @@
+From foo@baz Fri Nov 19 02:27:53 PM CET 2021
+From: Meng Li <Meng.Li@windriver.com>
+Date: Fri, 19 Nov 2021 10:53:54 +0800
+Subject: net: stmmac: add clocks management for gmac driver
+To: stable@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, mcoquelin.stm32@gmail.com, linux@armlinux.org.uk, andrew@lunn.ch, qiangqing.zhang@nxp.com
+Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, meng.li@windriver.com
+Message-ID: <20211119025359.30815-2-Meng.Li@windriver.com>
+
+From: Joakim Zhang <qiangqing.zhang@nxp.com>
+
+commit 5ec55823438e850c91c6b92aec93fb04ebde29e2 upstream.
+
+This patch intends to add clocks management for stmmac driver:
+
+If CONFIG_PM enabled:
+1. Keep clocks disabled after driver probed.
+2. Enable clocks when up the net device, and disable clocks when down
+the net device.
+
+If CONFIG_PM disabled:
+Keep clocks always enabled after driver probed.
+
+Note:
+1. It is fine for ethtool, since the way of implementing ethtool_ops::begin
+in stmmac is only can be accessed when interface is enabled, so the clocks
+are ticked.
+2. The MDIO bus has a different life cycle to the MAC, need ensure
+clocks are enabled when _mdio_read/write() need clocks, because these
+functions can be called while the interface it not opened.
+
+Stable backport notes:
+When run below command to remove ethernet driver on
+stratix10 platform, there will be warning trace as below:
+
+$ cd /sys/class/net/eth0/device/driver/
+$ echo ff800000.ethernet > unbind
+
+WARNING: CPU: 3 PID: 386 at drivers/clk/clk.c:810 clk_core_unprepare+0x114/0x274
+Modules linked in: sch_fq_codel
+CPU: 3 PID: 386 Comm: sh Tainted: G        W         5.10.74-yocto-standard #1
+Hardware name: SoCFPGA Stratix 10 SoCDK (DT)
+pstate: 00000005 (nzcv daif -PAN -UAO -TCO BTYPE=--)
+pc : clk_core_unprepare+0x114/0x274
+lr : clk_core_unprepare+0x114/0x274
+sp : ffff800011bdbb10
+clk_core_unprepare+0x114/0x274
+ clk_unprepare+0x38/0x50
+ stmmac_remove_config_dt+0x40/0x80
+ stmmac_pltfr_remove+0x64/0x80
+ platform_drv_remove+0x38/0x60
+ ... ..
+ el0_sync_handler+0x1a4/0x1b0
+ el0_sync+0x180/0x1c0
+This issue is introduced by introducing upstream commit 8f269102baf7
+("net: stmmac: disable clocks in stmmac_remove_config_dt()")
+
+But in latest mainline kernel, there is no this issue. Because this
+patch improved clocks management for stmmac driver.
+Therefore, backport it and its fixing patches to stable kernel v5.10.
+
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: stable@vger.kernel.org
+Signed-off-by: Meng Li <Meng.Li@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h          |    1 
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c     |   75 ++++++++++--
+ drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c     |  111 +++++++++++++-----
+ drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c |   24 +++
+ 4 files changed, 174 insertions(+), 37 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -270,6 +270,7 @@ void stmmac_disable_eee_mode(struct stmm
+ bool stmmac_eee_init(struct stmmac_priv *priv);
+ int stmmac_reinit_queues(struct net_device *dev, u32 rx_cnt, u32 tx_cnt);
+ int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size);
++int stmmac_bus_clks_config(struct stmmac_priv *priv, bool enabled);
+ #if IS_ENABLED(CONFIG_STMMAC_SELFTESTS)
+ void stmmac_selftest_run(struct net_device *dev,
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -28,6 +28,7 @@
+ #include <linux/if_vlan.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/slab.h>
++#include <linux/pm_runtime.h>
+ #include <linux/prefetch.h>
+ #include <linux/pinctrl/consumer.h>
+ #ifdef CONFIG_DEBUG_FS
+@@ -113,6 +114,28 @@ static void stmmac_exit_fs(struct net_de
+ #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
++int stmmac_bus_clks_config(struct stmmac_priv *priv, bool enabled)
++{
++      int ret = 0;
++
++      if (enabled) {
++              ret = clk_prepare_enable(priv->plat->stmmac_clk);
++              if (ret)
++                      return ret;
++              ret = clk_prepare_enable(priv->plat->pclk);
++              if (ret) {
++                      clk_disable_unprepare(priv->plat->stmmac_clk);
++                      return ret;
++              }
++      } else {
++              clk_disable_unprepare(priv->plat->stmmac_clk);
++              clk_disable_unprepare(priv->plat->pclk);
++      }
++
++      return ret;
++}
++EXPORT_SYMBOL_GPL(stmmac_bus_clks_config);
++
+ /**
+  * stmmac_verify_args - verify the driver parameters.
+  * Description: it checks the driver parameters and set a default in case of
+@@ -2792,6 +2815,12 @@ static int stmmac_open(struct net_device
+       u32 chan;
+       int ret;
++      ret = pm_runtime_get_sync(priv->device);
++      if (ret < 0) {
++              pm_runtime_put_noidle(priv->device);
++              return ret;
++      }
++
+       if (priv->hw->pcs != STMMAC_PCS_TBI &&
+           priv->hw->pcs != STMMAC_PCS_RTBI &&
+           priv->hw->xpcs == NULL) {
+@@ -2800,7 +2829,7 @@ static int stmmac_open(struct net_device
+                       netdev_err(priv->dev,
+                                  "%s: Cannot attach to PHY (error: %d)\n",
+                                  __func__, ret);
+-                      return ret;
++                      goto init_phy_error;
+               }
+       }
+@@ -2915,6 +2944,8 @@ init_error:
+       free_dma_desc_resources(priv);
+ dma_desc_error:
+       phylink_disconnect_phy(priv->phylink);
++init_phy_error:
++      pm_runtime_put(priv->device);
+       return ret;
+ }
+@@ -2965,6 +2996,8 @@ static int stmmac_release(struct net_dev
+       stmmac_release_ptp(priv);
++      pm_runtime_put(priv->device);
++
+       return 0;
+ }
+@@ -4616,6 +4649,12 @@ static int stmmac_vlan_rx_kill_vid(struc
+       bool is_double = false;
+       int ret;
++      ret = pm_runtime_get_sync(priv->device);
++      if (ret < 0) {
++              pm_runtime_put_noidle(priv->device);
++              return ret;
++      }
++
+       if (be16_to_cpu(proto) == ETH_P_8021AD)
+               is_double = true;
+@@ -4624,10 +4663,15 @@ static int stmmac_vlan_rx_kill_vid(struc
+       if (priv->hw->num_vlan) {
+               ret = stmmac_del_hw_vlan_rx_fltr(priv, ndev, priv->hw, proto, vid);
+               if (ret)
+-                      return ret;
++                      goto del_vlan_error;
+       }
+-      return stmmac_vlan_update(priv, is_double);
++      ret = stmmac_vlan_update(priv, is_double);
++
++del_vlan_error:
++      pm_runtime_put(priv->device);
++
++      return ret;
+ }
+ static const struct net_device_ops stmmac_netdev_ops = {
+@@ -5066,6 +5110,10 @@ int stmmac_dvr_probe(struct device *devi
+       stmmac_check_pcs_mode(priv);
++      pm_runtime_get_noresume(device);
++      pm_runtime_set_active(device);
++      pm_runtime_enable(device);
++
+       if (priv->hw->pcs != STMMAC_PCS_TBI &&
+           priv->hw->pcs != STMMAC_PCS_RTBI) {
+               /* MDIO bus Registration */
+@@ -5103,6 +5151,11 @@ int stmmac_dvr_probe(struct device *devi
+       stmmac_init_fs(ndev);
+ #endif
++      /* Let pm_runtime_put() disable the clocks.
++       * If CONFIG_PM is not enabled, the clocks will stay powered.
++       */
++      pm_runtime_put(device);
++
+       return ret;
+ error_serdes_powerup:
+@@ -5117,6 +5170,7 @@ error_mdio_register:
+       stmmac_napi_del(ndev);
+ error_hw_init:
+       destroy_workqueue(priv->wq);
++      stmmac_bus_clks_config(priv, false);
+       return ret;
+ }
+@@ -5152,8 +5206,8 @@ int stmmac_dvr_remove(struct device *dev
+       phylink_destroy(priv->phylink);
+       if (priv->plat->stmmac_rst)
+               reset_control_assert(priv->plat->stmmac_rst);
+-      clk_disable_unprepare(priv->plat->pclk);
+-      clk_disable_unprepare(priv->plat->stmmac_clk);
++      pm_runtime_put(dev);
++      pm_runtime_disable(dev);
+       if (priv->hw->pcs != STMMAC_PCS_TBI &&
+           priv->hw->pcs != STMMAC_PCS_RTBI)
+               stmmac_mdio_unregister(ndev);
+@@ -5176,6 +5230,7 @@ int stmmac_suspend(struct device *dev)
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       u32 chan;
++      int ret;
+       if (!ndev || !netif_running(ndev))
+               return 0;
+@@ -5219,8 +5274,9 @@ int stmmac_suspend(struct device *dev)
+               pinctrl_pm_select_sleep_state(priv->device);
+               /* Disable clock in case of PWM is off */
+               clk_disable_unprepare(priv->plat->clk_ptp_ref);
+-              clk_disable_unprepare(priv->plat->pclk);
+-              clk_disable_unprepare(priv->plat->stmmac_clk);
++              ret = pm_runtime_force_suspend(dev);
++              if (ret)
++                      return ret;
+       }
+       mutex_unlock(&priv->lock);
+@@ -5286,8 +5342,9 @@ int stmmac_resume(struct device *dev)
+       } else {
+               pinctrl_pm_select_default_state(priv->device);
+               /* enable the clk previously disabled */
+-              clk_prepare_enable(priv->plat->stmmac_clk);
+-              clk_prepare_enable(priv->plat->pclk);
++              ret = pm_runtime_force_resume(dev);
++              if (ret)
++                      return ret;
+               if (priv->plat->clk_ptp_ref)
+                       clk_prepare_enable(priv->plat->clk_ptp_ref);
+               /* reset the phy so that it's ready */
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+@@ -15,6 +15,7 @@
+ #include <linux/iopoll.h>
+ #include <linux/mii.h>
+ #include <linux/of_mdio.h>
++#include <linux/pm_runtime.h>
+ #include <linux/phy.h>
+ #include <linux/property.h>
+ #include <linux/slab.h>
+@@ -87,21 +88,29 @@ static int stmmac_xgmac2_mdio_read(struc
+       u32 tmp, addr, value = MII_XGMAC_BUSY;
+       int ret;
++      ret = pm_runtime_get_sync(priv->device);
++      if (ret < 0) {
++              pm_runtime_put_noidle(priv->device);
++              return ret;
++      }
++
+       /* Wait until any existing MII operation is complete */
+       if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+-                             !(tmp & MII_XGMAC_BUSY), 100, 10000))
+-              return -EBUSY;
++                             !(tmp & MII_XGMAC_BUSY), 100, 10000)) {
++              ret = -EBUSY;
++              goto err_disable_clks;
++      }
+       if (phyreg & MII_ADDR_C45) {
+               phyreg &= ~MII_ADDR_C45;
+               ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr);
+               if (ret)
+-                      return ret;
++                      goto err_disable_clks;
+       } else {
+               ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
+               if (ret)
+-                      return ret;
++                      goto err_disable_clks;
+               value |= MII_XGMAC_SADDR;
+       }
+@@ -112,8 +121,10 @@ static int stmmac_xgmac2_mdio_read(struc
+       /* Wait until any existing MII operation is complete */
+       if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+-                             !(tmp & MII_XGMAC_BUSY), 100, 10000))
+-              return -EBUSY;
++                             !(tmp & MII_XGMAC_BUSY), 100, 10000)) {
++              ret = -EBUSY;
++              goto err_disable_clks;
++      }
+       /* Set the MII address register to read */
+       writel(addr, priv->ioaddr + mii_address);
+@@ -121,11 +132,18 @@ static int stmmac_xgmac2_mdio_read(struc
+       /* Wait until any existing MII operation is complete */
+       if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+-                             !(tmp & MII_XGMAC_BUSY), 100, 10000))
+-              return -EBUSY;
++                             !(tmp & MII_XGMAC_BUSY), 100, 10000)) {
++              ret = -EBUSY;
++              goto err_disable_clks;
++      }
+       /* Read the data from the MII data register */
+-      return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
++      ret = (int)readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
++
++err_disable_clks:
++      pm_runtime_put(priv->device);
++
++      return ret;
+ }
+ static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
+@@ -138,21 +156,29 @@ static int stmmac_xgmac2_mdio_write(stru
+       u32 addr, tmp, value = MII_XGMAC_BUSY;
+       int ret;
++      ret = pm_runtime_get_sync(priv->device);
++      if (ret < 0) {
++              pm_runtime_put_noidle(priv->device);
++              return ret;
++      }
++
+       /* Wait until any existing MII operation is complete */
+       if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+-                             !(tmp & MII_XGMAC_BUSY), 100, 10000))
+-              return -EBUSY;
++                             !(tmp & MII_XGMAC_BUSY), 100, 10000)) {
++              ret = -EBUSY;
++              goto err_disable_clks;
++      }
+       if (phyreg & MII_ADDR_C45) {
+               phyreg &= ~MII_ADDR_C45;
+               ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr);
+               if (ret)
+-                      return ret;
++                      goto err_disable_clks;
+       } else {
+               ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
+               if (ret)
+-                      return ret;
++                      goto err_disable_clks;
+               value |= MII_XGMAC_SADDR;
+       }
+@@ -164,16 +190,23 @@ static int stmmac_xgmac2_mdio_write(stru
+       /* Wait until any existing MII operation is complete */
+       if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+-                             !(tmp & MII_XGMAC_BUSY), 100, 10000))
+-              return -EBUSY;
++                             !(tmp & MII_XGMAC_BUSY), 100, 10000)) {
++              ret = -EBUSY;
++              goto err_disable_clks;
++      }
+       /* Set the MII address register to write */
+       writel(addr, priv->ioaddr + mii_address);
+       writel(value, priv->ioaddr + mii_data);
+       /* Wait until any existing MII operation is complete */
+-      return readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+-                                !(tmp & MII_XGMAC_BUSY), 100, 10000);
++      ret = readl_poll_timeout(priv->ioaddr + mii_data, tmp,
++                               !(tmp & MII_XGMAC_BUSY), 100, 10000);
++
++err_disable_clks:
++      pm_runtime_put(priv->device);
++
++      return ret;
+ }
+ /**
+@@ -196,6 +229,12 @@ static int stmmac_mdio_read(struct mii_b
+       int data = 0;
+       u32 v;
++      data = pm_runtime_get_sync(priv->device);
++      if (data < 0) {
++              pm_runtime_put_noidle(priv->device);
++              return data;
++      }
++
+       value |= (phyaddr << priv->hw->mii.addr_shift)
+               & priv->hw->mii.addr_mask;
+       value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
+@@ -216,19 +255,26 @@ static int stmmac_mdio_read(struct mii_b
+       }
+       if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
+-                             100, 10000))
+-              return -EBUSY;
++                             100, 10000)) {
++              data = -EBUSY;
++              goto err_disable_clks;
++      }
+       writel(data, priv->ioaddr + mii_data);
+       writel(value, priv->ioaddr + mii_address);
+       if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
+-                             100, 10000))
+-              return -EBUSY;
++                             100, 10000)) {
++              data = -EBUSY;
++              goto err_disable_clks;
++      }
+       /* Read the data from the MII data register */
+       data = (int)readl(priv->ioaddr + mii_data) & MII_DATA_MASK;
++err_disable_clks:
++      pm_runtime_put(priv->device);
++
+       return data;
+ }
+@@ -247,10 +293,16 @@ static int stmmac_mdio_write(struct mii_
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       unsigned int mii_address = priv->hw->mii.addr;
+       unsigned int mii_data = priv->hw->mii.data;
++      int ret, data = phydata;
+       u32 value = MII_BUSY;
+-      int data = phydata;
+       u32 v;
++      ret = pm_runtime_get_sync(priv->device);
++      if (ret < 0) {
++              pm_runtime_put_noidle(priv->device);
++              return ret;
++      }
++
+       value |= (phyaddr << priv->hw->mii.addr_shift)
+               & priv->hw->mii.addr_mask;
+       value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
+@@ -275,16 +327,23 @@ static int stmmac_mdio_write(struct mii_
+       /* Wait until any existing MII operation is complete */
+       if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
+-                             100, 10000))
+-              return -EBUSY;
++                             100, 10000)) {
++              ret = -EBUSY;
++              goto err_disable_clks;
++      }
+       /* Set the MII address register to write */
+       writel(data, priv->ioaddr + mii_data);
+       writel(value, priv->ioaddr + mii_address);
+       /* Wait until any existing MII operation is complete */
+-      return readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
+-                                100, 10000);
++      ret = readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
++                               100, 10000);
++
++err_disable_clks:
++      pm_runtime_put(priv->device);
++
++      return ret;
+ }
+ /**
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -760,10 +760,30 @@ static int stmmac_pltfr_resume(struct de
+       return stmmac_resume(dev);
+ }
++
++static int stmmac_runtime_suspend(struct device *dev)
++{
++      struct net_device *ndev = dev_get_drvdata(dev);
++      struct stmmac_priv *priv = netdev_priv(ndev);
++
++      stmmac_bus_clks_config(priv, false);
++
++      return 0;
++}
++
++static int stmmac_runtime_resume(struct device *dev)
++{
++      struct net_device *ndev = dev_get_drvdata(dev);
++      struct stmmac_priv *priv = netdev_priv(ndev);
++
++      return stmmac_bus_clks_config(priv, true);
++}
+ #endif /* CONFIG_PM_SLEEP */
+-SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, stmmac_pltfr_suspend,
+-                                     stmmac_pltfr_resume);
++const struct dev_pm_ops stmmac_pltfr_pm_ops = {
++      SET_SYSTEM_SLEEP_PM_OPS(stmmac_pltfr_suspend, stmmac_pltfr_resume)
++      SET_RUNTIME_PM_OPS(stmmac_runtime_suspend, stmmac_runtime_resume, NULL)
++};
+ EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops);
+ MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet platform support");
diff --git a/queue-5.10/net-stmmac-dwmac-rk-fix-unbalanced-pm_runtime_enable-warnings.patch b/queue-5.10/net-stmmac-dwmac-rk-fix-unbalanced-pm_runtime_enable-warnings.patch
new file mode 100644 (file)
index 0000000..a345398
--- /dev/null
@@ -0,0 +1,70 @@
+From foo@baz Fri Nov 19 02:27:53 PM CET 2021
+From: Meng Li <Meng.Li@windriver.com>
+Date: Fri, 19 Nov 2021 10:53:59 +0800
+Subject: net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable warnings
+To: stable@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, mcoquelin.stm32@gmail.com, linux@armlinux.org.uk, andrew@lunn.ch, qiangqing.zhang@nxp.com
+Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, meng.li@windriver.com
+Message-ID: <20211119025359.30815-7-Meng.Li@windriver.com>
+
+From: Michael Riesch <michael.riesch@wolfvision.net>
+
+commit 2d26f6e39afb88d32b8f39e76a51b542c3c51674 upstream.
+
+This reverts commit 2c896fb02e7f65299646f295a007bda043e0f382
+"net: stmmac: dwmac-rk: add pd_gmac support for rk3399" and fixes
+unbalanced pm_runtime_enable warnings.
+
+In the commit to be reverted, support for power management was
+introduced to the Rockchip glue code. Later, power management support
+was introduced to the stmmac core code, resulting in multiple
+invocations of pm_runtime_{enable,disable,get_sync,put_sync}.
+
+The multiple invocations happen in rk_gmac_powerup and
+stmmac_{dvr_probe, resume} as well as in rk_gmac_powerdown and
+stmmac_{dvr_remove, suspend}, respectively, which are always called
+in conjunction.
+
+Fixes: 5ec55823438e850c91c6b92aec93fb04ebde29e2 ("net: stmmac: add clocks management for gmac driver")
+Signed-off-by: Michael Riesch <michael.riesch@wolfvision.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Meng Li <Meng.Li@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c |    9 ---------
+ 1 file changed, 9 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+@@ -21,7 +21,6 @@
+ #include <linux/delay.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+-#include <linux/pm_runtime.h>
+ #include "stmmac_platform.h"
+@@ -1336,9 +1335,6 @@ static int rk_gmac_powerup(struct rk_pri
+               return ret;
+       }
+-      pm_runtime_enable(dev);
+-      pm_runtime_get_sync(dev);
+-
+       if (bsp_priv->integrated_phy)
+               rk_gmac_integrated_phy_powerup(bsp_priv);
+@@ -1347,14 +1343,9 @@ static int rk_gmac_powerup(struct rk_pri
+ static void rk_gmac_powerdown(struct rk_priv_data *gmac)
+ {
+-      struct device *dev = &gmac->pdev->dev;
+-
+       if (gmac->integrated_phy)
+               rk_gmac_integrated_phy_powerdown(gmac);
+-      pm_runtime_put_sync(dev);
+-      pm_runtime_disable(dev);
+-
+       phy_power_on(gmac, false);
+       gmac_clk_enable(gmac, false);
+ }
diff --git a/queue-5.10/net-stmmac-fix-issue-where-clk-is-being-unprepared-twice.patch b/queue-5.10/net-stmmac-fix-issue-where-clk-is-being-unprepared-twice.patch
new file mode 100644 (file)
index 0000000..545c1c9
--- /dev/null
@@ -0,0 +1,95 @@
+From foo@baz Fri Nov 19 02:27:53 PM CET 2021
+From: Meng Li <Meng.Li@windriver.com>
+Date: Fri, 19 Nov 2021 10:53:58 +0800
+Subject: net: stmmac: fix issue where clk is being unprepared twice
+To: stable@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, mcoquelin.stm32@gmail.com, linux@armlinux.org.uk, andrew@lunn.ch, qiangqing.zhang@nxp.com
+Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, meng.li@windriver.com
+Message-ID: <20211119025359.30815-6-Meng.Li@windriver.com>
+
+From: Wong Vee Khee <vee.khee.wong@linux.intel.com>
+
+commit ab00f3e051e851a8458f0d0eb1bb426deadb6619 upstream.
+
+In the case of MDIO bus registration failure due to no external PHY
+devices is connected to the MAC, clk_disable_unprepare() is called in
+stmmac_bus_clk_config() and intel_eth_pci_probe() respectively.
+
+The second call in intel_eth_pci_probe() will caused the following:-
+
+[   16.578605] intel-eth-pci 0000:00:1e.5: No PHY found
+[   16.583778] intel-eth-pci 0000:00:1e.5: stmmac_dvr_probe: MDIO bus (id: 2) registration failed
+[   16.680181] ------------[ cut here ]------------
+[   16.684861] stmmac-0000:00:1e.5 already disabled
+[   16.689547] WARNING: CPU: 13 PID: 2053 at drivers/clk/clk.c:952 clk_core_disable+0x96/0x1b0
+[   16.697963] Modules linked in: dwc3 iTCO_wdt mei_hdcp iTCO_vendor_support udc_core x86_pkg_temp_thermal kvm_intel marvell10g kvm sch_fq_codel nfsd irqbypass dwmac_intel(+) stmmac uio ax88179_178a pcs_xpcs phylink uhid spi_pxa2xx_platform usbnet mei_me pcspkr tpm_crb mii i2c_i801 dw_dmac dwc3_pci thermal dw_dmac_core intel_rapl_msr libphy i2c_smbus mei tpm_tis intel_th_gth tpm_tis_core tpm intel_th_acpi intel_pmc_core intel_th i915 fuse configfs snd_hda_intel snd_intel_dspcfg snd_intel_sdw_acpi snd_hda_codec snd_hda_core snd_pcm snd_timer snd soundcore
+[   16.746785] CPU: 13 PID: 2053 Comm: systemd-udevd Tainted: G     U            5.13.0-rc3-intel-lts #76
+[   16.756134] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-S ADP-S DRR4 CRB, BIOS ADLIFSI1.R00.1494.B00.2012031421 12/03/2020
+[   16.769465] RIP: 0010:clk_core_disable+0x96/0x1b0
+[   16.774222] Code: 00 8b 05 45 96 17 01 85 c0 7f 24 48 8b 5b 30 48 85 db 74 a5 8b 43 7c 85 c0 75 93 48 8b 33 48 c7 c7 6e 32 cc b7 e8 b2 5d 52 00 <0f> 0b 5b 5d c3 65 8b 05 76 31 18 49 89 c0 48 0f a3 05 bc 92 1a 01
+[   16.793016] RSP: 0018:ffffa44580523aa0 EFLAGS: 00010086
+[   16.798287] RAX: 0000000000000000 RBX: ffff8d7d0eb70a00 RCX: 0000000000000000
+[   16.805435] RDX: 0000000000000002 RSI: ffffffffb7c62d5f RDI: 00000000ffffffff
+[   16.812610] RBP: 0000000000000287 R08: 0000000000000000 R09: ffffa445805238d0
+[   16.819759] R10: 0000000000000001 R11: 0000000000000001 R12: ffff8d7d0eb70a00
+[   16.826904] R13: ffff8d7d027370c8 R14: 0000000000000006 R15: ffffa44580523ad0
+[   16.834047] FS:  00007f9882fa2600(0000) GS:ffff8d80a0940000(0000) knlGS:0000000000000000
+[   16.842177] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   16.847966] CR2: 00007f9882bea3d8 CR3: 000000010b126001 CR4: 0000000000370ee0
+[   16.855144] Call Trace:
+[   16.857614]  clk_core_disable_lock+0x1b/0x30
+[   16.861941]  intel_eth_pci_probe.cold+0x11d/0x136 [dwmac_intel]
+[   16.867913]  pci_device_probe+0xcf/0x150
+[   16.871890]  really_probe+0xf5/0x3e0
+[   16.875526]  driver_probe_device+0x64/0x150
+[   16.879763]  device_driver_attach+0x53/0x60
+[   16.883998]  __driver_attach+0x9f/0x150
+[   16.887883]  ? device_driver_attach+0x60/0x60
+[   16.892288]  ? device_driver_attach+0x60/0x60
+[   16.896698]  bus_for_each_dev+0x77/0xc0
+[   16.900583]  bus_add_driver+0x184/0x1f0
+[   16.904469]  driver_register+0x6c/0xc0
+[   16.908268]  ? 0xffffffffc07ae000
+[   16.911598]  do_one_initcall+0x4a/0x210
+[   16.915489]  ? kmem_cache_alloc_trace+0x305/0x4e0
+[   16.920247]  do_init_module+0x5c/0x230
+[   16.924057]  load_module+0x2894/0x2b70
+[   16.927857]  ? __do_sys_finit_module+0xb5/0x120
+[   16.932441]  __do_sys_finit_module+0xb5/0x120
+[   16.936845]  do_syscall_64+0x42/0x80
+[   16.940476]  entry_SYSCALL_64_after_hwframe+0x44/0xae
+[   16.945586] RIP: 0033:0x7f98830e5ccd
+[   16.949177] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 93 31 0c 00 f7 d8 64 89 01 48
+[   16.967970] RSP: 002b:00007ffc66b60168 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
+[   16.975583] RAX: ffffffffffffffda RBX: 000055885de35ef0 RCX: 00007f98830e5ccd
+[   16.982725] RDX: 0000000000000000 RSI: 00007f98832541e3 RDI: 0000000000000012
+[   16.989868] RBP: 0000000000020000 R08: 0000000000000000 R09: 0000000000000000
+[   16.997042] R10: 0000000000000012 R11: 0000000000000246 R12: 00007f98832541e3
+[   17.004222] R13: 0000000000000000 R14: 0000000000000000 R15: 00007ffc66b60328
+[   17.011369] ---[ end trace df06a3dab26b988c ]---
+[   17.016062] ------------[ cut here ]------------
+[   17.020701] stmmac-0000:00:1e.5 already unprepared
+
+Removing the stmmac_bus_clks_config() call in stmmac_dvr_probe and let
+dwmac-intel to handle the unprepare and disable of the clk device.
+
+Fixes: 5ec55823438e ("net: stmmac: add clocks management for gmac driver")
+Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
+Signed-off-by: Wong Vee Khee <vee.khee.wong@linux.intel.com>
+Reviewed-by: Joakim Zhang <qiangqing.zhang@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Meng Li <Meng.Li@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -5179,7 +5179,6 @@ error_mdio_register:
+       stmmac_napi_del(ndev);
+ error_hw_init:
+       destroy_workqueue(priv->wq);
+-      stmmac_bus_clks_config(priv, false);
+       return ret;
+ }
diff --git a/queue-5.10/net-stmmac-fix-missing-unlock-on-error-in-stmmac_suspend.patch b/queue-5.10/net-stmmac-fix-missing-unlock-on-error-in-stmmac_suspend.patch
new file mode 100644 (file)
index 0000000..7931ac6
--- /dev/null
@@ -0,0 +1,39 @@
+From foo@baz Fri Nov 19 02:27:53 PM CET 2021
+From: Meng Li <Meng.Li@windriver.com>
+Date: Fri, 19 Nov 2021 10:53:56 +0800
+Subject: net: stmmac: fix missing unlock on error in stmmac_suspend()
+To: stable@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, mcoquelin.stm32@gmail.com, linux@armlinux.org.uk, andrew@lunn.ch, qiangqing.zhang@nxp.com
+Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, meng.li@windriver.com
+Message-ID: <20211119025359.30815-4-Meng.Li@windriver.com>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+commit 30f347ae7cc1178c431f968a89d4b4a375bc0d39 upstream
+
+Add the missing unlock before return from stmmac_suspend()
+in the error handling case.
+
+Fixes: 5ec55823438e ("net: stmmac: add clocks management for gmac driver")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Meng Li <Meng.Li@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -5275,8 +5275,10 @@ int stmmac_suspend(struct device *dev)
+               /* Disable clock in case of PWM is off */
+               clk_disable_unprepare(priv->plat->clk_ptp_ref);
+               ret = pm_runtime_force_suspend(dev);
+-              if (ret)
++              if (ret) {
++                      mutex_unlock(&priv->lock);
+                       return ret;
++              }
+       }
+       mutex_unlock(&priv->lock);
diff --git a/queue-5.10/net-stmmac-fix-system-hang-if-change-mac-address-after-interface-ifdown.patch b/queue-5.10/net-stmmac-fix-system-hang-if-change-mac-address-after-interface-ifdown.patch
new file mode 100644 (file)
index 0000000..ab6cc7c
--- /dev/null
@@ -0,0 +1,53 @@
+From foo@baz Fri Nov 19 02:27:53 PM CET 2021
+From: Meng Li <Meng.Li@windriver.com>
+Date: Fri, 19 Nov 2021 10:53:57 +0800
+Subject: net: stmmac: fix system hang if change mac address after interface ifdown
+To: stable@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, mcoquelin.stm32@gmail.com, linux@armlinux.org.uk, andrew@lunn.ch, qiangqing.zhang@nxp.com
+Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, meng.li@windriver.com
+Message-ID: <20211119025359.30815-5-Meng.Li@windriver.com>
+
+From: Joakim Zhang <qiangqing.zhang@nxp.com>
+
+commit 4691ffb18ac908609aab07d13af7995b6b89d33c upstream.
+
+Fix system hang with below sequences:
+~# ifconfig ethx down
+~# ifconfig ethx hw ether xx:xx:xx:xx:xx:xx
+
+After ethx down, stmmac all clocks gated off and then register access causes
+system hang.
+
+Fixes: 5ec55823438e ("net: stmmac: add clocks management for gmac driver")
+Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Meng Li <Meng.Li@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |   11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -4324,12 +4324,21 @@ static int stmmac_set_mac_address(struct
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       int ret = 0;
++      ret = pm_runtime_get_sync(priv->device);
++      if (ret < 0) {
++              pm_runtime_put_noidle(priv->device);
++              return ret;
++      }
++
+       ret = eth_mac_addr(ndev, addr);
+       if (ret)
+-              return ret;
++              goto set_mac_error;
+       stmmac_set_umac_addr(priv, priv->hw, ndev->dev_addr, 0);
++set_mac_error:
++      pm_runtime_put(priv->device);
++
+       return ret;
+ }
diff --git a/queue-5.10/net-stmmac-platform-fix-build-error-with-config_pm_sleep.patch b/queue-5.10/net-stmmac-platform-fix-build-error-with-config_pm_sleep.patch
new file mode 100644 (file)
index 0000000..c48ab7c
--- /dev/null
@@ -0,0 +1,94 @@
+From foo@baz Fri Nov 19 02:27:53 PM CET 2021
+From: Meng Li <Meng.Li@windriver.com>
+Date: Fri, 19 Nov 2021 10:53:55 +0800
+Subject: net: stmmac: platform: fix build error with !CONFIG_PM_SLEEP
+To: stable@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, mcoquelin.stm32@gmail.com, linux@armlinux.org.uk, andrew@lunn.ch, qiangqing.zhang@nxp.com
+Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, meng.li@windriver.com
+Message-ID: <20211119025359.30815-3-Meng.Li@windriver.com>
+
+From: Wei Yongjun <weiyongjun1@huawei.com>
+
+commit 7ec05a6035480f3a5934b2b31222620b2e906163 upstream
+
+Get rid of the CONFIG_PM_SLEEP ifdefery to fix the build error
+and use __maybe_unused for the suspend()/resume() hooks to avoid
+build warning:
+
+drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c:769:21:
+ error: 'stmmac_runtime_suspend' undeclared here (not in a function); did you mean 'stmmac_suspend'?
+  769 |  SET_RUNTIME_PM_OPS(stmmac_runtime_suspend, stmmac_runtime_resume, NULL)
+      |                     ^~~~~~~~~~~~~~~~~~~~~~
+./include/linux/pm.h:342:21: note: in definition of macro 'SET_RUNTIME_PM_OPS'
+  342 |  .runtime_suspend = suspend_fn, \
+      |                     ^~~~~~~~~~
+drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c:769:45:
+ error: 'stmmac_runtime_resume' undeclared here (not in a function)
+  769 |  SET_RUNTIME_PM_OPS(stmmac_runtime_suspend, stmmac_runtime_resume, NULL)
+      |                                             ^~~~~~~~~~~~~~~~~~~~~
+./include/linux/pm.h:343:20: note: in definition of macro 'SET_RUNTIME_PM_OPS'
+  343 |  .runtime_resume = resume_fn, \
+      |                    ^~~~~~~~~
+
+Fixes: 5ec55823438e ("net: stmmac: add clocks management for gmac driver")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Meng Li <Meng.Li@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c |   10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -720,7 +720,6 @@ int stmmac_pltfr_remove(struct platform_
+ }
+ EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
+-#ifdef CONFIG_PM_SLEEP
+ /**
+  * stmmac_pltfr_suspend
+  * @dev: device pointer
+@@ -728,7 +727,7 @@ EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
+  * call the main suspend function and then, if required, on some platform, it
+  * can call an exit helper.
+  */
+-static int stmmac_pltfr_suspend(struct device *dev)
++static int __maybe_unused stmmac_pltfr_suspend(struct device *dev)
+ {
+       int ret;
+       struct net_device *ndev = dev_get_drvdata(dev);
+@@ -749,7 +748,7 @@ static int stmmac_pltfr_suspend(struct d
+  * the main resume function, on some platforms, it can call own init helper
+  * if required.
+  */
+-static int stmmac_pltfr_resume(struct device *dev)
++static int __maybe_unused stmmac_pltfr_resume(struct device *dev)
+ {
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct stmmac_priv *priv = netdev_priv(ndev);
+@@ -761,7 +760,7 @@ static int stmmac_pltfr_resume(struct de
+       return stmmac_resume(dev);
+ }
+-static int stmmac_runtime_suspend(struct device *dev)
++static int __maybe_unused stmmac_runtime_suspend(struct device *dev)
+ {
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct stmmac_priv *priv = netdev_priv(ndev);
+@@ -771,14 +770,13 @@ static int stmmac_runtime_suspend(struct
+       return 0;
+ }
+-static int stmmac_runtime_resume(struct device *dev)
++static int __maybe_unused stmmac_runtime_resume(struct device *dev)
+ {
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       return stmmac_bus_clks_config(priv, true);
+ }
+-#endif /* CONFIG_PM_SLEEP */
+ const struct dev_pm_ops stmmac_pltfr_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(stmmac_pltfr_suspend, stmmac_pltfr_resume)
index 6b7236bff56af012544324eccdc06053adc8fb2a..2e965f48011c6228554472751bf0cc1fd834e762 100644 (file)
@@ -2,3 +2,9 @@ fortify-explicitly-disable-clang-support.patch
 block-add-a-helper-to-validate-the-block-size.patch
 loop-use-blk_validate_block_size-to-validate-block-size.patch
 bootconfig-init-fix-memblock-leak-in-xbc_make_cmdline.patch
+net-stmmac-add-clocks-management-for-gmac-driver.patch
+net-stmmac-platform-fix-build-error-with-config_pm_sleep.patch
+net-stmmac-fix-missing-unlock-on-error-in-stmmac_suspend.patch
+net-stmmac-fix-system-hang-if-change-mac-address-after-interface-ifdown.patch
+net-stmmac-fix-issue-where-clk-is-being-unprepared-twice.patch
+net-stmmac-dwmac-rk-fix-unbalanced-pm_runtime_enable-warnings.patch