Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: e6ea2d16fc61 ("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>

authored by

Thierry Reding and committed by
David S. Miller
29555fa3 1b40428c

+21 -24
+1 -1
drivers/net/ethernet/stmicro/stmmac/stmmac.h
··· 122 122 struct net_device *dev; 123 123 struct device *device; 124 124 struct mac_device_info *hw; 125 - spinlock_t lock; 125 + struct mutex lock; 126 126 127 127 /* RX Queue */ 128 128 struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES];
+6 -6
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
··· 390 390 ADVERTISED_10baseT_Half | 391 391 ADVERTISED_10baseT_Full); 392 392 393 - spin_lock(&priv->lock); 393 + mutex_lock(&priv->lock); 394 394 stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, priv->hw->ps, 0); 395 - spin_unlock(&priv->lock); 395 + mutex_unlock(&priv->lock); 396 396 397 397 return 0; 398 398 } ··· 632 632 { 633 633 struct stmmac_priv *priv = netdev_priv(dev); 634 634 635 - spin_lock_irq(&priv->lock); 635 + mutex_lock(&priv->lock); 636 636 if (device_can_wakeup(priv->device)) { 637 637 wol->supported = WAKE_MAGIC | WAKE_UCAST; 638 638 wol->wolopts = priv->wolopts; 639 639 } 640 - spin_unlock_irq(&priv->lock); 640 + mutex_unlock(&priv->lock); 641 641 } 642 642 643 643 static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ··· 666 666 disable_irq_wake(priv->wol_irq); 667 667 } 668 668 669 - spin_lock_irq(&priv->lock); 669 + mutex_lock(&priv->lock); 670 670 priv->wolopts = wol->wolopts; 671 - spin_unlock_irq(&priv->lock); 671 + mutex_unlock(&priv->lock); 672 672 673 673 return 0; 674 674 }
+14 -17
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 381 381 { 382 382 struct net_device *ndev = priv->dev; 383 383 int interface = priv->plat->interface; 384 - unsigned long flags; 385 384 bool ret = false; 386 385 387 386 if ((interface != PHY_INTERFACE_MODE_MII) && ··· 407 408 * changed). 408 409 * In that case the driver disable own timers. 409 410 */ 410 - spin_lock_irqsave(&priv->lock, flags); 411 + mutex_lock(&priv->lock); 411 412 if (priv->eee_active) { 412 413 netdev_dbg(priv->dev, "disable EEE\n"); 413 414 del_timer_sync(&priv->eee_ctrl_timer); ··· 415 416 tx_lpi_timer); 416 417 } 417 418 priv->eee_active = 0; 418 - spin_unlock_irqrestore(&priv->lock, flags); 419 + mutex_unlock(&priv->lock); 419 420 goto out; 420 421 } 421 422 /* Activate the EEE and start timers */ 422 - spin_lock_irqsave(&priv->lock, flags); 423 + mutex_lock(&priv->lock); 423 424 if (!priv->eee_active) { 424 425 priv->eee_active = 1; 425 426 timer_setup(&priv->eee_ctrl_timer, ··· 434 435 stmmac_set_eee_pls(priv, priv->hw, ndev->phydev->link); 435 436 436 437 ret = true; 437 - spin_unlock_irqrestore(&priv->lock, flags); 438 + mutex_unlock(&priv->lock); 438 439 439 440 netdev_dbg(priv->dev, "Energy-Efficient Ethernet initialized\n"); 440 441 } ··· 810 811 { 811 812 struct stmmac_priv *priv = netdev_priv(dev); 812 813 struct phy_device *phydev = dev->phydev; 813 - unsigned long flags; 814 814 bool new_state = false; 815 815 816 816 if (!phydev) 817 817 return; 818 818 819 - spin_lock_irqsave(&priv->lock, flags); 819 + mutex_lock(&priv->lock); 820 820 821 821 if (phydev->link) { 822 822 u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); ··· 874 876 if (new_state && netif_msg_link(priv)) 875 877 phy_print_status(phydev); 876 878 877 - spin_unlock_irqrestore(&priv->lock, flags); 879 + mutex_unlock(&priv->lock); 878 880 879 881 if (phydev->is_pseudo_fixed_link) 880 882 /* Stop PHY layer to call the hook to adjust the link in case ··· 4273 4275 (8 * priv->plat->rx_queues_to_use)); 4274 4276 } 4275 4277 4276 - spin_lock_init(&priv->lock); 4278 + mutex_init(&priv->lock); 4277 4279 4278 4280 /* If a specific clk_csr value is passed from the platform 4279 4281 * this means that the CSR Clock Range selection cannot be ··· 4357 4359 priv->hw->pcs != STMMAC_PCS_RTBI) 4358 4360 stmmac_mdio_unregister(ndev); 4359 4361 destroy_workqueue(priv->wq); 4362 + mutex_destroy(&priv->lock); 4360 4363 free_netdev(ndev); 4361 4364 4362 4365 return 0; ··· 4375 4376 { 4376 4377 struct net_device *ndev = dev_get_drvdata(dev); 4377 4378 struct stmmac_priv *priv = netdev_priv(ndev); 4378 - unsigned long flags; 4379 4379 4380 4380 if (!ndev || !netif_running(ndev)) 4381 4381 return 0; ··· 4382 4384 if (ndev->phydev) 4383 4385 phy_stop(ndev->phydev); 4384 4386 4385 - spin_lock_irqsave(&priv->lock, flags); 4387 + mutex_lock(&priv->lock); 4386 4388 4387 4389 netif_device_detach(ndev); 4388 4390 stmmac_stop_all_queues(priv); ··· 4403 4405 clk_disable(priv->plat->pclk); 4404 4406 clk_disable(priv->plat->stmmac_clk); 4405 4407 } 4406 - spin_unlock_irqrestore(&priv->lock, flags); 4408 + mutex_unlock(&priv->lock); 4407 4409 4408 4410 priv->oldlink = false; 4409 4411 priv->speed = SPEED_UNKNOWN; ··· 4448 4450 { 4449 4451 struct net_device *ndev = dev_get_drvdata(dev); 4450 4452 struct stmmac_priv *priv = netdev_priv(ndev); 4451 - unsigned long flags; 4452 4453 4453 4454 if (!netif_running(ndev)) 4454 4455 return 0; ··· 4459 4462 * from another devices (e.g. serial console). 4460 4463 */ 4461 4464 if (device_may_wakeup(priv->device)) { 4462 - spin_lock_irqsave(&priv->lock, flags); 4465 + mutex_lock(&priv->lock); 4463 4466 stmmac_pmt(priv, priv->hw, 0); 4464 - spin_unlock_irqrestore(&priv->lock, flags); 4467 + mutex_unlock(&priv->lock); 4465 4468 priv->irq_wake = 0; 4466 4469 } else { 4467 4470 pinctrl_pm_select_default_state(priv->device); ··· 4475 4478 4476 4479 netif_device_attach(ndev); 4477 4480 4478 - spin_lock_irqsave(&priv->lock, flags); 4481 + mutex_lock(&priv->lock); 4479 4482 4480 4483 stmmac_reset_queues_param(priv); 4481 4484 ··· 4489 4492 4490 4493 stmmac_start_all_queues(priv); 4491 4494 4492 - spin_unlock_irqrestore(&priv->lock, flags); 4495 + mutex_unlock(&priv->lock); 4493 4496 4494 4497 if (ndev->phydev) 4495 4498 phy_start(ndev->phydev);