mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 22:14:04 +02:00
UPSTREAM: 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:e6ea2d16fc("net: stmmac: dwc-qos: Add Tegra186 support") Reported-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Tested-by: Bhadram Varka <vbhadram@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net> (cherry picked from commit29555fa3de) Change-Id: I84200908368916c588f9154278486fcb1d22f8a0 Signed-off-by: David Wu <david.wu@rock-chips.com>
This commit is contained in:
parent
0495591680
commit
43bf8703a7
|
|
@ -84,7 +84,7 @@ struct stmmac_priv {
|
|||
struct net_device *dev;
|
||||
struct device *device;
|
||||
struct mac_device_info *hw;
|
||||
spinlock_t lock;
|
||||
struct mutex lock;
|
||||
|
||||
struct phy_device *phydev ____cacheline_aligned_in_smp;
|
||||
int oldlink;
|
||||
|
|
|
|||
|
|
@ -347,17 +347,17 @@ static int stmmac_ethtool_setsettings(struct net_device *dev,
|
|||
ADVERTISED_10baseT_Half |
|
||||
ADVERTISED_10baseT_Full);
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
mutex_lock(&priv->lock);
|
||||
if (priv->hw->mac->ctrl_ane)
|
||||
priv->hw->mac->ctrl_ane(priv->hw, 1);
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
mutex_lock(&priv->lock);
|
||||
rc = phy_ethtool_sset(phy, cmd);
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -554,12 +554,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)
|
||||
|
|
@ -588,9 +588,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,7 +271,6 @@ static void stmmac_eee_ctrl_timer(unsigned long arg)
|
|||
bool stmmac_eee_init(struct stmmac_priv *priv)
|
||||
{
|
||||
char *phy_bus_name = priv->plat->phy_bus_name;
|
||||
unsigned long flags;
|
||||
int interface = priv->plat->interface;
|
||||
bool ret = false;
|
||||
|
||||
|
|
@ -302,7 +301,7 @@ 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) {
|
||||
pr_debug("stmmac: disable EEE\n");
|
||||
del_timer_sync(&priv->eee_ctrl_timer);
|
||||
|
|
@ -310,11 +309,11 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
|
|||
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;
|
||||
setup_timer(&priv->eee_ctrl_timer,
|
||||
|
|
@ -331,7 +330,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
|
|||
priv->hw->mac->set_eee_pls(priv->hw, priv->phydev->link);
|
||||
|
||||
ret = true;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
pr_debug("stmmac: Energy-Efficient Ethernet initialized\n");
|
||||
}
|
||||
|
|
@ -697,14 +696,13 @@ static void stmmac_adjust_link(struct net_device *dev)
|
|||
{
|
||||
struct stmmac_priv *priv = netdev_priv(dev);
|
||||
struct phy_device *phydev = priv->phydev;
|
||||
unsigned long flags;
|
||||
int new_state = 0;
|
||||
unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
|
||||
|
||||
if (phydev == NULL)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
if (phydev->link) {
|
||||
u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
|
||||
|
|
@ -772,7 +770,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);
|
||||
|
||||
/* At this stage, it could be needed to setup the EEE or adjust some
|
||||
* MAC related HW registers.
|
||||
|
|
@ -2947,7 +2945,7 @@ int stmmac_dvr_probe(struct device *device,
|
|||
|
||||
netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
mutex_init(&priv->lock);
|
||||
spin_lock_init(&priv->tx_lock);
|
||||
|
||||
/* If a specific clk_csr value is passed from the platform
|
||||
|
|
@ -3027,6 +3025,7 @@ int stmmac_dvr_remove(struct device *dev)
|
|||
if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
|
||||
priv->pcs != STMMAC_PCS_RTBI)
|
||||
stmmac_mdio_unregister(ndev);
|
||||
mutex_destroy(&priv->lock);
|
||||
free_netdev(ndev);
|
||||
|
||||
return 0;
|
||||
|
|
@ -3044,7 +3043,6 @@ 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;
|
||||
|
|
@ -3052,13 +3050,12 @@ int stmmac_suspend(struct device *dev)
|
|||
if (priv->phydev)
|
||||
phy_stop(priv->phydev);
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
netif_device_detach(ndev);
|
||||
netif_stop_queue(ndev);
|
||||
|
||||
napi_disable(&priv->napi);
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
/* Stop TX/RX DMA */
|
||||
priv->hw->dma->stop_tx(priv->ioaddr);
|
||||
priv->hw->dma->stop_rx(priv->ioaddr);
|
||||
|
|
@ -3074,7 +3071,7 @@ int stmmac_suspend(struct device *dev)
|
|||
clk_disable(priv->pclk);
|
||||
clk_disable(priv->stmmac_clk);
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
priv->oldlink = 0;
|
||||
priv->speed = 0;
|
||||
|
|
@ -3093,7 +3090,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;
|
||||
|
|
@ -3105,9 +3101,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);
|
||||
priv->hw->mac->pmt(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);
|
||||
|
|
@ -3119,7 +3115,7 @@ int stmmac_resume(struct device *dev)
|
|||
stmmac_mdio_reset(priv->mii);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
priv->cur_rx = 0;
|
||||
priv->dirty_rx = 0;
|
||||
|
|
@ -3137,7 +3133,7 @@ int stmmac_resume(struct device *dev)
|
|||
|
||||
netif_device_attach(ndev);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
if (priv->phydev)
|
||||
phy_start(priv->phydev);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user