aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-09-03 05:04:41 -0400
committerDavid S. Miller <davem@davemloft.net>2008-09-03 05:05:19 -0400
commit5280267c1dddb8d413595b87dc406624bb497946 (patch)
tree541701a1c15d17b7b5535beebd8e4f258d31395c
parent9723f38eb53eac9a851210b629555a37afa3f15c (diff)
sparc: Fix handling of LANCE and ESP parent nodes in of_device.c
The device nodes that sit above 'esp' and 'le' on SBUS lack a 'ranges' property, but we should pass the translation up to the parent node so that the SBUS level ranges get applied. Based upon a bug report from Robert Reif. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc/kernel/of_device.c26
-rw-r--r--arch/sparc64/kernel/of_device.c11
2 files changed, 32 insertions, 5 deletions
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
index c59014886afe..4ef160755881 100644
--- a/arch/sparc/kernel/of_device.c
+++ b/arch/sparc/kernel/of_device.c
@@ -344,6 +344,27 @@ static int __init build_one_resource(struct device_node *parent,
344 return 1; 344 return 1;
345} 345}
346 346
347static int __init use_1to1_mapping(struct device_node *pp)
348{
349 /* If we have a ranges property in the parent, use it. */
350 if (of_find_property(pp, "ranges", NULL) != NULL)
351 return 0;
352
353 /* Some SBUS devices use intermediate nodes to express
354 * hierarchy within the device itself. These aren't
355 * real bus nodes, and don't have a 'ranges' property.
356 * But, we should still pass the translation work up
357 * to the SBUS itself.
358 */
359 if (!strcmp(pp->name, "dma") ||
360 !strcmp(pp->name, "espdma") ||
361 !strcmp(pp->name, "ledma") ||
362 !strcmp(pp->name, "lebuffer"))
363 return 0;
364
365 return 1;
366}
367
347static int of_resource_verbose; 368static int of_resource_verbose;
348 369
349static void __init build_device_resources(struct of_device *op, 370static void __init build_device_resources(struct of_device *op,
@@ -389,10 +410,7 @@ static void __init build_device_resources(struct of_device *op,
389 410
390 memcpy(addr, reg, na * 4); 411 memcpy(addr, reg, na * 4);
391 412
392 /* If the immediate parent has no ranges property to apply, 413 if (use_1to1_mapping(pp)) {
393 * just use a 1<->1 mapping.
394 */
395 if (of_find_property(pp, "ranges", NULL) == NULL) {
396 result = of_read_addr(addr, na); 414 result = of_read_addr(addr, na);
397 goto build_res; 415 goto build_res;
398 } 416 }
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index e427086e3b58..c15bcdf75c0d 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -438,8 +438,17 @@ static int __init use_1to1_mapping(struct device_node *pp)
438 438
439 /* If the parent is the dma node of an ISA bus, pass 439 /* If the parent is the dma node of an ISA bus, pass
440 * the translation up to the root. 440 * the translation up to the root.
441 *
442 * Some SBUS devices use intermediate nodes to express
443 * hierarchy within the device itself. These aren't
444 * real bus nodes, and don't have a 'ranges' property.
445 * But, we should still pass the translation work up
446 * to the SBUS itself.
441 */ 447 */
442 if (!strcmp(pp->name, "dma")) 448 if (!strcmp(pp->name, "dma") ||
449 !strcmp(pp->name, "espdma") ||
450 !strcmp(pp->name, "ledma") ||
451 !strcmp(pp->name, "lebuffer"))
443 return 0; 452 return 0;
444 453
445 /* Similarly for all PCI bridges, if we get this far 454 /* Similarly for all PCI bridges, if we get this far