diff options
-rw-r--r-- | drivers/net/ethernet/ti/davinci_cpdma.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/davinci_emac.c | 44 |
2 files changed, 31 insertions, 17 deletions
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c index 364d0c7952c0..88ef27067bf2 100644 --- a/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/drivers/net/ethernet/ti/davinci_cpdma.c | |||
@@ -355,7 +355,7 @@ int cpdma_ctlr_stop(struct cpdma_ctlr *ctlr) | |||
355 | int i; | 355 | int i; |
356 | 356 | ||
357 | spin_lock_irqsave(&ctlr->lock, flags); | 357 | spin_lock_irqsave(&ctlr->lock, flags); |
358 | if (ctlr->state != CPDMA_STATE_ACTIVE) { | 358 | if (ctlr->state == CPDMA_STATE_TEARDOWN) { |
359 | spin_unlock_irqrestore(&ctlr->lock, flags); | 359 | spin_unlock_irqrestore(&ctlr->lock, flags); |
360 | return -EINVAL; | 360 | return -EINVAL; |
361 | } | 361 | } |
@@ -891,7 +891,7 @@ int cpdma_chan_stop(struct cpdma_chan *chan) | |||
891 | unsigned timeout; | 891 | unsigned timeout; |
892 | 892 | ||
893 | spin_lock_irqsave(&chan->lock, flags); | 893 | spin_lock_irqsave(&chan->lock, flags); |
894 | if (chan->state != CPDMA_STATE_ACTIVE) { | 894 | if (chan->state == CPDMA_STATE_TEARDOWN) { |
895 | spin_unlock_irqrestore(&chan->lock, flags); | 895 | spin_unlock_irqrestore(&chan->lock, flags); |
896 | return -EINVAL; | 896 | return -EINVAL; |
897 | } | 897 | } |
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 251430450005..8f0e69ce07ca 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c | |||
@@ -1533,8 +1533,8 @@ static int emac_dev_open(struct net_device *ndev) | |||
1533 | u32 cnt; | 1533 | u32 cnt; |
1534 | struct resource *res; | 1534 | struct resource *res; |
1535 | int q, m, ret; | 1535 | int q, m, ret; |
1536 | int res_num = 0, irq_num = 0; | ||
1536 | int i = 0; | 1537 | int i = 0; |
1537 | int k = 0; | ||
1538 | struct emac_priv *priv = netdev_priv(ndev); | 1538 | struct emac_priv *priv = netdev_priv(ndev); |
1539 | 1539 | ||
1540 | pm_runtime_get(&priv->pdev->dev); | 1540 | pm_runtime_get(&priv->pdev->dev); |
@@ -1564,14 +1564,24 @@ static int emac_dev_open(struct net_device *ndev) | |||
1564 | } | 1564 | } |
1565 | 1565 | ||
1566 | /* Request IRQ */ | 1566 | /* Request IRQ */ |
1567 | while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, | ||
1568 | res_num))) { | ||
1569 | for (irq_num = res->start; irq_num <= res->end; irq_num++) { | ||
1570 | dev_err(emac_dev, "Request IRQ %d\n", irq_num); | ||
1571 | if (request_irq(irq_num, emac_irq, 0, ndev->name, | ||
1572 | ndev)) { | ||
1573 | dev_err(emac_dev, | ||
1574 | "DaVinci EMAC: request_irq() failed\n"); | ||
1575 | ret = -EBUSY; | ||
1567 | 1576 | ||
1568 | while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) { | ||
1569 | for (i = res->start; i <= res->end; i++) { | ||
1570 | if (request_irq(i, emac_irq, 0, ndev->name, ndev)) | ||
1571 | goto rollback; | 1577 | goto rollback; |
1578 | } | ||
1572 | } | 1579 | } |
1573 | k++; | 1580 | res_num++; |
1574 | } | 1581 | } |
1582 | /* prepare counters for rollback in case of an error */ | ||
1583 | res_num--; | ||
1584 | irq_num--; | ||
1575 | 1585 | ||
1576 | /* Start/Enable EMAC hardware */ | 1586 | /* Start/Enable EMAC hardware */ |
1577 | emac_hw_enable(priv); | 1587 | emac_hw_enable(priv); |
@@ -1638,19 +1648,23 @@ static int emac_dev_open(struct net_device *ndev) | |||
1638 | 1648 | ||
1639 | return 0; | 1649 | return 0; |
1640 | 1650 | ||
1641 | rollback: | 1651 | err: |
1642 | 1652 | emac_int_disable(priv); | |
1643 | dev_err(emac_dev, "DaVinci EMAC: request_irq() failed"); | 1653 | napi_disable(&priv->napi); |
1644 | 1654 | ||
1645 | for (q = k; k >= 0; k--) { | 1655 | rollback: |
1646 | for (m = i; m >= res->start; m--) | 1656 | for (q = res_num; q >= 0; q--) { |
1657 | res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, q); | ||
1658 | /* at the first iteration, irq_num is already set to the | ||
1659 | * right value | ||
1660 | */ | ||
1661 | if (q != res_num) | ||
1662 | irq_num = res->end; | ||
1663 | |||
1664 | for (m = irq_num; m >= res->start; m--) | ||
1647 | free_irq(m, ndev); | 1665 | free_irq(m, ndev); |
1648 | res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k-1); | ||
1649 | m = res->end; | ||
1650 | } | 1666 | } |
1651 | 1667 | cpdma_ctlr_stop(priv->dma); | |
1652 | ret = -EBUSY; | ||
1653 | err: | ||
1654 | pm_runtime_put(&priv->pdev->dev); | 1668 | pm_runtime_put(&priv->pdev->dev); |
1655 | return ret; | 1669 | return ret; |
1656 | } | 1670 | } |