Commit 4cd7e1cb authored by Andy Fleming's avatar Andy Fleming Committed by Kumar Gala

powerpc: Add support for multiple gfar mdio interfaces

The old code assumed there was only one, but the 8572 actually has 3.

Also, our usual id, 0xe0024520, gets resolved to -1 somewhere, and this was
preventing the multiple buses from having different ids.  So we only keep
the low 20 bits, which have the interesting info, anyway.
Signed-off-by: default avatarAndy Fleming <afleming@freescale.com>
Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
parent a47fda93
...@@ -207,38 +207,26 @@ static int __init of_add_fixed_phys(void) ...@@ -207,38 +207,26 @@ static int __init of_add_fixed_phys(void)
arch_initcall(of_add_fixed_phys); arch_initcall(of_add_fixed_phys);
#endif /* CONFIG_FIXED_PHY */ #endif /* CONFIG_FIXED_PHY */
static int __init gfar_mdio_of_init(void) static int gfar_mdio_of_init_one(struct device_node *np)
{ {
struct device_node *np = NULL;
struct platform_device *mdio_dev;
struct resource res;
int ret;
np = of_find_compatible_node(np, NULL, "fsl,gianfar-mdio");
/* try the deprecated version */
if (!np)
np = of_find_compatible_node(np, "mdio", "gianfar");
if (np) {
int k; int k;
struct device_node *child = NULL; struct device_node *child = NULL;
struct gianfar_mdio_data mdio_data; struct gianfar_mdio_data mdio_data;
struct platform_device *mdio_dev;
struct resource res;
int ret;
memset(&res, 0, sizeof(res)); memset(&res, 0, sizeof(res));
memset(&mdio_data, 0, sizeof(mdio_data)); memset(&mdio_data, 0, sizeof(mdio_data));
ret = of_address_to_resource(np, 0, &res); ret = of_address_to_resource(np, 0, &res);
if (ret) if (ret)
goto err; return ret;
mdio_dev = mdio_dev = platform_device_register_simple("fsl-gianfar_mdio",
platform_device_register_simple("fsl-gianfar_mdio", res.start&0xfffff, &res, 1);
res.start, &res, 1); if (IS_ERR(mdio_dev))
if (IS_ERR(mdio_dev)) { return PTR_ERR(mdio_dev);
ret = PTR_ERR(mdio_dev);
goto err;
}
for (k = 0; k < 32; k++) for (k = 0; k < 32; k++)
mdio_data.irq[k] = PHY_POLL; mdio_data.irq[k] = PHY_POLL;
...@@ -246,29 +234,33 @@ static int __init gfar_mdio_of_init(void) ...@@ -246,29 +234,33 @@ static int __init gfar_mdio_of_init(void)
while ((child = of_get_next_child(np, child)) != NULL) { while ((child = of_get_next_child(np, child)) != NULL) {
int irq = irq_of_parse_and_map(child, 0); int irq = irq_of_parse_and_map(child, 0);
if (irq != NO_IRQ) { if (irq != NO_IRQ) {
const u32 *id = of_get_property(child, const u32 *id = of_get_property(child, "reg", NULL);
"reg", NULL);
mdio_data.irq[*id] = irq; mdio_data.irq[*id] = irq;
} }
} }
ret = ret = platform_device_add_data(mdio_dev, &mdio_data,
platform_device_add_data(mdio_dev, &mdio_data,
sizeof(struct gianfar_mdio_data)); sizeof(struct gianfar_mdio_data));
if (ret) if (ret)
goto unreg;
}
of_node_put(np);
return 0;
unreg:
platform_device_unregister(mdio_dev); platform_device_unregister(mdio_dev);
err:
of_node_put(np);
return ret; return ret;
} }
static int __init gfar_mdio_of_init(void)
{
struct device_node *np = NULL;
for_each_compatible_node(np, NULL, "fsl,gianfar-mdio")
gfar_mdio_of_init_one(np);
/* try the deprecated version */
for_each_compatible_node(np, "mdio", "gianfar");
gfar_mdio_of_init_one(np);
return 0;
}
arch_initcall(gfar_mdio_of_init); arch_initcall(gfar_mdio_of_init);
static const char *gfar_tx_intr = "tx"; static const char *gfar_tx_intr = "tx";
...@@ -393,7 +385,7 @@ static int __init gfar_of_init(void) ...@@ -393,7 +385,7 @@ static int __init gfar_of_init(void)
gfar_data.phy_id = *id; gfar_data.phy_id = *id;
snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%llx", snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%llx",
(unsigned long long)res.start); (unsigned long long)res.start&0xfffff);
of_node_put(phy); of_node_put(phy);
of_node_put(mdio); of_node_put(mdio);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment