summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 10:38:02 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 10:38:02 -0700
commit3aed77bc84013fced136977b7cc17fff60eddf7a (patch)
tree75ee4060f58f033deb16771a303fb55dd370b6f9 /arch
parent0b968d23610d65a46299347b141a687e207bd294 (diff)
parentb2ad7b5e8115582cdf5bbda065aa516c24d62c21 (diff)
downloadlinux-3aed77bc84013fced136977b7cc17fff60eddf7a.tar.gz
Merge master.kernel.org:/pub/scm/linux/kernel/git/paulus/ppc64-2.6
Diffstat (limited to 'arch')
-rw-r--r--arch/ppc/kernel/syscalls.c4
-rw-r--r--arch/ppc64/Makefile21
-rw-r--r--arch/ppc64/boot/Makefile53
-rw-r--r--arch/ppc64/boot/main.c31
-rw-r--r--arch/ppc64/kernel/bpa_iic.c28
-rw-r--r--arch/ppc64/kernel/eeh.c55
-rw-r--r--arch/ppc64/kernel/iomap.c20
-rw-r--r--arch/ppc64/kernel/iommu.c3
-rw-r--r--arch/ppc64/kernel/maple_pci.c4
-rw-r--r--arch/ppc64/kernel/misc.S6
-rw-r--r--arch/ppc64/kernel/pSeries_iommu.c72
-rw-r--r--arch/ppc64/kernel/pci.c66
-rw-r--r--arch/ppc64/kernel/pci.h1
-rw-r--r--arch/ppc64/kernel/pci_dn.c47
-rw-r--r--arch/ppc64/kernel/pci_iommu.c2
-rw-r--r--arch/ppc64/kernel/pmac_feature.c8
-rw-r--r--arch/ppc64/kernel/pmac_pci.c6
-rw-r--r--arch/ppc64/kernel/prom.c1
-rw-r--r--arch/ppc64/kernel/rtas_pci.c39
-rw-r--r--arch/ppc64/kernel/sys_ppc32.c55
-rw-r--r--arch/ppc64/kernel/syscalls.c4
-rw-r--r--arch/ppc64/kernel/u3_iommu.c4
-rw-r--r--arch/ppc64/kernel/udbg.c6
-rw-r--r--arch/ppc64/mm/init.c4
24 files changed, 333 insertions, 207 deletions
diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
index 124313ce3c09..127f040de9de 100644
--- a/arch/ppc/kernel/syscalls.c
+++ b/arch/ppc/kernel/syscalls.c
@@ -41,10 +41,6 @@
 #include <asm/ipc.h>
 #include <asm/semaphore.h>
 
-void
-check_bugs(void)
-{
-}
 
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
index 8189953a372c..a91daa324e88 100644
--- a/arch/ppc64/Makefile
+++ b/arch/ppc64/Makefile
@@ -89,11 +89,12 @@ drivers-$(CONFIG_OPROFILE)	+= arch/ppc64/oprofile/
 
 boot := arch/ppc64/boot
 
-boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd
-boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd
-boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm
-boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd
-$(boottarget-y): vmlinux
+boottargets-$(CONFIG_PPC_PSERIES) += zImage zImage.initrd
+boottargets-$(CONFIG_PPC_PMAC) += zImage.vmode zImage.initrd.vmode
+boottargets-$(CONFIG_PPC_MAPLE) += zImage zImage.initrd
+boottargets-$(CONFIG_PPC_ISERIES) += vmlinux.sminitrd vmlinux.initrd vmlinux.sm
+boottargets-$(CONFIG_PPC_BPA) += zImage zImage.initrd
+$(boottargets-y): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage
@@ -131,10 +132,12 @@ include3/asm:
 	$(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm
 
 define archhelp
-  echo  '* zImage       - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
-  echo  '  zImage.initrd- Compressed kernel image with initrd attached,'
-  echo  '		   sourced from arch/$(ARCH)/boot/ramdisk.image.gz'
-  echo  '		   (arch/$(ARCH)/boot/zImage.initrd)'
+  echo  '  zImage.vmode        - Compressed kernel image (arch/$(ARCH)/boot/zImage.vmode)'
+  echo  '  zImage.initrd.vmode - Compressed kernel image with initrd attached,'
+  echo  '                        sourced from arch/$(ARCH)/boot/ramdisk.image.gz'
+  echo  '                        (arch/$(ARCH)/boot/zImage.initrd.vmode)'
+  echo  '  zImage              - zImage for pSeries machines'
+  echo  '  zImage.initrd       - zImage with initrd for pSeries machines'
 endef
 
 CLEAN_FILES += include/asm-ppc64/offsets.h
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
index 2c5f5e73d00c..33fdc8710891 100644
--- a/arch/ppc64/boot/Makefile
+++ b/arch/ppc64/boot/Makefile
@@ -37,6 +37,9 @@ quiet_cmd_bootcc = BOOTCC  $@
 quiet_cmd_bootas = BOOTAS  $@
       cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
 
+quiet_cmd_bootld = BOOTLD  $@
+      cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2)
+
 $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c
 	$(call if_changed_dep,bootcc)
 $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S
@@ -53,7 +56,7 @@ src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
 gz-sec  = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
 
 hostprogs-y		:= addnote addRamDisk
-targets 		+= zImage zImage.initrd imagesize.c \
+targets 		+= zImage.vmode zImage.initrd.vmode zImage zImage.initrd imagesize.c \
 			   $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
 			   $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
 			   $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
@@ -63,7 +66,7 @@ extra-y			:= initrd.o
 quiet_cmd_ramdisk = RAMDISK $@
       cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@
 
-quiet_cmd_stripvm = STRIP $@
+quiet_cmd_stripvm = STRIP   $@
       cmd_stripvm = $(STRIP) -s $< -o $@
 
 vmlinux.strip: vmlinux FORCE
@@ -71,12 +74,20 @@ vmlinux.strip: vmlinux FORCE
 $(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE
 	$(call if_changed,ramdisk)
 
-addsection = $(CROSS32OBJCOPY) $(1) \
-		--add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \
-		--set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS)
+quiet_cmd_addsection = ADDSEC  $@
+      cmd_addsection = $(CROSS32OBJCOPY) $@ \
+		--add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \
+		--set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS)
+
+quiet_cmd_imagesize = GENSIZE $@
+      cmd_imagesize = ls -l vmlinux.strip | \
+		awk '{printf "/* generated -- do not edit! */\n" "unsigned long vmlinux_filesize = %d;\n", $$5}' \
+		> $(obj)/imagesize.c && \
+		$(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
+		awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c
 
-quiet_cmd_addnote = ADDNOTE $@ 
-      cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@
+quiet_cmd_addnote = ADDNOTE $@
+      cmd_addnote = $(obj)/addnote $@
 
 $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE
 	$(call if_changed,gzip)
@@ -85,28 +96,30 @@ $(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz
 	cp -f $(obj)/ramdisk.image.gz $@
 
 $(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE
-	touch $@
+	@touch $@
 
 $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE
 	$(call if_changed_dep,bootcc)
-	$(call addsection, $@)
+	$(call cmd,addsection)
+
+$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required))
+$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE
+	$(call cmd,bootld,$(obj-boot))
+
+$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd))
+$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE
+	$(call cmd,bootld,$(obj-boot))
 
-$(obj)/zImage: obj-boot += $(call obj-sec, $(required))
-$(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) $(obj)/addnote FORCE
+$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote FORCE
+	@cp -f $< $@
 	$(call if_changed,addnote)
 
-$(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd))
-$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE
+$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE
+	@cp -f $< $@
 	$(call if_changed,addnote)
 
 $(obj)/imagesize.c: vmlinux.strip
-	@echo Generating $@
-	ls -l vmlinux.strip | \
-	awk '{printf "/* generated -- do not edit! */\n" \
-		"unsigned long vmlinux_filesize = %d;\n", $$5}' > $(obj)/imagesize.c
-	$(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
-	awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' \
-		>> $(obj)/imagesize.c
+	$(call cmd,imagesize)
 
 install: $(CONFIGURE) $(BOOTIMAGE)
 	sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
index 99e68cfbe688..f7ec19a2d0b0 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -23,7 +23,8 @@ extern void flush_cache(void *, unsigned long);
 
 /* Value picked to match that used by yaboot */
 #define PROG_START	0x01400000
-#define RAM_END		(256<<20) // Fixme: use OF */
+#define RAM_END		(512<<20) // Fixme: use OF */
+#define	ONE_MB		0x100000
 
 static char *avail_ram;
 static char *begin_avail, *end_avail;
@@ -32,6 +33,7 @@ static unsigned int heap_use;
 static unsigned int heap_max;
 
 extern char _start[];
+extern char _end[];
 extern char _vmlinux_start[];
 extern char _vmlinux_end[];
 extern char _initrd_start[];
@@ -58,13 +60,13 @@ typedef void (*kernel_entry_t)( unsigned long,
 
 #undef DEBUG
 
-static unsigned long claim_base = PROG_START;
+static unsigned long claim_base;
 
 static unsigned long try_claim(unsigned long size)
 {
 	unsigned long addr = 0;
 
-	for(; claim_base < RAM_END; claim_base += 0x100000) {
+	for(; claim_base < RAM_END; claim_base += ONE_MB) {
 #ifdef DEBUG
 		printf("    trying: 0x%08lx\n\r", claim_base);
 #endif
@@ -95,7 +97,26 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
 	if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
 		exit();
 
-	printf("\n\rzImage starting: loaded at 0x%x\n\r", (unsigned)_start);
+	printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned long) _start);
+
+	/*
+	 * The first available claim_base must be above the end of the
+	 * the loaded kernel wrapper file (_start to _end includes the
+	 * initrd image if it is present) and rounded up to a nice
+	 * 1 MB boundary for good measure.
+	 */
+
+	claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
+
+#if defined(PROG_START)
+	/*
+	 * Maintain a "magic" minimum address. This keeps some older
+	 * firmware platforms running.
+	 */
+
+	if (claim_base < PROG_START)
+		claim_base = PROG_START;
+#endif
 
 	/*
 	 * Now we try to claim some memory for the kernel itself
@@ -105,7 +126,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
 	 * size... In practice we add 1Mb, that is enough, but we should really
 	 * consider fixing the Makefile to put a _raw_ kernel in there !
 	 */
-	vmlinux_memsize += 0x100000;
+	vmlinux_memsize += ONE_MB;
 	printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize);
 	vmlinux.addr = try_claim(vmlinux_memsize);
 	if (vmlinux.addr == 0) {
diff --git a/arch/ppc64/kernel/bpa_iic.c b/arch/ppc64/kernel/bpa_iic.c
index c8f3dc3fad70..0aaa878e19d3 100644
--- a/arch/ppc64/kernel/bpa_iic.c
+++ b/arch/ppc64/kernel/bpa_iic.c
@@ -205,6 +205,18 @@ static struct iic_regs __iomem *find_iic(int cpu)
 }
 
 #ifdef CONFIG_SMP
+
+/* Use the highest interrupt priorities for IPI */
+static inline int iic_ipi_to_irq(int ipi)
+{
+	return IIC_IPI_OFFSET + IIC_NUM_IPIS - 1 - ipi;
+}
+
+static inline int iic_irq_to_ipi(int irq)
+{
+	return IIC_NUM_IPIS - 1 - (irq - IIC_IPI_OFFSET);
+}
+
 void iic_setup_cpu(void)
 {
 	out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
@@ -212,18 +224,20 @@ void iic_setup_cpu(void)
 
 void iic_cause_IPI(int cpu, int mesg)
 {
-	out_be64(&per_cpu(iic, cpu).regs->generate, mesg);
+	out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4);
 }
 
 static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
 {
-
-	smp_message_recv(irq - IIC_IPI_OFFSET, regs);
+	smp_message_recv(iic_irq_to_ipi(irq), regs);
 	return IRQ_HANDLED;
 }
 
-static void iic_request_ipi(int irq, const char *name)
+static void iic_request_ipi(int ipi, const char *name)
 {
+	int irq;
+
+	irq = iic_ipi_to_irq(ipi);
 	/* IPIs are marked SA_INTERRUPT as they must run with irqs
 	 * disabled */
 	get_irq_desc(irq)->handler = &iic_pic;
@@ -233,10 +247,10 @@ static void iic_request_ipi(int irq, const char *name)
 
 void iic_request_IPIs(void)
 {
-	iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call");
-	iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched");
+	iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call");
+	iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched");
 #ifdef CONFIG_DEBUGGER
-	iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
+	iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
 #endif /* CONFIG_DEBUGGER */
 }
 #endif /* CONFIG_SMP */
diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
index 4c857a6516fc..ba93fd731222 100644
--- a/arch/ppc64/kernel/eeh.c
+++ b/arch/ppc64/kernel/eeh.c
@@ -254,6 +254,7 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
 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 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
 	}
 
 	/* 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 @@ int eeh_unregister_notifier(struct notifier_block *nb)
 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 @@ static int read_slot_reset_state(struct device_node *dn, int rets[])
 		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 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
 	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 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
 
 	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 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
 	 * 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 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
 	}
 
 	/* 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 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
 	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 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
 	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 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
 
 	/* 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 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
 		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 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
 				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 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
 
 			/* 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 @@ void __init eeh_init(void)
 	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 @@ void eeh_add_device_early(struct device_node *dn)
 	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/iomap.c b/arch/ppc64/kernel/iomap.c
index 09a3062309e7..6160c8dbb7c5 100644
--- a/arch/ppc64/kernel/iomap.c
+++ b/arch/ppc64/kernel/iomap.c
@@ -22,13 +22,23 @@ unsigned int fastcall ioread16(void __iomem *addr)
 {
 	return readw(addr);
 }
+unsigned int fastcall ioread16be(void __iomem *addr)
+{
+	return in_be16(addr);
+}
 unsigned int fastcall ioread32(void __iomem *addr)
 {
 	return readl(addr);
 }
+unsigned int fastcall ioread32be(void __iomem *addr)
+{
+	return in_be32(addr);
+}
 EXPORT_SYMBOL(ioread8);
 EXPORT_SYMBOL(ioread16);
+EXPORT_SYMBOL(ioread16be);
 EXPORT_SYMBOL(ioread32);
+EXPORT_SYMBOL(ioread32be);
 
 void fastcall iowrite8(u8 val, void __iomem *addr)
 {
@@ -38,13 +48,23 @@ void fastcall iowrite16(u16 val, void __iomem *addr)
 {
 	writew(val, addr);
 }
+void fastcall iowrite16be(u16 val, void __iomem *addr)
+{
+	out_be16(addr, val);
+}
 void fastcall iowrite32(u32 val, void __iomem *addr)
 {
 	writel(val, addr);
 }
+void fastcall iowrite32be(u32 val, void __iomem *addr)
+{
+	out_be32(addr, val);
+}
 EXPORT_SYMBOL(iowrite8);
 EXPORT_SYMBOL(iowrite16);
+EXPORT_SYMBOL(iowrite16be);
 EXPORT_SYMBOL(iowrite32);
+EXPORT_SYMBOL(iowrite32be);
 
 /*
  * These are the "repeat read/write" functions. Note the
diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c
index 845eebd1e28d..9032b6bfe036 100644
--- a/arch/ppc64/kernel/iommu.c
+++ b/arch/ppc64/kernel/iommu.c
@@ -438,7 +438,8 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl)
 
 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 53993999b265..5a8b4d8c2dd6 100644
--- a/arch/ppc64/kernel/maple_pci.c
+++ b/arch/ppc64/kernel/maple_pci.c
@@ -447,9 +447,9 @@ void __init maple_pci_init(void)
 	 */
 	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/misc.S b/arch/ppc64/kernel/misc.S
index 6d860c1d9fa0..c047663eb48d 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -1431,9 +1431,9 @@ _GLOBAL(sys_call_table)
 	.llong .sys_ni_syscall		/* 195 - 32bit only stat64 */
 	.llong .sys_ni_syscall		/* 32bit only lstat64 */
 	.llong .sys_ni_syscall		/* 32bit only fstat64 */
-	.llong .sys_ni_syscall		/* 32bit only pciconfig_read */
-	.llong .sys_ni_syscall		/* 32bit only pciconfig_write */
-	.llong .sys_ni_syscall		/* 32bit only pciconfig_iobase */
+	.llong .sys_pciconfig_read
+	.llong .sys_pciconfig_write
+	.llong .sys_pciconfig_iobase	/* 200 - pciconfig_iobase */
 	.llong .sys_ni_syscall		/* reserved for MacOnLinux */
 	.llong .sys_getdents64
 	.llong .sys_pivot_root
diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c
index 9d5e1e7fc389..f0fd7fbd6531 100644
--- a/arch/ppc64/kernel/pSeries_iommu.c
+++ b/arch/ppc64/kernel/pSeries_iommu.c
@@ -295,7 +295,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
 				      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_table_setparms_lpar(struct pci_controller *phb,
 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 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
 	 */
 
 	dn = pci_bus_to_OF_node(bus);
+	pci = dn->data;
 
 	if (!bus->self) {
 		/* Root bus */
@@ -341,18 +343,18 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
 				 * 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 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
 			 * 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 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
 
 			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 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
 {
 	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 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
 		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 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev)
 	 */
 	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 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
 {
 	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 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
 	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 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
 	 */
 	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 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
 		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 b5ca7d8347e2..8447dcc2c2b3 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -21,6 +21,7 @@
 #include <linux/bootmem.h>
 #include <linux/mm.h>
 #include <linux/list.h>
+#include <linux/syscalls.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
@@ -837,9 +838,11 @@ int pcibios_scan_all_fns(struct pci_bus *bus, int devfn)
         * 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;
 }
@@ -982,3 +985,62 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
 }
 
 #endif /* CONFIG_PPC_MULTIPLATFORM */
+
+
+#define IOBASE_BRIDGE_NUMBER	0
+#define IOBASE_MEMORY		1
+#define IOBASE_IO		2
+#define IOBASE_ISA_IO		3
+#define IOBASE_ISA_MEM		4
+
+long sys_pciconfig_iobase(long which, unsigned long in_bus,
+			  unsigned long in_devfn)
+{
+	struct pci_controller* hose;
+	struct list_head *ln;
+	struct pci_bus *bus = NULL;
+	struct device_node *hose_node;
+
+	/* Argh ! Please forgive me for that hack, but that's the
+	 * simplest way to get existing XFree to not lockup on some
+	 * G5 machines... So when something asks for bus 0 io base
+	 * (bus 0 is HT root), we return the AGP one instead.
+	 */
+#ifdef CONFIG_PPC_PMAC
+	if (systemcfg->platform == PLATFORM_POWERMAC &&
+	    machine_is_compatible("MacRISC4"))
+		if (in_bus == 0)
+			in_bus = 0xf0;
+#endif /* CONFIG_PPC_PMAC */
+
+	/* That syscall isn't quite compatible with PCI domains, but it's
+	 * used on pre-domains setup. We return the first match
+	 */
+
+	for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
+		bus = pci_bus_b(ln);
+		if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate))
+			break;
+		bus = NULL;
+	}
+	if (bus == NULL || bus->sysdata == NULL)
+		return -ENODEV;
+
+	hose_node = (struct device_node *)bus->sysdata;
+	hose = PCI_DN(hose_node)->phb;
+
+	switch (which) {
+	case IOBASE_BRIDGE_NUMBER:
+		return (long)hose->first_busno;
+	case IOBASE_MEMORY:
+		return (long)hose->pci_mem_offset;
+	case IOBASE_IO:
+		return (long)hose->io_base_phys;
+	case IOBASE_ISA_IO:
+		return (long)isa_io_base;
+	case IOBASE_ISA_MEM:
+		return -EINVAL;
+	}
+
+	return -EOPNOTSUPP;
+}
diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
index 26be78b13af1..5eb2cc320566 100644
--- a/arch/ppc64/kernel/pci.h
+++ b/arch/ppc64/kernel/pci.h
@@ -34,7 +34,6 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
 
 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 ec345462afc3..a86389d07d57 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 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
 	struct pci_controller *phb = data;
 	int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL);
 	u32 *regs;
