diff options
author | Claudiu Manoil <claudiu.manoil@freescale.com> | 2014-02-24 10:13:44 (GMT) |
---|---|---|
committer | Madalin-Cristian Bucur <madalin.bucur@freescale.com> | 2014-02-26 09:54:48 (GMT) |
commit | 1e2b17446aff898c61d678bb645f52504ea20dda (patch) | |
tree | 83d5d43c466fd8563e12fcf2d6f229bb35215baa /drivers/net | |
parent | 9a59b54452d8906b7bad87248df5ae281374bc37 (diff) | |
download | linux-fsl-qoriq-1e2b17446aff898c61d678bb645f52504ea20dda.tar.xz |
gianfar: Don't free/request irqs on device reset
Resetting the device (stop_gfar()/startup_gfar()) should
be fast and to the point, in order to timely recover
from an error condition (like Tx timeout) or during
device reconfig. The irq free/ request routines are just
redundant here, and they should be part of the device
close/ open routines instead.
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Change-Id: I3f22ec285591c720f3c9f09d03e68d2ffc37e399
Reviewed-on: http://git.am.freescale.net:8181/9149
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com>
Tested-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 77 |
1 files changed, 45 insertions, 32 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 187217e..c3172dde 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1709,18 +1709,10 @@ void gfar_halt(struct gfar_private *priv) gfar_write(®s->maccfg1, tempval); } -static void free_grp_irqs(struct gfar_priv_grp *grp) -{ - free_irq(gfar_irq(grp, TX)->irq, grp); - free_irq(gfar_irq(grp, RX)->irq, grp); - free_irq(gfar_irq(grp, ER)->irq, grp); -} - void stop_gfar(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); unsigned long flags; - int i; phy_stop(priv->phydev); @@ -1736,16 +1728,6 @@ void stop_gfar(struct net_device *dev) unlock_tx_qs(priv); local_irq_restore(flags); - /* Free the IRQs */ - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { - for (i = 0; i < priv->num_grps; i++) - free_grp_irqs(&priv->gfargrp[i]); - } else { - for (i = 0; i < priv->num_grps; i++) - free_irq(gfar_irq(&priv->gfargrp[i], TX)->irq, - &priv->gfargrp[i]); - } - free_skb_resources(priv); } @@ -1913,6 +1895,13 @@ void gfar_configure_coalescing_all(struct gfar_private *priv) gfar_configure_coalescing(priv, 0xFF, 0xFF); } +static void free_grp_irqs(struct gfar_priv_grp *grp) +{ + free_irq(gfar_irq(grp, TX)->irq, grp); + free_irq(gfar_irq(grp, RX)->irq, grp); + free_irq(gfar_irq(grp, ER)->irq, grp); +} + static int register_grp_irqs(struct gfar_priv_grp *grp) { struct gfar_private *priv = grp->priv; @@ -1969,11 +1958,42 @@ err_irq_fail: } +static void gfar_free_irq(struct gfar_private *priv) +{ + int i; + + /* Free the IRQs */ + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { + for (i = 0; i < priv->num_grps; i++) + free_grp_irqs(&priv->gfargrp[i]); + } else { + for (i = 0; i < priv->num_grps; i++) + free_irq(gfar_irq(&priv->gfargrp[i], TX)->irq, + &priv->gfargrp[i]); + } +} + +static int gfar_request_irq(struct gfar_private *priv) +{ + int err, i, j; + + for (i = 0; i < priv->num_grps; i++) { + err = register_grp_irqs(&priv->gfargrp[i]); + if (err) { + for (j = 0; j < i; j++) + free_grp_irqs(&priv->gfargrp[j]); + return err; + } + } + + return 0; +} + /* Bring the controller up and running */ int startup_gfar(struct net_device *ndev) { struct gfar_private *priv = netdev_priv(ndev); - int err, i, j; + int err; gfar_mac_reset(priv); @@ -1983,25 +2003,12 @@ int startup_gfar(struct net_device *ndev) gfar_init_tx_rx_base(priv); - for (i = 0; i < priv->num_grps; i++) { - err = register_grp_irqs(&priv->gfargrp[i]); - if (err) { - for (j = 0; j < i; j++) - free_grp_irqs(&priv->gfargrp[j]); - goto irq_fail; - } - } - /* Start the controller */ gfar_start(priv); phy_start(priv->phydev); return 0; - -irq_fail: - free_skb_resources(priv); - return err; } /* Called when something needs to use the ethernet device @@ -2021,6 +2028,10 @@ static int gfar_enet_open(struct net_device *dev) return err; } + err = gfar_request_irq(priv); + if (err) + return err; + err = startup_gfar(dev); if (err) { disable_napi(priv); @@ -2368,6 +2379,8 @@ static int gfar_close(struct net_device *dev) netif_tx_stop_all_queues(dev); + gfar_free_irq(priv); + return 0; } |