[SPARC64]: Use in-kernel PROM tree for EBUS and ISA.

Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index 3125a5b..919a91d 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -285,36 +285,38 @@
 
 static void __init ebus_ranges_init(struct linux_ebus *ebus)
 {
-	int success;
+	struct linux_prom_ebus_ranges *rngs;
+	int len;
 
 	ebus->num_ebus_ranges = 0;
-	success = prom_getproperty(ebus->prom_node, "ranges",
-				   (char *)ebus->ebus_ranges,
-				   sizeof(ebus->ebus_ranges));
-	if (success != -1)
-		ebus->num_ebus_ranges = (success/sizeof(struct linux_prom_ebus_ranges));
+	rngs = of_get_property(ebus->prom_node, "ranges", &len);
+	if (rngs) {
+		memcpy(ebus->ebus_ranges, rngs, len);
+		ebus->num_ebus_ranges =
+			(len / sizeof(struct linux_prom_ebus_ranges));
+	}
 }
 
 static void __init ebus_intmap_init(struct linux_ebus *ebus)
 {
-	int success;
+	struct linux_prom_ebus_intmap *imap;
+	struct linux_prom_ebus_intmask *imask;
+	int len;
 
 	ebus->num_ebus_intmap = 0;
-	success = prom_getproperty(ebus->prom_node, "interrupt-map",
-				   (char *)ebus->ebus_intmap,
-				   sizeof(ebus->ebus_intmap));
-	if (success == -1)
+	imap = of_get_property(ebus->prom_node, "interrupt-map", &len);
+	if (!imap)
 		return;
 
-	ebus->num_ebus_intmap = (success/sizeof(struct linux_prom_ebus_intmap));
+	memcpy(ebus->ebus_intmap, imap, len);
+	ebus->num_ebus_intmap = (len / sizeof(struct linux_prom_ebus_intmap));
 
-	success = prom_getproperty(ebus->prom_node, "interrupt-map-mask",
-				   (char *)&ebus->ebus_intmask,
-				   sizeof(ebus->ebus_intmask));
-	if (success == -1) {
-		prom_printf("%s: can't get interrupt-map-mask\n", __FUNCTION__);
+	imask = of_get_property(ebus->prom_node, "interrupt-map-mask", &len);
+	if (!imask) {
+		prom_printf("EBUS: can't get interrupt-map-mask\n");
 		prom_halt();
 	}
+	memcpy(&ebus->ebus_intmask, imask, sizeof(ebus->ebus_intmask));
 }
 
 int __init ebus_intmap_match(struct linux_ebus *ebus,
@@ -341,19 +343,23 @@
 	return -1;
 }
 
-void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
-			    struct linux_ebus_child *dev, int non_standard_regs)
+void __init fill_ebus_child(struct device_node *dp,
+			    struct linux_prom_registers *preg,
+			    struct linux_ebus_child *dev,
+			    int non_standard_regs)
 {
-	int regs[PROMREG_MAX];
-	int irqs[PROMREG_MAX];
+	int *regs;
+	int *irqs;
 	int i, len;
 
-	dev->prom_node = node;
-	prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
-	printk(" (%s)", dev->prom_name);
+	dev->prom_node = dp;
+	printk(" (%s)", dp->name);
 
-	len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
-	dev->num_addrs = len / sizeof(regs[0]);
+	regs = of_get_property(dp, "reg", &len);
+	if (!regs)
+		dev->num_addrs = 0;
+	else
+		dev->num_addrs = len / sizeof(regs[0]);
 
 	if (non_standard_regs) {
 		/* This is to handle reg properties which are not
@@ -370,21 +376,21 @@
 			int rnum = regs[i];
 			if (rnum >= dev->parent->num_addrs) {
 				prom_printf("UGH: property for %s was %d, need < %d\n",
-					    dev->prom_name, len, dev->parent->num_addrs);
-				panic(__FUNCTION__);
+					    dp->name, len, dev->parent->num_addrs);
+				prom_halt();
 			}
 			dev->resource[i].start = dev->parent->resource[i].start;
 			dev->resource[i].end = dev->parent->resource[i].end;
 			dev->resource[i].flags = IORESOURCE_MEM;
-			dev->resource[i].name = dev->prom_name;
+			dev->resource[i].name = dp->name;
 		}
 	}
 
 	for (i = 0; i < PROMINTR_MAX; i++)
 		dev->irqs[i] = PCI_IRQ_NONE;
 
-	len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
-	if ((len == -1) || (len == 0)) {
+	irqs = of_get_property(dp, "interrupts", &len);
+	if (!irqs) {
 		dev->num_irqs = 0;
 		/*
 		 * Oh, well, some PROMs don't export interrupts
@@ -392,8 +398,8 @@
 		 *
 		 * Be smart about PS/2 keyboard and mouse.
 		 */
-		if (!strcmp(dev->parent->prom_name, "8042")) {
-			if (!strcmp(dev->prom_name, "kb_ps2")) {
+		if (!strcmp(dev->parent->prom_node->name, "8042")) {
+			if (!strcmp(dev->prom_node->name, "kb_ps2")) {
 				dev->num_irqs = 1;
 				dev->irqs[0] = dev->parent->irqs[0];
 			} else {
@@ -423,32 +429,32 @@
 
 static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
 {
-	if (!strcmp(dev->prom_name, "i2c") ||
-	    !strcmp(dev->prom_name, "SUNW,lombus"))
+	if (!strcmp(dev->prom_node->name, "i2c") ||
+	    !strcmp(dev->prom_node->name, "SUNW,lombus"))
 		return 1;
 	return 0;
 }
 
-void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
+void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
 {
-	struct linux_prom_registers regs[PROMREG_MAX];
+	struct linux_prom_registers *regs;
 	struct linux_ebus_child *child;
-	int irqs[PROMINTR_MAX];
+	int *irqs;
 	int i, n, len;
 
-	dev->prom_node = node;
-	prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
-	printk(" [%s", dev->prom_name);
+	dev->prom_node = dp;
 
-	len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
-	if (len == -1) {
+	printk(" [%s", dp->name);
+
+	regs = of_get_property(dp, "reg", &len);
+	if (!regs) {
 		dev->num_addrs = 0;
 		goto probe_interrupts;
 	}
 
 	if (len % sizeof(struct linux_prom_registers)) {
 		prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
-			    dev->prom_name, len,
+			    dev->prom_node->name, len,
 			    (int)sizeof(struct linux_prom_registers));
 		prom_halt();
 	}
@@ -466,7 +472,7 @@
 		dev->resource[i].end    =
 			(dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
 		dev->resource[i].flags  = IORESOURCE_MEM;
-		dev->resource[i].name   = dev->prom_name;
+		dev->resource[i].name   = dev->prom_node->name;
 		request_resource(&dev->bus->self->resource[n],
 				 &dev->resource[i]);
 	}
@@ -475,8 +481,8 @@
 	for (i = 0; i < PROMINTR_MAX; i++)
 		dev->irqs[i] = PCI_IRQ_NONE;
 
-	len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
-	if ((len == -1) || (len == 0)) {
+	irqs = of_get_property(dp, "interrupts", &len);
+	if (!irqs) {
 		dev->num_irqs = 0;
 	} else {
 		dev->num_irqs = len / sizeof(irqs[0]);
@@ -497,7 +503,8 @@
 		}
 	}
 
-	if ((node = prom_getchild(node))) {
+	dp = dp->child;
+	if (dp) {
 		printk(" ->");
 		dev->children = ebus_alloc(sizeof(struct linux_ebus_child));
 
@@ -505,18 +512,18 @@
 		child->next = NULL;
 		child->parent = dev;
 		child->bus = dev->bus;
-		fill_ebus_child(node, &regs[0],
-				child, child_regs_nonstandard(dev));
+		fill_ebus_child(dp, regs, child,
+				child_regs_nonstandard(dev));
 
-		while ((node = prom_getsibling(node)) != 0) {
+		while ((dp = dp->sibling) != NULL) {
 			child->next = ebus_alloc(sizeof(struct linux_ebus_child));
 
 			child = child->next;
 			child->next = NULL;
 			child->parent = dev;
 			child->bus = dev->bus;
-			fill_ebus_child(node, &regs[0],
-					child, child_regs_nonstandard(dev));
+			fill_ebus_child(dp, regs, child,
+					child_regs_nonstandard(dev));
 		}
 	}
 	printk("]");
@@ -543,7 +550,8 @@
 	struct linux_ebus *ebus;
 	struct pci_dev *pdev;
 	struct pcidev_cookie *cookie;
-	int nd, ebusnd, is_rio;
+	struct device_node *dp;
+	int is_rio;
 	int num_ebus = 0;
 
 	pdev = find_next_ebus(NULL, &is_rio);
@@ -553,20 +561,22 @@
 	}
 
 	cookie = pdev->sysdata;
-	ebusnd = cookie->prom_node->node;
+	dp = cookie->prom_node;
 
 	ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
 	ebus->next = NULL;
 	ebus->is_rio = is_rio;
 
-	while (ebusnd) {
+	while (dp) {
+		struct device_node *child;
+
 		/* SUNW,pci-qfe uses four empty ebuses on it.
 		   I think we should not consider them here,
 		   as they have half of the properties this
 		   code expects and once we do PCI hot-plug,
 		   we'd have to tweak with the ebus_chain
 		   in the runtime after initialization. -jj */
-		if (!prom_getchild (ebusnd)) {
+		if (!dp->child) {
 			pdev = find_next_ebus(pdev, &is_rio);
 			if (!pdev) {
 				if (ebus == ebus_chain) {
@@ -578,22 +588,21 @@
 			}
 			ebus->is_rio = is_rio;
 			cookie = pdev->sysdata;
-			ebusnd = cookie->prom_node->node;
+			dp = cookie->prom_node;
 			continue;
 		}
 		printk("ebus%d:", num_ebus);
 
-		prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name));
 		ebus->index = num_ebus;
-		ebus->prom_node = ebusnd;
+		ebus->prom_node = dp;
 		ebus->self = pdev;
 		ebus->parent = pbm = cookie->pbm;
 
 		ebus_ranges_init(ebus);
 		ebus_intmap_init(ebus);
 
-		nd = prom_getchild(ebusnd);
-		if (!nd)
+		child = dp->child;
+		if (!child)
 			goto next_ebus;
 
 		ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));
@@ -602,16 +611,16 @@
 		dev->next = NULL;
 		dev->children = NULL;
 		dev->bus = ebus;
-		fill_ebus_device(nd, dev);
+		fill_ebus_device(child, dev);
 
-		while ((nd = prom_getsibling(nd)) != 0) {
+		while ((child = child->sibling) != NULL) {
 			dev->next = ebus_alloc(sizeof(struct linux_ebus_device));
 
 			dev = dev->next;
 			dev->next = NULL;
 			dev->children = NULL;
 			dev->bus = ebus;
-			fill_ebus_device(nd, dev);
+			fill_ebus_device(child, dev);
 		}
 
 	next_ebus:
@@ -622,7 +631,7 @@
 			break;
 
 		cookie = pdev->sysdata;
-		ebusnd = cookie->prom_node->node;
+		dp = cookie->prom_node;
 
 		ebus->next = ebus_alloc(sizeof(struct linux_ebus));
 		ebus = ebus->next;