[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/auxio.c b/arch/sparc64/kernel/auxio.c
index 8852c20..db36b66 100644
--- a/arch/sparc64/kernel/auxio.c
+++ b/arch/sparc64/kernel/auxio.c
@@ -136,7 +136,7 @@
 
 		for_each_ebus(ebus) {
 			for_each_ebusdev(edev, ebus) {
-				if (!strcmp(edev->prom_name, "auxio"))
+				if (!strcmp(edev->prom_node->name, "auxio"))
 					goto ebus_done;
 			}
 		}
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;
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
index ae02c38..8c8c5a4 100644
--- a/arch/sparc64/kernel/isa.c
+++ b/arch/sparc64/kernel/isa.c
@@ -15,23 +15,19 @@
 static void __init report_dev(struct sparc_isa_device *isa_dev, int child)
 {
 	if (child)
-		printk(" (%s)", isa_dev->prom_name);
+		printk(" (%s)", isa_dev->prom_node->name);
 	else
-		printk(" [%s", isa_dev->prom_name);
+		printk(" [%s", isa_dev->prom_node->name);
 }
 
-static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev,
-					struct linux_prom_registers *pregs,
-					int pregs_size)
+static struct linux_prom_registers * __init
+isa_dev_get_resource(struct sparc_isa_device *isa_dev)
 {
+	struct linux_prom_registers *pregs;
 	unsigned long base, len;
 	int prop_len;
 
-	prop_len = prom_getproperty(isa_dev->prom_node, "reg",
-				    (char *) pregs, pregs_size);
-
-	if (prop_len <= 0)
-		return;
+	pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len);
 
 	/* Only the first one is interesting. */
 	len = pregs[0].reg_size;
@@ -42,10 +38,12 @@
 	isa_dev->resource.start = base;
 	isa_dev->resource.end   = (base + len - 1UL);
 	isa_dev->resource.flags = IORESOURCE_IO;
-	isa_dev->resource.name  = isa_dev->prom_name;
+	isa_dev->resource.name  = isa_dev->prom_node->name;
 
 	request_resource(&isa_dev->bus->parent->io_space,
 			 &isa_dev->resource);
+
+	return pregs;
 }
 
 /* I can't believe they didn't put a real INO in the isa device
@@ -98,8 +96,8 @@
 {
 	int irq_prop;
 
-	irq_prop = prom_getintdefault(isa_dev->prom_node,
-				      "interrupts", -1);
+	irq_prop = of_getintprop_default(isa_dev->prom_node,
+					 "interrupts", -1);
 	if (irq_prop <= 0) {
 		goto no_irq;
 	} else {
@@ -141,16 +139,15 @@
 
 static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
 {
-	int node = prom_getchild(parent_isa_dev->prom_node);
+	struct device_node *dp = parent_isa_dev->prom_node->child;
 
-	if (node == 0)
+	if (!dp)
 		return;
 
 	printk(" ->");
-	while (node != 0) {
-		struct linux_prom_registers regs[PROMREG_MAX];
+	while (dp) {
+		struct linux_prom_registers *regs;
 		struct sparc_isa_device *isa_dev;
-		int prop_len;
 
 		isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
 		if (!isa_dev) {
@@ -165,40 +162,24 @@
 		parent_isa_dev->child = isa_dev;
 
 		isa_dev->bus = parent_isa_dev->bus;
-		isa_dev->prom_node = node;
-		prop_len = prom_getproperty(node, "name",
-					    (char *) isa_dev->prom_name,
-					    sizeof(isa_dev->prom_name));
-		if (prop_len <= 0) {
-			fatal_err("cannot get child isa_dev OBP node name");
-			prom_halt();
-		}
+		isa_dev->prom_node = dp;
 
-		prop_len = prom_getproperty(node, "compatible",
-					    (char *) isa_dev->compatible,
-					    sizeof(isa_dev->compatible));
-
-		/* Not having this is OK. */
-		if (prop_len <= 0)
-			isa_dev->compatible[0] = '\0';
-
-		isa_dev_get_resource(isa_dev, regs, sizeof(regs));
+		regs = isa_dev_get_resource(isa_dev);
 		isa_dev_get_irq(isa_dev, regs);
 
 		report_dev(isa_dev, 1);
 