-
-	dn->phb = phb;
+	struct pci_dn *pdn;
+
+	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 *traverse_pci_devices(struct device_node *start, traverse_func pre,
 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 @@ void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
 
 /*
  * 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 @@ static void *is_devfn_node(struct device_node *dn, void *data)
 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 @@ EXPORT_SYMBOL(fetch_dev_dn);
 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 ef0a62b916be..14647e09c9cd 100644
--- a/arch/ppc64/kernel/pci_iommu.c
+++ b/arch/ppc64/kernel/pci_iommu.c
@@ -66,7 +66,7 @@ static inline struct iommu_table *devnode_table(struct device *dev)
 #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 98ed2bccab1a..eb4e6c3f694d 100644
--- a/arch/ppc64/kernel/pmac_feature.c
+++ b/arch/ppc64/kernel/pmac_feature.c
@@ -674,6 +674,7 @@ void __init pmac_check_ht_link(void)
 #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 @@ void __init pmac_check_ht_link(void)
 		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 71fe911ad183..d37bff2d7d40 100644
--- a/arch/ppc64/kernel/pmac_pci.c
+++ b/arch/ppc64/kernel/pmac_pci.c
@@ -242,7 +242,7 @@ static int u3_ht_skip_device(struct pci_controller *hose,
 	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 @@ void __init pmac_pci_init(void)
 	 */
 	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 6ad5a8467f87..7035deb6de92 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -1733,6 +1733,7 @@ static void of_node_release(struct kref *kref)
 	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 1dccadaddd1d..4a9719b48abe 100644
--- a/arch/ppc64/kernel/rtas_pci.c
+++ b/arch/ppc64/kernel/rtas_pci.c
@@ -48,7 +48,7 @@ static int write_pci_config;
 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 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
 	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 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
 	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 @@ static int rtas_pci_read_config(struct pci_bus *bus,
 
 	/* 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 @@ static int rtas_pci_write_config(struct pci_bus *bus,
 
 	/* 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 214914a95a50..e93c13458910 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -708,62 +708,9 @@ asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubu
 				   compat_ptr(ubuf));
 }
 
-#define IOBASE_BRIDGE_NUMBER	0
-#define IOBASE_MEMORY		1
-#define IOBASE_IO		2
-#define IOBASE_ISA_IO		3
-#define IOBASE_ISA_MEM		4
-
 asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
 {
-#ifdef CONFIG_PCI
-	struct pci_controller* hose;
-	struct list_head *ln;
-	struct pci_bus *bus = NULL;
-	struct device_node *hose_node;
-
-	/* Argh ! Please forgive me for that hack, but that's the
-	 * simplest way to get existing XFree to not lockup on some
-	 * G5 machines... So when something asks for bus 0 io base
-	 * (bus 0 is HT root), we return the AGP one instead.
-	 */
-#ifdef CONFIG_PPC_PMAC
-	if (systemcfg->platform == PLATFORM_POWERMAC &&
-	    machine_is_compatible("MacRISC4"))
-		if (in_bus == 0)
-			in_bus = 0xf0;
-#endif /* CONFIG_PPC_PMAC */
-
-	/* That syscall isn't quite compatible with PCI domains, but it's
-	 * used on pre-domains setup. We return the first match
-	 */
-
-	for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		bus = pci_bus_b(ln);
-		if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate))
-			break;
-		bus = NULL;
-	}
-	if (bus == NULL || bus->sysdata == NULL)
-		return -ENODEV;
-
-	hose_node = (struct device_node *)bus->sysdata;
-	hose = hose_node->phb;
-
-	switch (which) {
-	case IOBASE_BRIDGE_NUMBER:
-		return (long)hose->first_busno;
-	case IOBASE_MEMORY:
-		return (long)hose->pci_mem_offset;
-	case IOBASE_IO:
-		return (long)hose->io_base_phys;
-	case IOBASE_ISA_IO:
-		return (long)isa_io_base;
-	case IOBASE_ISA_MEM:
-		return -EINVAL;
-	}
-#endif	/* CONFIG_PCI */
-	return -EOPNOTSUPP;
+	return sys_pciconfig_iobase(which, in_bus, in_devfn);
 }
 
 
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c
index a8cbb202b8cd..05f16633bd2c 100644
--- a/arch/ppc64/kernel/syscalls.c
+++ b/arch/ppc64/kernel/syscalls.c
@@ -46,10 +46,6 @@
 
 extern unsigned long wall_jiffies;
 
