diff options
author | Andy Fleming <afleming@freescale.com> | 2008-05-02 14:03:50 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2008-07-16 18:57:44 -0400 |
commit | 4cd7e1cbd43bb67927af2b8b4e0ffd43fd5ed6b4 (patch) | |
tree | f0195868c2e82a66ab3186241dcd200218c776c3 /arch/powerpc/sysdev | |
parent | a47fda930777f2d84209c9d140557b983e84a16a (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.c | 84 |
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) | |||
207 | arch_initcall(of_add_fixed_phys); | 207 | arch_initcall(of_add_fixed_phys); |
208 | #endif /* CONFIG_FIXED_PHY */ | 208 | #endif /* CONFIG_FIXED_PHY */ |
209 | 209 | ||
210 | static int __init gfar_mdio_of_init(void) | 210 | static 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 = | 250 | static 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 | ||
265 | unreg: | 257 | /* try the deprecated version */ |
266 | platform_device_unregister(mdio_dev); | 258 | for_each_compatible_node(np, "mdio", "gianfar"); |
267 | err: | 259 | gfar_mdio_of_init_one(np); |
268 | of_node_put(np); | 260 | |
269 | return ret; | 261 | return 0; |
270 | } | 262 | } |
271 | 263 | ||
272 | arch_initcall(gfar_mdio_of_init); | 264 | arch_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); |