]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/sparc/kernel/of_device.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6-omap-h63xx.git] / arch / sparc / kernel / of_device.c
index f58c537446a87547bafbbf396a42a65b2875c924..0837bd52e28f454e2f4fc18aa003970caf3a455b 100644 (file)
@@ -29,15 +29,38 @@ struct of_device *of_find_device_by_node(struct device_node *dp)
 }
 EXPORT_SYMBOL(of_find_device_by_node);
 
-#ifdef CONFIG_PCI
-struct bus_type ebus_bus_type;
-EXPORT_SYMBOL(ebus_bus_type);
-#endif
+unsigned int irq_of_parse_and_map(struct device_node *node, int index)
+{
+       struct of_device *op = of_find_device_by_node(node);
+
+       if (!op || index >= op->num_irqs)
+               return 0;
+
+       return op->irqs[index];
+}
+EXPORT_SYMBOL(irq_of_parse_and_map);
+
+/* Take the archdata values for IOMMU, STC, and HOSTDATA found in
+ * BUS and propagate to all child of_device objects.
+ */
+void of_propagate_archdata(struct of_device *bus)
+{
+       struct dev_archdata *bus_sd = &bus->dev.archdata;
+       struct device_node *bus_dp = bus->node;
+       struct device_node *dp;
+
+       for (dp = bus_dp->child; dp; dp = dp->sibling) {
+               struct of_device *op = of_find_device_by_node(dp);
 
-#ifdef CONFIG_SBUS
-struct bus_type sbus_bus_type;
-EXPORT_SYMBOL(sbus_bus_type);
-#endif
+               op->dev.archdata.iommu = bus_sd->iommu;
+               op->dev.archdata.stc = bus_sd->stc;
+               op->dev.archdata.host_controller = bus_sd->host_controller;
+               op->dev.archdata.numa_node = bus_sd->numa_node;
+
+               if (dp->child)
+                       of_propagate_archdata(op);
+       }
+}
 
 struct bus_type of_platform_bus_type;
 EXPORT_SYMBOL(of_platform_bus_type);
@@ -327,6 +350,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,
@@ -373,10 +417,7 @@ static void __init build_device_resources(struct of_device *op,
 
                flags = bus->get_flags(reg, 0);
 
-               /* 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;
                }
@@ -565,15 +606,6 @@ static int __init of_bus_driver_init(void)
        int err;
 
        err = of_bus_type_init(&of_platform_bus_type, "of");
-#ifdef CONFIG_PCI
-       if (!err)
-               err = of_bus_type_init(&ebus_bus_type, "ebus");
-#endif
-#ifdef CONFIG_SBUS
-       if (!err)
-               err = of_bus_type_init(&sbus_bus_type, "sbus");
-#endif
-
        if (!err)
                scan_of_devices();