[PATCH] Separate pci bits out of struct device_node

This patch pulls the PCI-related junk out of struct device_node and
puts it in a separate structure, struct pci_dn.  The device_node now
just has a void * pointer in it, which points to a struct pci_dn for
nodes that represent PCI devices.  It could potentially be used in
future for device-specific data for other sorts of devices, such as
virtual I/O devices.

Signed-off-by: Paul Mackerras <paulus@samba.org>
diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
index 4c857a6..ba93fd7 100644
--- a/arch/ppc64/kernel/eeh.c
+++ b/arch/ppc64/kernel/eeh.c
@@ -254,6 +254,7 @@
 static void __pci_addr_cache_insert_device(struct pci_dev *dev)
 {
 	struct device_node *dn;
+	struct pci_dn *pdn;
 	int i;
 	int inserted = 0;
 
@@ -265,8 +266,9 @@
 	}
 
 	/* Skip any devices for which EEH is not enabled. */
-	if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) ||
-	    dn->eeh_mode & EEH_MODE_NOCHECK) {
+	pdn = dn->data;
+	if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
+	    pdn->eeh_mode & EEH_MODE_NOCHECK) {
 #ifdef DEBUG
 		printk(KERN_INFO "PCI: skip building address cache for=%s\n",
 		       pci_name(dev));
@@ -415,6 +417,7 @@
 static int read_slot_reset_state(struct device_node *dn, int rets[])
 {
 	int token, outputs;
+	struct pci_dn *pdn = dn->data;
 
 	if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) {
 		token = ibm_read_slot_reset_state2;
@@ -424,8 +427,8 @@
 		outputs = 3;
 	}
 
-	return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr,
-			 BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid));
+	return rtas_call(token, 3, outputs, rets, pdn->eeh_config_addr,
+			 BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid));
 }
 
 /**
@@ -534,6 +537,7 @@
 	unsigned long flags;
 	int rc, reset_state;
 	struct eeh_event  *event;
+	struct pci_dn *pdn;
 
 	__get_cpu_var(total_mmio_ffs)++;
 
@@ -542,14 +546,15 @@
 
 	if (!dn)
 		return 0;
+	pdn = dn->data;
 
 	/* Access to IO BARs might get this far and still not want checking. */
-	if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) ||
-	    dn->eeh_mode & EEH_MODE_NOCHECK) {
+	if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
+	    pdn->eeh_mode & EEH_MODE_NOCHECK) {
 		return 0;
 	}
 
