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

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
Loading
Loading
Loading
Loading
+38 −46
Original line number Original line Diff line number Diff line
@@ -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,27 +234,31 @@ 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;
		platform_device_unregister(mdio_dev);

	return ret;
}
}


	of_node_put(np);
static int __init gfar_mdio_of_init(void)
	return 0;
{
	struct device_node *np = NULL;


unreg:
	for_each_compatible_node(np, NULL, "fsl,gianfar-mdio")
	platform_device_unregister(mdio_dev);
		gfar_mdio_of_init_one(np);
err:

	of_node_put(np);
	/* try the deprecated version */
	return ret;
	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);
@@ -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);