net: stmmac: dwmac-sun8i: make clk really gated during rpm suspended
authorJisheng Zhang <jszhang@kernel.org>
Fri, 28 Jan 2022 14:52:13 +0000 (22:52 +0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 28 Jan 2022 15:15:04 +0000 (15:15 +0000)
Currently, the dwmac-sun8i's stmmaceth clk isn't disabled even if the
the device has been runtime suspended. The reason is the driver gets
the "stmmaceth" clk as tx_clk and enabling it during probe. But
there's no other usage of tx_clk except preparing and enabling, so
we can remove tx_clk and its usage then rely on the common routine
stmmac_probe_config_dt() to prepare and enable the stmmaceth clk
during driver initialization, and benefit from the runtime pm feature
after probed.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c

index 09644ab..f86cc83 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/of_net.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regmap.h>
 #include <linux/stmmac.h>
@@ -57,7 +58,6 @@ struct emac_variant {
 };
 
 /* struct sunxi_priv_data - hold all sunxi private data
- * @tx_clk:    reference to MAC TX clock
  * @ephy_clk:  reference to the optional EPHY clock for the internal PHY
  * @regulator: reference to the optional regulator
  * @rst_ephy:  reference to the optional EPHY reset for the internal PHY
@@ -68,7 +68,6 @@ struct emac_variant {
  * @mux_handle:        Internal pointer used by mdio-mux lib
  */
 struct sunxi_priv_data {
-       struct clk *tx_clk;
        struct clk *ephy_clk;
        struct regulator *regulator;
        struct reset_control *rst_ephy;
@@ -579,22 +578,14 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
                }
        }
 
-       ret = clk_prepare_enable(gmac->tx_clk);
-       if (ret) {
-               dev_err(&pdev->dev, "Could not enable AHB clock\n");
-               goto err_disable_regulator;
-       }
-
        if (gmac->use_internal_phy) {
                ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev));
                if (ret)
-                       goto err_disable_clk;
+                       goto err_disable_regulator;
        }
 
        return 0;
 
-err_disable_clk:
-       clk_disable_unprepare(gmac->tx_clk);
 err_disable_regulator:
        if (gmac->regulator)
                regulator_disable(gmac->regulator);
@@ -1043,8 +1034,6 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
        if (gmac->variant->soc_has_internal_phy)
                sun8i_dwmac_unpower_internal_phy(gmac);
 
-       clk_disable_unprepare(gmac->tx_clk);
-
        if (gmac->regulator)
                regulator_disable(gmac->regulator);
 }
@@ -1167,12 +1156,6 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       gmac->tx_clk = devm_clk_get(dev, "stmmaceth");
-       if (IS_ERR(gmac->tx_clk)) {
-               dev_err(dev, "Could not get TX clock\n");
-               return PTR_ERR(gmac->tx_clk);
-       }
-
        /* Optional regulator for PHY */
        gmac->regulator = devm_regulator_get_optional(dev, "phy");
        if (IS_ERR(gmac->regulator)) {
@@ -1254,6 +1237,12 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
        ndev = dev_get_drvdata(&pdev->dev);
        priv = netdev_priv(ndev);
 
+       /* the MAC is runtime suspended after stmmac_dvr_probe(), so we
+        * need to ensure the MAC resume back before other operations such
+        * as reset.
+        */
+       pm_runtime_get_sync(&pdev->dev);
+
        /* The mux must be registered after parent MDIO
         * so after stmmac_dvr_probe()
         */
@@ -1272,12 +1261,15 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
                        goto dwmac_remove;
        }
 
+       pm_runtime_put(&pdev->dev);
+
        return 0;
 
 dwmac_mux:
        reset_control_put(gmac->rst_ephy);
        clk_put(gmac->ephy_clk);
 dwmac_remove:
+       pm_runtime_put_noidle(&pdev->dev);
        stmmac_dvr_remove(&pdev->dev);
 dwmac_exit:
        sun8i_dwmac_exit(pdev, gmac);