-	if (!dn->eeh_config_addr) {
+	if (!pdn->eeh_config_addr) {
 		return 0;
 	}
 
@@ -557,7 +562,7 @@
 	 * If we already have a pending isolation event for this
 	 * slot, we know it's bad already, we don't need to check...
 	 */
-	if (dn->eeh_mode & EEH_MODE_ISOLATED) {
+	if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
 		atomic_inc(&eeh_fail_count);
 		if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) {
 			/* re-read the slot reset state */
@@ -582,7 +587,7 @@
 	}
 
 	/* prevent repeated reports of this failure */
-	dn->eeh_mode |= EEH_MODE_ISOLATED;
+	pdn->eeh_mode |= EEH_MODE_ISOLATED;
 
 	reset_state = rets[0];
 
@@ -590,9 +595,9 @@
 	memset(slot_errbuf, 0, eeh_error_buf_size);
 
 	rc = rtas_call(ibm_slot_error_detail,
-	               8, 1, NULL, dn->eeh_config_addr,
-	               BUID_HI(dn->phb->buid),
-	               BUID_LO(dn->phb->buid), NULL, 0,
+	               8, 1, NULL, pdn->eeh_config_addr,
+	               BUID_HI(pdn->phb->buid),
+	               BUID_LO(pdn->phb->buid), NULL, 0,
 	               virt_to_phys(slot_errbuf),
 	               eeh_error_buf_size,
 	               1 /* Temporary Error */);
@@ -679,8 +684,9 @@
 	u32 *device_id = (u32 *)get_property(dn, "device-id", NULL);
 	u32 *regs;
 	int enable;
+	struct pci_dn *pdn = dn->data;
 
-	dn->eeh_mode = 0;
+	pdn->eeh_mode = 0;
 
 	if (status && strcmp(status, "ok") != 0)
 		return NULL;	/* ignore devices with bad status */
@@ -691,7 +697,7 @@
 
 	/* There is nothing to check on PCI to ISA bridges */
 	if (dn->type && !strcmp(dn->type, "isa")) {
-		dn->eeh_mode |= EEH_MODE_NOCHECK;
+		pdn->eeh_mode |= EEH_MODE_NOCHECK;
 		return NULL;
 	}
 
@@ -708,7 +714,7 @@
 		enable = 0;
 
 	if (!enable)
-		dn->eeh_mode |= EEH_MODE_NOCHECK;
+		pdn->eeh_mode |= EEH_MODE_NOCHECK;
 
 	/* Ok... see if this device supports EEH.  Some do, some don't,
 	 * and the only way to find out is to check each and every one. */
@@ -721,8 +727,8 @@
 				EEH_ENABLE);
 		if (ret == 0) {
 			eeh_subsystem_enabled = 1;
-			dn->eeh_mode |= EEH_MODE_SUPPORTED;
-			dn->eeh_config_addr = regs[0];
+			pdn->eeh_mode |= EEH_MODE_SUPPORTED;
+			pdn->eeh_config_addr = regs[0];
 #ifdef DEBUG
 			printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name);
 #endif
@@ -730,10 +736,11 @@
 
 			/* This device doesn't support EEH, but it may have an
 			 * EEH parent, in which case we mark it as supported. */
-			if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) {
+			if (dn->parent && dn->parent->data
+			    && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
 				/* Parent supports EEH. */
-				dn->eeh_mode |= EEH_MODE_SUPPORTED;
-				dn->eeh_config_addr = dn->parent->eeh_config_addr;
+				pdn->eeh_mode |= EEH_MODE_SUPPORTED;
+				pdn->eeh_config_addr = PCI_DN(dn->parent)->eeh_config_addr;
 				return NULL;
 			}
 		}
@@ -790,11 +797,13 @@
 	for (phb = of_find_node_by_name(NULL, "pci"); phb;
 	     phb = of_find_node_by_name(phb, "pci")) {
 		unsigned long buid;
+		struct pci_dn *pci;
 
 		buid = get_phb_buid(phb);
-		if (buid == 0)
+		if (buid == 0 || phb->data == NULL)
 			continue;
 
+		pci = phb->data;
 		info.buid_lo = BUID_LO(buid);
 		info.buid_hi = BUID_HI(buid);
 		traverse_pci_devices(phb, early_enable_eeh, &info);
@@ -823,9 +832,9 @@
 	struct pci_controller *phb;
 	struct eeh_early_enable_info info;
 
-	if (!dn)
+	if (!dn || !dn->data)
 		return;
-	phb = dn->phb;
+	phb = PCI_DN(dn)->phb;
 	if (NULL == phb || 0 == phb->buid) {
 		printk(KERN_WARNING "EEH: Expected buid but found none\n");
 		return;
diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c
index 845eebd..9032b6b 100644
--- a/arch/ppc64/kernel/iommu.c
+++ b/arch/ppc64/kernel/iommu.c
@@ -438,7 +438,8 @@
 
 void iommu_free_table(struct device_node *dn)
 {
-	struct iommu_table *tbl = dn->iommu_table;
+	struct pci_dn *pdn = dn->data;
+	struct iommu_table *tbl = pdn->iommu_table;
 	unsigned long bitmap_sz, i;
 	unsigned int order;
 
diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c
index 5399399..5a8b4d8 100644
--- a/arch/ppc64/kernel/maple_pci.c
+++ b/arch/ppc64/kernel/maple_pci.c
@@ -447,9 +447,9 @@
 	 */
 	if (u3_agp) {
 		struct device_node *np = u3_agp->arch_data;
-		np->busno = 0xf0;
+		PCI_DN(np)->busno = 0xf0;
 		for (np = np->child; np; np = np->sibling)
-			np->busno = 0xf0;
+			PCI_DN(np)->busno = 0xf0;
 	}
 
 	/* Tell pci.c to use the common resource allocation mecanism */
diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c
index 9d5e1e7..f0fd7fb 100644
--- a/arch/ppc64/kernel/pSeries_iommu.c
+++ b/arch/ppc64/kernel/pSeries_iommu.c
@@ -295,7 +295,7 @@
 				      struct iommu_table *tbl,
 				      unsigned int *dma_window)
 {
-	tbl->it_busno  = dn->bussubno;
+	tbl->it_busno  = PCI_DN(dn)->bussubno;
 
 	/* TODO: Parse field size properties properly. */
 	tbl->it_size   = (((unsigned long)dma_window[4] << 32) |
@@ -311,6 +311,7 @@
 static void iommu_bus_setup_pSeries(struct pci_bus *bus)
 {
 	struct device_node *dn, *pdn;
+	struct pci_dn *pci;
 	struct iommu_table *tbl;
 
 	DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
@@ -325,6 +326,7 @@
 	 */
 
 	dn = pci_bus_to_OF_node(bus);
+	pci = dn->data;
 
 	if (!bus->self) {
 		/* Root bus */
@@ -341,18 +343,18 @@
 				 * alltogether. This leaves 768MB for the window.
 				 */
 				DBG("PHB has io-hole, reserving 256MB\n");
-				dn->phb->dma_window_size = 3 << 28;
-				dn->phb->dma_window_base_cur = 1 << 28;
+				pci->phb->dma_window_size = 3 << 28;
+				pci->phb->dma_window_base_cur = 1 << 28;
 			} else {
 				/* 1GB window by default */
-				dn->phb->dma_window_size = 1 << 30;
-				dn->phb->dma_window_base_cur = 0;
+				pci->phb->dma_window_size = 1 << 30;
+				pci->phb->dma_window_base_cur = 0;
 			}
 
 			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
 
-			iommu_table_setparms(dn->phb, dn, tbl);
-			dn->iommu_table = iommu_init_table(tbl);
+			iommu_table_setparms(pci->phb, dn, tbl);
+			pci->iommu_table = iommu_init_table(tbl);
 		} else {
 			/* Do a 128MB table at root. This is used for the IDE
 			 * controller on some SMP-mode POWER4 machines. It
@@ -363,16 +365,16 @@
 			 * Allocate at offset 128MB to avoid having to deal
 			 * with ISA holes; 128MB table for IDE is plenty.
 			 */
-			dn->phb->dma_window_size = 1 << 27;
-			dn->phb->dma_window_base_cur = 1 << 27;
+			pci->phb->dma_window_size = 1 << 27;
+			pci->phb->dma_window_base_cur = 1 << 27;
 
 			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
 
-			iommu_table_setparms(dn->phb, dn, tbl);
-			dn->iommu_table = iommu_init_table(tbl);
+			iommu_table_setparms(pci->phb, dn, tbl);
+			pci->iommu_table = iommu_init_table(tbl);
 
 			/* All child buses have 256MB tables */
-			dn->phb->dma_window_size = 1 << 28;
+			pci->phb->dma_window_size = 1 << 28;
 		}
 	} else {
 		pdn = pci_bus_to_OF_node(bus->parent);
@@ -386,12 +388,12 @@
 
 			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
 
-			iommu_table_setparms(dn->phb, dn, tbl);
+			iommu_table_setparms(pci->phb, dn, tbl);
 
-			dn->iommu_table = iommu_init_table(tbl);
+			pci->iommu_table = iommu_init_table(tbl);
 		} else {
 			/* Lower than first child or under python, use parent table */
-			dn->iommu_table = pdn->iommu_table;
+			pci->iommu_table = PCI_DN(pdn)->iommu_table;
 		}
 	}
 }
@@ -401,6 +403,7 @@
 {
 	struct iommu_table *tbl;
 	struct device_node *dn, *pdn;
+	struct pci_dn *ppci;
 	unsigned int *dma_window = NULL;
 
 	DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
@@ -419,22 +422,24 @@
 		return;
 	}
 
-	if (!pdn->iommu_table) {
+	ppci = pdn->data;
+	if (!ppci->iommu_table) {
 		/* Bussubno hasn't been copied yet.
 		 * Do it now because iommu_table_setparms_lpar needs it.
 		 */
-		pdn->bussubno = bus->number;
+
+		ppci->bussubno = bus->number;
 
 		tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
 						    GFP_KERNEL);
 	
-		iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window);
+		iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
 
-		pdn->iommu_table = iommu_init_table(tbl);
+		ppci->iommu_table = iommu_init_table(tbl);
 	}
 
 	if (pdn != dn)
