diff options
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r-- | drivers/net/gianfar.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index b5bb7ae2817..83a5cb6aa23 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -161,7 +161,7 @@ static int gfar_probe(struct platform_device *pdev) struct gfar_private *priv = NULL; struct gianfar_platform_data *einfo; struct resource *r; - int err = 0; + int err = 0, irq; DECLARE_MAC_BUF(mac); einfo = (struct gianfar_platform_data *) pdev->dev.platform_data; @@ -187,15 +187,25 @@ static int gfar_probe(struct platform_device *pdev) /* fill out IRQ fields */ if (einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { - priv->interruptTransmit = platform_get_irq_byname(pdev, "tx"); - priv->interruptReceive = platform_get_irq_byname(pdev, "rx"); - priv->interruptError = platform_get_irq_byname(pdev, "error"); - if (priv->interruptTransmit < 0 || priv->interruptReceive < 0 || priv->interruptError < 0) + irq = platform_get_irq_byname(pdev, "tx"); + if (irq < 0) + goto regs_fail; + priv->interruptTransmit = irq; + + irq = platform_get_irq_byname(pdev, "rx"); + if (irq < 0) + goto regs_fail; + priv->interruptReceive = irq; + + irq = platform_get_irq_byname(pdev, "error"); + if (irq < 0) goto regs_fail; + priv->interruptError = irq; } else { - priv->interruptTransmit = platform_get_irq(pdev, 0); - if (priv->interruptTransmit < 0) + irq = platform_get_irq(pdev, 0); + if (irq < 0) goto regs_fail; + priv->interruptTransmit = irq; } /* get a pointer to the register memory */ @@ -576,6 +586,18 @@ static void gfar_configure_serdes(struct net_device *dev) struct gfar_mii __iomem *regs = (void __iomem *)&priv->regs->gfar_mii_regs; int tbipa = gfar_read(&priv->regs->tbipa); + struct mii_bus *bus = gfar_get_miibus(priv); + + if (bus) + mutex_lock(&bus->mdio_lock); + + /* If the link is already up, we must already be ok, and don't need to + * configure and reset the TBI<->SerDes link. Maybe U-Boot configured + * everything for us? Resetting it takes the link down and requires + * several seconds for it to come back. + */ + if (gfar_local_mdio_read(regs, tbipa, MII_BMSR) & BMSR_LSTATUS) + goto done; /* Single clk mode, mii mode off(for serdes communication) */ gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT); @@ -586,6 +608,10 @@ static void gfar_configure_serdes(struct net_device *dev) gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); + + done: + if (bus) + mutex_unlock(&bus->mdio_lock); } static void init_registers(struct net_device *dev) |