sparc: Fix handling of LANCE and ESP parent nodes in of_device.c
authorDavid S. Miller <davem@davemloft.net>
Wed, 3 Sep 2008 09:04:41 +0000 (02:04 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 3 Sep 2008 09:05:19 +0000 (02:05 -0700)
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>
arch/sparc/kernel/of_device.c
arch/sparc64/kernel/of_device.c

index c59014886afe4b9c6a63f8c6977ccc88fb742d2f..4ef160755881b61ed52f34c5e25d54dd98ee6483 100644 (file)
@@ -344,6 +344,27 @@ static int __init build_one_resource(struct device_node *parent,
        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 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);
 
-               /* If the immediate parent has no ranges property to apply,
-                * just use a 1<->1 mapping.
-                */
-               if (of_find_property(pp, "ranges", NULL) == NULL) {
+               if (use_1to1_mapping(pp)) {
                        result = of_read_addr(addr, na);
                        goto build_res;
                }
index e427086e3b58049dbdfbe45b1e41007c24d96d44..c15bcdf75c0d242359b296e82c93c3c103349ef9 100644 (file)
@@ -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
         * 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;
 
        /* Similarly for all PCI bridges, if we get this far