-		dn->iommu_table = pdn->iommu_table;
+		PCI_DN(dn)->iommu_table = ppci->iommu_table;
 }
 
 
@@ -449,11 +454,11 @@
 	 */
 	mydn = dn = pci_device_to_OF_node(dev);
 
-	while (dn && dn->iommu_table == NULL)
+	while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL)
 		dn = dn->parent;
 
-	if (dn) {
-		mydn->iommu_table = dn->iommu_table;
+	if (dn && dn->data) {
+		PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;
 	} else {
 		DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name);
 	}
@@ -463,10 +468,11 @@
 {
 	int err = NOTIFY_OK;
 	struct device_node *np = node;
+	struct pci_dn *pci = np->data;
 
 	switch (action) {
 	case PSERIES_RECONFIG_REMOVE:
-		if (np->iommu_table &&
+		if (pci->iommu_table &&
 		    get_property(np, "ibm,dma-window", NULL))
 			iommu_free_table(np);
 		break;
@@ -486,6 +492,7 @@
 	struct device_node *pdn, *dn;
 	struct iommu_table *tbl;
 	int *dma_window = NULL;
+	struct pci_dn *pci;
 
 	DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name);
 
@@ -497,8 +504,10 @@
 	 */
 	dn = pci_device_to_OF_node(dev);
 
-	for (pdn = dn; pdn && !pdn->iommu_table; pdn = pdn->parent) {
-		dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL);
+	for (pdn = dn; pdn && pdn->data && !PCI_DN(pdn)->iommu_table;
+	     pdn = pdn->parent) {
+		dma_window = (unsigned int *)
+			get_property(pdn, "ibm,dma-window", NULL);
 		if (dma_window)
 			break;
 	}
@@ -515,20 +524,21 @@
 		DBG("Found DMA window, allocating table\n");
 	}
 
-	if (!pdn->iommu_table) {
+	pci = pdn->data;
+	if (!pci->iommu_table) {
 		/* iommu_table_setparms_lpar needs bussubno. */
-		pdn->bussubno = pdn->phb->bus->number;
+		pci->bussubno = pci->phb->bus->number;
 
 		tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
 						    GFP_KERNEL);
 
-		iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window);
+		iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
 
-		pdn->iommu_table = iommu_init_table(tbl);
+		pci->iommu_table = iommu_init_table(tbl);
 	}
 
 	if (pdn != dn)
-		dn->iommu_table = pdn->iommu_table;
+		PCI_DN(dn)->iommu_table = pci->iommu_table;
 }
 
 static void iommu_bus_setup_null(struct pci_bus *b) { }
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index b5ca7d8..446b465 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -837,9 +837,11 @@
         * device tree.  If they are then we need to scan all the
         * functions of this slot.
         */
-       for (dn = busdn->child; dn; dn = dn->sibling)
-               if ((dn->devfn >> 3) == (devfn >> 3))
+       for (dn = busdn->child; dn; dn = dn->sibling) {
+	       struct pci_dn *pdn = dn->data;
+	       if (pdn && (pdn->devfn >> 3) == (devfn >> 3))
                        return 1;
+       }
 
        return 0;
 }
diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
index 26be78b..5eb2cc3 100644
--- a/arch/ppc64/kernel/pci.h
+++ b/arch/ppc64/kernel/pci.h
@@ -34,7 +34,6 @@
 
 void pci_devs_phb_init(void);
 void pci_devs_phb_init_dynamic(struct pci_controller *phb);
-struct device_node *fetch_dev_dn(struct pci_dev *dev);
 
 /* PCI address cache management routines */
 void pci_addr_cache_insert_device(struct pci_dev *dev);
diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
index ec34546..a86389d 100644
--- a/arch/ppc64/kernel/pci_dn.c
+++ b/arch/ppc64/kernel/pci_dn.c
@@ -23,6 +23,8 @@
 #include <linux/pci.h>
 #include <linux/string.h>
 #include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -40,16 +42,26 @@
 	struct pci_controller *phb = data;
 	int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL);
 	u32 *regs;
+	struct pci_dn *pdn;
 
-	dn->phb = phb;
+	if (phb->is_dynamic)
+		pdn = kmalloc(sizeof(*pdn), GFP_KERNEL);
+	else
+		pdn = alloc_bootmem(sizeof(*pdn));
+	if (pdn == NULL)
+		return NULL;
+	memset(pdn, 0, sizeof(*pdn));
+	dn->data = pdn;
+	pdn->node = dn;
+	pdn->phb = phb;
 	regs = (u32 *)get_property(dn, "reg", NULL);
 	if (regs) {
 		/* First register entry is addr (00BBSS00)  */
-		dn->busno = (regs[0] >> 16) & 0xff;
-		dn->devfn = (regs[0] >> 8) & 0xff;
+		pdn->busno = (regs[0] >> 16) & 0xff;
+		pdn->devfn = (regs[0] >> 8) & 0xff;
 	}
 
-	dn->pci_ext_config_space = (type && *type == 1);
+	pdn->pci_ext_config_space = (type && *type == 1);
 	return NULL;
 }
 
@@ -112,10 +124,15 @@
 void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
 {
 	struct device_node * dn = (struct device_node *) phb->arch_data;
+	struct pci_dn *pdn;
 
 	/* PHB nodes themselves must not match */
-	dn->devfn = dn->busno = -1;
-	dn->phb = phb;
+	update_dn_pci_info(dn, phb);
+	pdn = dn->data;
+	if (pdn) {
+		pdn->devfn = pdn->busno = -1;
+		pdn->phb = phb;
+	}
 
 	/* Update dn->phb ptrs for new phb and children devices */
 	traverse_pci_devices(dn, update_dn_pci_info, phb);
@@ -123,14 +140,17 @@
 
 /*
  * Traversal func that looks for a <busno,devfcn> value.
- * If found, the device_node is returned (thus terminating the traversal).
+ * If found, the pci_dn is returned (thus terminating the traversal).
  */
 static void *is_devfn_node(struct device_node *dn, void *data)
 {
 	int busno = ((unsigned long)data >> 8) & 0xff;
 	int devfn = ((unsigned long)data) & 0xff;
+	struct pci_dn *pci = dn->data;
 
-	return ((devfn == dn->devfn) && (busno == dn->busno)) ? dn : NULL;
+	if (pci && (devfn == pci->devfn) && (busno == pci->busno))
+		return dn;
+	return NULL;
 }
 
 /*
@@ -149,13 +169,10 @@
 struct device_node *fetch_dev_dn(struct pci_dev *dev)
 {
 	struct device_node *orig_dn = dev->sysdata;
-	struct pci_controller *phb = orig_dn->phb; /* assume same phb as orig_dn */
-	struct device_node *phb_dn;
 	struct device_node *dn;
 	unsigned long searchval = (dev->bus->number << 8) | dev->devfn;
 
-	phb_dn = phb->arch_data;
-	dn = traverse_pci_devices(phb_dn, is_devfn_node, (void *)searchval);
+	dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval);
 	if (dn)
 		dev->sysdata = dn;
 	return dn;
@@ -165,11 +182,13 @@
 static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
 {
 	struct device_node *np = node;
+	struct pci_dn *pci;
 	int err = NOTIFY_OK;
 
 	switch (action) {
 	case PSERIES_RECONFIG_ADD:
-		update_dn_pci_info(np, np->parent->phb);
+		pci = np->parent->data;
+		update_dn_pci_info(np, pci->phb);
 		break;
 	default:
 		err = NOTIFY_DONE;
diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c
index ef0a62b..14647e0 100644
--- a/arch/ppc64/kernel/pci_iommu.c
+++ b/arch/ppc64/kernel/pci_iommu.c
@@ -66,7 +66,7 @@
 #endif /* CONFIG_PPC_ISERIES */
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
-	return PCI_GET_DN(pdev)->iommu_table;
+	return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
 #endif /* CONFIG_PPC_MULTIPLATFORM */
 }
 
diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c
index 98ed2bc..eb4e6c3 100644
--- a/arch/ppc64/kernel/pmac_feature.c
+++ b/arch/ppc64/kernel/pmac_feature.c
@@ -674,6 +674,7 @@
 #if 0 /* Disabled for now */
 	u32	ufreq, freq, ucfg, cfg;
 	struct device_node *pcix_node;
+	struct pci_dn *pdn;
 	u8  	px_bus, px_devfn;
 	struct pci_controller *px_hose;
 
@@ -687,9 +688,10 @@
 		printk("No PCI-X bridge found\n");
 		return;
 	}
-	px_hose = pcix_node->phb;
-	px_bus = pcix_node->busno;
-	px_devfn = pcix_node->devfn;
+	pdn = pcix_node->data;
+	px_hose = pdn->phb;
+	px_bus = pdn->busno;
+	px_devfn = pdn->devfn;
 	
 	early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
 	early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c
index 71fe911..d37bff2 100644
--- a/arch/ppc64/kernel/pmac_pci.c
+++ b/arch/ppc64/kernel/pmac_pci.c
@@ -242,7 +242,7 @@
 	else
 		busdn = hose->arch_data;
 	for (dn = busdn->child; dn; dn = dn->sibling)
-		if (dn->devfn == devfn)
+		if (dn->data && PCI_DN(dn)->devfn == devfn)
 			break;
 	if (dn == NULL)
 		return -1;
@@ -746,9 +746,9 @@
 	 */
 	if (u3_agp) {
 		struct device_node *np = u3_agp->arch_data;
-		np->busno = 0xf0;
+		PCI_DN(np)->busno = 0xf0;
 		for (np = np->child; np; np = np->sibling)
-			np->busno = 0xf0;
+			PCI_DN(np)->busno = 0xf0;
 	}
 
 	pmac_check_ht_link();
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 6ad5a84..7035deb 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -1733,6 +1733,7 @@
 	kfree(node->intrs);
 	kfree(node->addrs);
 	kfree(node->full_name);
+	kfree(node->data);
 	kfree(node);
 }
 
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c
index 1dccada..4a9719b 100644
--- a/arch/ppc64/kernel/rtas_pci.c
+++ b/arch/ppc64/kernel/rtas_pci.c
@@ -48,7 +48,7 @@
 static int ibm_read_pci_config;
 static int ibm_write_pci_config;
 
