aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorAndy Fleming <afleming@freescale.com>2008-05-02 14:03:50 -0400
committerKumar Gala <galak@kernel.crashing.org>2008-07-16 18:57:44 -0400
commit4cd7e1cbd43bb67927af2b8b4e0ffd43fd5ed6b4 (patch)
treef0195868c2e82a66ab3186241dcd200218c776c3 /arch/powerpc/sysdev
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>
Diffstat (limited to 'arch/powerpc/sysdev')
-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)
207arch_initcall(of_add_fixed_phys); 207arch_initcall(of_add_fixed_phys);
208#endif /* CONFIG_FIXED_PHY */ 208#endif /* CONFIG_FIXED_PHY */
209 209
210static int __init gfar_mdio_of_init(void) 210static int gfar_mdio_of_init_one(struct device_node *np)
211{ 211{
212 struct device_node *np = NULL; 212 int k;
213 struct device_node *child = NULL;
214 struct gianfar_mdio_data mdio_data;
213 struct platform_device *mdio_dev; 215 struct platform_device *mdio_dev;
214 struct resource res; 216 struct resource res;
215 int ret; 217 int ret;
216 218
217 np = of_find_compatible_node(np, NULL, "fsl,gianfar-mdio"); 219 memset(&res, 0, sizeof(res));
218 220 memset(&mdio_data, 0, sizeof(mdio_data));
219 /* try the deprecated version */
220 if (!np)
221 np = of_find_compatible_node(np, "mdio", "gianfar");
222 221
223 if (np) { 222 ret = of_address_to_resource(np, 0, &res);
224 int k; 223 if (ret)
225 struct device_node *child = NULL; 224 return ret;
226 struct gianfar_mdio_data mdio_data;
227 225
228 memset(&res, 0, sizeof(res)); 226 mdio_dev = platform_device_register_simple("fsl-gianfar_mdio",
229 memset(&mdio_data, 0, sizeof(mdio_data)); 227 res.start&0xfffff, &res, 1);
228 if (IS_ERR(mdio_dev))
229 return PTR_ERR(mdio_dev);
230 230
231 ret = of_address_to_resource(np, 0, &res); 231 for (k = 0; k < 32; k++)
232 if (ret) 232 mdio_data.irq[k] = PHY_POLL;
233 goto err;
234 233
235 mdio_dev = 234 while ((child = of_get_next_child(np, child)) != NULL) {
236 platform_device_register_simple("fsl-gianfar_mdio", 235 int irq = irq_of_parse_and_map(child, 0);
237 res.start, &res, 1); 236 if (irq != NO_IRQ) {
238 if (IS_ERR(mdio_dev)) { 237 const u32 *id = of_get_property(child, "reg", NULL);
239 ret = PTR_ERR(mdio_dev); 238 mdio_data.irq[*id] = irq;
240 goto err;
241 } 239 }
240 }
242 241
243 for (k = 0; k < 32; k++) 242 ret = platform_device_add_data(mdio_dev, &mdio_data,
244 mdio_data.irq[k] = PHY_POLL; 243 sizeof(struct gianfar_mdio_data));
244 if (ret)
245 platform_device_unregister(mdio_dev);
245 246
246 while ((child = of_get_next_child(np, child)) != NULL) { 247 return ret;
247 int irq = irq_of_parse_and_map(child, 0); 248}
248 if (irq != NO_IRQ) {
249 const u32 *id = of_get_property(child,
250 "reg", NULL);
251 mdio_data.irq[*id] = irq;
252 }
253 }
254 249
255 ret = 250static int __init gfar_mdio_of_init(void)
256 platform_device_add_data(mdio_dev, &mdio_data, 251{
257 sizeof(struct gianfar_mdio_data)); 252 struct device_node *np = NULL;
258 if (ret)
259 goto unreg;
260 }
261 253
262 of_node_put(np); 254 for_each_compatible_node(np, NULL, "fsl,gianfar-mdio")
263 return 0; 255 gfar_mdio_of_init_one(np);
264 256
265unreg: 257 /* try the deprecated version */
266 platform_device_unregister(mdio_dev); 258 for_each_compatible_node(np, "mdio", "gianfar");
267err: 259 gfar_mdio_of_init_one(np);
268 of_node_put(np); 260
269 return ret; 261 return 0;
270} 262}
271 263
272arch_initcall(gfar_mdio_of_init); 264arch_initcall(gfar_mdio_of_init);
@@ -393,7 +385,7 @@ static int __init gfar_of_init(void)
393 385
394 gfar_data.phy_id = *id; 386 gfar_data.phy_id = *id;
395 snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%llx", 387 snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%llx",
396 (unsigned long long)res.start); 388 (unsigned long long)res.start&0xfffff);
397 389
398 of_node_put(phy); 390 of_node_put(phy);
399 of_node_put(mdio); 391 of_node_put(mdio);