Commit 29555fa3 authored by Thierry Reding's avatar Thierry Reding Committed by David S. Miller

net: stmmac: Use mutex instead of spinlock

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: e6ea2d16 ("net: stmmac: dwc-qos: Add Tegra186 support")
Reported-by: default avatarJon Hunter <jonathanh@nvidia.com>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
Tested-by: default avatarBhadram Varka <vbhadram@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1b40428c
...@@ -122,7 +122,7 @@ struct stmmac_priv { ...@@ -122,7 +122,7 @@ struct stmmac_priv {
struct net_device *dev; struct net_device *dev;
struct device *device; struct device *device;
struct mac_device_info *hw; struct mac_device_info *hw;
spinlock_t lock; struct mutex lock;
/* RX Queue */ /* RX Queue */
struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES]; struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES];
......
...@@ -390,9 +390,9 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev, ...@@ -390,9 +390,9 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev,
ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Half |
ADVERTISED_10baseT_Full); ADVERTISED_10baseT_Full);
spin_lock(&priv->lock); mutex_lock(&priv->lock);
stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, priv->hw->ps, 0); stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, priv->hw->ps, 0);
spin_unlock(&priv->lock); mutex_unlock(&priv->lock);
return 0; return 0;
} }
...@@ -632,12 +632,12 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ...@@ -632,12 +632,12 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{ {
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
spin_lock_irq(&priv->lock); mutex_lock(&priv->lock);
if (device_can_wakeup(priv->device)) { if (device_can_wakeup(priv->device)) {
wol->supported = WAKE_MAGIC | WAKE_UCAST; wol->supported = WAKE_MAGIC | WAKE_UCAST;
wol->wolopts = priv->wolopts; 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) static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
...@@ -666,9 +666,9 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ...@@ -666,9 +666,9 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
disable_irq_wake(priv->wol_irq); disable_irq_wake(priv->wol_irq);
} }
spin_lock_irq(&priv->lock); mutex_lock(&priv->lock);
priv->wolopts = wol->wolopts; priv->wolopts = wol->wolopts;
spin_unlock_irq(&priv->lock); mutex_unlock(&priv->lock);
return 0; return 0;
} }
......
...@@ -381,7 +381,6 @@ bool stmmac_eee_init(struct stmmac_priv *priv) ...@@ -381,7 +381,6 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
{ {
struct net_device *ndev = priv->dev; struct net_device *ndev = priv->dev;
int interface = priv->plat->interface; int interface = priv->plat->interface;
unsigned long flags;
bool ret = false; bool ret = false;
if ((interface != PHY_INTERFACE_MODE_MII) && if ((interface != PHY_INTERFACE_MODE_MII) &&
...@@ -408,7 +407,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv) ...@@ -408,7 +407,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
* changed). * changed).
* In that case the driver disable own timers. * In that case the driver disable own timers.
*/ */
spin_lock_irqsave(&priv->lock, flags); mutex_lock(&priv->lock);
if (priv->eee_active) { if (priv->eee_active) {
netdev_dbg(priv->dev, "disable EEE\n"); netdev_dbg(priv->dev, "disable EEE\n");
del_timer_sync(&priv->eee_ctrl_timer); del_timer_sync(&priv->eee_ctrl_timer);
...@@ -416,11 +415,11 @@ bool stmmac_eee_init(struct stmmac_priv *priv) ...@@ -416,11 +415,11 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
tx_lpi_timer); tx_lpi_timer);
} }
priv->eee_active = 0; priv->eee_active = 0;
spin_unlock_irqrestore(&priv->lock, flags); mutex_unlock(&priv->lock);
goto out; goto out;
} }
/* Activate the EEE and start timers */ /* Activate the EEE and start timers */
spin_lock_irqsave(&priv->lock, flags); mutex_lock(&priv->lock);
if (!priv->eee_active) { if (!priv->eee_active) {
priv->eee_active = 1; priv->eee_active = 1;
timer_setup(&priv->eee_ctrl_timer, timer_setup(&priv->eee_ctrl_timer,
...@@ -435,7 +434,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv) ...@@ -435,7 +434,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
stmmac_set_eee_pls(priv, priv->hw, ndev->phydev->link); stmmac_set_eee_pls(priv, priv->hw, ndev->phydev->link);
ret = true; ret = true;
spin_unlock_irqrestore(&priv->lock, flags); mutex_unlock(&priv->lock);
netdev_dbg(priv->dev, "Energy-Efficient Ethernet initialized\n"); netdev_dbg(priv->dev, "Energy-Efficient Ethernet initialized\n");
} }
...@@ -811,13 +810,12 @@ static void stmmac_adjust_link(struct net_device *dev) ...@@ -811,13 +810,12 @@ static void stmmac_adjust_link(struct net_device *dev)
{ {
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phydev = dev->phydev; struct phy_device *phydev = dev->phydev;
unsigned long flags;
bool new_state = false; bool new_state = false;
if (!phydev) if (!phydev)
return; return;
spin_lock_irqsave(&priv->lock, flags); mutex_lock(&priv->lock);
if (phydev->link) { if (phydev->link) {
u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
...@@ -876,7 +874,7 @@ static void stmmac_adjust_link(struct net_device *dev) ...@@ -876,7 +874,7 @@ static void stmmac_adjust_link(struct net_device *dev)
if (new_state && netif_msg_link(priv)) if (new_state && netif_msg_link(priv))
phy_print_status(phydev); phy_print_status(phydev);
spin_unlock_irqrestore(&priv->lock, flags); mutex_unlock(&priv->lock);
if (phydev->is_pseudo_fixed_link) if (phydev->is_pseudo_fixed_link)
/* Stop PHY layer to call the hook to adjust the link in case /* Stop PHY layer to call the hook to adjust the link in case
...@@ -4275,7 +4273,7 @@ int stmmac_dvr_probe(struct device *device, ...@@ -4275,7 +4273,7 @@ int stmmac_dvr_probe(struct device *device,
(8 * priv->plat->rx_queues_to_use)); (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 /* If a specific clk_csr value is passed from the platform
* this means that the CSR Clock Range selection cannot be * this means that the CSR Clock Range selection cannot be
...@@ -4359,6 +4357,7 @@ int stmmac_dvr_remove(struct device *dev) ...@@ -4359,6 +4357,7 @@ int stmmac_dvr_remove(struct device *dev)
priv->hw->pcs != STMMAC_PCS_RTBI) priv->hw->pcs != STMMAC_PCS_RTBI)
stmmac_mdio_unregister(ndev); stmmac_mdio_unregister(ndev);
destroy_workqueue(priv->wq); destroy_workqueue(priv->wq);
mutex_destroy(&priv->lock);
free_netdev(ndev); free_netdev(ndev);
return 0; return 0;
...@@ -4376,7 +4375,6 @@ int stmmac_suspend(struct device *dev) ...@@ -4376,7 +4375,6 @@ int stmmac_suspend(struct device *dev)
{ {
struct net_device *ndev = dev_get_drvdata(dev); struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev); struct stmmac_priv *priv = netdev_priv(ndev);
unsigned long flags;
if (!ndev || !netif_running(ndev)) if (!ndev || !netif_running(ndev))
return 0; return 0;
...@@ -4384,7 +4382,7 @@ int stmmac_suspend(struct device *dev) ...@@ -4384,7 +4382,7 @@ int stmmac_suspend(struct device *dev)
if (ndev->phydev) if (ndev->phydev)
phy_stop(ndev->phydev); phy_stop(ndev->phydev);
spin_lock_irqsave(&priv->lock, flags); mutex_lock(&priv->lock);
netif_device_detach(ndev); netif_device_detach(ndev);
stmmac_stop_all_queues(priv); stmmac_stop_all_queues(priv);
...@@ -4405,7 +4403,7 @@ int stmmac_suspend(struct device *dev) ...@@ -4405,7 +4403,7 @@ int stmmac_suspend(struct device *dev)
clk_disable(priv->plat->pclk); clk_disable(priv->plat->pclk);
clk_disable(priv->plat->stmmac_clk); clk_disable(priv->plat->stmmac_clk);
} }
spin_unlock_irqrestore(&priv->lock, flags); mutex_unlock(&priv->lock);
priv->oldlink = false; priv->oldlink = false;
priv->speed = SPEED_UNKNOWN; priv->speed = SPEED_UNKNOWN;
...@@ -4450,7 +4448,6 @@ int stmmac_resume(struct device *dev) ...@@ -4450,7 +4448,6 @@ int stmmac_resume(struct device *dev)
{ {
struct net_device *ndev = dev_get_drvdata(dev); struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev); struct stmmac_priv *priv = netdev_priv(ndev);
unsigned long flags;
if (!netif_running(ndev)) if (!netif_running(ndev))
return 0; return 0;
...@@ -4462,9 +4459,9 @@ int stmmac_resume(struct device *dev) ...@@ -4462,9 +4459,9 @@ int stmmac_resume(struct device *dev)
* from another devices (e.g. serial console). * from another devices (e.g. serial console).
*/ */
if (device_may_wakeup(priv->device)) { if (device_may_wakeup(priv->device)) {
spin_lock_irqsave(&priv->lock, flags); mutex_lock(&priv->lock);
stmmac_pmt(priv, priv->hw, 0); stmmac_pmt(priv, priv->hw, 0);
spin_unlock_irqrestore(&priv->lock, flags); mutex_unlock(&priv->lock);
priv->irq_wake = 0; priv->irq_wake = 0;
} else { } else {
pinctrl_pm_select_default_state(priv->device); pinctrl_pm_select_default_state(priv->device);
...@@ -4478,7 +4475,7 @@ int stmmac_resume(struct device *dev) ...@@ -4478,7 +4475,7 @@ int stmmac_resume(struct device *dev)
netif_device_attach(ndev); netif_device_attach(ndev);
spin_lock_irqsave(&priv->lock, flags); mutex_lock(&priv->lock);
stmmac_reset_queues_param(priv); stmmac_reset_queues_param(priv);
...@@ -4492,7 +4489,7 @@ int stmmac_resume(struct device *dev) ...@@ -4492,7 +4489,7 @@ int stmmac_resume(struct device *dev)
stmmac_start_all_queues(priv); stmmac_start_all_queues(priv);
spin_unlock_irqrestore(&priv->lock, flags); mutex_unlock(&priv->lock);
if (ndev->phydev) if (ndev->phydev)
phy_start(ndev->phydev); phy_start(ndev->phydev);
......
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