-static int config_access_valid(struct device_node *dn, int where)
+static int config_access_valid(struct pci_dn *dn, int where)
 {
 	if (where < 256)
 		return 1;
@@ -78,15 +78,17 @@
 	int returnval = -1;
 	unsigned long buid, addr;
 	int ret;
+	struct pci_dn *pdn;
 
-	if (!dn)
+	if (!dn || !dn->data)
 		return PCIBIOS_DEVICE_NOT_FOUND;
-	if (!config_access_valid(dn, where))
+	pdn = dn->data;
+	if (!config_access_valid(pdn, where))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
-		(dn->devfn << 8) | (where & 0xff);
-	buid = dn->phb->buid;
+	addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
+		(pdn->devfn << 8) | (where & 0xff);
+	buid = pdn->phb->buid;
 	if (buid) {
 		ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
 				addr, buid >> 32, buid & 0xffffffff, size);
@@ -98,8 +100,8 @@
 	if (ret)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	if (returnval == EEH_IO_ERROR_VALUE(size)
-	    && eeh_dn_check_failure (dn, NULL))
+	if (returnval == EEH_IO_ERROR_VALUE(size) &&
+	    eeh_dn_check_failure (dn, NULL))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	return PCIBIOS_SUCCESSFUL;
@@ -118,24 +120,28 @@
 
 	/* Search only direct children of the bus */
 	for (dn = busdn->child; dn; dn = dn->sibling)
-		if (dn->devfn == devfn && of_device_available(dn))
+		if (dn->data && PCI_DN(dn)->devfn == devfn
+		    && of_device_available(dn))
 			return rtas_read_config(dn, where, size, val);
+
 	return PCIBIOS_DEVICE_NOT_FOUND;
 }
 
-static int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
+int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
 {
 	unsigned long buid, addr;
 	int ret;
+	struct pci_dn *pdn;
 
-	if (!dn)
+	if (!dn || !dn->data)
 		return PCIBIOS_DEVICE_NOT_FOUND;
-	if (!config_access_valid(dn, where))
+	pdn = dn->data;
+	if (!config_access_valid(pdn, where))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
-		(dn->devfn << 8) | (where & 0xff);
-	buid = dn->phb->buid;
+	addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
+		(pdn->devfn << 8) | (where & 0xff);
+	buid = pdn->phb->buid;
 	if (buid) {
 		ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
 	} else {
@@ -161,7 +167,8 @@
 
 	/* Search only direct children of the bus */
 	for (dn = busdn->child; dn; dn = dn->sibling)
-		if (dn->devfn == devfn && of_device_available(dn))
+		if (dn->data && PCI_DN(dn)->devfn == devfn
+		    && of_device_available(dn))
 			return rtas_write_config(dn, where, size, val);
 	return PCIBIOS_DEVICE_NOT_FOUND;
 }
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index 214914a..57a6db7 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -747,8 +747,8 @@
 	if (bus == NULL || bus->sysdata == NULL)
 		return -ENODEV;
 
-	hose_node = (struct device_node *)bus->sysdata;
-	hose = hose_node->phb;
+	hose_node = bus->sysdata;
+	hose = PCI_DN(hose_node)->phb;
 
 	switch (which) {
 	case IOBASE_BRIDGE_NUMBER:
diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c
index b6e3bca..41ea09c 100644
--- a/arch/ppc64/kernel/u3_iommu.c
+++ b/arch/ppc64/kernel/u3_iommu.c
@@ -276,7 +276,7 @@
 	dn = pci_device_to_OF_node(dev);
 
 	if (dn)
-		dn->iommu_table = &iommu_table_u3;
+		PCI_DN(dn)->iommu_table = &iommu_table_u3;
 }
 
 static void iommu_bus_setup_u3(struct pci_bus *bus)
@@ -291,7 +291,7 @@
 	dn = pci_bus_to_OF_node(bus);
 
 	if (dn)
-		dn->iommu_table = &iommu_table_u3;
+		PCI_DN(dn)->iommu_table = &iommu_table_u3;
 }
 
 static void iommu_dev_setup_null(struct pci_dev *dev) { }