diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2009-04-25 08:53:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-27 05:53:47 -0400 |
commit | ca816d98170942371535b3e862813b0aba9b7d90 (patch) | |
tree | 1321117c2ea1e35a9f00303d2677e603e09ebfca /drivers/net/fec_mpc52xx_phy.c | |
parent | 8bc487d150b939e69830c39322df4ee486efe381 (diff) |
net: Rework mpc5200 fec driver to use of_mdio infrastructure.
The patch reworks the MPC5200 Fast Ethernet Controller (FEC) driver to
use the of_mdio infrastructure for registering PHY devices from data out
openfirmware device tree, and eliminates the assumption that the PHY
for the FEC is always attached to the FEC's own MDIO bus. With this
patch, the FEC can use a PHY attached to any MDIO bus if it is described
in the device tree.
Tested on Freescale Lite5200b eval board
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/fec_mpc52xx_phy.c')
-rw-r--r-- | drivers/net/fec_mpc52xx_phy.c | 26 |
1 files changed, 6 insertions, 20 deletions
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index dd9bfa42ac34..fec9f245116b 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c | |||
@@ -14,12 +14,14 @@ | |||
14 | #include <linux/netdevice.h> | 14 | #include <linux/netdevice.h> |
15 | #include <linux/phy.h> | 15 | #include <linux/phy.h> |
16 | #include <linux/of_platform.h> | 16 | #include <linux/of_platform.h> |
17 | #include <linux/of_mdio.h> | ||
17 | #include <asm/io.h> | 18 | #include <asm/io.h> |
18 | #include <asm/mpc52xx.h> | 19 | #include <asm/mpc52xx.h> |
19 | #include "fec_mpc52xx.h" | 20 | #include "fec_mpc52xx.h" |
20 | 21 | ||
21 | struct mpc52xx_fec_mdio_priv { | 22 | struct mpc52xx_fec_mdio_priv { |
22 | struct mpc52xx_fec __iomem *regs; | 23 | struct mpc52xx_fec __iomem *regs; |
24 | int mdio_irqs[PHY_MAX_ADDR]; | ||
23 | }; | 25 | }; |
24 | 26 | ||
25 | static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id, | 27 | static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id, |
@@ -27,7 +29,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id, | |||
27 | { | 29 | { |
28 | struct mpc52xx_fec_mdio_priv *priv = bus->priv; | 30 | struct mpc52xx_fec_mdio_priv *priv = bus->priv; |
29 | struct mpc52xx_fec __iomem *fec; | 31 | struct mpc52xx_fec __iomem *fec; |
30 | int tries = 100; | 32 | int tries = 3; |
31 | 33 | ||
32 | value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK; | 34 | value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK; |
33 | value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK; | 35 | value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK; |
@@ -38,7 +40,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id, | |||
38 | 40 | ||
39 | /* wait for it to finish, this takes about 23 us on lite5200b */ | 41 | /* wait for it to finish, this takes about 23 us on lite5200b */ |
40 | while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries) | 42 | while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries) |
41 | udelay(5); | 43 | msleep(1); |
42 | 44 | ||
43 | if (!tries) | 45 | if (!tries) |
44 | return -ETIMEDOUT; | 46 | return -ETIMEDOUT; |
@@ -64,7 +66,6 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, | |||
64 | { | 66 | { |
65 | struct device *dev = &of->dev; | 67 | struct device *dev = &of->dev; |
66 | struct device_node *np = of->node; | 68 | struct device_node *np = of->node; |
67 | struct device_node *child = NULL; | ||
68 | struct mii_bus *bus; | 69 | struct mii_bus *bus; |
69 | struct mpc52xx_fec_mdio_priv *priv; | 70 | struct mpc52xx_fec_mdio_priv *priv; |
70 | struct resource res = {}; | 71 | struct resource res = {}; |
@@ -85,22 +86,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, | |||
85 | bus->write = mpc52xx_fec_mdio_write; | 86 | bus->write = mpc52xx_fec_mdio_write; |
86 | 87 | ||
87 | /* setup irqs */ | 88 | /* setup irqs */ |
88 | bus->irq = kmalloc(sizeof(bus->irq[0]) * PHY_MAX_ADDR, GFP_KERNEL); | 89 | bus->irq = priv->mdio_irqs; |
89 | if (bus->irq == NULL) { | ||
90 | err = -ENOMEM; | ||
91 | goto out_free; | ||
92 | } | ||
93 | for (i=0; i<PHY_MAX_ADDR; i++) | ||
94 | bus->irq[i] = PHY_POLL; | ||
95 | |||
96 | while ((child = of_get_next_child(np, child)) != NULL) { | ||
97 | int irq = irq_of_parse_and_map(child, 0); | ||
98 | if (irq != NO_IRQ) { | ||
99 | const u32 *id = of_get_property(child, "reg", NULL); | ||
100 | if (id) | ||
101 | bus->irq[*id] = irq; | ||
102 | } | ||
103 | } | ||
104 | 90 | ||
105 | /* setup registers */ | 91 | /* setup registers */ |
106 | err = of_address_to_resource(np, 0, &res); | 92 | err = of_address_to_resource(np, 0, &res); |
@@ -122,7 +108,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, | |||
122 | out_be32(&priv->regs->mii_speed, | 108 | out_be32(&priv->regs->mii_speed, |
123 | ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1); | 109 | ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1); |
124 | 110 | ||
125 | err = mdiobus_register(bus); | 111 | err = of_mdiobus_register(bus, np); |
126 | if (err) | 112 | if (err) |
127 | goto out_unmap; | 113 | goto out_unmap; |
128 | 114 | ||