Skip to content

Commit

Permalink
net: stmmac: Use mutex instead of spinlock
Browse files Browse the repository at this point in the history
Some drivers, such as DWC EQOS on Tegra, need to perform operations that
can sleep under this lock (clk_set_rate() in tegra_eqos_fix_speed()) for
proper operation. Since there is no need for this lock to be a spinlock,
convert it to a mutex instead.

Fixes: e6ea2d1 ("net: stmmac: dwc-qos: Add Tegra186 support")
Reported-by: Jon Hunter <[email protected]>
Signed-off-by: Thierry Reding <[email protected]>
Tested-by: Bhadram Varka <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
thierryreding authored and davem330 committed May 29, 2018
1 parent 1b40428 commit 29555fa
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 24 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/stmicro/stmmac/stmmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ struct stmmac_priv {
struct net_device *dev;
struct device *device;
struct mac_device_info *hw;
spinlock_t lock;
struct mutex lock;

/* RX Queue */
struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES];
Expand Down
12 changes: 6 additions & 6 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,9 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev,
ADVERTISED_10baseT_Half |
ADVERTISED_10baseT_Full);

spin_lock(&priv->lock);
mutex_lock(&priv->lock);
stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, priv->hw->ps, 0);
spin_unlock(&priv->lock);
mutex_unlock(&priv->lock);

return 0;
}
Expand Down Expand Up @@ -632,12 +632,12 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct stmmac_priv *priv = netdev_priv(dev);

spin_lock_irq(&priv->lock);
mutex_lock(&priv->lock);
if (device_can_wakeup(priv->device)) {
wol->supported = WAKE_MAGIC | WAKE_UCAST;
wol->wolopts = priv->wolopts;
}
spin_unlock_irq(&priv->lock);
mutex_unlock(&priv->lock);
}

static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
Expand Down Expand Up @@ -666,9 +666,9 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
disable_irq_wake(priv->wol_irq);
}

spin_lock_irq(&priv->lock);
mutex_lock(&priv->lock);
priv->wolopts = wol->wolopts;
spin_unlock_irq(&priv->lock);
mutex_unlock(&priv->lock);

return 0;
}
Expand Down
31 changes: 14 additions & 17 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,6 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
{
struct net_device *ndev = priv->dev;
int interface = priv->plat->interface;
unsigned long flags;
bool ret = false;

if ((interface != PHY_INTERFACE_MODE_MII) &&
Expand All @@ -408,19 +407,19 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
* changed).
* In that case the driver disable own timers.
*/
spin_lock_irqsave(&priv->lock, flags);
mutex_lock(&priv->lock);
if (priv->eee_active) {
netdev_dbg(priv->dev, "disable EEE\n");
del_timer_sync(&priv->eee_ctrl_timer);
stmmac_set_eee_timer(priv, priv->hw, 0,
tx_lpi_timer);
}
priv->eee_active = 0;
spin_unlock_irqrestore(&priv->lock, flags);
mutex_unlock(&priv->lock);
goto out;
}
/* Activate the EEE and start timers */
spin_lock_irqsave(&priv->lock, flags);
mutex_lock(&priv->lock);
if (!priv->eee_active) {
priv->eee_active = 1;
timer_setup(&priv->eee_ctrl_timer,
Expand All @@ -435,7 +434,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
stmmac_set_eee_pls(priv, priv->hw, ndev->phydev->link);

ret = true;
spin_unlock_irqrestore(&priv->lock, flags);
mutex_unlock(&priv->lock);

netdev_dbg(priv->dev, "Energy-Efficient Ethernet initialized\n");
}
Expand Down Expand Up @@ -811,13 +810,12 @@ static void stmmac_adjust_link(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phydev = dev->phydev;
unsigned long flags;
bool new_state = false;

if (!phydev)
return;

spin_lock_irqsave(&priv->lock, flags);
mutex_lock(&priv->lock);

if (phydev->link) {
u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
Expand Down Expand Up @@ -876,7 +874,7 @@ static void stmmac_adjust_link(struct net_device *dev)
if (new_state && netif_msg_link(priv))
phy_print_status(phydev);

spin_unlock_irqrestore(&priv->lock, flags);
mutex_unlock(&priv->lock);

if (phydev->is_pseudo_fixed_link)
/* Stop PHY layer to call the hook to adjust the link in case
Expand Down Expand Up @@ -4275,7 +4273,7 @@ int stmmac_dvr_probe(struct device *device,
(8 * priv->plat->rx_queues_to_use));
}

spin_lock_init(&priv->lock);
mutex_init(&priv->lock);

/* If a specific clk_csr value is passed from the platform
* this means that the CSR Clock Range selection cannot be
Expand Down Expand Up @@ -4359,6 +4357,7 @@ int stmmac_dvr_remove(struct device *dev)
priv->hw->pcs != STMMAC_PCS_RTBI)
stmmac_mdio_unregister(ndev);
destroy_workqueue(priv->wq);
mutex_destroy(&priv->lock);
free_netdev(ndev);

return 0;
Expand All @@ -4376,15 +4375,14 @@ int stmmac_suspend(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);
unsigned long flags;

if (!ndev || !netif_running(ndev))
return 0;

if (ndev->phydev)
phy_stop(ndev->phydev);

spin_lock_irqsave(&priv->lock, flags);
mutex_lock(&priv->lock);

netif_device_detach(ndev);
stmmac_stop_all_queues(priv);
Expand All @@ -4405,7 +4403,7 @@ int stmmac_suspend(struct device *dev)
clk_disable(priv->plat->pclk);
clk_disable(priv->plat->stmmac_clk);
}
spin_unlock_irqrestore(&priv->lock, flags);
mutex_unlock(&priv->lock);

priv->oldlink = false;
priv->speed = SPEED_UNKNOWN;
Expand Down Expand Up @@ -4450,7 +4448,6 @@ int stmmac_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);
unsigned long flags;

if (!netif_running(ndev))
return 0;
Expand All @@ -4462,9 +4459,9 @@ int stmmac_resume(struct device *dev)
* from another devices (e.g. serial console).
*/
if (device_may_wakeup(priv->device)) {
spin_lock_irqsave(&priv->lock, flags);
mutex_lock(&priv->lock);
stmmac_pmt(priv, priv->hw, 0);
spin_unlock_irqrestore(&priv->lock, flags);
mutex_unlock(&priv->lock);
priv->irq_wake = 0;
} else {
pinctrl_pm_select_default_state(priv->device);
Expand All @@ -4478,7 +4475,7 @@ int stmmac_resume(struct device *dev)

netif_device_attach(ndev);

spin_lock_irqsave(&priv->lock, flags);
mutex_lock(&priv->lock);

stmmac_reset_queues_param(priv);

Expand All @@ -4492,7 +4489,7 @@ int stmmac_resume(struct device *dev)

stmmac_start_all_queues(priv);

spin_unlock_irqrestore(&priv->lock, flags);
mutex_unlock(&priv->lock);

if (ndev->phydev)
phy_start(ndev->phydev);
Expand Down

0 comments on commit 29555fa

Please sign in to comment.