-		node = prom_getsibling(node);
+		dp = dp->sibling;
 	}
 }
 
 static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
 {
-	int node = prom_getchild(isa_br->prom_node);
+	struct device_node *dp = isa_br->prom_node->child;
 
-	while (node != 0) {
-		struct linux_prom_registers regs[PROMREG_MAX];
+	while (dp) {
+		struct linux_prom_registers *regs;
 		struct sparc_isa_device *isa_dev;
-		int prop_len;
 
 		isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
 		if (!isa_dev) {
@@ -222,24 +203,9 @@
 		}
 
 		isa_dev->bus = isa_br;
-		isa_dev->prom_node = node;
-		prop_len = prom_getproperty(node, "name",
-					    (char *) isa_dev->prom_name,
-					    sizeof(isa_dev->prom_name));
-		if (prop_len <= 0) {
-			fatal_err("cannot get isa_dev OBP node name");
-			prom_halt();
-		}
+		isa_dev->prom_node = dp;
 
-		prop_len = prom_getproperty(node, "compatible",
-					    (char *) isa_dev->compatible,
-					    sizeof(isa_dev->compatible));
-
-		/* Not having this is OK. */
-		if (prop_len <= 0)
-			isa_dev->compatible[0] = '\0';
-
-		isa_dev_get_resource(isa_dev, regs, sizeof(regs));
+		regs = isa_dev_get_resource(isa_dev);
 		isa_dev_get_irq(isa_dev, regs);
 
 		report_dev(isa_dev, 0);
@@ -248,10 +214,40 @@
 
 		printk("]");
 
-		node = prom_getsibling(node);
+		dp = dp->sibling;
 	}
 }
 
+static void __init get_bridge_props(struct sparc_isa_bridge *isa_br)
+{
+	struct device_node *dp = isa_br->prom_node;
+	void *pval;
+	int len;
+
+	pval = of_get_property(dp, "ranges", &len);
+	if (pval) {
+		memcpy(isa_br->isa_ranges, pval, len);
+		isa_br->num_isa_ranges =
+			len / sizeof(struct linux_prom_isa_ranges);
+	} else {
+		isa_br->num_isa_ranges = 0;
+	}
+
+	pval = of_get_property(dp, "interrupt-map", &len);
+	if (pval) {
+		memcpy(isa_br->isa_intmap, pval, len);
+		isa_br->num_isa_intmap =
+			(len / sizeof(struct linux_prom_isa_intmap));
+	} else {
+		isa_br->num_isa_intmap = 0;
+	}
+
+	pval = of_get_property(dp, "interrupt-map-mask", &len);
+	if (pval)
+		memcpy(&isa_br->isa_intmask, pval,
+		       sizeof(isa_br->isa_intmask));
+}
+
 void __init isa_init(void)
 {
 	struct pci_dev *pdev;
@@ -266,7 +262,6 @@
 		struct pcidev_cookie *pdev_cookie;
 		struct pci_pbm_info *pbm;
 		struct sparc_isa_bridge *isa_br;
-		int prop_len;
 
 		pdev_cookie = pdev->sysdata;
 		if (!pdev_cookie) {
@@ -291,34 +286,9 @@
 		isa_br->parent = pbm;
 		isa_br->self = pdev;
 		isa_br->index = index++;
-		isa_br->prom_node = pdev_cookie->prom_node->node;
-		strncpy(isa_br->prom_name, pdev_cookie->prom_node->name,
-			sizeof(isa_br->prom_name));
+		isa_br->prom_node = pdev_cookie->prom_node;
 
-		prop_len = prom_getproperty(isa_br->prom_node,
-					    "ranges",
-					    (char *) isa_br->isa_ranges,
-					    sizeof(isa_br->isa_ranges));
-		if (prop_len <= 0)
-			isa_br->num_isa_ranges = 0;
-		else
-			isa_br->num_isa_ranges =
-				(prop_len / sizeof(struct linux_prom_isa_ranges));
-
-		prop_len = prom_getproperty(isa_br->prom_node,
-					    "interrupt-map",
-					    (char *) isa_br->isa_intmap,
-					    sizeof(isa_br->isa_intmap));
-		if (prop_len <= 0)
-			isa_br->num_isa_intmap = 0;
-		else
-			isa_br->num_isa_intmap =
-				(prop_len / sizeof(struct linux_prom_isa_intmap));
-
-		prop_len = prom_getproperty(isa_br->prom_node,
-					    "interrupt-map-mask",
-					    (char *) &(isa_br->isa_intmask),
-					    sizeof(isa_br->isa_intmask));
+		get_bridge_props(isa_br);
 
 		printk("isa%d:", isa_br->index);
 
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 30bcaf5..75159a7 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -105,24 +105,24 @@
 	return 0;
 }
 
-static int __init has_button_interrupt(unsigned int irq, int prom_node)
+static int __init has_button_interrupt(unsigned int irq, struct device_node *dp)
 {
 	if (irq == PCI_IRQ_NONE)
 		return 0;
-	if (!prom_node_has_property(prom_node, "button"))
+	if (!of_find_property(dp, "button", NULL))
 		return 0;
 
 	return 1;
 }
 
-static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, int *prom_node_p)
+static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, struct device_node **prom_node_p)
 {
 	struct linux_ebus *ebus;
 	struct linux_ebus_device *edev;
 
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, "power")) {
+			if (!strcmp(edev->prom_node->name, "power")) {
 				*resp = &edev->resource[0];
 				*irq_p = edev->irqs[0];
 				*prom_node_p = edev->prom_node;
@@ -133,14 +133,14 @@
 	return -ENODEV;
 }
 
-static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, int *prom_node_p)
+static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, struct device_node **prom_node_p)
 {
 	struct sparc_isa_bridge *isa_bus;
 	struct sparc_isa_device *isa_dev;
 
 	for_each_isa(isa_bus) {
 		for_each_isadev(isa_dev, isa_bus) {
-			if (!strcmp(isa_dev->prom_name, "power")) {
+			if (!strcmp(isa_dev->prom_node->name, "power")) {
 				*resp = &isa_dev->resource;
 				*irq_p = isa_dev->irq;
 				*prom_node_p = isa_dev->prom_node;
@@ -155,17 +155,17 @@
 {
 	struct resource *res = NULL;
 	unsigned int irq;
-	int prom_node;
+	struct device_node *dp;
 	static int invoked;
 
 	if (invoked)
 		return;
 	invoked = 1;
 
-	if (!power_probe_ebus(&res, &irq, &prom_node))
+	if (!power_probe_ebus(&res, &irq, &dp))
 		goto found;
 
-	if (!power_probe_isa(&res, &irq, &prom_node))
+	if (!power_probe_isa(&res, &irq, &dp))
 		goto found;
 
 	return;
@@ -174,7 +174,7 @@
 	power_reg = ioremap(res->start, 0x4);
 	printk("power: Control reg at %p ... ", power_reg);
 	poweroff_method = machine_halt;  /* able to use the standard halt */
-	if (has_button_interrupt(irq, prom_node)) {
+	if (has_button_interrupt(irq, dp)) {
 		if (kernel_thread(powerd, NULL, CLONE_FS) < 0) {
 			printk("Failed to start power daemon.\n");
 			return;
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index fb112c3..7809100 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -63,6 +63,7 @@
 
 	return np;
 }
+EXPORT_SYMBOL(of_find_node_by_path);
 
 struct device_node *of_find_node_by_phandle(phandle handle)
 {
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index aa5438a..d072b86 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -756,24 +756,200 @@
 	return -EOPNOTSUPP;
 }
 
-void __init clock_probe(void)
+static int __init clock_model_matches(char *model)
+{
+	if (strcmp(model, "mk48t02") &&
+	    strcmp(model, "mk48t08") &&
+	    strcmp(model, "mk48t59") &&
+	    strcmp(model, "m5819") &&
+	    strcmp(model, "m5819p") &&
+	    strcmp(model, "m5823") &&
+	    strcmp(model, "ds1287"))
+		return 0;
+
+	return 1;
+}
+
+static void __init __clock_assign_common(void __iomem *addr, char *model)
+{
+	if (model[5] == '0' && model[6] == '2') {
+		mstk48t02_regs = addr;
+	} else if(model[5] == '0' && model[6] == '8') {
+		mstk48t08_regs = addr;
+		mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
+	} else {
+		mstk48t59_regs = addr;
+		mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
+	}
+}
+
+static void __init clock_assign_clk_reg(struct linux_prom_registers *clk_reg,
+					char *model)
+{
+	unsigned long addr;
+
+	addr = ((unsigned long) clk_reg[0].phys_addr |
+		(((unsigned long) clk_reg[0].which_io) << 32UL));
+
+	__clock_assign_common((void __iomem *) addr, model);
+}
+
+static int __init clock_probe_central(void)
 {
 	struct linux_prom_registers clk_reg[2];
-	char model[128];
-	int node, busnd = -1, err;
-	unsigned long flags;
-	struct linux_central *cbus;
+	char model[64];
+	int node;
+
+	if (!central_bus)
+		return 0;
+
+	/* Get Central FHC's prom node.  */
+	node = central_bus->child->prom_node;
+
+	/* Then get the first child device below it.  */
+	node = prom_getchild(node);
+
+	while (node) {
+		prom_getstring(node, "model", model, sizeof(model));
+		if (!clock_model_matches(model))
+			goto next_sibling;
+
+		prom_getproperty(node, "reg", (char *)clk_reg,
+				 sizeof(clk_reg));
+
+		apply_fhc_ranges(central_bus->child, clk_reg, 1);
+		apply_central_ranges(central_bus, clk_reg, 1);
+
+		clock_assign_clk_reg(clk_reg, model);
+		return 1;
+
+	next_sibling:
+		node = prom_getsibling(node);
+	}
+
+	return 0;
+}
+
 #ifdef CONFIG_PCI
-	struct linux_ebus *ebus = NULL;
-	struct sparc_isa_bridge *isa_br = NULL;
+static void __init clock_isa_ebus_assign_regs(struct resource *res, char *model)
+{
+	if (!strcmp(model, "ds1287") ||
+	    !strcmp(model, "m5819") ||
+	    !strcmp(model, "m5819p") ||
+	    !strcmp(model, "m5823")) {
+		ds1287_regs = res->start;
+	} else {
+		mstk48t59_regs = (void __iomem *) res->start;
+		mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
+	}
+}
+
+static int __init clock_probe_one_ebus_dev(struct linux_ebus_device *edev)
+{
+	struct device_node *dp = edev->prom_node;
+	char *model;
+
+	model = of_get_property(dp, "model", NULL);
+	if (!clock_model_matches(model))
+		return 0;
+
+	clock_isa_ebus_assign_regs(&edev->resource[0], model);
+
+	return 1;
+}
+
+static int __init clock_probe_ebus(void)
+{
+	struct linux_ebus *ebus;
+
+	for_each_ebus(ebus) {
+		struct linux_ebus_device *edev;
+
+		for_each_ebusdev(edev, ebus) {
+			if (clock_probe_one_ebus_dev(edev))
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int __init clock_probe_one_isa_dev(struct sparc_isa_device *idev)
+{
+	struct device_node *dp = idev->prom_node;
+	char *model;
+
+	model = of_get_property(dp, "model", NULL);
+	if (!clock_model_matches(model))
+		return 0;
+
+	clock_isa_ebus_assign_regs(&idev->resource, model);
+
+	return 1;
+}
+
+static int __init clock_probe_isa(void)
+{
+	struct sparc_isa_bridge *isa_br;
+
+	for_each_isa(isa_br) {
+		struct sparc_isa_device *isa_dev;
+
+		for_each_isadev(isa_dev, isa_br) {
+			if (clock_probe_one_isa_dev(isa_dev))
+				return 1;
+		}
+	}
+
+	return 0;
+}
+#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_SBUS
+static int __init clock_probe_one_sbus_dev(struct sbus_bus *sbus, struct sbus_dev *sdev)
+{
+	struct resource *res;
+	char model[64];
+	void __iomem *addr;
+
+	prom_getstring(sdev->prom_node, "model", model, sizeof(model));
+	if (!clock_model_matches(model))
+		return 0;
+
+	res = &sdev->resource[0];
+	addr = sbus_ioremap(res, 0, 0x800UL, "eeprom");
+
+	__clock_assign_common(addr, model);
+
+	return 1;
+}
+
+static int __init clock_probe_sbus(void)
+{
+	struct sbus_bus *sbus;
+
+	for_each_sbus(sbus) {
+		struct sbus_dev *sdev;
+
+		for_each_sbusdev(sdev, sbus) {
+			if (clock_probe_one_sbus_dev(sbus, sdev))
+				return 1;
+		}
+	}
+
+	return 0;
+}
 #endif
+
+void __init clock_probe(void)
+{
 	static int invoked;
+	unsigned long flags;
 
 	if (invoked)
 		return;
 	invoked = 1;
 
-
 	if (this_is_starfire) {
 		xtime.tv_sec = starfire_get_time();
 		xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
@@ -789,182 +965,26 @@
 		return;
 	}
 
-	local_irq_save(flags);
-
-	cbus = central_bus;
-	if (cbus != NULL)
-		busnd = central_bus->child->prom_node;
-
 	/* Check FHC Central then EBUSs then ISA bridges then SBUSs.
 	 * That way we handle the presence of multiple properly.
 	 *
 	 * As a special case, machines with Central must provide the
 	 * timer chip there.
 	 */
+	if (!clock_probe_central() &&
 #ifdef CONFIG_PCI
-	if (ebus_chain != NULL) {
-		ebus = ebus_chain;
-		if (busnd == -1)
-			busnd = ebus->prom_node;
-	}
-	if (isa_chain != NULL) {
-		isa_br = isa_chain;
-		if (busnd == -1)
-			busnd = isa_br->prom_node;
-	}
+	    !clock_probe_ebus() &&
+	    !clock_probe_isa() &&
 #endif
-	if (sbus_root != NULL && busnd == -1)
-		busnd = sbus_root->prom_node;
-
-	if (busnd == -1) {
-		prom_printf("clock_probe: problem, cannot find bus to search.\n");
-		prom_halt();
+#ifdef CONFIG_SBUS
+	    !clock_probe_sbus()
+#endif
+		) {
+		printk(KERN_WARNING "No clock chip found.\n");
+		return;
 	}
 
-	node = prom_getchild(busnd);
-
-	while (1) {
-		if (!node)
-			model[0] = 0;
-		else
-			prom_getstring(node, "model", model, sizeof(model));
-		if (strcmp(model, "mk48t02") &&
-		    strcmp(model, "mk48t08") &&
-		    strcmp(model, "mk48t59") &&
-		    strcmp(model, "m5819") &&
-		    strcmp(model, "m5819p") &&
-		    strcmp(model, "m5823") &&
-		    strcmp(model, "ds1287")) {
-			if (cbus != NULL) {
-				prom_printf("clock_probe: Central bus lacks timer chip.\n");
-				prom_halt();
-			}
-
-		   	if (node != 0)
-				node = prom_getsibling(node);
-#ifdef CONFIG_PCI
-			while ((node == 0) && ebus != NULL) {
-				ebus = ebus->next;
-				if (ebus != NULL) {
-					busnd = ebus->prom_node;
-					node = prom_getchild(busnd);
-				}
-			}
-			while ((node == 0) && isa_br != NULL) {
-				isa_br = isa_br->next;
-				if (isa_br != NULL) {
-					busnd = isa_br->prom_node;
-					node = prom_getchild(busnd);
-				}
-			}
-#endif
-			if (node == 0) {
-				prom_printf("clock_probe: Cannot find timer chip\n");
-				prom_halt();
-			}
-			continue;
-		}
-
-		err = prom_getproperty(node, "reg", (char *)clk_reg,
-				       sizeof(clk_reg));
-		if(err == -1) {
-			prom_printf("clock_probe: Cannot get Mostek reg property\n");
-			prom_halt();
-		}
-
-		if (cbus != NULL) {
-			apply_fhc_ranges(central_bus->child, clk_reg, 1);
-			apply_central_ranges(central_bus, clk_reg, 1);
-		}
-#ifdef CONFIG_PCI
-		else if (ebus != NULL) {
-			struct linux_ebus_device *edev;
-
-			for_each_ebusdev(edev, ebus)
-				if (edev->prom_node == node)
-					break;
-			if (edev == NULL) {
-				if (isa_chain != NULL)
-					goto try_isa_clock;
-				prom_printf("%s: Mostek not probed by EBUS\n",
-					    __FUNCTION__);
-				prom_halt();
-			}
-
-			if (!strcmp(model, "ds1287") ||
-			    !strcmp(model, "m5819") ||
-			    !strcmp(model, "m5819p") ||
-			    !strcmp(model, "m5823")) {
-				ds1287_regs = edev->resource[0].start;
-			} else {
-				mstk48t59_regs = (void __iomem *)
-					edev->resource[0].start;
-				mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
-			}
-			break;
-		}
-		else if (isa_br != NULL) {
-			struct sparc_isa_device *isadev;
-
-try_isa_clock:
-			for_each_isadev(isadev, isa_br)
-				if (isadev->prom_node == node)
-					break;
-			if (isadev == NULL) {
-				prom_printf("%s: Mostek not probed by ISA\n");
-				prom_halt();
-			}
-			if (!strcmp(model, "ds1287") ||
-			    !strcmp(model, "m5819") ||
-			    !strcmp(model, "m5819p") ||
-			    !strcmp(model, "m5823")) {
-				ds1287_regs = isadev->resource.start;
-			} else {
-				mstk48t59_regs = (void __iomem *)
-					isadev->resource.start;
-				mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
-			}
-			break;
-		}
-#endif
-		else {
-			if (sbus_root->num_sbus_ranges) {
-				int nranges = sbus_root->num_sbus_ranges;
-				int rngc;
-
-				for (rngc = 0; rngc < nranges; rngc++)
-					if (clk_reg[0].which_io ==
-					    sbus_root->sbus_ranges[rngc].ot_child_space)
-						break;
-				if (rngc == nranges) {
-					prom_printf("clock_probe: Cannot find ranges for "
-						    "clock regs.\n");
-					prom_halt();
-				}
-				clk_reg[0].which_io =
-					sbus_root->sbus_ranges[rngc].ot_parent_space;
-				clk_reg[0].phys_addr +=
-					sbus_root->sbus_ranges[rngc].ot_parent_base;
-			}
-		}
-
-		if(model[5] == '0' && model[6] == '2') {
-			mstk48t02_regs = (void __iomem *)
-				(((u64)clk_reg[0].phys_addr) |
-				 (((u64)clk_reg[0].which_io)<<32UL));
-		} else if(model[5] == '0' && model[6] == '8') {
-			mstk48t08_regs = (void __iomem *)
-				(((u64)clk_reg[0].phys_addr) |
-				 (((u64)clk_reg[0].which_io)<<32UL));
-			mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
-		} else {
-			mstk48t59_regs = (void __iomem *)
-				(((u64)clk_reg[0].phys_addr) |
-				 (((u64)clk_reg[0].which_io)<<32UL));
-			mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
-		}
-		break;
-	}
+	local_irq_save(flags);
 
 	if (mstk48t02_regs != NULL) {
 		/* Report a low battery voltage condition. */
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index f6686fc..0897b0c 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -928,7 +928,7 @@
 #ifdef __sparc__
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
-			if(strcmp(edev->prom_name, "rtc") == 0) {
+			if(strcmp(edev->prom_node->name, "rtc") == 0) {
 				rtc_port = edev->resource[0].start;
 				rtc_irq = edev->irqs[0];
 				goto found;
@@ -938,7 +938,7 @@
 #ifdef __sparc_v9__
 	for_each_isa(isa_br) {
 		for_each_isadev(isa_dev, isa_br) {
-			if (strcmp(isa_dev->prom_name, "rtc") == 0) {
+			if (strcmp(isa_dev->prom_node->name, "rtc") == 0) {
 				rtc_port = isa_dev->resource.start;
 				rtc_irq = isa_dev->irq;
 				goto found;
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index f0fd2c4..ed95dc9 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -199,7 +199,7 @@
 
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, "beep")) {
+			if (!strcmp(edev->prom_node->name, "beep")) {
 				beep_name = "Sparc EBUS Speaker";
 				beep_event = ebus_spkr_event;
 				beep_iobase = edev->resource[0].start;
@@ -213,7 +213,7 @@
 			/* A hack, the beep device's base lives in
 			 * the DMA isa node.
 			 */
-			if (!strcmp(isa_dev->prom_name, "dma")) {
+			if (!strcmp(isa_dev->prom_node->name, "dma")) {
 				beep_name = "Sparc ISA Speaker";
 				beep_event = isa_spkr_event,
 				beep_iobase = isa_dev->resource.start;
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h
index ed9446f..6d66351 100644
--- a/drivers/input/serio/i8042-sparcio.h
+++ b/drivers/input/serio/i8042-sparcio.h
@@ -74,7 +74,7 @@
 
 		for_each_ebus(ebus) {
 			for_each_ebusdev(edev, ebus) {
-				if (!strcmp(edev->prom_name, "8042"))
+				if (!strcmp(edev->prom_node->name, "8042"))
 					goto edev_found;
 			}
 		}
@@ -82,14 +82,14 @@
 
 	edev_found:
 		for_each_edevchild(edev, child) {
-			if (!strcmp(child->prom_name, OBP_PS2KBD_NAME1) ||
-			    !strcmp(child->prom_name, OBP_PS2KBD_NAME2)) {
+			if (!strcmp(child->prom_node->name, OBP_PS2KBD_NAME1) ||
+			    !strcmp(child->prom_node->name, OBP_PS2KBD_NAME2)) {
 				i8042_kbd_irq = child->irqs[0];
 				kbd_iobase =
 					ioremap(child->resource[0].start, 8);
 			}
-			if (!strcmp(child->prom_name, OBP_PS2MS_NAME1) ||
-			    !strcmp(child->prom_name, OBP_PS2MS_NAME2))
+			if (!strcmp(child->prom_node->name, OBP_PS2MS_NAME1) ||
+			    !strcmp(child->prom_node->name, OBP_PS2MS_NAME2))
 				i8042_aux_irq = child->irqs[0];
 		}
 		if (i8042_kbd_irq == -1 ||
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
index d89f83f..1cc706e 100644
--- a/drivers/sbus/char/bbc_envctrl.c
+++ b/drivers/sbus/char/bbc_envctrl.c
@@ -575,9 +575,9 @@
 	int devidx = 0;
 
 	while ((echild = bbc_i2c_getdev(devidx++)) != NULL) {
-		if (!strcmp(echild->prom_name, "temperature"))
+		if (!strcmp(echild->prom_node->name, "temperature"))
 			attach_one_temp(echild, temp_index++);
-		if (!strcmp(echild->prom_name, "fan-control"))
+		if (!strcmp(echild->prom_node->name, "fan-control"))
 			attach_one_fan(echild, fan_index++);
 	}
 	if (temp_index != 0 && fan_index != 0) {
diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c
index 3e156e0..7363437 100644
--- a/drivers/sbus/char/bbc_i2c.c
+++ b/drivers/sbus/char/bbc_i2c.c
@@ -423,7 +423,7 @@
 
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, "bbc"))
+			if (!strcmp(edev->prom_node->name, "bbc"))
 				return 1;
 		}
 	}
@@ -446,7 +446,7 @@
 
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, "i2c")) {
+			if (!strcmp(edev->prom_node->name, "i2c")) {
 				if (!attach_one_i2c(edev, index))
 					index++;
 			}
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index c3a51d1..d92bc88 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -184,7 +184,7 @@
 
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, D7S_OBPNAME))
+			if (!strcmp(edev->prom_node->name, D7S_OBPNAME))
 				goto ebus_done;
 		}
 	}
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index 19e8edd..cf97e9e 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -768,16 +768,14 @@
  *                       decoding tables, monitor type, optional properties.
  * Return: None.
  */
-static void envctrl_init_adc(struct i2c_child_t *pchild, int node)
+static void envctrl_init_adc(struct i2c_child_t *pchild, struct device_node *dp)
 {
-	char chnls_desc[CHANNEL_DESC_SZ];
 	int i = 0, len;
-	char *pos = chnls_desc;
+	char *pos;
+	unsigned int *pval;
 
 	/* Firmware describe channels into a stream separated by a '\0'. */
-	len = prom_getproperty(node, "channels-description", chnls_desc,
-			       CHANNEL_DESC_SZ);
-	chnls_desc[CHANNEL_DESC_SZ - 1] = '\0';
+	pos = of_get_property(dp, "channels-description", &len);
 
 	while (len > 0) {
 		int l = strlen(pos) + 1;
@@ -787,10 +785,13 @@
 	}
 
 	/* Get optional properties. */
-        len = prom_getproperty(node, "warning-temp", (char *)&warning_temperature,
-			       sizeof(warning_temperature));
-        len = prom_getproperty(node, "shutdown-temp", (char *)&shutdown_temperature,
-			       sizeof(shutdown_temperature));
+	pval = of_get_property(dp, "warning-temp", NULL);
+	if (pval)
+		warning_temperature = *pval;
+
+	pval = of_get_property(dp, "shutdown-temp", NULL);
+	if (pval)
+		shutdown_temperature = *pval;
 }
 
 /* Function Description: Initialize child device monitoring fan status.
@@ -864,21 +865,18 @@
 static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child,
 				   struct i2c_child_t *pchild)
 {
-	int node, len, i, tbls_size = 0;
-
-	node = edev_child->prom_node;
+	int len, i, tbls_size = 0;
+	struct device_node *dp = edev_child->prom_node;
+	void *pval;
 
 	/* Get device address. */
-	len = prom_getproperty(node, "reg",
-			       (char *) &(pchild->addr),
-			       sizeof(pchild->addr));
+	pval = of_get_property(dp, "reg", &len);
+	memcpy(&pchild->addr, pval, len);
 
 	/* Get tables property.  Read firmware temperature tables. */
-	len = prom_getproperty(node, "translation",
-			       (char *) pchild->tblprop_array,
-			       (PCF8584_MAX_CHANNELS *
-				sizeof(struct pcf8584_tblprop)));
-	if (len > 0) {
+	pval = of_get_property(dp, "translation", &len);
+	if (pval && len > 0) {
+		memcpy(pchild->tblprop_array, pval, len);
                 pchild->total_tbls = len / sizeof(struct pcf8584_tblprop);
 		for (i = 0; i < pchild->total_tbls; i++) {
 			if ((pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset) > tbls_size) {
@@ -891,12 +889,12 @@
 			printk("envctrl: Failed to allocate table.\n");
 			return;
 		}
-                len = prom_getproperty(node, "tables",
-				       (char *) pchild->tables, tbls_size);
-                if (len <= 0) {
+		pval = of_get_property(dp, "tables", &len);
+                if (!pval || len <= 0) {
 			printk("envctrl: Failed to get table.\n");
 			return;
 		}
+		memcpy(pchild->tables, pval, len);
 	}
 
 	/* SPARCengine ASM Reference Manual (ref. SMI doc 805-7581-04)
@@ -907,12 +905,11 @@
 	 * 'NULL' monitor type.
 	 */
 	if (ENVCTRL_CPCI_IGNORED_NODE == pchild->addr) {
+		struct device_node *root_node;
 		int len;
-		char prop[56];
 
-		len = prom_getproperty(prom_root_node, "name", prop, sizeof(prop));
-		if (0 < len && (0 == strncmp(prop, "SUNW,UltraSPARC-IIi-cEngine", len)))
-		{
+		root_node = of_find_node_by_path("/");
+		if (!strcmp(root_node->name, "SUNW,UltraSPARC-IIi-cEngine")) {
 			for (len = 0; len < PCF8584_MAX_CHANNELS; ++len) {
 				pchild->mon_type[len] = ENVCTRL_NOMON;
 			}
@@ -921,16 +918,14 @@
 	}
 
 	/* Get the monitor channels. */
-	len = prom_getproperty(node, "channels-in-use",
-			       (char *) pchild->chnl_array,
-			       (PCF8584_MAX_CHANNELS *
-				sizeof(struct pcf8584_channel)));
+	pval = of_get_property(dp, "channels-in-use", &len);
+	memcpy(pchild->chnl_array, pval, len);
 	pchild->total_chnls = len / sizeof(struct pcf8584_channel);
 
 	for (i = 0; i < pchild->total_chnls; i++) {
 		switch (pchild->chnl_array[i].type) {
 		case PCF8584_TEMP_TYPE:
-			envctrl_init_adc(pchild, node);
+			envctrl_init_adc(pchild, dp);
 			break;
 
 		case PCF8584_GLOBALADDR_TYPE:
@@ -945,7 +940,7 @@
 
 		case PCF8584_VOLTAGE_TYPE:
 			if (pchild->i2ctype == I2C_ADC) {
-				envctrl_init_adc(pchild,node);
+				envctrl_init_adc(pchild,dp);
 			} else {
 				envctrl_init_voltage_status(pchild);
 			}
@@ -1046,7 +1041,7 @@
 
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, "bbc")) {
+			if (!strcmp(edev->prom_node->name, "bbc")) {
 				/* If we find a boot-bus controller node,
 				 * then this envctrl driver is not for us.
 				 */
@@ -1060,14 +1055,14 @@
 	 */
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, "i2c")) {
+			if (!strcmp(edev->prom_node->name, "i2c")) {
 				i2c = ioremap(edev->resource[0].start, 0x2);
 				for_each_edevchild(edev, edev_child) {
-					if (!strcmp("gpio", edev_child->prom_name)) {
+					if (!strcmp("gpio", edev_child->prom_node->name)) {
 						i2c_childlist[i].i2ctype = I2C_GPIO;
 						envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++]));
 					}
-					if (!strcmp("adc", edev_child->prom_name)) {
+					if (!strcmp("adc", edev_child->prom_node->name)) {
 						i2c_childlist[i].i2ctype = I2C_ADC;
 						envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++]));
 					}
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 2beb3dd..5ae684c 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -192,9 +192,11 @@
 	}
 	if (!sdev) {
 #ifdef CONFIG_PCI
+		struct linux_prom_registers *ebus_regs;
+
 		for_each_ebus(ebus) {
 			for_each_ebusdev(edev, ebus) {
-				if (!strcmp(edev->prom_name, "flashprom"))
+				if (!strcmp(edev->prom_node->name, "flashprom"))
 					goto ebus_done;
 			}
 		}
@@ -202,23 +204,23 @@
 		if (!edev)
 			return -ENODEV;
 
-		len = prom_getproperty(edev->prom_node, "reg", (void *)regs, sizeof(regs));
-		if ((len % sizeof(regs[0])) != 0) {
+		ebus_regs = of_get_property(edev->prom_node, "reg", &len);
+		if (!ebus_regs || (len % sizeof(regs[0])) != 0) {
 			printk("flash: Strange reg property size %d\n", len);
 			return -ENODEV;
 		}
 
-		nregs = len / sizeof(regs[0]);
+		nregs = len / sizeof(ebus_regs[0]);
 
 		flash.read_base = edev->resource[0].start;
-		flash.read_size = regs[0].reg_size;
+		flash.read_size = ebus_regs[0].reg_size;
 
 		if (nregs == 1) {
 			flash.write_base = edev->resource[0].start;
-			flash.write_size = regs[0].reg_size;
+			flash.write_size = ebus_regs[0].reg_size;
 		} else if (nregs == 2) {
 			flash.write_base = edev->resource[1].start;
-			flash.write_size = regs[1].reg_size;
+			flash.write_size = ebus_regs[1].reg_size;
 		} else {
 			printk("flash: Strange number of regs %d\n", nregs);
 			return -ENODEV;
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index bfbe9dc..e4c0fd2 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -984,19 +984,19 @@
 
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, "se")) {
+			if (!strcmp(edev->prom_node->name, "se")) {
 				callback(edev, arg);
 				continue;
-			} else if (!strcmp(edev->prom_name, "serial")) {
-				char compat[32];
+			} else if (!strcmp(edev->prom_node->name, "serial")) {
+				char *compat;
 				int clen;
 
 				/* On RIO this can be an SE, check it.  We could
 				 * just check ebus->is_rio, but this is more portable.
 				 */
-				clen = prom_getproperty(edev->prom_node, "compatible",
-							compat, sizeof(compat));
-				if (clen > 0) {
+				compat = of_get_property(edev->prom_node,
+							 "compatible", &clen);
+				if (compat && clen > 0) {
 					if (strncmp(compat, "sab82532", 8) == 0) {
 						callback(edev, arg);
 						continue;
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 4cdb610..0268b30 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1053,7 +1053,7 @@
 	 */
 	for_each_ebus(ebus) {
 		for_each_ebusdev(dev, ebus) {
-			if (dev->prom_node == up->port_node) {
+			if (dev->prom_node->node == up->port_node) {
 				/*
 				 * The EBus is broken on sparc; it delivers
 				 * virtual addresses in resources. Oh well...
@@ -1073,7 +1073,7 @@
 #ifdef CONFIG_SPARC64
 	for_each_isa(isa_br) {
 		for_each_isadev(isa_dev, isa_br) {
-			if (isa_dev->prom_node == up->port_node) {
+			if (isa_dev->prom_node->node == up->port_node) {
 				/* Same on sparc64. Cool architecure... */
 				up->port.membase = (char *) isa_dev->resource.start;
 				up->port.mapbase = isa_dev->resource.start;
diff --git a/include/asm-sparc64/ebus.h b/include/asm-sparc64/ebus.h
index 7a408a0..876912f 100644
--- a/include/asm-sparc64/ebus.h
+++ b/include/asm-sparc64/ebus.h
@@ -10,13 +10,13 @@
 
 #include <asm/pbm.h>
 #include <asm/oplib.h>
+#include <asm/prom.h>
 
 struct linux_ebus_child {
 	struct linux_ebus_child		*next;
 	struct linux_ebus_device	*parent;
 	struct linux_ebus		*bus;
-	int				 prom_node;
-	char				 prom_name[64];
+	struct device_node		*prom_node;
 	struct resource			 resource[PROMREG_MAX];
 	int				 num_addrs;
 	unsigned int			 irqs[PROMINTR_MAX];
@@ -27,8 +27,7 @@
 	struct linux_ebus_device	*next;
 	struct linux_ebus_child		*children;
 	struct linux_ebus		*bus;
-	int				 prom_node;
-	char				 prom_name[64];
+	struct device_node		*prom_node;
 	struct resource			 resource[PROMREG_MAX];
 	int				 num_addrs;
 	unsigned int			 irqs[PROMINTR_MAX];
@@ -42,8 +41,7 @@
 	struct pci_dev			*self;
 	int				 index;
 	int				 is_rio;
-	int				 prom_node;
-	char				 prom_name[64];
+	struct device_node		*prom_node;
 	struct linux_prom_ebus_ranges	 ebus_ranges[PROMREG_MAX];
 	int				 num_ebus_ranges;
 	struct linux_prom_ebus_intmap	 ebus_intmap[PROMREG_MAX];
diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h
index 07ccd6f..f8d57bb 100644
--- a/include/asm-sparc64/floppy.h
+++ b/include/asm-sparc64/floppy.h
@@ -498,15 +498,14 @@
 #ifdef CONFIG_PCI
 static int __init ebus_fdthree_p(struct linux_ebus_device *edev)
 {
-	if (!strcmp(edev->prom_name, "fdthree"))
+	if (!strcmp(edev->prom_node->name, "fdthree"))
 		return 1;
-	if (!strcmp(edev->prom_name, "floppy")) {
-		char compat[16];
-		prom_getstring(edev->prom_node,
-			       "compatible",
-			       compat, sizeof(compat));
-		compat[15] = '\0';
-		if (!strcmp(compat, "fdthree"))
+	if (!strcmp(edev->prom_node->name, "floppy")) {
+		char *compat;
+
+		compat = of_get_property(edev->prom_node,
+					 "compatible", NULL);
+		if (compat && !strcmp(compat, "fdthree"))
 			return 1;
 	}
 	return 0;
@@ -524,12 +523,12 @@
 
 	for_each_isa(isa_br) {
 		for_each_isadev(isa_dev, isa_br) {
-			if (!strcmp(isa_dev->prom_name, "dma")) {
+			if (!strcmp(isa_dev->prom_node->name, "dma")) {
 				struct sparc_isa_device *child =
 					isa_dev->child;
 
 				while (child) {
-					if (!strcmp(child->prom_name,
+					if (!strcmp(child->prom_node->name,
 						    "floppy")) {
 						isa_dev = child;
 						goto isa_done;
@@ -614,6 +613,7 @@
 		struct linux_ebus_device *edev = NULL;
 		unsigned long config = 0;
 		void __iomem *auxio_reg;
+		char *state_prop;
 
 		for_each_ebus(ebus) {
 			for_each_ebusdev(edev, ebus) {
@@ -630,9 +630,8 @@
 #endif
 		}
 
-		prom_getproperty(edev->prom_node, "status",
-				 state, sizeof(state));
-		if (!strncmp(state, "disabled", 8))
+		state_prop = of_get_property(edev->prom_node, "status", NULL);
+		if (state_prop && !strncmp(state_prop, "disabled", 8))
 			return 0;
 			
 		FLOPPY_IRQ = edev->irqs[0];
@@ -703,7 +702,7 @@
 		 */
 		for_each_ebus(ebus) {
 			for_each_ebusdev(edev, ebus) {
-				if (!strcmp(edev->prom_name, "ecpp")) {
+				if (!strcmp(edev->prom_node->name, "ecpp")) {
 					config = edev->resource[1].start;
 					goto config_done;
 				}
diff --git a/include/asm-sparc64/isa.h b/include/asm-sparc64/isa.h
index 4601bbf..e110435 100644
--- a/include/asm-sparc64/isa.h
+++ b/include/asm-sparc64/isa.h
@@ -9,6 +9,7 @@
 
 #include <asm/pbm.h>
 #include <asm/oplib.h>
+#include <asm/prom.h>
 
 struct sparc_isa_bridge;
 
@@ -16,9 +17,7 @@
 	struct sparc_isa_device	*next;
 	struct sparc_isa_device	*child;
 	struct sparc_isa_bridge	*bus;
-	int			prom_node;
-	char			prom_name[64];
-	char			compatible[64];
+	struct device_node	*prom_node;
 	struct resource		resource;
 	unsigned int		irq;
 };
@@ -29,8 +28,7 @@
 	struct pci_pbm_info	*parent;
 	struct pci_dev		*self;
 	int			index;
-	int			prom_node;
-	char			prom_name[64];
+	struct device_node	*prom_node;
 #define linux_prom_isa_ranges linux_prom_ebus_ranges
 	struct linux_prom_isa_ranges	isa_ranges[PROMREG_MAX];
 	int			num_isa_ranges;
diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h
index 56b5197d..d389587 100644
--- a/include/asm-sparc64/parport.h
+++ b/include/asm-sparc64/parport.h
@@ -67,18 +67,17 @@
 
 static int ebus_ecpp_p(struct linux_ebus_device *edev)
 {
-	if (!strcmp(edev->prom_name, "ecpp"))
+	if (!strcmp(edev->prom_node->name, "ecpp"))
 		return 1;
-	if (!strcmp(edev->prom_name, "parallel")) {
-		char compat[19];
-		prom_getstring(edev->prom_node,
-			       "compatible",
-			       compat, sizeof(compat));
-		compat[18] = '\0';
-		if (!strcmp(compat, "ecpp"))
-			return 1;
-		if (!strcmp(compat, "ns87317-ecpp") &&
-		    !strcmp(compat + 13, "ecpp"))
+	if (!strcmp(edev->prom_node->name, "parallel")) {
+		char *compat;
+
+		compat = of_get_property(edev->prom_node,
+					 "compatible", NULL);
+		if (compat &&
+		    (!strcmp(compat, "ecpp") ||
+		     !strcmp(compat, "ns87317-ecpp") ||
+		     !strcmp(compat + 13, "ecpp")))
 			return 1;
 	}
 	return 0;
@@ -94,12 +93,12 @@
 			struct sparc_isa_device *child;
 			unsigned long base;
 
-			if (strcmp(isa_dev->prom_name, "dma"))
+			if (strcmp(isa_dev->prom_node->name, "dma"))
 				continue;
 
 			child = isa_dev->child;
 			while (child) {
-				if (!strcmp(child->prom_name, "parallel"))
+				if (!strcmp(child->prom_node->name, "parallel"))
 					break;
 				child = child->next;
 			}
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index b3efc9a..da54d04 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -2284,15 +2284,14 @@
 		for_each_ebusdev(edev, ebus) {
 			int match = 0;
 
-			if (!strcmp(edev->prom_name, "SUNW,CS4231")) {
+			if (!strcmp(edev->prom_node->name, "SUNW,CS4231")) {
 				match = 1;
-			} else if (!strcmp(edev->prom_name, "audio")) {
-				char compat[16];
+			} else if (!strcmp(edev->prom_node->name, "audio")) {
+				char *compat;
 
-				prom_getstring(edev->prom_node, "compatible",
-					       compat, sizeof(compat));
-				compat[15] = '\0';
-				if (!strcmp(compat, "SUNW,CS4231"))
+				compat = of_get_property(edev->prom_node,
+							 "compatible", NULL);
+				if (compat && !strcmp(compat, "SUNW,CS4231"))
 					match = 1;
 			}