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 b5bb7ae2817f..83a5cb6aa23b 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -161,7 +161,7 @@ static int gfar_probe(struct platform_device *pdev) | |||
161 | struct gfar_private *priv = NULL; | 161 | struct gfar_private *priv = NULL; |
162 | struct gianfar_platform_data *einfo; | 162 | struct gianfar_platform_data *einfo; |
163 | struct resource *r; | 163 | struct resource *r; |
164 | int err = 0; | 164 | int err = 0, irq; |
165 | DECLARE_MAC_BUF(mac); | 165 | DECLARE_MAC_BUF(mac); |
166 | 166 | ||
167 | einfo = (struct gianfar_platform_data *) pdev->dev.platform_data; | 167 | einfo = (struct gianfar_platform_data *) pdev->dev.platform_data; |
@@ -187,15 +187,25 @@ static int gfar_probe(struct platform_device *pdev) | |||
187 | 187 | ||
188 | /* fill out IRQ fields */ | 188 | /* fill out IRQ fields */ |
189 | if (einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { | 189 | if (einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { |
190 | priv->interruptTransmit = platform_get_irq_byname(pdev, "tx"); | 190 | irq = platform_get_irq_byname(pdev, "tx"); |
191 | priv->interruptReceive = platform_get_irq_byname(pdev, "rx"); | 191 | if (irq < 0) |
192 | priv->interruptError = platform_get_irq_byname(pdev, "error"); | 192 | goto regs_fail; |
193 | if (priv->interruptTransmit < 0 || priv->interruptReceive < 0 || priv->interruptError < 0) | 193 | priv->interruptTransmit = irq; |
194 | |||
195 | irq = platform_get_irq_byname(pdev, "rx"); | ||
196 | if (irq < 0) | ||
197 | goto regs_fail; | ||
198 | priv->interruptReceive = irq; | ||
199 | |||
200 | irq = platform_get_irq_byname(pdev, "error"); | ||
201 | if (irq < 0) | ||
194 | goto regs_fail; | 202 | goto regs_fail; |
203 | priv->interruptError = irq; | ||
195 | } else { | 204 | } else { |
196 | priv->interruptTransmit = platform_get_irq(pdev, 0); | 205 | irq = platform_get_irq(pdev, 0); |
197 | if (priv->interruptTransmit < 0) | 206 | if (irq < 0) |
198 | goto regs_fail; | 207 | goto regs_fail; |
208 | priv->interruptTransmit = irq; | ||
199 | } | 209 | } |
200 | 210 | ||
201 | /* get a pointer to the register memory */ | 211 | /* get a pointer to the register memory */ |
@@ -576,6 +586,18 @@ static void gfar_configure_serdes(struct net_device *dev) | |||
576 | struct gfar_mii __iomem *regs = | 586 | struct gfar_mii __iomem *regs = |
577 | (void __iomem *)&priv->regs->gfar_mii_regs; | 587 | (void __iomem *)&priv->regs->gfar_mii_regs; |
578 | int tbipa = gfar_read(&priv->regs->tbipa); | 588 | int tbipa = gfar_read(&priv->regs->tbipa); |
589 | struct mii_bus *bus = gfar_get_miibus(priv); | ||
590 | |||
591 | if (bus) | ||
592 | mutex_lock(&bus->mdio_lock); | ||
593 | |||
594 | /* If the link is already up, we must already be ok, and don't need to | ||
595 | * configure and reset the TBI<->SerDes link. Maybe U-Boot configured | ||
596 | * everything for us? Resetting it takes the link down and requires | ||
597 | * several seconds for it to come back. | ||
598 | */ | ||
599 | if (gfar_local_mdio_read(regs, tbipa, MII_BMSR) & BMSR_LSTATUS) | ||
600 | goto done; | ||
579 | 601 | ||
580 | /* Single clk mode, mii mode off(for serdes communication) */ | 602 | /* Single clk mode, mii mode off(for serdes communication) */ |
581 | gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT); | 603 | gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT); |
@@ -586,6 +608,10 @@ static void gfar_configure_serdes(struct net_device *dev) | |||
586 | 608 | ||
587 | gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE | | 609 | gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE | |
588 | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); | 610 | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); |
611 | |||
612 | done: | ||
613 | if (bus) | ||
614 | mutex_unlock(&bus->mdio_lock); | ||
589 | } | 615 | } |
590 | 616 | ||
591 | static void init_registers(struct net_device *dev) | 617 | static void init_registers(struct net_device *dev) |