summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/of_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/of_device.c')
-rw-r--r--arch/sparc64/kernel/of_device.c71
1 files changed, 46 insertions, 25 deletions
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index f845f150f56..0f616ae3246 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -55,15 +55,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;
-#ifdef CONFIG_SBUS
-struct bus_type sbus_bus_type;
-EXPORT_SYMBOL(sbus_bus_type);
-#endif
+ for (dp = bus_dp->child; dp; dp = dp->sibling) {
+ struct of_device *op = of_find_device_by_node(dp);
+
+ 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);
@@ -169,7 +192,7 @@ static unsigned long of_bus_default_get_flags(const u32 *addr, unsigned long fla
static int of_bus_pci_match(struct device_node *np)
{
- if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
+ if (!strcmp(np->name, "pci")) {
const char *model = of_get_property(np, "model", NULL);
if (model && !strcmp(model, "SUNW,simba"))
@@ -200,7 +223,7 @@ static int of_bus_simba_match(struct device_node *np)
/* Treat PCI busses lacking ranges property just like
* simba.
*/
- if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
+ if (!strcmp(np->name, "pci")) {
if (!of_find_property(np, "ranges", NULL))
return 1;
}
@@ -378,8 +401,7 @@ static int __init build_one_resource(struct device_node *parent,
int na, int ns, int pna)
{
const u32 *ranges;
- unsigned int rlen;
- int rone;
+ int rone, rlen;
ranges = of_get_property(parent, "ranges", &rlen);
if (ranges == NULL || rlen == 0) {
@@ -421,15 +443,24 @@ 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
* it lacks a ranges property, and this will include
* cases like Simba.
*/
- if (!strcmp(pp->type, "pci") || !strcmp(pp->type, "pciex"))
+ if (!strcmp(pp->name, "pci"))
return 0;
return 1;
@@ -714,8 +745,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op,
break;
}
} else {
- if (!strcmp(pp->type, "pci") ||
- !strcmp(pp->type, "pciex")) {
+ if (!strcmp(pp->name, "pci")) {
unsigned int this_orig_irq = irq;
irq = pci_irq_swizzle(dp, pp, irq);
@@ -845,15 +875,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();