diff options
Diffstat (limited to 'arch/powerpc/sysdev/fsl_soc.c')
-rw-r--r-- | arch/powerpc/sysdev/fsl_soc.c | 90 |
1 files changed, 44 insertions, 46 deletions
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index ebcec7362f95..214388e11807 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)); |
220 | memset(&mdio_data, 0, sizeof(mdio_data)); | ||
218 | 221 | ||
219 | /* try the deprecated version */ | 222 | ret = of_address_to_resource(np, 0, &res); |
220 | if (!np) | 223 | if (ret) |
221 | np = of_find_compatible_node(np, "mdio", "gianfar"); | 224 | return ret; |
222 | 225 | ||
223 | if (np) { | 226 | mdio_dev = platform_device_register_simple("fsl-gianfar_mdio", |
224 | int k; | 227 | res.start&0xfffff, &res, 1); |
225 | struct device_node *child = NULL; | 228 | if (IS_ERR(mdio_dev)) |
226 | struct gianfar_mdio_data mdio_data; | 229 | return PTR_ERR(mdio_dev); |
227 | 230 | ||
228 | memset(&res, 0, sizeof(res)); | 231 | for (k = 0; k < 32; k++) |
229 | memset(&mdio_data, 0, sizeof(mdio_data)); | 232 | mdio_data.irq[k] = PHY_POLL; |
230 | 233 | ||
231 | ret = of_address_to_resource(np, 0, &res); | 234 | while ((child = of_get_next_child(np, child)) != NULL) { |
232 | if (ret) | 235 | int irq = irq_of_parse_and_map(child, 0); |
233 | goto err; | 236 | if (irq != NO_IRQ) { |
234 | 237 | const u32 *id = of_get_property(child, "reg", NULL); | |
235 | mdio_dev = | 238 | mdio_data.irq[*id] = irq; |
236 | platform_device_register_simple("fsl-gianfar_mdio", | ||
237 | res.start, &res, 1); | ||
238 | if (IS_ERR(mdio_dev)) { | ||
239 | ret = PTR_ERR(mdio_dev); | ||
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); |
@@ -296,6 +288,9 @@ static int __init gfar_of_init(void) | |||
296 | const phandle *ph; | 288 | const phandle *ph; |
297 | int n_res = 2; | 289 | int n_res = 2; |
298 | 290 | ||
291 | if (!of_device_is_available(np)) | ||
292 | continue; | ||
293 | |||
299 | memset(r, 0, sizeof(r)); | 294 | memset(r, 0, sizeof(r)); |
300 | memset(&gfar_data, 0, sizeof(gfar_data)); | 295 | memset(&gfar_data, 0, sizeof(gfar_data)); |
301 | 296 | ||
@@ -357,6 +352,9 @@ static int __init gfar_of_init(void) | |||
357 | else | 352 | else |
358 | gfar_data.interface = PHY_INTERFACE_MODE_MII; | 353 | gfar_data.interface = PHY_INTERFACE_MODE_MII; |
359 | 354 | ||
355 | if (of_get_property(np, "fsl,magic-packet", NULL)) | ||
356 | gfar_data.device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET; | ||
357 | |||
360 | ph = of_get_property(np, "phy-handle", NULL); | 358 | ph = of_get_property(np, "phy-handle", NULL); |
361 | if (ph == NULL) { | 359 | if (ph == NULL) { |
362 | u32 *fixed_link; | 360 | u32 *fixed_link; |
@@ -390,7 +388,7 @@ static int __init gfar_of_init(void) | |||
390 | 388 | ||
391 | gfar_data.phy_id = *id; | 389 | gfar_data.phy_id = *id; |
392 | snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%llx", | 390 | snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%llx", |
393 | (unsigned long long)res.start); | 391 | (unsigned long long)res.start&0xfffff); |
394 | 392 | ||
395 | of_node_put(phy); | 393 | of_node_put(phy); |
396 | of_node_put(mdio); | 394 | of_node_put(mdio); |