-void
-check_bugs(void)
-{
-}
 
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c
index b6e3bca4102d..41ea09cb9ac7 100644
--- a/arch/ppc64/kernel/u3_iommu.c
+++ b/arch/ppc64/kernel/u3_iommu.c
@@ -276,7 +276,7 @@ static void iommu_dev_setup_u3(struct pci_dev *dev)
 	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 @@ static void iommu_bus_setup_u3(struct pci_bus *bus)
 	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) { }
diff --git a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c
index ed6766e21f5a..d49c3613c8ec 100644
--- a/arch/ppc64/kernel/udbg.c
+++ b/arch/ppc64/kernel/udbg.c
@@ -158,14 +158,20 @@ static struct console udbg_console = {
 	.index	= -1,
 };
 
+static int early_console_initialized;
+
 void __init disable_early_printk(void)
 {
+	if (!early_console_initialized)
+		return;
 	unregister_console(&udbg_console);
+	early_console_initialized = 0;
 }
 
 /* called by setup_system */
 void register_early_udbg_console(void)
 {
+	early_console_initialized = 1;
 	register_console(&udbg_console);
 }
 
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index a14ab87df491..c2157c9c3acb 100644
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -554,12 +554,12 @@ void __init do_init_bootmem(void)
 	 * present.
 	 */
 	for (i=0; i < lmb.memory.cnt; i++)
-		free_bootmem(lmb_start_pfn(&lmb.memory, i),
+		free_bootmem(lmb.memory.region[i].base,
 			     lmb_size_bytes(&lmb.memory, i));
 
 	/* reserve the sections we're already using */
 	for (i=0; i < lmb.reserved.cnt; i++)
-		reserve_bootmem(lmb_start_pfn(&lmb.reserved, i),
+		reserve_bootmem(lmb.reserved.region[i].base,
 				lmb_size_bytes(&lmb.reserved, i));
 
 	for (i=0; i < lmb.memory.cnt; i++)