Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 118332
b: refs/heads/master
c: c132419
h: refs/heads/master
v: v3
  • Loading branch information
Trent Piepho authored and Jeff Garzik committed Oct 31, 2008
1 parent 49fa7ae commit 9c9b6fd
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 71527ef484426f2a4fb868da379b46f4408e80d6
refs/heads/master: c132419e560a2ecd3c8cf77f9c37e103e74b3754
26 changes: 26 additions & 0 deletions trunk/arch/powerpc/sysdev/fsl_soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ static int gfar_mdio_of_init_one(struct device_node *np)
if (ret)
return ret;

/* The gianfar device will try to use the same ID created below to find
* this bus, to coordinate register access (since they share). */
mdio_dev = platform_device_register_simple("fsl-gianfar_mdio",
res.start&0xfffff, &res, 1);
if (IS_ERR(mdio_dev))
Expand Down Expand Up @@ -394,6 +396,30 @@ static int __init gfar_of_init(void)
of_node_put(mdio);
}

/* Get MDIO bus controlled by this eTSEC, if any. Normally only
* eTSEC 1 will control an MDIO bus, not necessarily the same
* bus that its PHY is on ('mdio' above), so we can't just use
* that. What we do is look for a gianfar mdio device that has
* overlapping registers with this device. That's really the
* whole point, to find the device sharing our registers to
* coordinate access with it.
*/
for_each_compatible_node(mdio, NULL, "fsl,gianfar-mdio") {
if (of_address_to_resource(mdio, 0, &res))
continue;

if (res.start >= r[0].start && res.end <= r[0].end) {
/* Get the ID the mdio bus platform device was
* registered with. gfar_data.bus_id is
* different because it's for finding a PHY,
* while this is for finding a MII bus.
*/
gfar_data.mdio_bus = res.start&0xfffff;
of_node_put(mdio);
break;
}
}

ret =
platform_device_add_data(gfar_dev, &gfar_data,
sizeof(struct
Expand Down
7 changes: 7 additions & 0 deletions trunk/drivers/net/gianfar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
Expand Down
21 changes: 21 additions & 0 deletions trunk/drivers/net/gianfar_mii.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/gianfar_mii.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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 */
3 changes: 2 additions & 1 deletion trunk/include/linux/fsl_devices.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ struct gianfar_platform_data {
u32 device_flags;
/* board specific information */
u32 board_flags;
char bus_id[MII_BUS_ID_SIZE];
int mdio_bus; /* Bus controlled by us */
char bus_id[MII_BUS_ID_SIZE]; /* Bus PHY is on */
u32 phy_id;
u8 mac_addr[6];
phy_interface_t interface;
Expand Down

0 comments on commit 9c9b6fd

Please sign in to comment.