Commit e8f25965 authored by David S. Miller's avatar David S. Miller

Merge branch 'net-systemport-Clock-support'

Florian Fainelli says:

====================
net: systemport: Clock support

This patch series makes the SYSTEMPORT driver request and manage its
main and Wake-on-LAN clocks appropriately.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2adc6edc 6328a126
......@@ -20,6 +20,11 @@ Optional properties:
- systemport,num-tier1-arb: number of tier 1 arbiters, an integer
- systemport,num-txq: number of HW transmit queues, an integer
- systemport,num-rxq: number of HW receive queues, an integer
- clocks: When provided, must be two phandles to the functional clocks nodes of
the SYSTEMPORT block. The first phandle is the main SYSTEMPORT clock used
during normal operation, while the second phandle is the Wake-on-LAN clock.
- clock-names: When provided, names of the functional clock phandles, first
name should be "sw_sysport" and second should be "sw_sysportwol".
Example:
ethernet@f04a0000 {
......
......@@ -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),
......@@ -2564,6 +2583,10 @@ static int bcm_sysport_probe(struct platform_device *pdev)
if (!ret)
device_set_wakeup_capable(&pdev->dev, 1);
priv->wol_clk = devm_clk_get_optional(&pdev->dev, "sw_sysportwol");
if (IS_ERR(priv->wol_clk))
return PTR_ERR(priv->wol_clk);
/* Set the needed headroom once and for all */
BUILD_BUG_ON(sizeof(struct bcm_tsb) != 8);
dev->needed_headroom += sizeof(struct bcm_tsb);
......@@ -2588,6 +2611,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 +2621,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:
......@@ -2749,8 +2776,12 @@ static int __maybe_unused bcm_sysport_suspend(struct device *d)
bcm_sysport_fini_rx_ring(priv);
/* Get prepared for Wake-on-LAN */
if (device_may_wakeup(d) && priv->wolopts)
if (device_may_wakeup(d) && priv->wolopts) {
clk_prepare_enable(priv->wol_clk);
ret = bcm_sysport_suspend_to_wol(priv);
}
clk_disable_unprepare(priv->clk);
return ret;
}
......@@ -2765,6 +2796,10 @@ static int __maybe_unused bcm_sysport_resume(struct device *d)
if (!netif_running(dev))
return 0;
clk_prepare_enable(priv->clk);
if (priv->wolopts)
clk_disable_unprepare(priv->wol_clk);
umac_reset(priv);
/* Disable the UniMAC RX/TX */
......@@ -2844,6 +2879,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;
}
......
......@@ -770,6 +770,8 @@ struct bcm_sysport_priv {
u32 wolopts;
u8 sopass[SOPASS_MAX];
unsigned int wol_irq_disabled:1;
struct clk *clk;
struct clk *wol_clk;
/* MIB related fields */
struct bcm_sysport_mib mib;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment