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 | } |
