diff options
author | David S. Miller <davem@davemloft.net> | 2008-09-03 05:04:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-09-03 05:05:19 -0400 |
commit | 5280267c1dddb8d413595b87dc406624bb497946 (patch) | |
tree | 541701a1c15d17b7b5535beebd8e4f258d31395c | |
parent | 9723f38eb53eac9a851210b629555a37afa3f15c (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.c | 26 | ||||
-rw-r--r-- | arch/sparc64/kernel/of_device.c | 11 |
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 | ||
347 | static 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 | |||
347 | static int of_resource_verbose; | 368 | static int of_resource_verbose; |
348 | 369 | ||
349 | static void __init build_device_resources(struct of_device *op, | 370 | static 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 |