[PATCH] powerpc: Remove device_node addrs/n_addr

The pre-parsed addrs/n_addrs fields in struct device_node are finally
gone. Remove the dodgy heuristics that did that parsing at boot and
remove the fields themselves since we now have a good replacement with
the new OF parsing code. This patch also fixes a bunch of drivers to use
the new code instead, so that at least pmac32, pseries, iseries and g5
defconfigs build.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 7e798d5..1b97e13 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -57,21 +57,6 @@
 #define DBG(fmt...)
 #endif
 
-struct pci_reg_property {
-	struct pci_address addr;
-	u32 size_hi;
-	u32 size_lo;
-};
-
-struct isa_reg_property {
-	u32 space;
-	u32 address;
-	u32 size;
-};
-
-
-typedef int interpret_func(struct device_node *, unsigned long *,
-			   int, int, int);
 
 static int __initdata dt_root_addr_cells;
 static int __initdata dt_root_size_cells;
@@ -410,237 +395,19 @@
 	return 0;
 }
 
-static int __devinit interpret_pci_props(struct device_node *np,
-					 unsigned long *mem_start,
-					 int naddrc, int nsizec,
-					 int measure_only)
-{
-	struct address_range *adr;
-	struct pci_reg_property *pci_addrs;
-	int i, l, n_addrs;
-
-	pci_addrs = (struct pci_reg_property *)
-		get_property(np, "assigned-addresses", &l);
-	if (!pci_addrs)
-		return 0;
-
-	n_addrs = l / sizeof(*pci_addrs);
-
-	adr = prom_alloc(n_addrs * sizeof(*adr), mem_start);
-	if (!adr)
-		return -ENOMEM;
-
- 	if (measure_only)
- 		return 0;
-
- 	np->addrs = adr;
- 	np->n_addrs = n_addrs;
-
- 	for (i = 0; i < n_addrs; i++) {
- 		adr[i].space = pci_addrs[i].addr.a_hi;
- 		adr[i].address = pci_addrs[i].addr.a_lo |
-			((u64)pci_addrs[i].addr.a_mid << 32);
- 		adr[i].size = pci_addrs[i].size_lo;
-	}
-
-	return 0;
-}
-
-static int __init interpret_dbdma_props(struct device_node *np,
-					unsigned long *mem_start,
-					int naddrc, int nsizec,
-					int measure_only)
-{
-	struct reg_property32 *rp;
-	struct address_range *adr;
-	unsigned long base_address;
-	int i, l;
-	struct device_node *db;
-
-	base_address = 0;
-	if (!measure_only) {
-		for (db = np->parent; db != NULL; db = db->parent) {
-			if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
-				base_address = db->addrs[0].address;
-				break;
-			}
-		}
-	}
-
-	rp = (struct reg_property32 *) get_property(np, "reg", &l);
-	if (rp != 0 && l >= sizeof(struct reg_property32)) {
-		i = 0;
-		adr = (struct address_range *) (*mem_start);
-		while ((l -= sizeof(struct reg_property32)) >= 0) {
-			if (!measure_only) {
-				adr[i].space = 2;
-				adr[i].address = rp[i].address + base_address;
-				adr[i].size = rp[i].size;
-			}
-			++i;
-		}
-		np->addrs = adr;
-		np->n_addrs = i;
-		(*mem_start) += i * sizeof(struct address_range);
-	}
-
-	return 0;
-}
-
-static int __init interpret_macio_props(struct device_node *np,
-					unsigned long *mem_start,
-					int naddrc, int nsizec,
-					int measure_only)
-{
-	struct reg_property32 *rp;
-	struct address_range *adr;
-	unsigned long base_address;
-	int i, l;
-	struct device_node *db;
-
-	base_address = 0;
-	if (!measure_only) {
-		for (db = np->parent; db != NULL; db = db->parent) {
-			if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
-				base_address = db->addrs[0].address;
-				break;
-			}
-		}
-	}
-
-	rp = (struct reg_property32 *) get_property(np, "reg", &l);
-	if (rp != 0 && l >= sizeof(struct reg_property32)) {
-		i = 0;
-		adr = (struct address_range *) (*mem_start);
-		while ((l -= sizeof(struct reg_property32)) >= 0) {
-			if (!measure_only) {
-				adr[i].space = 2;
-				adr[i].address = rp[i].address + base_address;
-				adr[i].size = rp[i].size;
-			}
-			++i;
-		}
-		np->addrs = adr;
-		np->n_addrs = i;
-		(*mem_start) += i * sizeof(struct address_range);
-	}
-
-	return 0;
-}
-
-static int __init interpret_isa_props(struct device_node *np,
-				      unsigned long *mem_start,
-				      int naddrc, int nsizec,
-				      int measure_only)
-{
-	struct isa_reg_property *rp;
-	struct address_range *adr;
-	int i, l;
-
-	rp = (struct isa_reg_property *) get_property(np, "reg", &l);
-	if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
-		i = 0;
-		adr = (struct address_range *) (*mem_start);
-		while ((l -= sizeof(struct isa_reg_property)) >= 0) {
-			if (!measure_only) {
-				adr[i].space = rp[i].space;
-				adr[i].address = rp[i].address;
-				adr[i].size = rp[i].size;
-			}
-			++i;
-		}
-		np->addrs = adr;
-		np->n_addrs = i;
-		(*mem_start) += i * sizeof(struct address_range);
-	}
-
-	return 0;
-}
-
-static int __init interpret_root_props(struct device_node *np,
-				       unsigned long *mem_start,
-				       int naddrc, int nsizec,
-				       int measure_only)
-{
-	struct address_range *adr;
-	int i, l;
-	unsigned int *rp;
-	int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
-
-	rp = (unsigned int *) get_property(np, "linux,usable-memory", &l);
-	if (rp == NULL)
-		rp = (unsigned int *) get_property(np, "reg", &l);
-
-	if (rp != 0 && l >= rpsize) {
-		i = 0;
-		adr = (struct address_range *) (*mem_start);
-		while ((l -= rpsize) >= 0) {
-			if (!measure_only) {
-				adr[i].space = 0;
-				adr[i].address = rp[naddrc - 1];
-				adr[i].size = rp[naddrc + nsizec - 1];
-			}
-			++i;
-			rp += naddrc + nsizec;
-		}
-		np->addrs = adr;
-		np->n_addrs = i;
-		(*mem_start) += i * sizeof(struct address_range);
-	}
-
-	return 0;
-}
-
 static int __devinit finish_node(struct device_node *np,
 				 unsigned long *mem_start,
-				 interpret_func *ifunc,
-				 int naddrc, int nsizec,
 				 int measure_only)
 {
 	struct device_node *child;
-	int *ip, rc = 0;
-
-	/* get the device addresses and interrupts */
-	if (ifunc != NULL)
-		rc = ifunc(np, mem_start, naddrc, nsizec, measure_only);
-	if (rc)
-		goto out;
+	int rc = 0;
 
 	rc = finish_node_interrupts(np, mem_start, measure_only);
 	if (rc)
 		goto out;
 
-	/* Look for #address-cells and #size-cells properties. */
-	ip = (int *) get_property(np, "#address-cells", NULL);
-	if (ip != NULL)
-		naddrc = *ip;
-	ip = (int *) get_property(np, "#size-cells", NULL);
-	if (ip != NULL)
-		nsizec = *ip;
-
-	if (!strcmp(np->name, "device-tree") || np->parent == NULL)
-		ifunc = interpret_root_props;
-	else if (np->type == 0)
-		ifunc = NULL;
-	else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
-		ifunc = interpret_pci_props;
-	else if (!strcmp(np->type, "dbdma"))
-		ifunc = interpret_dbdma_props;
-	else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
-		ifunc = interpret_macio_props;
-	else if (!strcmp(np->type, "isa"))
-		ifunc = interpret_isa_props;
-	else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
-		ifunc = interpret_root_props;
-	else if (!((ifunc == interpret_dbdma_props
-		    || ifunc == interpret_macio_props)
-		   && (!strcmp(np->type, "escc")
-		       || !strcmp(np->type, "media-bay"))))
-		ifunc = NULL;
-
 	for (child = np->child; child != NULL; child = child->sibling) {
-		rc = finish_node(child, mem_start, ifunc,
-				 naddrc, nsizec, measure_only);
+		rc = finish_node(child, mem_start, measure_only);
 		if (rc)
 			goto out;
 	}
@@ -702,10 +469,10 @@
 	 * reason and then remove those additional 16 bytes
 	 */
 	size = 16;
-	finish_node(allnodes, &size, NULL, 0, 0, 1);
+	finish_node(allnodes, &size, 1);
 	size -= 16;
 	end = start = (unsigned long) __va(lmb_alloc(size, 128));
-	finish_node(allnodes, &end, NULL, 0, 0, 0);
+	finish_node(allnodes, &end, 0);
 	BUG_ON(end != start + size);
 
 	DBG(" <- finish_device_tree\n");
@@ -1822,7 +1589,6 @@
 		prop = next;
 	}
 	kfree(node->intrs);
