diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/gianfar.c | 7 | ||||
-rw-r--r-- | drivers/net/gianfar_mii.c | 21 | ||||
-rw-r--r-- | drivers/net/gianfar_mii.h | 3 |
3 files changed, 31 insertions, 0 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 64b201134fdb..249541a1814b 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -586,6 +586,10 @@ 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); /* Single clk mode, mii mode off(for serdes communication) */ gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT); @@ -596,6 +600,9 @@ 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); + + if (bus) + mutex_unlock(&bus->mdio_lock); } static void init_registers(struct net_device *dev) diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index bf73eea98010..0e2595d24933 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c @@ -269,6 +269,27 @@ static struct device_driver gianfar_mdio_driver = { .remove = gfar_mdio_remove, }; +static int match_mdio_bus(struct device *dev, void *data) +{ + const struct gfar_private *priv = data; + const struct platform_device *pdev = to_platform_device(dev); + + return !strcmp(pdev->name, gianfar_mdio_driver.name) && + pdev->id == priv->einfo->mdio_bus; +} + +/* Given a gfar_priv structure, find the mii_bus controlled by this device (not + * necessarily the same as the bus the gfar's PHY is on), if one exists. + * Normally only the first gianfar controls a mii_bus. */ +struct mii_bus *gfar_get_miibus(const struct gfar_private *priv) +{ + /*const*/ struct device *d; + + d = bus_find_device(gianfar_mdio_driver.bus, NULL, (void *)priv, + match_mdio_bus); + return d ? dev_get_drvdata(d) : NULL; +} + int __init gfar_mdio_init(void) { return driver_register(&gianfar_mdio_driver); diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h index 2af28b16a0e2..02dc970ca1ff 100644 --- a/drivers/net/gianfar_mii.h +++ b/drivers/net/gianfar_mii.h @@ -18,6 +18,8 @@ #ifndef __GIANFAR_MII_H #define __GIANFAR_MII_H +struct gfar_private; /* forward ref */ + #define MIIMIND_BUSY 0x00000001 #define MIIMIND_NOTVALID 0x00000004 @@ -44,6 +46,7 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, int regnum, u16 value); int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum); +struct mii_bus *gfar_get_miibus(const struct gfar_private *priv); int __init gfar_mdio_init(void); void gfar_mdio_exit(void); #endif /* GIANFAR_PHY_H */ |