[PATCH net-next 2/3] net: systemport: fetch and use clock resources
From: Florian Fainelli <f.fainelli@gmail.com>
Date: 2020-09-01 21:44:22
Also in:
lkml, netdev
Subsystem:
broadcom systemport ethernet driver, networking drivers, the rest · Maintainers:
Florian Fainelli, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
We disable clocks shortly after probing the device to save as much power as possible in case the interface is never used. When bcm_sysport_open() is invoked, clocks are enabled, and disabled in bcm_sysport_stop(). A similar scheme is applied to the suspend/resume functions. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> --- drivers/net/ethernet/broadcom/bcmsysport.c | 30 +++++++++++++++++++++- drivers/net/ethernet/broadcom/bcmsysport.h | 1 + 2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index dfed9ade6950..91eadba5540c 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c@@ -20,6 +20,7 @@ #include <linux/phy.h> #include <linux/phy_fixed.h> #include <net/dsa.h> +#include <linux/clk.h> #include <net/ip.h> #include <net/ipv6.h>
@@ -186,6 +187,11 @@ static int bcm_sysport_set_features(struct net_device *dev, netdev_features_t features) { struct bcm_sysport_priv *priv = netdev_priv(dev); + int ret; + + ret = clk_prepare_enable(priv->clk); + if (ret) + return ret; /* Read CRC forward */ if (!priv->is_lite)
@@ -197,6 +203,8 @@ static int bcm_sysport_set_features(struct net_device *dev, bcm_sysport_set_rx_csum(dev, features); bcm_sysport_set_tx_csum(dev, features); + clk_disable_unprepare(priv->clk); + return 0; }
@@ -1940,6 +1948,8 @@ static int bcm_sysport_open(struct net_device *dev) unsigned int i; int ret; + clk_prepare_enable(priv->clk); + /* Reset UniMAC */ umac_reset(priv);
@@ -1970,7 +1980,8 @@ static int bcm_sysport_open(struct net_device *dev) 0, priv->phy_interface); if (!phydev) { netdev_err(dev, "could not attach to PHY\n"); - return -ENODEV; + ret = -ENODEV; + goto out_clk_disable; } /* Reset house keeping link status */
@@ -2048,6 +2059,8 @@ static int bcm_sysport_open(struct net_device *dev) free_irq(priv->irq0, dev); out_phy_disconnect: phy_disconnect(phydev); +out_clk_disable: + clk_disable_unprepare(priv->clk); return ret; }
@@ -2106,6 +2119,8 @@ static int bcm_sysport_stop(struct net_device *dev) /* Disconnect from PHY */ phy_disconnect(dev->phydev); + clk_disable_unprepare(priv->clk); + return 0; }
@@ -2487,6 +2502,10 @@ static int bcm_sysport_probe(struct platform_device *pdev) /* Initialize private members */ priv = netdev_priv(dev); + priv->clk = devm_clk_get_optional(&pdev->dev, "sw_sysport"); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); + /* Allocate number of TX rings */ priv->tx_rings = devm_kcalloc(&pdev->dev, txq, sizeof(struct bcm_sysport_tx_ring),
@@ -2588,6 +2607,8 @@ static int bcm_sysport_probe(struct platform_device *pdev) goto err_deregister_notifier; } + clk_prepare_enable(priv->clk); + priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK; dev_info(&pdev->dev, "Broadcom SYSTEMPORT%s " REV_FMT
@@ -2596,6 +2617,8 @@ static int bcm_sysport_probe(struct platform_device *pdev) (priv->rev >> 8) & 0xff, priv->rev & 0xff, priv->irq0, priv->irq1, txq, rxq); + clk_disable_unprepare(priv->clk); + return 0; err_deregister_notifier:
@@ -2752,6 +2775,8 @@ static int __maybe_unused bcm_sysport_suspend(struct device *d) if (device_may_wakeup(d) && priv->wolopts) ret = bcm_sysport_suspend_to_wol(priv); + clk_disable_unprepare(priv->clk); + return ret; }
@@ -2765,6 +2790,8 @@ static int __maybe_unused bcm_sysport_resume(struct device *d) if (!netif_running(dev)) return 0; + clk_prepare_enable(priv->clk); + umac_reset(priv); /* Disable the UniMAC RX/TX */
@@ -2844,6 +2871,7 @@ static int __maybe_unused bcm_sysport_resume(struct device *d) out_free_tx_rings: for (i = 0; i < dev->num_tx_queues; i++) bcm_sysport_fini_tx_ring(priv, i); + clk_disable_unprepare(priv->clk); return ret; }
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h
index 6d80735fbc7f..51800053e88c 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.h
+++ b/drivers/net/ethernet/broadcom/bcmsysport.h@@ -770,6 +770,7 @@ struct bcm_sysport_priv { u32 wolopts; u8 sopass[SOPASS_MAX]; unsigned int wol_irq_disabled:1; + struct clk *clk; /* MIB related fields */ struct bcm_sysport_mib mib;
--
2.25.1