summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Fleming <afleming@freescale.com>2008-05-02 13:03:50 -0500
committerKumar Gala <galak@kernel.crashing.org>2008-07-16 17:57:44 -0500
commit4cd7e1cbd43bb67927af2b8b4e0ffd43fd5ed6b4 (patch)
treef0195868c2e82a66ab3186241dcd200218c776c3
parenta47fda930777f2d84209c9d140557b983e84a16a (diff)
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: Andy Fleming <afleming@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c84
1 files changed, 38 insertions, 46 deletions
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index ca180a93bca1..ef4cb0d67a72 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -207,66 +207,58 @@ static int __init of_add_fixed_phys(void)
arch_initcall(of_add_fixed_phys);
#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;
+ int k;
+ struct device_node *child = NULL;
+ struct gianfar_mdio_data mdio_data;
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");
+ memset(&res, 0, sizeof(res));
+ memset(&mdio_data, 0, sizeof(mdio_data));
- if (np) {
- int k;
- struct device_node *child = NULL;
- struct gianfar_mdio_data mdio_data;
+ ret = of_address_to_resource(np, 0, &res);
+ if (ret)
+ return ret;
- memset(&res, 0, sizeof(res));
- memset(&mdio_data, 0, sizeof(mdio_data));
+ mdio_dev = platform_device_register_simple("fsl-gianfar_mdio",
+ res.start&0xfffff, &res, 1);
+ if (IS_ERR(mdio_dev))
+ return PTR_ERR(mdio_dev);
- ret = of_address_to_resource(np, 0, &res);
- if (ret)
- goto err;
+ for (k = 0; k < 32; k++)
+ mdio_data.irq[k] = PHY_POLL;
- mdio_dev =
- platform_device_register_simple("fsl-gianfar_mdio",
- res.start, &res, 1);
- if (IS_ERR(mdio_dev)) {
- ret = PTR_ERR(mdio_dev);
- goto err;
+ while ((child = of_get_next_child(np, child)) != NULL) {
+ int irq = irq_of_parse_and_map(child, 0);
+ if (irq != NO_IRQ) {
+ const u32 *id = of_get_property(child, "reg", NULL);
+ mdio_data.irq[*id] = irq;
}
+ }
- for (k = 0; k < 32; k++)
- mdio_data.irq[k] = PHY_POLL;
+ ret = platform_device_add_data(mdio_dev, &mdio_data,
+ sizeof(struct gianfar_mdio_data));
+ if (ret)
+ platform_device_unregister(mdio_dev);
- while ((child = of_get_next_child(np, child)) != NULL) {
- int irq = irq_of_parse_and_map(child, 0);
- if (irq != NO_IRQ) {
- const u32 *id = of_get_property(child,
- "reg", NULL);
- mdio_data.irq[*id] = irq;
- }
- }
+ return ret;
+}
- ret =
- platform_device_add_data(mdio_dev, &mdio_data,
- sizeof(struct gianfar_mdio_data));
- if (ret)
- goto unreg;
- }
+static int __init gfar_mdio_of_init(void)
+{
+ struct device_node *np = NULL;
- of_node_put(np);
- return 0;
+ for_each_compatible_node(np, NULL, "fsl,gianfar-mdio")
+ gfar_mdio_of_init_one(np);
-unreg:
- platform_device_unregister(mdio_dev);
-err:
- of_node_put(np);
- return ret;
+ /* 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);
@@ -393,7 +385,7 @@ static int __init gfar_of_init(void)
gfar_data.phy_id = *id;
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(mdio);