diff options
author | Christian Riesch <christian.riesch@omicron.at> | 2014-03-24 08:46:26 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-24 15:32:03 -0400 |
commit | 33b7107f59a61236d94ecd6b45e20283cd5abcc8 (patch) | |
tree | 26aec0e59cfad25d27c772f8191bf75c039c67c0 | |
parent | c27f0872a3448c46e561e226b5b97f77187b06d2 (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.c | 25 |
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 | ||
1642 | rollback: | 1641 | rollback: |
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; |
1646 | err: | 1653 | err: |
1647 | pm_runtime_put(&priv->pdev->dev); | 1654 | pm_runtime_put(&priv->pdev->dev); |
@@ -1659,6 +1666,9 @@ err: | |||
1659 | */ | 1666 | */ |
1660 | static int emac_dev_stop(struct net_device *ndev) | 1667 | static 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 | ||