-	kfree(node->addrs);
 	kfree(node->full_name);
 	kfree(node->data);
 	kfree(node);
@@ -1904,9 +1670,7 @@
  * This should probably be split up into smaller chunks.
  */
 
-static int of_finish_dynamic_node(struct device_node *node,
-				  unsigned long *unused1, int unused2,
-				  int unused3, int unused4)
+static int of_finish_dynamic_node(struct device_node *node)
 {
 	struct device_node *parent = of_get_parent(node);
 	int err = 0;
@@ -1927,7 +1691,8 @@
 		return -ENODEV;
 
 	/* fix up new node's linux_phandle field */
-	if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL)))
+	if ((ibm_phandle = (unsigned int *)get_property(node,
+							"ibm,phandle", NULL)))
 		node->linux_phandle = *ibm_phandle;
 
 out:
@@ -1942,7 +1707,9 @@
 
 	switch (action) {
 	case PSERIES_RECONFIG_ADD:
-		err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0);
+		err = of_finish_dynamic_node(node);
+		if (!err)
+			finish_node(node, NULL, 0);
 		if (err < 0) {
 			printk(KERN_ERR "finish_node returned %d\n", err);
 			err = NOTIFY_BAD;
@@ -2016,175 +1783,4 @@
 	return 0;
 }
 
