Skip to content

Commit 122e9b7

Browse files
committed
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 <[email protected]>
2 parents c882219 + 213fa10 commit 122e9b7

File tree

3 files changed

+10
-14
lines changed

3 files changed

+10
-14
lines changed

arch/arm/mach-omap2/omap_device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ static int _omap_device_notifier_call(struct notifier_block *nb,
194194
int err;
195195

196196
switch (event) {
197-
case BUS_NOTIFY_DEL_DEVICE:
197+
case BUS_NOTIFY_REMOVED_DEVICE:
198198
if (pdev->archdata.od)
199199
omap_device_delete(pdev->archdata.od);
200200
break;

drivers/net/ethernet/ti/cpsw.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2564,28 +2564,27 @@ static int cpsw_probe(struct platform_device *pdev)
25642564
return ret;
25652565
}
25662566

2567-
static int cpsw_remove_child_device(struct device *dev, void *c)
2568-
{
2569-
struct platform_device *pdev = to_platform_device(dev);
2570-
2571-
of_device_unregister(pdev);
2572-
2573-
return 0;
2574-
}
2575-
25762567
static int cpsw_remove(struct platform_device *pdev)
25772568
{
25782569
struct net_device *ndev = platform_get_drvdata(pdev);
25792570
struct cpsw_priv *priv = netdev_priv(ndev);
2571+
int ret;
2572+
2573+
ret = pm_runtime_get_sync(&pdev->dev);
2574+
if (ret < 0) {
2575+
pm_runtime_put_noidle(&pdev->dev);
2576+
return ret;
2577+
}
25802578

25812579
if (priv->data.dual_emac)
25822580
unregister_netdev(cpsw_get_slave_ndev(priv, 1));
25832581
unregister_netdev(ndev);
25842582

25852583
cpsw_ale_destroy(priv->ale);
25862584
cpdma_ctlr_destroy(priv->dma);
2585+
of_platform_depopulate(&pdev->dev);
2586+
pm_runtime_put_sync(&pdev->dev);
25872587
pm_runtime_disable(&pdev->dev);
2588-
device_for_each_child(&pdev->dev, NULL, cpsw_remove_child_device);
25892588
if (priv->data.dual_emac)
25902589
free_netdev(cpsw_get_slave_ndev(priv, 1));
25912590
free_netdev(ndev);

drivers/net/ethernet/ti/davinci_cpdma.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,21 +357,18 @@ EXPORT_SYMBOL_GPL(cpdma_ctlr_stop);
357357

358358
int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
359359
{
360-
unsigned long flags;
361360
int ret = 0, i;
362361

363362
if (!ctlr)
364363
return -EINVAL;
365364

366-
spin_lock_irqsave(&ctlr->lock, flags);
367365
if (ctlr->state != CPDMA_STATE_IDLE)
368366
cpdma_ctlr_stop(ctlr);
369367

370368
for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++)
371369
cpdma_chan_destroy(ctlr->channels[i]);
372370

373371
cpdma_desc_pool_destroy(ctlr->pool);
374-
spin_unlock_irqrestore(&ctlr->lock, flags);
375372
return ret;
376373
}
377374
EXPORT_SYMBOL_GPL(cpdma_ctlr_destroy);

0 commit comments

Comments
 (0)