aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Riesch <christian.riesch@omicron.at>2014-03-24 08:46:26 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-24 15:32:03 -0400
commit33b7107f59a61236d94ecd6b45e20283cd5abcc8 (patch)
tree26aec0e59cfad25d27c772f8191bf75c039c67c0
parentc27f0872a3448c46e561e226b5b97f77187b06d2 (diff)
net: davinci_emac: Replace devm_request_irq with request_irq
In commit 6892b41d9701283085b655c6086fb57a5d63fa47 Author: Lad, Prabhakar <prabhakar.csengg@gmail.com> Date: Tue Jun 25 21:24:51 2013 +0530 net: davinci: emac: Convert to devm_* api the call of request_irq is replaced by devm_request_irq and the call of free_irq is removed. But since interrupts are requested in emac_dev_open, doing ifconfig up/down on the board requests the interrupts again each time, causing devm_request_irq to fail. The interface is dead until the device is rebooted. This patch reverts said commit partially: It changes the driver back to use request_irq instead of devm_request_irq, puts free_irq back in place, but keeps the remaining changes of the original patch. Reported-by: Jon Ringle <jon@ringle.org> Signed-off-by: Christian Riesch <christian.riesch@omicron.at> Cc: Lad, Prabhakar <prabhakar.csengg@gmail.com> Cc: <stable@vger.kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/ti/davinci_emac.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index cd9b164a0434..251430450005 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1532,7 +1532,7 @@ static int emac_dev_open(struct net_device *ndev)
1532 struct device *emac_dev = &ndev->dev; 1532 struct device *emac_dev = &ndev->dev;
1533 u32 cnt; 1533 u32 cnt;
1534 struct resource *res; 1534 struct resource *res;
1535 int ret; 1535 int q, m, ret;
1536 int i = 0; 1536 int i = 0;
1537 int k = 0; 1537 int k = 0;
1538 struct emac_priv *priv = netdev_priv(ndev); 1538 struct emac_priv *priv = netdev_priv(ndev);
@@ -1567,8 +1567,7 @@ static int emac_dev_open(struct net_device *ndev)
1567 1567
1568 while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) { 1568 while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) {
1569 for (i = res->start; i <= res->end; i++) { 1569 for (i = res->start; i <= res->end; i++) {
1570 if (devm_request_irq(&priv->pdev->dev, i, emac_irq, 1570 if (request_irq(i, emac_irq, 0, ndev->name, ndev))
1571 0, ndev->name, ndev))
1572 goto rollback; 1571 goto rollback;
1573 } 1572 }
1574 k++; 1573 k++;
@@ -1641,7 +1640,15 @@ static int emac_dev_open(struct net_device *ndev)
1641 1640
1642rollback: 1641rollback:
1643 1642
1644 dev_err(emac_dev, "DaVinci EMAC: devm_request_irq() failed"); 1643 dev_err(emac_dev, "DaVinci EMAC: request_irq() failed");
1644
1645 for (q = k; k >= 0; k--) {
1646 for (m = i; m >= res->start; m--)
1647 free_irq(m, ndev);
1648 res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k-1);
1649 m = res->end;
1650 }
1651
1645 ret = -EBUSY; 1652 ret = -EBUSY;
1646err: 1653err:
1647 pm_runtime_put(&priv->pdev->dev); 1654 pm_runtime_put(&priv->pdev->dev);
@@ -1659,6 +1666,9 @@ err:
1659 */ 1666 */
1660static int emac_dev_stop(struct net_device *ndev) 1667static int emac_dev_stop(struct net_device *ndev)
1661{ 1668{
1669 struct resource *res;
1670 int i = 0;
1671 int irq_num;
1662 struct emac_priv *priv = netdev_priv(ndev); 1672 struct emac_priv *priv = netdev_priv(ndev);
1663 struct device *emac_dev = &ndev->dev; 1673 struct device *emac_dev = &ndev->dev;
1664 1674
@@ -1674,6 +1684,13 @@ static int emac_dev_stop(struct net_device *ndev)
1674 if (priv->phydev) 1684 if (priv->phydev)
1675 phy_disconnect(priv->phydev); 1685 phy_disconnect(priv->phydev);
1676 1686
1687 /* Free IRQ */
1688 while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, i))) {
1689 for (irq_num = res->start; irq_num <= res->end; irq_num++)
1690 free_irq(irq_num, priv->ndev);
1691 i++;
1692 }
1693
1677 if (netif_msg_drv(priv)) 1694 if (netif_msg_drv(priv))
1678 dev_notice(emac_dev, "DaVinci EMAC: %s stopped\n", ndev->name); 1695 dev_notice(emac_dev, "DaVinci EMAC: %s stopped\n", ndev->name);
1679 1696