mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-18 19:01:44 +00:00
Merge branch 'cpsw-fixes'
Grygorii Strashko says: ==================== drivers: net: cpsw: fix driver loading/unloading This series fixes set of isssues observed when CPSW driver module is unloaded/loaded: 1) rmmod: deadlock in cpdma_ctlr_destroy 2) rmmod: L3 back-trace and crash if all net interfaces are down, because CPSW can be powerred down by PM runtime in this case. 3) insmod: mdio device is not recreated on next insmod - need to use of_platform_depopulate() in cpsw_remove(). 4) rmmod: system crash on omap_device removal Tested on: am437x-idk, am57xx-beagle-x15 Changes in v2: - build warning fixed - added fix for correct omap_device removal Link on v1: https://lkml.org/lkml/2016/7/22/240 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
122e9b7127
@ -194,7 +194,7 @@ static int _omap_device_notifier_call(struct notifier_block *nb,
|
||||
int err;
|
||||
|
||||
switch (event) {
|
||||
case BUS_NOTIFY_DEL_DEVICE:
|
||||
case BUS_NOTIFY_REMOVED_DEVICE:
|
||||
if (pdev->archdata.od)
|
||||
omap_device_delete(pdev->archdata.od);
|
||||
break;
|
||||
|
@ -2564,19 +2564,17 @@ clean_ndev_ret:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cpsw_remove_child_device(struct device *dev, void *c)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
of_device_unregister(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpsw_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct cpsw_priv *priv = netdev_priv(ndev);
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(&pdev->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (priv->data.dual_emac)
|
||||
unregister_netdev(cpsw_get_slave_ndev(priv, 1));
|
||||
@ -2584,8 +2582,9 @@ static int cpsw_remove(struct platform_device *pdev)
|
||||
|
||||
cpsw_ale_destroy(priv->ale);
|
||||
cpdma_ctlr_destroy(priv->dma);
|
||||
of_platform_depopulate(&pdev->dev);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
device_for_each_child(&pdev->dev, NULL, cpsw_remove_child_device);
|
||||
if (priv->data.dual_emac)
|
||||
free_netdev(cpsw_get_slave_ndev(priv, 1));
|
||||
free_netdev(ndev);
|
||||
|
@ -357,13 +357,11 @@ EXPORT_SYMBOL_GPL(cpdma_ctlr_stop);
|
||||
|
||||
int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret = 0, i;
|
||||
|
||||
if (!ctlr)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&ctlr->lock, flags);
|
||||
if (ctlr->state != CPDMA_STATE_IDLE)
|
||||
cpdma_ctlr_stop(ctlr);
|
||||
|
||||
@ -371,7 +369,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
|
||||
cpdma_chan_destroy(ctlr->channels[i]);
|
||||
|
||||
cpdma_desc_pool_destroy(ctlr->pool);
|
||||
spin_unlock_irqrestore(&ctlr->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpdma_ctlr_destroy);
|
||||
|
Loading…
x
Reference in New Issue
Block a user