-/* I quickly hacked that one, check against spec ! */
-static inline unsigned long
-bus_space_to_resource_flags(unsigned int bus_space)
-{
-	u8 space = (bus_space >> 24) & 0xf;
-	if (space == 0)
-		space = 0x02;
-	if (space == 0x02)
-		return IORESOURCE_MEM;
-	else if (space == 0x01)
-		return IORESOURCE_IO;
-	else {
-		printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n",
-		    	bus_space);
-		return 0;
-	}
-}
 
-#ifdef CONFIG_PCI
-static struct resource *find_parent_pci_resource(struct pci_dev* pdev,
-						 struct address_range *range)
-{
-	unsigned long mask;
-	int i;
-
-	/* Check this one */
-	mask = bus_space_to_resource_flags(range->space);
-	for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
-		if ((pdev->resource[i].flags & mask) == mask &&
-			pdev->resource[i].start <= range->address &&
-			pdev->resource[i].end > range->address) {
-				if ((range->address + range->size - 1) > pdev->resource[i].end) {
-					/* Add better message */
-					printk(KERN_WARNING "PCI/OF resource overlap !\n");
-					return NULL;
-				}
-				break;
-			}
-	}
-	if (i == DEVICE_COUNT_RESOURCE)
-		return NULL;
-	return &pdev->resource[i];
-}
-
-/*
- * Request an OF device resource. Currently handles child of PCI devices,
- * or other nodes attached to the root node. Ultimately, put some
- * link to resources in the OF node.
- */
-struct resource *request_OF_resource(struct device_node* node, int index,
-				     const char* name_postfix)
-{
-	struct pci_dev* pcidev;
-	u8 pci_bus, pci_devfn;
-	unsigned long iomask;
-	struct device_node* nd;
-	struct resource* parent;
-	struct resource *res = NULL;
-	int nlen, plen;
-
-	if (index >= node->n_addrs)
-		goto fail;
-
-	/* Sanity check on bus space */
-	iomask = bus_space_to_resource_flags(node->addrs[index].space);
-	if (iomask & IORESOURCE_MEM)
-		parent = &iomem_resource;
-	else if (iomask & IORESOURCE_IO)
-		parent = &ioport_resource;
-	else
-		goto fail;
-
-	/* Find a PCI parent if any */
-	nd = node;
-	pcidev = NULL;
-	while (nd) {
-		if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
-			pcidev = pci_find_slot(pci_bus, pci_devfn);
-		if (pcidev) break;
-		nd = nd->parent;
-	}
-	if (pcidev)
-		parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
-	if (!parent) {
-		printk(KERN_WARNING "request_OF_resource(%s), parent not found\n",
-			node->name);
-		goto fail;
-	}
-
-	res = __request_region(parent, node->addrs[index].address,
-			       node->addrs[index].size, NULL);
-	if (!res)
-		goto fail;
-	nlen = strlen(node->name);
-	plen = name_postfix ? strlen(name_postfix) : 0;
-	res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL);
-	if (res->name) {
-		strcpy((char *)res->name, node->name);
-		if (plen)
-			strcpy((char *)res->name+nlen, name_postfix);
-	}
-	return res;
-fail:
-	return NULL;
-}
-EXPORT_SYMBOL(request_OF_resource);
-
-int release_OF_resource(struct device_node *node, int index)
-{
-	struct pci_dev* pcidev;
-	u8 pci_bus, pci_devfn;
-	unsigned long iomask, start, end;
-	struct device_node* nd;
-	struct resource* parent;
-	struct resource *res = NULL;
-
-	if (index >= node->n_addrs)
-		return -EINVAL;
-
-	/* Sanity check on bus space */
-	iomask = bus_space_to_resource_flags(node->addrs[index].space);
-	if (iomask & IORESOURCE_MEM)
-		parent = &iomem_resource;
-	else if (iomask & IORESOURCE_IO)
-		parent = &ioport_resource;
-	else
-		return -EINVAL;
-
-	/* Find a PCI parent if any */
-	nd = node;
-	pcidev = NULL;
-	while(nd) {
-		if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
-			pcidev = pci_find_slot(pci_bus, pci_devfn);
-		if (pcidev) break;
-		nd = nd->parent;
-	}
-	if (pcidev)
-		parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
-	if (!parent) {
-		printk(KERN_WARNING "release_OF_resource(%s), parent not found\n",
-			node->name);
-		return -ENODEV;
-	}
-
-	/* Find us in the parent and its childs */
-	res = parent->child;
-	start = node->addrs[index].address;
-	end = start + node->addrs[index].size - 1;
-	while (res) {
-		if (res->start == start && res->end == end &&
-		    (res->flags & IORESOURCE_BUSY))
-		    	break;
-		if (res->start <= start && res->end >= end)
-			res = res->child;
-		else
-			res = res->sibling;
-	}
-	if (!res)
-		return -ENODEV;
-
-	if (res->name) {
-		kfree(res->name);
-		res->name = NULL;
-	}
-	release_resource(res);
-	kfree(res);
-
-	return 0;
-}
-EXPORT_SYMBOL(release_OF_resource);
-#endif /* CONFIG_PCI */