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>
This commit is contained in:
parent
9723f38eb5
commit
5280267c1d
2 changed files with 32 additions and 5 deletions
|
@ -344,6 +344,27 @@ static int __init build_one_resource(struct device_node *parent,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __init use_1to1_mapping(struct device_node *pp)
|
||||||
|
{
|
||||||
|
/* If we have a ranges property in the parent, use it. */
|
||||||
|
if (of_find_property(pp, "ranges", NULL) != NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Some SBUS devices use intermediate nodes to express
|
||||||
|
* hierarchy within the device itself. These aren't
|
||||||
|
* real bus nodes, and don't have a 'ranges' property.
|
||||||
|
* But, we should still pass the translation work up
|
||||||
|
* to the SBUS itself.
|
||||||
|
*/
|
||||||
|
if (!strcmp(pp->name, "dma") ||
|
||||||
|
!strcmp(pp->name, "espdma") ||
|
||||||
|
!strcmp(pp->name, "ledma") ||
|
||||||
|
!strcmp(pp->name, "lebuffer"))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int of_resource_verbose;
|
static int of_resource_verbose;
|
||||||
|
|
||||||
static void __init build_device_resources(struct of_device *op,
|
static void __init build_device_resources(struct of_device *op,
|
||||||
|
@ -389,10 +410,7 @@ static void __init build_device_resources(struct of_device *op,
|
||||||
|
|
||||||
memcpy(addr, reg, na * 4);
|
memcpy(addr, reg, na * 4);
|
||||||
|
|
||||||
/* If the immediate parent has no ranges property to apply,
|
if (use_1to1_mapping(pp)) {
|
||||||
* just use a 1<->1 mapping.
|
|
||||||
*/
|
|
||||||
if (of_find_property(pp, "ranges", NULL) == NULL) {
|
|
||||||
result = of_read_addr(addr, na);
|
result = of_read_addr(addr, na);
|
||||||
goto build_res;
|
goto build_res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -438,8 +438,17 @@ static int __init use_1to1_mapping(struct device_node *pp)
|
||||||
|
|
||||||
/* If the parent is the dma node of an ISA bus, pass
|
/* If the parent is the dma node of an ISA bus, pass
|
||||||
* the translation up to the root.
|
* the translation up to the root.
|
||||||
|
*
|
||||||
|
* Some SBUS devices use intermediate nodes to express
|
||||||
|
* hierarchy within the device itself. These aren't
|
||||||
|
* real bus nodes, and don't have a 'ranges' property.
|
||||||
|
* But, we should still pass the translation work up
|
||||||
|
* to the SBUS itself.
|
||||||
*/
|
*/
|
||||||
if (!strcmp(pp->name, "dma"))
|
if (!strcmp(pp->name, "dma") ||
|
||||||
|
!strcmp(pp->name, "espdma") ||
|
||||||
|
!strcmp(pp->name, "ledma") ||
|
||||||
|
!strcmp(pp->name, "lebuffer"))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Similarly for all PCI bridges, if we get this far
|
/* Similarly for all PCI bridges, if we get this far
|
||||||
|
|
Loading…
Reference in a new issue