Browse Source

Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge

Linus Torvalds 19 years ago
parent
commit
87530db5ec
80 changed files with 3452 additions and 937 deletions
  1. 2 5
      arch/powerpc/Makefile
  2. 34 15
      arch/powerpc/boot/Makefile
  3. 13 8
      arch/powerpc/boot/crt0.S
  4. 84 0
      arch/powerpc/boot/hack-coff.c
  5. 22 24
      arch/powerpc/boot/main.c
  6. 102 436
      arch/powerpc/boot/prom.c
  7. 26 10
      arch/powerpc/boot/prom.h
  8. 243 0
      arch/powerpc/boot/rs6000.h
  9. 325 0
      arch/powerpc/boot/stdio.c
  10. 0 6
      arch/powerpc/boot/stdio.h
  11. 17 3
      arch/powerpc/boot/string.S
  12. 46 0
      arch/powerpc/boot/zImage.coff.lds
  13. 911 0
      arch/powerpc/configs/mpc834x_sys_defconfig
  14. 1 1
      arch/powerpc/kernel/asm-offsets.c
  15. 2 2
      arch/powerpc/kernel/cpu_setup_power4.S
  16. 154 70
      arch/powerpc/kernel/cputable.c
  17. 1 1
      arch/powerpc/kernel/entry_32.S
  18. 7 8
      arch/powerpc/kernel/entry_64.S
  19. 5 5
      arch/powerpc/kernel/fpu.S
  20. 60 52
      arch/powerpc/kernel/head_64.S
  21. 4 4
      arch/powerpc/kernel/idle_power4.S
  22. 4 8
      arch/powerpc/kernel/irq.c
  23. 5 8
      arch/powerpc/kernel/lparcfg.c
  24. 2 2
      arch/powerpc/kernel/misc_32.S
  25. 5 5
      arch/powerpc/kernel/misc_64.S
  26. 24 12
      arch/powerpc/kernel/paca.c
  27. 1 2
      arch/powerpc/kernel/ppc_ksyms.c
  28. 101 8
      arch/powerpc/kernel/prom.c
  29. 2 1
      arch/powerpc/kernel/prom_parse.c
  30. 95 1
      arch/powerpc/kernel/rtas.c
  31. 6 3
      arch/powerpc/kernel/setup-common.c
  32. 1 1
      arch/powerpc/kernel/time.c
  33. 2 6
      arch/powerpc/lib/locks.c
  34. 4 4
      arch/powerpc/oprofile/common.c
  35. 1 0
      arch/powerpc/platforms/83xx/Kconfig
  36. 243 0
      arch/powerpc/platforms/83xx/mpc834x_sys.c
  37. 23 0
      arch/powerpc/platforms/83xx/mpc834x_sys.h
  38. 14 0
      arch/powerpc/platforms/83xx/mpc83xx.h
  39. 99 0
      arch/powerpc/platforms/83xx/pci.c
  40. 17 10
      arch/powerpc/platforms/chrp/pci.c
  41. 4 3
      arch/powerpc/platforms/chrp/setup.c
  42. 5 2
      arch/powerpc/platforms/chrp/time.c
  43. 2 4
      arch/powerpc/platforms/iseries/irq.c
  44. 2 1
      arch/powerpc/platforms/iseries/misc.S
  45. 4 4
      arch/powerpc/platforms/iseries/setup.c
  46. 1 1
      arch/powerpc/platforms/iseries/smp.c
  47. 2 2
      arch/powerpc/platforms/pseries/lpar.c
  48. 100 0
      arch/powerpc/platforms/pseries/reconfig.c
  49. 9 11
      arch/powerpc/platforms/pseries/setup.c
  50. 1 0
      arch/powerpc/sysdev/Makefile
  51. 317 0
      arch/powerpc/sysdev/fsl_soc.c
  52. 8 0
      arch/powerpc/sysdev/fsl_soc.h
  53. 77 0
      arch/ppc/kernel/head_8xx.S
  54. 0 1
      arch/ppc/kernel/ppc_ksyms.c
  55. 4 6
      arch/ppc/platforms/83xx/mpc834x_sys.c
  56. 6 8
      arch/ppc/platforms/85xx/mpc8540_ads.c
  57. 4 7
      arch/ppc/platforms/85xx/mpc8560_ads.c
  58. 8 8
      arch/ppc/platforms/85xx/mpc85xx_cds_common.c
  59. 4 6
      arch/ppc/platforms/85xx/sbc8560.c
  60. 4 6
      arch/ppc/platforms/85xx/stx_gp3.c
  61. 6 10
      arch/ppc/platforms/85xx/tqm85xx.c
  62. 8 2
      arch/ppc/syslib/mpc83xx_devices.c
  63. 8 2
      arch/ppc/syslib/mpc85xx_devices.c
  64. 8 5
      drivers/macintosh/macio-adb.c
  65. 24 0
      fs/proc/proc_devtree.c
  66. 23 23
      include/asm-powerpc/atomic.h
  67. 3 3
      include/asm-powerpc/bitops.h
  68. 9 5
      include/asm-powerpc/cputable.h
  69. 7 9
      include/asm-powerpc/elf.h
  70. 1 1
      include/asm-powerpc/futex.h
  71. 5 0
      include/asm-powerpc/hvcall.h
  72. 5 1
      include/asm-powerpc/lppaca.h
  73. 1 13
      include/asm-powerpc/paca.h
  74. 40 36
      include/asm-powerpc/ppc_asm.h
  75. 8 0
      include/asm-powerpc/prom.h
  76. 11 10
      include/asm-powerpc/spinlock.h
  77. 4 19
      include/asm-powerpc/synch.h
  78. 4 4
      include/asm-powerpc/system.h
  79. 2 3
      include/asm-powerpc/time.h
  80. 5 0
      include/linux/proc_fs.h

+ 2 - 5
arch/powerpc/Makefile

@@ -139,17 +139,14 @@ drivers-$(CONFIG_CPM2)		+= arch/ppc/8260_io/
 
 drivers-$(CONFIG_OPROFILE)	+= arch/powerpc/oprofile/
 
-defaultimage-$(CONFIG_PPC32)	:= zImage
+# Default to zImage, override when needed
+defaultimage-y			:= zImage
 defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
-defaultimage-$(CONFIG_PPC_PSERIES) := zImage
 KBUILD_IMAGE := $(defaultimage-y)
 all: $(KBUILD_IMAGE)
 
 CPPFLAGS_vmlinux.lds	:= -Upowerpc
 
-# All the instructions talk about "make bzImage".
-bzImage: zImage
-
 BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage
 
 .PHONY: $(BOOT_TARGETS)

+ 34 - 15
arch/powerpc/boot/Makefile

@@ -25,8 +25,8 @@ HOSTCC		:= gcc
 BOOTCFLAGS	:= $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \
 		   $(shell $(CROSS32CC) -print-file-name=include) -fPIC
 BOOTAFLAGS	:= -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
-BOOTLFLAGS	:= -T $(srctree)/$(src)/zImage.lds
 OBJCOPYFLAGS    := contents,alloc,load,readonly,data
+OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000
 
 zlib       := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
 zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h
@@ -35,7 +35,7 @@ zliblinuxheader := zlib.h zconf.h zutil.h
 $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
 #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
 
-src-boot := string.S prom.c main.c div64.S crt0.S
+src-boot := crt0.S string.S prom.c stdio.c main.c div64.S
 src-boot += $(zlib)
 src-boot := $(addprefix $(obj)/, $(src-boot))
 obj-boot := $(addsuffix .o, $(basename $(src-boot)))
@@ -70,7 +70,7 @@ quiet_cmd_bootas = BOOTAS  $@
       cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
 
 quiet_cmd_bootld = BOOTLD  $@
-      cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2)
+      cmd_bootld = $(CROSS32LD) -T $(srctree)/$(src)/$(3) -o $@ $(2)
 
 $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c
 	$(call if_changed_dep,bootcc)
@@ -87,12 +87,14 @@ obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section)))
 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.vmode zImage.initrd.vmode zImage zImage.initrd \
-			   $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
-			   $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
-			   $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
-			   vmlinux.initrd
+hostprogs-y		:= addnote addRamDisk hack-coff
+
+targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
+	   zImage.coff zImage.initrd.coff \
+	   $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
+	   $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
+	   $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
+	   vmlinux.initrd
 extra-y			:= initrd.o
 
 quiet_cmd_ramdisk = RAMDISK $@
@@ -114,6 +116,10 @@ quiet_cmd_addsection = ADDSEC  $@
 quiet_cmd_addnote = ADDNOTE $@
       cmd_addnote = $(obj)/addnote $@
 
+quiet_cmd_gencoff = COFF    $@
+      cmd_gencoff = $(OBJCOPY) $(OBJCOPY_COFF_ARGS) $@ && \
+		    $(obj)/hack-coff $@
+
 $(call gz-sec, $(required)): $(obj)/kernel-%.gz: %
 	$(call if_changed,gzip)
 
@@ -127,22 +133,35 @@ $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c
 	$(call if_changed_dep,bootcc)
 	$(call cmd,addsection)
 
-$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required))
+$(obj)/zImage.vmode $(obj)/zImage.coff: obj-boot += $(call obj-sec, $(required))
 $(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds
-	$(call cmd,bootld,$(obj-boot))
+	$(call cmd,bootld,$(obj-boot),zImage.lds)
 
-$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd))
+$(obj)/zImage.initrd.vmode $(obj)/zImage.initrd.coff: obj-boot += $(call obj-sec, $(required) $(initrd))
 $(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds
-	$(call cmd,bootld,$(obj-boot))
+	$(call cmd,bootld,$(obj-boot),zImage.lds)
+
+# For 32-bit powermacs, build the COFF images as well as the ELF images.
+coffimage-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.coff
+coffrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.initrd.coff
 
-$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote
+$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote $(coffimage-y-y)
 	@cp -f $< $@
 	$(call if_changed,addnote)
 
-$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote
+$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote $(coffrdimg-y-y)
 	@cp -f $< $@
 	$(call if_changed,addnote)
 
+$(obj)/zImage.coff: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
+	$(call cmd,bootld,$(obj-boot),zImage.coff.lds)
+	$(call cmd,gencoff)
+
+$(obj)/zImage.initrd.coff: $(call obj-sec, $(required) $(initrd)) $(obj-boot) \
+			   $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
+	$(call cmd,bootld,$(obj-boot),zImage.coff.lds)
+	$(call cmd,gencoff)
+
 #-----------------------------------------------------------
 # build u-boot images
 #-----------------------------------------------------------

+ 13 - 8
arch/powerpc/boot/crt0.S

@@ -12,17 +12,23 @@
 #include "ppc_asm.h"
 
 	.text
+	/* a procedure descriptor used when booting this as a COFF file */
+_zimage_start_opd:
+	.long	_zimage_start, 0, 0, 0
+
 	.globl	_zimage_start
 _zimage_start:
+	/* Work out the offset between the address we were linked at
+	   and the address where we're running. */
 	bl	1f
-
-1:
-	mflr	r0
+1:	mflr	r0
 	lis	r9,1b@ha
 	addi	r9,r9,1b@l
 	subf.	r0,r9,r0
-	beq	3f
+	beq	3f		/* if running at same address as linked */
 
+	/* The .got2 section contains a list of addresses, so add
+	   the address offset onto each entry. */
 	lis	r9,__got2_start@ha
 	addi	r9,r9,__got2_start@l
 	lis	r8,__got2_end@ha
@@ -32,15 +38,14 @@ _zimage_start:
 	srwi.	r8,r8,2
 	mtctr	r8
 	add	r9,r0,r9
-2:
-	lwz	r8,0(r9)
+2:	lwz	r8,0(r9)
 	add	r8,r8,r0
 	stw	r8,0(r9)
 	addi	r9,r9,4
 	bdnz	2b
 
-3:
-	lis	r9,_start@h
+	/* Do a cache flush for our text, in case OF didn't */
+3:	lis	r9,_start@h
 	add	r9,r0,r9
 	lis	r8,_etext@ha
 	addi	r8,r8,_etext@l

+ 84 - 0
arch/powerpc/boot/hack-coff.c

@@ -0,0 +1,84 @@
+/*
+ * hack-coff.c - hack the header of an xcoff file to fill in
+ * a few fields needed by the Open Firmware xcoff loader on
+ * Power Macs but not initialized by objcopy.
+ *
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include "rs6000.h"
+
+#define AOUT_MAGIC	0x010b
+
+#define get_16be(x)	((((unsigned char *)(x))[0] << 8) \
+			 + ((unsigned char *)(x))[1])
+#define put_16be(x, v)	(((unsigned char *)(x))[0] = (v) >> 8, \
+			 ((unsigned char *)(x))[1] = (v) & 0xff)
+#define get_32be(x)	((((unsigned char *)(x))[0] << 24) \
+			 + (((unsigned char *)(x))[1] << 16) \
+			 + (((unsigned char *)(x))[2] << 8) \
+			 + ((unsigned char *)(x))[3])
+
+int
+main(int ac, char **av)
+{
+    int fd;
+    int i, nsect;
+    int aoutsz;
+    struct external_filehdr fhdr;
+    AOUTHDR aout;
+    struct external_scnhdr shdr;
+
+    if (ac != 2) {
+	fprintf(stderr, "Usage: hack-coff coff-file\n");
+	exit(1);
+    }
+    if ((fd = open(av[1], 2)) == -1) {
+	perror(av[2]);
+	exit(1);
+    }
+    if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr))
+	goto readerr;
+    i = get_16be(fhdr.f_magic);
+    if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) {
+	fprintf(stderr, "%s: not an xcoff file\n", av[1]);
+	exit(1);
+    }
+    aoutsz = get_16be(fhdr.f_opthdr);
+    if (read(fd, &aout, aoutsz) != aoutsz)
+	goto readerr;
+    nsect = get_16be(fhdr.f_nscns);
+    for (i = 0; i < nsect; ++i) {
+	if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
+	    goto readerr;
+	if (strcmp(shdr.s_name, ".text") == 0) {
+	    put_16be(aout.o_snentry, i+1);
+	    put_16be(aout.o_sntext, i+1);
+	} else if (strcmp(shdr.s_name, ".data") == 0) {
+	    put_16be(aout.o_sndata, i+1);
+	} else if (strcmp(shdr.s_name, ".bss") == 0) {
+	    put_16be(aout.o_snbss, i+1);
+	}
+    }
+    put_16be(aout.magic, AOUT_MAGIC);
+    if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1
+	|| write(fd, &aout, aoutsz) != aoutsz) {
+	fprintf(stderr, "%s: write error\n", av[1]);
+	exit(1);
+    }
+    close(fd);
+    exit(0);
+
+readerr:
+    fprintf(stderr, "%s: read error or file too short\n", av[1]);
+    exit(1);
+}

+ 22 - 24
arch/powerpc/boot/main.c

@@ -21,8 +21,8 @@ extern void flush_cache(void *, unsigned long);
 
 
 /* Value picked to match that used by yaboot */
-#define PROG_START	0x01400000
-#define RAM_END		(512<<20) // Fixme: use OF */
+#define PROG_START	0x01400000	/* only used on 64-bit systems */
+#define RAM_END		(512<<20)	/* Fixme: use OF */
 #define	ONE_MB		0x100000
 
 extern char _start[];
@@ -160,6 +160,17 @@ static int is_elf64(void *hdr)
 	elfoffset = (unsigned long)elf64ph->p_offset;
 	vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
 	vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
+
+#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
+
 	return 1;
 }
 
@@ -206,12 +217,18 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
 		exit();
 	if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
 		exit();
-	stderr = stdout;
-	if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
-		exit();
 
 	printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
 
+	/*
+	 * 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);
+
 	vmlinuz.addr = (unsigned long)_vmlinux_start;
 	vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
 
@@ -228,25 +245,6 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
 		exit();
 	}
 
-	/*
-	 * 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
-
 	/* We need to claim the memsize plus the file offset since gzip
 	 * will expand the header (file offset), then the kernel, then
 	 * possible rubbish we don't care about. But the kernel bss must

+ 102 - 436
arch/powerpc/boot/prom.c

@@ -13,487 +13,153 @@
 #include "prom.h"
 
 int (*prom)(void *);
+phandle chosen_handle;
+ihandle stdout;
 
-void *chosen_handle;
-
-void *stdin;
-void *stdout;
-void *stderr;
-
-
-int
-write(void *handle, void *ptr, int nb)
-{
-	struct prom_args {
-		char *service;
-		int nargs;
-		int nret;
-		void *ihandle;
-		void *addr;
-		int len;
-		int actual;
-	} args;
-
-	args.service = "write";
-	args.nargs = 3;
-	args.nret = 1;
-	args.ihandle = handle;
-	args.addr = ptr;
-	args.len = nb;
-	args.actual = -1;
-	(*prom)(&args);
-	return args.actual;
-}
-
-int
-read(void *handle, void *ptr, int nb)
+int call_prom(const char *service, int nargs, int nret, ...)
 {
+	int i;
 	struct prom_args {
-		char *service;
+		const char *service;
 		int nargs;
 		int nret;
-		void *ihandle;
-		void *addr;
-		int len;
-		int actual;
-	} args;
-
-	args.service = "read";
-	args.nargs = 3;
-	args.nret = 1;
-	args.ihandle = handle;
-	args.addr = ptr;
-	args.len = nb;
-	args.actual = -1;
-	(*prom)(&args);
-	return args.actual;
-}
-
-void
-exit()
-{
-	struct prom_args {
-		char *service;
-	} args;
-
-	for (;;) {
-		args.service = "exit";
-		(*prom)(&args);
-	}
-}
-
-void
-pause(void)
-{
-	struct prom_args {
-		char *service;
+		unsigned int args[12];
 	} args;
+	va_list list;
 
-	args.service = "enter";
-	(*prom)(&args);
-}
+	args.service = service;
+	args.nargs = nargs;
+	args.nret = nret;
 
-void *
-finddevice(const char *name)
-{
-	struct prom_args {
-		char *service;
-		int nargs;
-		int nret;
-		const char *devspec;
-		void *phandle;
-	} args;
+	va_start(list, nret);
+	for (i = 0; i < nargs; i++)
+		args.args[i] = va_arg(list, unsigned int);
+	va_end(list);
 
-	args.service = "finddevice";
-	args.nargs = 1;
-	args.nret = 1;
-	args.devspec = name;
-	args.phandle = (void *) -1;
-	(*prom)(&args);
-	return args.phandle;
-}
+	for (i = 0; i < nret; i++)
+		args.args[nargs+i] = 0;
 
-void *
-claim(unsigned long virt, unsigned long size, unsigned long align)
-{
-	struct prom_args {
-		char *service;
-		int nargs;
-		int nret;
-		unsigned int virt;
-		unsigned int size;
-		unsigned int align;
-		void *ret;
-	} args;
+	if (prom(&args) < 0)
+		return -1;
 
-	args.service = "claim";
-	args.nargs = 3;
-	args.nret = 1;
-	args.virt = virt;
-	args.size = size;
-	args.align = align;
-	(*prom)(&args);
-	return args.ret;
+	return (nret > 0)? args.args[nargs]: 0;
 }
 
-int
-getprop(void *phandle, const char *name, void *buf, int buflen)
+int call_prom_ret(const char *service, int nargs, int nret,
+		  unsigned int *rets, ...)
 {
+	int i;
 	struct prom_args {
-		char *service;
+		const char *service;
 		int nargs;
 		int nret;
-		void *phandle;
-		const char *name;
-		void *buf;
-		int buflen;
-		int size;
+		unsigned int args[12];
 	} args;
+	va_list list;
 
-	args.service = "getprop";
-	args.nargs = 4;
-	args.nret = 1;
-	args.phandle = phandle;
-	args.name = name;
-	args.buf = buf;
-	args.buflen = buflen;
-	args.size = -1;
-	(*prom)(&args);
-	return args.size;
-}
+	args.service = service;
+	args.nargs = nargs;
+	args.nret = nret;
 
-int
-putc(int c, void *f)
-{
-	char ch = c;
+	va_start(list, rets);
+	for (i = 0; i < nargs; i++)
+		args.args[i] = va_arg(list, unsigned int);
+	va_end(list);
 
-	if (c == '\n')
-		putc('\r', f);
-	return write(f, &ch, 1) == 1? c: -1;
-}
+	for (i = 0; i < nret; i++)
+		args.args[nargs+i] = 0;
 
-int
-putchar(int c)
-{
-	return putc(c, stdout);
-}
+	if (prom(&args) < 0)
+		return -1;
 
-int
-fputs(char *str, void *f)
-{
-	int n = strlen(str);
+	if (rets != (void *) 0)
+		for (i = 1; i < nret; ++i)
+			rets[i-1] = args.args[nargs+i];
 
-	return write(f, str, n) == n? 0: -1;
+	return (nret > 0)? args.args[nargs]: 0;
 }
 
-size_t strnlen(const char * s, size_t count)
+int write(void *handle, void *ptr, int nb)
 {
-	const char *sc;
-
-	for (sc = s; count-- && *sc != '\0'; ++sc)
-		/* nothing */;
-	return sc - s;
+	return call_prom("write", 3, 1, handle, ptr, nb);
 }
 
-extern unsigned int __div64_32(unsigned long long *dividend,
-			       unsigned int divisor);
-
-/* The unnecessary pointer compare is there
- * to check for type safety (n must be 64bit)
+/*
+ * Older OF's require that when claiming a specific range of addresses,
+ * we claim the physical space in the /memory node and the virtual
+ * space in the chosen mmu node, and then do a map operation to
+ * map virtual to physical.
  */
-# define do_div(n,base) ({						\
-	unsigned int __base = (base);					\
-	unsigned int __rem;						\
-	(void)(((typeof((n)) *)0) == ((unsigned long long *)0));	\
-	if (((n) >> 32) == 0) {						\
-		__rem = (unsigned int)(n) % __base;			\
-		(n) = (unsigned int)(n) / __base;			\
-	} else								\
-		__rem = __div64_32(&(n), __base);			\
-	__rem;								\
- })
+static int need_map = -1;
+static ihandle chosen_mmu;
+static phandle memory;
 
-static int skip_atoi(const char **s)
+/* returns true if s2 is a prefix of s1 */
+static int string_match(const char *s1, const char *s2)
 {
-	int i, c;
-
-	for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
-		i = i*10 + c - '0';
-	return i;
+	for (; *s2; ++s2)
+		if (*s1++ != *s2)
+			return 0;
+	return 1;
 }
 
-#define ZEROPAD	1		/* pad with zero */
-#define SIGN	2		/* unsigned/signed long */
-#define PLUS	4		/* show plus */
-#define SPACE	8		/* space if plus */
-#define LEFT	16		/* left justified */
-#define SPECIAL	32		/* 0x */
-#define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
-
-static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
+static int check_of_version(void)
 {
-	char c,sign,tmp[66];
-	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
-	int i;
+	phandle oprom, chosen;
+	char version[64];
 
-	if (type & LARGE)
-		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-	if (type & LEFT)
-		type &= ~ZEROPAD;
-	if (base < 2 || base > 36)
+	oprom = finddevice("/openprom");
+	if (oprom == (phandle) -1)
 		return 0;
-	c = (type & ZEROPAD) ? '0' : ' ';
-	sign = 0;
-	if (type & SIGN) {
-		if ((signed long long)num < 0) {
-			sign = '-';
-			num = - (signed long long)num;
-			size--;
-		} else if (type & PLUS) {
-			sign = '+';
-			size--;
-		} else if (type & SPACE) {
-			sign = ' ';
-			size--;
+	if (getprop(oprom, "model", version, sizeof(version)) <= 0)
+		return 0;
+	version[sizeof(version)-1] = 0;
+	printf("OF version = '%s'\r\n", version);
+	if (!string_match(version, "Open Firmware, 1.")
+	    && !string_match(version, "FirmWorks,3."))
+		return 0;
+	chosen = finddevice("/chosen");
+	if (chosen == (phandle) -1) {
+		chosen = finddevice("/chosen@0");
+		if (chosen == (phandle) -1) {
+			printf("no chosen\n");
+			return 0;
 		}
 	}
-	if (type & SPECIAL) {
-		if (base == 16)
-			size -= 2;
-		else if (base == 8)
-			size--;
-	}
-	i = 0;
-	if (num == 0)
-		tmp[i++]='0';
-	else while (num != 0) {
-		tmp[i++] = digits[do_div(num, base)];
+	if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
+		printf("no mmu\n");
+		return 0;
 	}
-	if (i > precision)
-		precision = i;
-	size -= precision;
-	if (!(type&(ZEROPAD+LEFT)))
-		while(size-->0)
-			*str++ = ' ';
-	if (sign)
-		*str++ = sign;
-	if (type & SPECIAL) {
-		if (base==8)
-			*str++ = '0';
-		else if (base==16) {
-			*str++ = '0';
-			*str++ = digits[33];
+	memory = (ihandle) call_prom("open", 1, 1, "/memory");
+	if (memory == (ihandle) -1) {
+		memory = (ihandle) call_prom("open", 1, 1, "/memory@0");
+		if (memory == (ihandle) -1) {
+			printf("no memory node\n");
+			return 0;
 		}
 	}
-	if (!(type & LEFT))
-		while (size-- > 0)
-			*str++ = c;
-	while (i < precision--)
-		*str++ = '0';
-	while (i-- > 0)
-		*str++ = tmp[i];
-	while (size-- > 0)
-		*str++ = ' ';
-	return str;
+	printf("old OF detected\r\n");
+	return 1;
 }
 
-int vsprintf(char *buf, const char *fmt, va_list args)
+void *claim(unsigned long virt, unsigned long size, unsigned long align)
 {
-	int len;
-	unsigned long long num;
-	int i, base;
-	char * str;
-	const char *s;
-
-	int flags;		/* flags to number() */
-
-	int field_width;	/* width of output field */
-	int precision;		/* min. # of digits for integers; max
-				   number of chars for from string */
-	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
-	                        /* 'z' support added 23/7/1999 S.H.    */
-				/* 'z' changed to 'Z' --davidm 1/25/99 */
+	int ret;
+	unsigned int result;
 
+	if (need_map < 0)
+		need_map = check_of_version();
+	if (align || !need_map)
+		return (void *) call_prom("claim", 3, 1, virt, size, align);
 	
-	for (str=buf ; *fmt ; ++fmt) {
-		if (*fmt != '%') {
-			*str++ = *fmt;
-			continue;
-		}
-			
-		/* process flags */
-		flags = 0;
-		repeat:
-			++fmt;		/* this also skips first '%' */
-			switch (*fmt) {
-				case '-': flags |= LEFT; goto repeat;
-				case '+': flags |= PLUS; goto repeat;
-				case ' ': flags |= SPACE; goto repeat;
-				case '#': flags |= SPECIAL; goto repeat;
-				case '0': flags |= ZEROPAD; goto repeat;
-				}
-		
-		/* get field width */
-		field_width = -1;
-		if ('0' <= *fmt && *fmt <= '9')
-			field_width = skip_atoi(&fmt);
-		else if (*fmt == '*') {
-			++fmt;
-			/* it's the next argument */
-			field_width = va_arg(args, int);
-			if (field_width < 0) {
-				field_width = -field_width;
-				flags |= LEFT;
-			}
-		}
-
-		/* get the precision */
-		precision = -1;
-		if (*fmt == '.') {
-			++fmt;	
-			if ('0' <= *fmt && *fmt <= '9')
-				precision = skip_atoi(&fmt);
-			else if (*fmt == '*') {
-				++fmt;
-				/* it's the next argument */
-				precision = va_arg(args, int);
-			}
-			if (precision < 0)
-				precision = 0;
-		}
-
-		/* get the conversion qualifier */
-		qualifier = -1;
-		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
-			qualifier = *fmt;
-			++fmt;
-		}
-
-		/* default base */
-		base = 10;
-
-		switch (*fmt) {
-		case 'c':
-			if (!(flags & LEFT))
-				while (--field_width > 0)
-					*str++ = ' ';
-			*str++ = (unsigned char) va_arg(args, int);
-			while (--field_width > 0)
-				*str++ = ' ';
-			continue;
-
-		case 's':
-			s = va_arg(args, char *);
-			if (!s)
-				s = "<NULL>";
-
-			len = strnlen(s, precision);
-
-			if (!(flags & LEFT))
-				while (len < field_width--)
-					*str++ = ' ';
-			for (i = 0; i < len; ++i)
-				*str++ = *s++;
-			while (len < field_width--)
-				*str++ = ' ';
-			continue;
-
-		case 'p':
-			if (field_width == -1) {
-				field_width = 2*sizeof(void *);
-				flags |= ZEROPAD;
-			}
-			str = number(str,
-				(unsigned long) va_arg(args, void *), 16,
-				field_width, precision, flags);
-			continue;
-
-
-		case 'n':
-			if (qualifier == 'l') {
-				long * ip = va_arg(args, long *);
-				*ip = (str - buf);
-			} else if (qualifier == 'Z') {
-				size_t * ip = va_arg(args, size_t *);
-				*ip = (str - buf);
-			} else {
-				int * ip = va_arg(args, int *);
-				*ip = (str - buf);
-			}
-			continue;
-
-		case '%':
-			*str++ = '%';
-			continue;
-
-		/* integer number formats - set up the flags and "break" */
-		case 'o':
-			base = 8;
-			break;
-
-		case 'X':
-			flags |= LARGE;
-		case 'x':
-			base = 16;
-			break;
-
-		case 'd':
-		case 'i':
-			flags |= SIGN;
-		case 'u':
-			break;
-
-		default:
-			*str++ = '%';
-			if (*fmt)
-				*str++ = *fmt;
-			else
-				--fmt;
-			continue;
-		}
-		if (qualifier == 'l') {
-			num = va_arg(args, unsigned long);
-			if (flags & SIGN)
-				num = (signed long) num;
-		} else if (qualifier == 'Z') {
-			num = va_arg(args, size_t);
-		} else if (qualifier == 'h') {
-			num = (unsigned short) va_arg(args, int);
-			if (flags & SIGN)
-				num = (signed short) num;
-		} else {
-			num = va_arg(args, unsigned int);
-			if (flags & SIGN)
-				num = (signed int) num;
-		}
-		str = number(str, num, base, field_width, precision, flags);
-	}
-	*str = '\0';
-	return str-buf;
-}
-
-int sprintf(char * buf, const char *fmt, ...)
-{
-	va_list args;
-	int i;
-
-	va_start(args, fmt);
-	i=vsprintf(buf,fmt,args);
-	va_end(args);
-	return i;
-}
-
-static char sprint_buf[1024];
-
-int
-printf(const char *fmt, ...)
-{
-	va_list args;
-	int n;
-
-	va_start(args, fmt);
-	n = vsprintf(sprint_buf, fmt, args);
-	va_end(args);
-	write(stdout, sprint_buf, n);
-	return n;
+	ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
+			    align, size, virt);
+	if (ret != 0 || result == -1)
+		return (void *) -1;
+	ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
+			    align, size, virt);
+	/* 0x12 == coherent + read/write */
+	ret = call_prom("call-method", 6, 1, "map", chosen_mmu,
+			0x12, size, virt, virt);
+	return (void *) virt;
 }

+ 26 - 10
arch/powerpc/boot/prom.h

@@ -1,18 +1,34 @@
 #ifndef _PPC_BOOT_PROM_H_
 #define _PPC_BOOT_PROM_H_
 
+typedef void *phandle;
+typedef void *ihandle;
+
 extern int (*prom) (void *);
-extern void *chosen_handle;
+extern phandle chosen_handle;
+extern ihandle stdout;
 
-extern void *stdin;
-extern void *stdout;
-extern void *stderr;
+int	call_prom(const char *service, int nargs, int nret, ...);
+int	call_prom_ret(const char *service, int nargs, int nret,
+		      unsigned int *rets, ...);
 
 extern int write(void *handle, void *ptr, int nb);
-extern int read(void *handle, void *ptr, int nb);
-extern void exit(void);
-extern void pause(void);
-extern void *finddevice(const char *);
-extern void *claim(unsigned long virt, unsigned long size, unsigned long align);
-extern int getprop(void *phandle, const char *name, void *buf, int buflen);
+extern void *claim(unsigned long virt, unsigned long size, unsigned long aln);
+
+static inline void exit(void)
+{
+	call_prom("exit", 0, 0);
+}
+
+static inline phandle finddevice(const char *name)
+{
+	return (phandle) call_prom("finddevice", 1, 1, name);
+}
+
+static inline int getprop(void *phandle, const char *name,
+			  void *buf, int buflen)
+{
+	return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
+}
+
 #endif				/* _PPC_BOOT_PROM_H_ */

+ 243 - 0
arch/powerpc/boot/rs6000.h

@@ -0,0 +1,243 @@
+/* IBM RS/6000 "XCOFF" file definitions for BFD.
+   Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+   FIXME: Can someone provide a transliteration of this name into ASCII?
+   Using the following chars caused a compiler warning on HIUX (so I replaced
+   them with octal escapes), and isn't useful without an understanding of what
+   character set it is.
+   Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM
+   and John Gilmore of Cygnus Support.  */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+	char f_magic[2];	/* magic number			*/
+	char f_nscns[2];	/* number of sections		*/
+	char f_timdat[4];	/* time & date stamp		*/
+	char f_symptr[4];	/* file pointer to symtab	*/
+	char f_nsyms[4];	/* number of symtab entries	*/
+	char f_opthdr[2];	/* sizeof(optional hdr)		*/
+	char f_flags[2];	/* flags			*/
+};
+
+        /* IBM RS/6000 */
+#define U802WRMAGIC     0730    /* writeable text segments **chh**      */
+#define U802ROMAGIC     0735    /* readonly sharable text segments      */
+#define U802TOCMAGIC    0737    /* readonly text segments and TOC       */
+
+#define BADMAG(x)	\
+	((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \
+	 (x).f_magic != U802TOCMAGIC)
+
+#define	FILHDR	struct external_filehdr
+#define	FILHSZ	20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+  unsigned char	magic[2];	/* type of file			*/
+  unsigned char	vstamp[2];	/* version stamp		*/
+  unsigned char	tsize[4];	/* text size in bytes, padded to FW bdry */
+  unsigned char	dsize[4];	/* initialized data "  "	*/
+  unsigned char	bsize[4];	/* uninitialized data "   "	*/
+  unsigned char	entry[4];	/* entry pt.			*/
+  unsigned char	text_start[4];	/* base of text used for this file */
+  unsigned char	data_start[4];	/* base of data used for this file */
+  unsigned char	o_toc[4];	/* address of TOC */
+  unsigned char	o_snentry[2];	/* section number of entry point */
+  unsigned char	o_sntext[2];	/* section number of .text section */
+  unsigned char	o_sndata[2];	/* section number of .data section */
+  unsigned char	o_sntoc[2];	/* section number of TOC */
+  unsigned char	o_snloader[2];	/* section number of .loader section */
+  unsigned char	o_snbss[2];	/* section number of .bss section */
+  unsigned char	o_algntext[2];	/* .text alignment */
+  unsigned char	o_algndata[2];	/* .data alignment */
+  unsigned char	o_modtype[2];	/* module type (??) */
+  unsigned char o_cputype[2];	/* cpu type */
+  unsigned char	o_maxstack[4];	/* max stack size (??) */
+  unsigned char o_maxdata[4];	/* max data size (??) */
+  unsigned char	o_resv2[12];	/* reserved */
+}
+AOUTHDR;
+
+#define AOUTSZ 72
+#define SMALL_AOUTSZ (28)
+#define AOUTHDRSZ 72
+
+#define	RS6K_AOUTHDR_OMAGIC	0x0107	/* old: text & data writeable */
+#define	RS6K_AOUTHDR_NMAGIC	0x0108	/* new: text r/o, data r/w */
+#define	RS6K_AOUTHDR_ZMAGIC	0x010B	/* paged: text r/o, both page-aligned */
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+	char		s_name[8];	/* section name			*/
+	char		s_paddr[4];	/* physical address, aliased s_nlib */
+	char		s_vaddr[4];	/* virtual address		*/
+	char		s_size[4];	/* section size			*/
+	char		s_scnptr[4];	/* file ptr to raw data for section */
+	char		s_relptr[4];	/* file ptr to relocation	*/
+	char		s_lnnoptr[4];	/* file ptr to line numbers	*/
+	char		s_nreloc[2];	/* number of relocation entries	*/
+	char		s_nlnno[2];	/* number of line number entries*/
+	char		s_flags[4];	/* flags			*/
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT	".text"
+#define _DATA	".data"
+#define _BSS	".bss"
+#define _PAD	".pad"
+#define _LOADER	".loader"
+
+#define	SCNHDR	struct external_scnhdr
+#define	SCNHSZ	40
+
+/* XCOFF uses a special .loader section with type STYP_LOADER.  */
+#define STYP_LOADER 0x1000
+
+/* XCOFF uses a special .debug section with type STYP_DEBUG.  */
+#define STYP_DEBUG 0x2000
+
+/* XCOFF handles line number or relocation overflow by creating
+   another section header with STYP_OVRFLO set.  */
+#define STYP_OVRFLO 0x8000
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+	union {
+		char l_symndx[4];	/* function name symbol index, iff l_lnno == 0*/
+		char l_paddr[4];	/* (physical) address of line number	*/
+	} l_addr;
+	char l_lnno[2];	/* line number		*/
+};
+
+
+#define	LINENO	struct external_lineno
+#define	LINESZ	6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN	8	/* # characters in a symbol name	*/
+#define E_FILNMLEN	14	/* # characters in a file name		*/
+#define E_DIMNUM	4	/* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+  union {
+    char e_name[E_SYMNMLEN];
+    struct {
+      char e_zeroes[4];
+      char e_offset[4];
+    } e;
+  } e;
+  char e_value[4];
+  char e_scnum[2];
+  char e_type[2];
+  char e_sclass[1];
+  char e_numaux[1];
+};
+
+
+
+#define N_BTMASK	(017)
+#define N_TMASK		(060)
+#define N_BTSHFT	(4)
+#define N_TSHIFT	(2)
+
+
+union external_auxent {
+	struct {
+		char x_tagndx[4];	/* str, un, or enum tag indx */
+		union {
+			struct {
+			    char  x_lnno[2]; /* declaration line number */
+			    char  x_size[2]; /* str/union/array size */
+			} x_lnsz;
+			char x_fsize[4];	/* size of function */
+		} x_misc;
+		union {
+			struct {		/* if ISFCN, tag, or .bb */
+			    char x_lnnoptr[4];	/* ptr to fcn line # */
+			    char x_endndx[4];	/* entry ndx past block end */
+			} x_fcn;
+			struct {		/* if ISARY, up to 4 dimen. */
+			    char x_dimen[E_DIMNUM][2];
+			} x_ary;
+		} x_fcnary;
+		char x_tvndx[2];		/* tv index */
+	} x_sym;
+
+	union {
+		char x_fname[E_FILNMLEN];
+		struct {
+			char x_zeroes[4];
+			char x_offset[4];
+		} x_n;
+	} x_file;
+
+	struct {
+		char x_scnlen[4];			/* section length */
+		char x_nreloc[2];	/* # relocation entries */
+		char x_nlinno[2];	/* # line numbers */
+	} x_scn;
+
+        struct {
+		char x_tvfill[4];	/* tv fill value */
+		char x_tvlen[2];	/* length of .tv */
+		char x_tvran[2][2];	/* tv range */
+	} x_tv;		/* info about .tv section (in auxent of symbol .tv)) */
+
+	struct {
+		unsigned char x_scnlen[4];
+		unsigned char x_parmhash[4];
+		unsigned char x_snhash[2];
+		unsigned char x_smtyp[1];
+		unsigned char x_smclas[1];
+		unsigned char x_stab[4];
+		unsigned char x_snstab[2];
+	} x_csect;
+
+};
+
+#define	SYMENT	struct external_syment
+#define	SYMESZ	18
+#define	AUXENT	union external_auxent
+#define	AUXESZ	18
+#define DBXMASK 0x80		/* for dbx storage mask */
+#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK)
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+struct external_reloc {
+  char r_vaddr[4];
+  char r_symndx[4];
+  char r_size[1];
+  char r_type[1];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+
+#define DEFAULT_DATA_SECTION_ALIGNMENT 4
+#define DEFAULT_BSS_SECTION_ALIGNMENT 4
+#define DEFAULT_TEXT_SECTION_ALIGNMENT 4
+/* For new sections we havn't heard of before */
+#define DEFAULT_SECTION_ALIGNMENT 4

+ 325 - 0
arch/powerpc/boot/stdio.c

@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include "string.h"
+#include "stdio.h"
+#include "prom.h"
+
+size_t strnlen(const char * s, size_t count)
+{
+	const char *sc;
+
+	for (sc = s; count-- && *sc != '\0'; ++sc)
+		/* nothing */;
+	return sc - s;
+}
+
+extern unsigned int __div64_32(unsigned long long *dividend,
+			       unsigned int divisor);
+
+/* The unnecessary pointer compare is there
+ * to check for type safety (n must be 64bit)
+ */
+# define do_div(n,base) ({						\
+	unsigned int __base = (base);					\
+	unsigned int __rem;						\
+	(void)(((typeof((n)) *)0) == ((unsigned long long *)0));	\
+	if (((n) >> 32) == 0) {						\
+		__rem = (unsigned int)(n) % __base;			\
+		(n) = (unsigned int)(n) / __base;			\
+	} else								\
+		__rem = __div64_32(&(n), __base);			\
+	__rem;								\
+ })
+
+static int skip_atoi(const char **s)
+{
+	int i, c;
+
+	for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
+		i = i*10 + c - '0';
+	return i;
+}
+
+#define ZEROPAD	1		/* pad with zero */
+#define SIGN	2		/* unsigned/signed long */
+#define PLUS	4		/* show plus */
+#define SPACE	8		/* space if plus */
+#define LEFT	16		/* left justified */
+#define SPECIAL	32		/* 0x */
+#define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
+
+static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
+{
+	char c,sign,tmp[66];
+	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+	int i;
+
+	if (type & LARGE)
+		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+	if (type & LEFT)
+		type &= ~ZEROPAD;
+	if (base < 2 || base > 36)
+		return 0;
+	c = (type & ZEROPAD) ? '0' : ' ';
+	sign = 0;
+	if (type & SIGN) {
+		if ((signed long long)num < 0) {
+			sign = '-';
+			num = - (signed long long)num;
+			size--;
+		} else if (type & PLUS) {
+			sign = '+';
+			size--;
+		} else if (type & SPACE) {
+			sign = ' ';
+			size--;
+		}
+	}
+	if (type & SPECIAL) {
+		if (base == 16)
+			size -= 2;
+		else if (base == 8)
+			size--;
+	}
+	i = 0;
+	if (num == 0)
+		tmp[i++]='0';
+	else while (num != 0) {
+		tmp[i++] = digits[do_div(num, base)];
+	}
+	if (i > precision)
+		precision = i;
+	size -= precision;
+	if (!(type&(ZEROPAD+LEFT)))
+		while(size-->0)
+			*str++ = ' ';
+	if (sign)
+		*str++ = sign;
+	if (type & SPECIAL) {
+		if (base==8)
+			*str++ = '0';
+		else if (base==16) {
+			*str++ = '0';
+			*str++ = digits[33];
+		}
+	}
+	if (!(type & LEFT))
+		while (size-- > 0)
+			*str++ = c;
+	while (i < precision--)
+		*str++ = '0';
+	while (i-- > 0)
+		*str++ = tmp[i];
+	while (size-- > 0)
+		*str++ = ' ';
+	return str;
+}
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+	int len;
+	unsigned long long num;
+	int i, base;
+	char * str;
+	const char *s;
+
+	int flags;		/* flags to number() */
+
+	int field_width;	/* width of output field */
+	int precision;		/* min. # of digits for integers; max
+				   number of chars for from string */
+	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
+	                        /* 'z' support added 23/7/1999 S.H.    */
+				/* 'z' changed to 'Z' --davidm 1/25/99 */
+
+	
+	for (str=buf ; *fmt ; ++fmt) {
+		if (*fmt != '%') {
+			*str++ = *fmt;
+			continue;
+		}
+			
+		/* process flags */
+		flags = 0;
+		repeat:
+			++fmt;		/* this also skips first '%' */
+			switch (*fmt) {
+				case '-': flags |= LEFT; goto repeat;
+				case '+': flags |= PLUS; goto repeat;
+				case ' ': flags |= SPACE; goto repeat;
+				case '#': flags |= SPECIAL; goto repeat;
+				case '0': flags |= ZEROPAD; goto repeat;
+				}
+		
+		/* get field width */
+		field_width = -1;
+		if ('0' <= *fmt && *fmt <= '9')
+			field_width = skip_atoi(&fmt);
+		else if (*fmt == '*') {
+			++fmt;
+			/* it's the next argument */
+			field_width = va_arg(args, int);
+			if (field_width < 0) {
+				field_width = -field_width;
+				flags |= LEFT;
+			}
+		}
+
+		/* get the precision */
+		precision = -1;
+		if (*fmt == '.') {
+			++fmt;	
+			if ('0' <= *fmt && *fmt <= '9')
+				precision = skip_atoi(&fmt);
+			else if (*fmt == '*') {
+				++fmt;
+				/* it's the next argument */
+				precision = va_arg(args, int);
+			}
+			if (precision < 0)
+				precision = 0;
+		}
+
+		/* get the conversion qualifier */
+		qualifier = -1;
+		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
+			qualifier = *fmt;
+			++fmt;
+		}
+
+		/* default base */
+		base = 10;
+
+		switch (*fmt) {
+		case 'c':
+			if (!(flags & LEFT))
+				while (--field_width > 0)
+					*str++ = ' ';
+			*str++ = (unsigned char) va_arg(args, int);
+			while (--field_width > 0)
+				*str++ = ' ';
+			continue;
+
+		case 's':
+			s = va_arg(args, char *);
+			if (!s)
+				s = "<NULL>";
+
+			len = strnlen(s, precision);
+
+			if (!(flags & LEFT))
+				while (len < field_width--)
+					*str++ = ' ';
+			for (i = 0; i < len; ++i)
+				*str++ = *s++;
+			while (len < field_width--)
+				*str++ = ' ';
+			continue;
+
+		case 'p':
+			if (field_width == -1) {
+				field_width = 2*sizeof(void *);
+				flags |= ZEROPAD;
+			}
+			str = number(str,
+				(unsigned long) va_arg(args, void *), 16,
+				field_width, precision, flags);
+			continue;
+
+
+		case 'n':
+			if (qualifier == 'l') {
+				long * ip = va_arg(args, long *);
+				*ip = (str - buf);
+			} else if (qualifier == 'Z') {
+				size_t * ip = va_arg(args, size_t *);
+				*ip = (str - buf);
+			} else {
+				int * ip = va_arg(args, int *);
+				*ip = (str - buf);
+			}
+			continue;
+
+		case '%':
+			*str++ = '%';
+			continue;
+
+		/* integer number formats - set up the flags and "break" */
+		case 'o':
+			base = 8;
+			break;
+
+		case 'X':
+			flags |= LARGE;
+		case 'x':
+			base = 16;
+			break;
+
+		case 'd':
+		case 'i':
+			flags |= SIGN;
+		case 'u':
+			break;
+
+		default:
+			*str++ = '%';
+			if (*fmt)
+				*str++ = *fmt;
+			else
+				--fmt;
+			continue;
+		}
+		if (qualifier == 'l') {
+			num = va_arg(args, unsigned long);
+			if (flags & SIGN)
+				num = (signed long) num;
+		} else if (qualifier == 'Z') {
+			num = va_arg(args, size_t);
+		} else if (qualifier == 'h') {
+			num = (unsigned short) va_arg(args, int);
+			if (flags & SIGN)
+				num = (signed short) num;
+		} else {
+			num = va_arg(args, unsigned int);
+			if (flags & SIGN)
+				num = (signed int) num;
+		}
+		str = number(str, num, base, field_width, precision, flags);
+	}
+	*str = '\0';
+	return str-buf;
+}
+
+int sprintf(char * buf, const char *fmt, ...)
+{
+	va_list args;
+	int i;
+
+	va_start(args, fmt);
+	i=vsprintf(buf,fmt,args);
+	va_end(args);
+	return i;
+}
+
+static char sprint_buf[1024];
+
+int
+printf(const char *fmt, ...)
+{
+	va_list args;
+	int n;
+
+	va_start(args, fmt);
+	n = vsprintf(sprint_buf, fmt, args);
+	va_end(args);
+	write(stdout, sprint_buf, n);
+	return n;
+}

+ 0 - 6
arch/powerpc/boot/stdio.h

@@ -7,10 +7,4 @@ extern int sprintf(char *buf, const char *fmt, ...);
 
 extern int vsprintf(char *buf, const char *fmt, va_list args);
 
-extern int putc(int c, void *f);
-extern int putchar(int c);
-extern int getchar(void);
-
-extern int fputs(char *str, void *f);
-
 #endif				/* _PPC_BOOT_STDIO_H_ */

+ 17 - 3
arch/powerpc/boot/string.S

@@ -107,10 +107,12 @@ memcpy:
 	rlwinm.	r7,r5,32-3,3,31		/* r7 = r5 >> 3 */
 	addi	r6,r3,-4
 	addi	r4,r4,-4
-	beq	2f			/* if less than 8 bytes to do */
+	beq	3f			/* if less than 8 bytes to do */
 	andi.	r0,r6,3			/* get dest word aligned */
 	mtctr	r7
 	bne	5f
+	andi.	r0,r4,3			/* check src word aligned too */
+	bne	3f
 1:	lwz	r7,4(r4)
 	lwzu	r8,8(r4)
 	stw	r7,4(r6)
@@ -132,6 +134,11 @@ memcpy:
 	bdnz	4b
 	blr
 5:	subfic	r0,r0,4
+	cmpw	cr1,r0,r5
+	add	r7,r0,r4
+	andi.	r7,r7,3			/* will source be word-aligned too? */
+	ble	cr1,3b
+	bne	3b			/* do byte-by-byte if not */
 	mtctr	r0
 6:	lbz	r7,4(r4)
 	addi	r4,r4,1
@@ -149,10 +156,12 @@ backwards_memcpy:
 	rlwinm.	r7,r5,32-3,3,31		/* r7 = r5 >> 3 */
 	add	r6,r3,r5
 	add	r4,r4,r5
-	beq	2f
+	beq	3f
 	andi.	r0,r6,3
 	mtctr	r7
 	bne	5f
+	andi.	r0,r4,3
+	bne	3f
 1:	lwz	r7,-4(r4)
 	lwzu	r8,-8(r4)
 	stw	r7,-4(r6)
@@ -171,7 +180,12 @@ backwards_memcpy:
 	stbu	r0,-1(r6)
 	bdnz	4b
 	blr
-5:	mtctr	r0
+5:	cmpw	cr1,r0,r5
+	subf	r7,r0,r4
+	andi.	r7,r7,3
+	ble	cr1,3b
+	bne	3b
+	mtctr	r0
 6:	lbzu	r7,-1(r4)
 	stbu	r7,-1(r6)
 	bdnz	6b

+ 46 - 0
arch/powerpc/boot/zImage.coff.lds

@@ -0,0 +1,46 @@
+OUTPUT_ARCH(powerpc:common)
+ENTRY(_start)
+SECTIONS
+{
+  . = (5*1024*1024);
+  _start = .;
+  .text      :
+  {
+    *(.text)
+    *(.fixup)
+  }
+  _etext = .;
+  . = ALIGN(4096);
+  .data    :
+  {
+    *(.rodata*)
+    *(.data*)
+    *(.sdata*)
+    __got2_start = .;
+    *(.got2)
+    __got2_end = .;
+
+    _vmlinux_start =  .;
+    *(.kernel:vmlinux.strip)
+    _vmlinux_end =  .;
+
+    _initrd_start =  .;
+    *(.kernel:initrd)
+    _initrd_end =  .;
+  }
+
+  . = ALIGN(4096);
+  _edata  =  .;
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss)
+   *(.bss)
+  }
+  _end = . ;
+
+  /DISCARD/ :
+  {
+    *(.comment)
+  }
+}

+ 911 - 0
arch/powerpc/configs/mpc834x_sys_defconfig

@@ -0,0 +1,911 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.15-g461d4edf-dirty
+# Fri Jan 13 11:01:47 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_DEFAULT_UIMAGE=y
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+CONFIG_PPC_83xx=y
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+# CONFIG_E500 is not set
+CONFIG_6xx=y
+CONFIG_83xx=y
+CONFIG_PPC_FPU=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_SMP is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_PPC_GEN550=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Platform support
+#
+CONFIG_MPC834x_SYS=y
+CONFIG_MPC834x=y
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_PPC_I8259 is not set
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCI_LEGACY_PROC is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+# CONFIG_GFAR_NAPI is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_83xx_WDT=y
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
+# CONFIG_PPC_EARLY_DEBUG_G5 is not set
+# CONFIG_PPC_EARLY_DEBUG_RTAS is not set
+# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
+# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# SEC2.x Options
+#
+CONFIG_MPC8349E_SEC2x=y
+
+#
+# SEC2.x Test Options
+#
+CONFIG_MPC8349E_SEC2xTEST=y

+ 1 - 1
arch/powerpc/kernel/asm-offsets.c

@@ -135,7 +135,7 @@ int main(void)
 	DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
 	DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
 	DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
-	DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca));
+	DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
 	DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
 
 	DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));

+ 2 - 2
arch/powerpc/kernel/cpu_setup_power4.S

@@ -130,7 +130,7 @@ _GLOBAL(__save_cpu_setup)
 	mfcr	r7
 
 	/* Get storage ptr */
-	LOADADDR(r5,cpu_state_storage)
+	LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
 
 	/* We only deal with 970 for now */
 	mfspr	r0,SPRN_PVR
@@ -164,7 +164,7 @@ _GLOBAL(__restore_cpu_setup)
 	/* Get storage ptr (FIXME when using anton reloc as we
 	 * are running with translation disabled here
 	 */
-	LOADADDR(r5,cpu_state_storage)
+	LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
 
 	/* We only deal with 970 for now */
 	mfspr	r0,SPRN_PVR

+ 154 - 70
arch/powerpc/kernel/cputable.c

@@ -55,7 +55,8 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
 #define COMMON_USER_POWER4	(COMMON_USER_PPC64 | PPC_FEATURE_POWER4)
 #define COMMON_USER_POWER5	(COMMON_USER_PPC64 | PPC_FEATURE_POWER5)
 #define COMMON_USER_POWER5_PLUS	(COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS)
-
+#define COMMON_USER_BOOKE	(PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
+				 PPC_FEATURE_BOOKE)
 
 /* We only set the spe features if the kernel was compiled with
  * spe support
@@ -79,7 +80,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_power3,
 		.oprofile_cpu_type	= "ppc64/power3",
-		.oprofile_type		= RS64,
+		.oprofile_type		= PPC_OPROFILE_RS64,
+		.platform		= "power3",
 	},
 	{	/* Power3+ */
 		.pvr_mask		= 0xffff0000,
@@ -92,7 +94,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_power3,
 		.oprofile_cpu_type	= "ppc64/power3",
-		.oprofile_type		= RS64,
+		.oprofile_type		= PPC_OPROFILE_RS64,
+		.platform		= "power3",
 	},
 	{	/* Northstar */
 		.pvr_mask		= 0xffff0000,
@@ -105,7 +108,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_power3,
 		.oprofile_cpu_type	= "ppc64/rs64",
-		.oprofile_type		= RS64,
+		.oprofile_type		= PPC_OPROFILE_RS64,
+		.platform		= "rs64",
 	},
 	{	/* Pulsar */
 		.pvr_mask		= 0xffff0000,
@@ -118,7 +122,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_power3,
 		.oprofile_cpu_type	= "ppc64/rs64",
-		.oprofile_type		= RS64,
+		.oprofile_type		= PPC_OPROFILE_RS64,
+		.platform		= "rs64",
 	},
 	{	/* I-star */
 		.pvr_mask		= 0xffff0000,
@@ -131,7 +136,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_power3,
 		.oprofile_cpu_type	= "ppc64/rs64",
-		.oprofile_type		= RS64,
+		.oprofile_type		= PPC_OPROFILE_RS64,
+		.platform		= "rs64",
 	},
 	{	/* S-star */
 		.pvr_mask		= 0xffff0000,
@@ -144,7 +150,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_power3,
 		.oprofile_cpu_type	= "ppc64/rs64",
-		.oprofile_type		= RS64,
+		.oprofile_type		= PPC_OPROFILE_RS64,
+		.platform		= "rs64",
 	},
 	{	/* Power4 */
 		.pvr_mask		= 0xffff0000,
@@ -157,7 +164,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_power4,
 		.oprofile_cpu_type	= "ppc64/power4",
-		.oprofile_type		= POWER4,
+		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.platform		= "power4",
 	},
 	{	/* Power4+ */
 		.pvr_mask		= 0xffff0000,
@@ -170,7 +178,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_power4,
 		.oprofile_cpu_type	= "ppc64/power4",
-		.oprofile_type		= POWER4,
+		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.platform		= "power4",
 	},
 	{	/* PPC970 */
 		.pvr_mask		= 0xffff0000,
@@ -184,7 +193,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_ppc970,
 		.oprofile_cpu_type	= "ppc64/970",
-		.oprofile_type		= POWER4,
+		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.platform		= "ppc970",
 	},
 #endif /* CONFIG_PPC64 */
 #if defined(CONFIG_PPC64) || defined(CONFIG_POWER4)
@@ -204,7 +214,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 8,
 		.cpu_setup		= __setup_cpu_ppc970,
 		.oprofile_cpu_type	= "ppc64/970",
-		.oprofile_type		= POWER4,
+		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.platform		= "ppc970",
 	},
 #endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */
 #ifdef CONFIG_PPC64
@@ -219,7 +230,8 @@ struct cpu_spec	cpu_specs[] = {
 		.dcache_bsize		= 128,
 		.cpu_setup		= __setup_cpu_ppc970,
 		.oprofile_cpu_type	= "ppc64/970",
-		.oprofile_type		= POWER4,
+		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.platform		= "ppc970",
 	},
 	{	/* Power5 GR */
 		.pvr_mask		= 0xffff0000,
@@ -232,7 +244,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_power4,
 		.oprofile_cpu_type	= "ppc64/power5",
-		.oprofile_type		= POWER4,
+		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.platform		= "power5",
 	},
 	{	/* Power5 GS */
 		.pvr_mask		= 0xffff0000,
@@ -245,7 +258,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_power4,
 		.oprofile_cpu_type	= "ppc64/power5+",
-		.oprofile_type		= POWER4,
+		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.platform		= "power5+",
 	},
 	{	/* Cell Broadband Engine */
 		.pvr_mask		= 0xffff0000,
@@ -257,6 +271,7 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.cpu_setup		= __setup_cpu_be,
+		.platform		= "ppc-cell-be",
 	},
 	{	/* default match */
 		.pvr_mask		= 0x00000000,
@@ -268,6 +283,7 @@ struct cpu_spec	cpu_specs[] = {
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_power4,
+		.platform		= "power4",
 	}
 #endif	/* CONFIG_PPC64 */
 #ifdef CONFIG_PPC32
@@ -281,6 +297,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc601",
 	},
 	{	/* 603 */
 		.pvr_mask		= 0xffff0000,
@@ -290,7 +307,8 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= COMMON_USER,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
-		.cpu_setup		= __setup_cpu_603
+		.cpu_setup		= __setup_cpu_603,
+		.platform		= "ppc603",
 	},
 	{	/* 603e */
 		.pvr_mask		= 0xffff0000,
@@ -300,7 +318,8 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= COMMON_USER,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
-		.cpu_setup		= __setup_cpu_603
+		.cpu_setup		= __setup_cpu_603,
+		.platform		= "ppc603",
 	},
 	{	/* 603ev */
 		.pvr_mask		= 0xffff0000,
@@ -310,7 +329,8 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= COMMON_USER,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
-		.cpu_setup		= __setup_cpu_603
+		.cpu_setup		= __setup_cpu_603,
+		.platform		= "ppc603",
 	},
 	{	/* 604 */
 		.pvr_mask		= 0xffff0000,
@@ -321,7 +341,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 2,
-		.cpu_setup		= __setup_cpu_604
+		.cpu_setup		= __setup_cpu_604,
+		.platform		= "ppc604",
 	},
 	{	/* 604e */
 		.pvr_mask		= 0xfffff000,
@@ -332,7 +353,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_604
+		.cpu_setup		= __setup_cpu_604,
+		.platform		= "ppc604",
 	},
 	{	/* 604r */
 		.pvr_mask		= 0xffff0000,
@@ -343,7 +365,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_604
+		.cpu_setup		= __setup_cpu_604,
+		.platform		= "ppc604",
 	},
 	{	/* 604ev */
 		.pvr_mask		= 0xffff0000,
@@ -354,7 +377,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_604
+		.cpu_setup		= __setup_cpu_604,
+		.platform		= "ppc604",
 	},
 	{	/* 740/750 (0x4202, don't support TAU ?) */
 		.pvr_mask		= 0xffffffff,
@@ -365,7 +389,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_750
+		.cpu_setup		= __setup_cpu_750,
+		.platform		= "ppc750",
 	},
 	{	/* 750CX (80100 and 8010x?) */
 		.pvr_mask		= 0xfffffff0,
@@ -376,7 +401,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_750cx
+		.cpu_setup		= __setup_cpu_750cx,
+		.platform		= "ppc750",
 	},
 	{	/* 750CX (82201 and 82202) */
 		.pvr_mask		= 0xfffffff0,
@@ -387,7 +413,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_750cx
+		.cpu_setup		= __setup_cpu_750cx,
+		.platform		= "ppc750",
 	},
 	{	/* 750CXe (82214) */
 		.pvr_mask		= 0xfffffff0,
@@ -398,7 +425,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_750cx
+		.cpu_setup		= __setup_cpu_750cx,
+		.platform		= "ppc750",
 	},
 	{	/* 750CXe "Gekko" (83214) */
 		.pvr_mask		= 0xffffffff,
@@ -409,7 +437,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_750cx
+		.cpu_setup		= __setup_cpu_750cx,
+		.platform		= "ppc750",
 	},
 	{	/* 745/755 */
 		.pvr_mask		= 0xfffff000,
@@ -420,7 +449,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_750
+		.cpu_setup		= __setup_cpu_750,
+		.platform		= "ppc750",
 	},
 	{	/* 750FX rev 1.x */
 		.pvr_mask		= 0xffffff00,
@@ -431,7 +461,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_750
+		.cpu_setup		= __setup_cpu_750,
+		.platform		= "ppc750",
 	},
 	{	/* 750FX rev 2.0 must disable HID0[DPM] */
 		.pvr_mask		= 0xffffffff,
@@ -442,7 +473,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_750
+		.cpu_setup		= __setup_cpu_750,
+		.platform		= "ppc750",
 	},
 	{	/* 750FX (All revs except 2.0) */
 		.pvr_mask		= 0xffff0000,
@@ -453,7 +485,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_750fx
+		.cpu_setup		= __setup_cpu_750fx,
+		.platform		= "ppc750",
 	},
 	{	/* 750GX */
 		.pvr_mask		= 0xffff0000,
@@ -464,7 +497,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_750fx
+		.cpu_setup		= __setup_cpu_750fx,
+		.platform		= "ppc750",
 	},
 	{	/* 740/750 (L2CR bit need fixup for 740) */
 		.pvr_mask		= 0xffff0000,
@@ -475,7 +509,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_750
+		.cpu_setup		= __setup_cpu_750,
+		.platform		= "ppc750",
 	},
 	{	/* 7400 rev 1.1 ? (no TAU) */
 		.pvr_mask		= 0xffffffff,
@@ -486,7 +521,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_7400
+		.cpu_setup		= __setup_cpu_7400,
+		.platform		= "ppc7400",
 	},
 	{	/* 7400 */
 		.pvr_mask		= 0xffff0000,
@@ -497,7 +533,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_7400
+		.cpu_setup		= __setup_cpu_7400,
+		.platform		= "ppc7400",
 	},
 	{	/* 7410 */
 		.pvr_mask		= 0xffff0000,
@@ -508,7 +545,8 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
-		.cpu_setup		= __setup_cpu_7410
+		.cpu_setup		= __setup_cpu_7410,
+		.platform		= "ppc7400",
 	},
 	{	/* 7450 2.0 - no doze/nap */
 		.pvr_mask		= 0xffffffff,
@@ -521,7 +559,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_745x,
 		.oprofile_cpu_type      = "ppc/7450",
-		.oprofile_type		= G4,
+		.oprofile_type		= PPC_OPROFILE_G4,
+		.platform		= "ppc7450",
 	},
 	{	/* 7450 2.1 */
 		.pvr_mask		= 0xffffffff,
@@ -534,7 +573,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_745x,
 		.oprofile_cpu_type      = "ppc/7450",
-		.oprofile_type		= G4,
+		.oprofile_type		= PPC_OPROFILE_G4,
+		.platform		= "ppc7450",
 	},
 	{	/* 7450 2.3 and newer */
 		.pvr_mask		= 0xffff0000,
@@ -547,7 +587,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_745x,
 		.oprofile_cpu_type      = "ppc/7450",
-		.oprofile_type		= G4,
+		.oprofile_type		= PPC_OPROFILE_G4,
+		.platform		= "ppc7450",
 	},
 	{	/* 7455 rev 1.x */
 		.pvr_mask		= 0xffffff00,
@@ -560,7 +601,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_745x,
 		.oprofile_cpu_type      = "ppc/7450",
-		.oprofile_type		= G4,
+		.oprofile_type		= PPC_OPROFILE_G4,
+		.platform		= "ppc7450",
 	},
 	{	/* 7455 rev 2.0 */
 		.pvr_mask		= 0xffffffff,
@@ -573,7 +615,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_745x,
 		.oprofile_cpu_type      = "ppc/7450",
-		.oprofile_type		= G4,
+		.oprofile_type		= PPC_OPROFILE_G4,
+		.platform		= "ppc7450",
 	},
 	{	/* 7455 others */
 		.pvr_mask		= 0xffff0000,
@@ -586,7 +629,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_745x,
 		.oprofile_cpu_type      = "ppc/7450",
-		.oprofile_type		= G4,
+		.oprofile_type		= PPC_OPROFILE_G4,
+		.platform		= "ppc7450",
 	},
 	{	/* 7447/7457 Rev 1.0 */
 		.pvr_mask		= 0xffffffff,
@@ -599,7 +643,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_745x,
 		.oprofile_cpu_type      = "ppc/7450",
-		.oprofile_type		= G4,
+		.oprofile_type		= PPC_OPROFILE_G4,
+		.platform		= "ppc7450",
 	},
 	{	/* 7447/7457 Rev 1.1 */
 		.pvr_mask		= 0xffffffff,
@@ -612,7 +657,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_745x,
 		.oprofile_cpu_type      = "ppc/7450",
-		.oprofile_type		= G4,
+		.oprofile_type		= PPC_OPROFILE_G4,
+		.platform		= "ppc7450",
 	},
 	{	/* 7447/7457 Rev 1.2 and later */
 		.pvr_mask		= 0xffff0000,
@@ -625,7 +671,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_745x,
 		.oprofile_cpu_type      = "ppc/7450",
-		.oprofile_type		= G4,
+		.oprofile_type		= PPC_OPROFILE_G4,
+		.platform		= "ppc7450",
 	},
 	{	/* 7447A */
 		.pvr_mask		= 0xffff0000,
@@ -638,7 +685,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_745x,
 		.oprofile_cpu_type      = "ppc/7450",
-		.oprofile_type		= G4,
+		.oprofile_type		= PPC_OPROFILE_G4,
+		.platform		= "ppc7450",
 	},
 	{	/* 7448 */
 		.pvr_mask		= 0xffff0000,
@@ -651,7 +699,8 @@ struct cpu_spec	cpu_specs[] = {
 		.num_pmcs		= 6,
 		.cpu_setup		= __setup_cpu_745x,
 		.oprofile_cpu_type      = "ppc/7450",
-		.oprofile_type		= G4,
+		.oprofile_type		= PPC_OPROFILE_G4,
+		.platform		= "ppc7450",
 	},
 	{	/* 82xx (8240, 8245, 8260 are all 603e cores) */
 		.pvr_mask		= 0x7fff0000,
@@ -661,7 +710,8 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= COMMON_USER,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
-		.cpu_setup		= __setup_cpu_603
+		.cpu_setup		= __setup_cpu_603,
+		.platform		= "ppc603",
 	},
 	{	/* All G2_LE (603e core, plus some) have the same pvr */
 		.pvr_mask		= 0x7fff0000,
@@ -671,7 +721,8 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= COMMON_USER,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
-		.cpu_setup		= __setup_cpu_603
+		.cpu_setup		= __setup_cpu_603,
+		.platform		= "ppc603",
 	},
 	{	/* e300 (a 603e core, plus some) on 83xx */
 		.pvr_mask		= 0x7fff0000,
@@ -681,7 +732,8 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= COMMON_USER,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
-		.cpu_setup		= __setup_cpu_603
+		.cpu_setup		= __setup_cpu_603,
+		.platform		= "ppc603",
 	},
 	{	/* default match, we assume split I/D cache & TB (non-601)... */
 		.pvr_mask		= 0x00000000,
@@ -691,6 +743,7 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= COMMON_USER,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc603",
 	},
 #endif /* CLASSIC_PPC */
 #ifdef CONFIG_8xx
@@ -704,6 +757,7 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
 		.icache_bsize		= 16,
 		.dcache_bsize		= 16,
+		.platform		= "ppc823",
 	},
 #endif /* CONFIG_8xx */
 #ifdef CONFIG_40x
@@ -715,6 +769,7 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
 		.icache_bsize		= 16,
 		.dcache_bsize		= 16,
+		.platform		= "ppc403",
 	},
 	{	/* 403GCX */
 		.pvr_mask		= 0xffffff00,
@@ -725,6 +780,7 @@ struct cpu_spec	cpu_specs[] = {
 		 	PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
 		.icache_bsize		= 16,
 		.dcache_bsize		= 16,
+		.platform		= "ppc403",
 	},
 	{	/* 403G ?? */
 		.pvr_mask		= 0xffff0000,
@@ -734,6 +790,7 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
 		.icache_bsize		= 16,
 		.dcache_bsize		= 16,
+		.platform		= "ppc403",
 	},
 	{	/* 405GP */
 		.pvr_mask		= 0xffff0000,
@@ -744,6 +801,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 	{	/* STB 03xxx */
 		.pvr_mask		= 0xffff0000,
@@ -754,6 +812,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 	{	/* STB 04xxx */
 		.pvr_mask		= 0xffff0000,
@@ -764,6 +823,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 	{	/* NP405L */
 		.pvr_mask		= 0xffff0000,
@@ -774,6 +834,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 	{	/* NP4GS3 */
 		.pvr_mask		= 0xffff0000,
@@ -784,6 +845,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 	{   /* NP405H */
 		.pvr_mask		= 0xffff0000,
@@ -794,6 +856,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 	{	/* 405GPr */
 		.pvr_mask		= 0xffff0000,
@@ -804,6 +867,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 	{   /* STBx25xx */
 		.pvr_mask		= 0xffff0000,
@@ -814,6 +878,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 	{	/* 405LP */
 		.pvr_mask		= 0xffff0000,
@@ -823,6 +888,7 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 	{	/* Xilinx Virtex-II Pro  */
 		.pvr_mask		= 0xffff0000,
@@ -833,6 +899,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 	{	/* 405EP */
 		.pvr_mask		= 0xffff0000,
@@ -843,6 +910,7 @@ struct cpu_spec	cpu_specs[] = {
 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc405",
 	},
 
 #endif /* CONFIG_40x */
@@ -852,81 +920,90 @@ struct cpu_spec	cpu_specs[] = {
 		.pvr_value		= 0x40000850,
 		.cpu_name		= "440EP Rev. A",
 		.cpu_features		= CPU_FTRS_44X,
-		.cpu_user_features	= COMMON_USER, /* 440EP has an FPU */
+		.cpu_user_features	= COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc440",
 	},
 	{
 		.pvr_mask		= 0xf0000fff,
 		.pvr_value		= 0x400008d3,
 		.cpu_name		= "440EP Rev. B",
 		.cpu_features		= CPU_FTRS_44X,
-		.cpu_user_features	= COMMON_USER, /* 440EP has an FPU */
+		.cpu_user_features	= COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc440",
 	},
 	{	/* 440GP Rev. B */
 		.pvr_mask		= 0xf0000fff,
 		.pvr_value		= 0x40000440,
 		.cpu_name		= "440GP Rev. B",
 		.cpu_features		= CPU_FTRS_44X,
-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc440gp",
 	},
 	{	/* 440GP Rev. C */
 		.pvr_mask		= 0xf0000fff,
 		.pvr_value		= 0x40000481,
 		.cpu_name		= "440GP Rev. C",
 		.cpu_features		= CPU_FTRS_44X,
-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc440gp",
 	},
 	{ /* 440GX Rev. A */
 		.pvr_mask		= 0xf0000fff,
 		.pvr_value		= 0x50000850,
 		.cpu_name		= "440GX Rev. A",
 		.cpu_features		= CPU_FTRS_44X,
-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc440",
 	},
 	{ /* 440GX Rev. B */
 		.pvr_mask		= 0xf0000fff,
 		.pvr_value		= 0x50000851,
 		.cpu_name		= "440GX Rev. B",
 		.cpu_features		= CPU_FTRS_44X,
-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc440",
 	},
 	{ /* 440GX Rev. C */
 		.pvr_mask		= 0xf0000fff,
 		.pvr_value		= 0x50000892,
 		.cpu_name		= "440GX Rev. C",
 		.cpu_features		= CPU_FTRS_44X,
-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc440",
 	},
 	{ /* 440GX Rev. F */
 		.pvr_mask		= 0xf0000fff,
 		.pvr_value		= 0x50000894,
 		.cpu_name		= "440GX Rev. F",
 		.cpu_features		= CPU_FTRS_44X,
-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc440",
 	},
 	{ /* 440SP Rev. A */
 		.pvr_mask		= 0xff000fff,
 		.pvr_value		= 0x53000891,
 		.cpu_name		= "440SP Rev. A",
 		.cpu_features		= CPU_FTRS_44X,
-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc440",
 	},
 	{ /* 440SPe Rev. A */
 		.pvr_mask		= 0xff000fff,
@@ -934,9 +1011,10 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_name		= "440SPe Rev. A",
 		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
 			CPU_FTR_USE_TB,
-		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "ppc440",
 	},
 #endif /* CONFIG_44x */
 #ifdef CONFIG_FSL_BOOKE
@@ -946,10 +1024,11 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_name		= "e200z5",
 		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
 		.cpu_features		= CPU_FTRS_E200,
-		.cpu_user_features	= PPC_FEATURE_32 |
-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE |
+		.cpu_user_features	= COMMON_USER_BOOKE |
+			PPC_FEATURE_HAS_EFP_SINGLE |
 			PPC_FEATURE_UNIFIED_CACHE,
 		.dcache_bsize		= 32,
+		.platform		= "ppc5554",
 	},
 	{	/* e200z6 */
 		.pvr_mask		= 0xfff00000,
@@ -957,11 +1036,12 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_name		= "e200z6",
 		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
 		.cpu_features		= CPU_FTRS_E200,
-		.cpu_user_features	= PPC_FEATURE_32 |
-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
+		.cpu_user_features	= COMMON_USER_BOOKE |
+			PPC_FEATURE_SPE_COMP |
 			PPC_FEATURE_HAS_EFP_SINGLE |
 			PPC_FEATURE_UNIFIED_CACHE,
 		.dcache_bsize		= 32,
+		.platform		= "ppc5554",
 	},
 	{	/* e500 */
 		.pvr_mask		= 0xffff0000,
@@ -969,14 +1049,15 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_name		= "e500",
 		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
 		.cpu_features		= CPU_FTRS_E500,
-		.cpu_user_features	= PPC_FEATURE_32 |
-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
+		.cpu_user_features	= COMMON_USER_BOOKE |
+			PPC_FEATURE_SPE_COMP |
 			PPC_FEATURE_HAS_EFP_SINGLE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
 		.oprofile_cpu_type	= "ppc/e500",
-		.oprofile_type		= BOOKE,
+		.oprofile_type		= PPC_OPROFILE_BOOKE,
+		.platform		= "ppc8540",
 	},
 	{	/* e500v2 */
 		.pvr_mask		= 0xffff0000,
@@ -984,14 +1065,16 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_name		= "e500v2",
 		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
 		.cpu_features		= CPU_FTRS_E500_2,
-		.cpu_user_features	= PPC_FEATURE_32 |
-			PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
-			PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE,
+		.cpu_user_features	= COMMON_USER_BOOKE |
+			PPC_FEATURE_SPE_COMP |
+			PPC_FEATURE_HAS_EFP_SINGLE |
+			PPC_FEATURE_HAS_EFP_DOUBLE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
 		.oprofile_cpu_type	= "ppc/e500",
-		.oprofile_type		= BOOKE,
+		.oprofile_type		= PPC_OPROFILE_BOOKE,
+		.platform		= "ppc8548",
 	},
 #endif
 #if !CLASSIC_PPC
@@ -1003,6 +1086,7 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_user_features	= PPC_FEATURE_32,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.platform		= "powerpc",
 	}
 #endif /* !CLASSIC_PPC */
 #endif /* CONFIG_PPC32 */

+ 1 - 1
arch/powerpc/kernel/entry_32.S

@@ -988,7 +988,7 @@ _GLOBAL(enter_rtas)
 	stwu	r1,-INT_FRAME_SIZE(r1)
 	mflr	r0
 	stw	r0,INT_FRAME_SIZE+4(r1)
-	LOADADDR(r4, rtas)
+	LOAD_REG_ADDR(r4, rtas)
 	lis	r6,1f@ha	/* physical return address for rtas */
 	addi	r6,r6,1f@l
 	tophys(r6,r6)

+ 7 - 8
arch/powerpc/kernel/entry_64.S

@@ -511,7 +511,8 @@ restore:
 	cmpdi	0,r5,0
 	beq	4f
 	/* Check for pending interrupts (iSeries) */
-	ld	r3,PACALPPACA+LPPACAANYINT(r13)
+	ld	r3,PACALPPACAPTR(r13)
+	ld	r3,LPPACAANYINT(r3)
 	cmpdi	r3,0
 	beq+	4f			/* skip do_IRQ if no interrupts */
 
@@ -689,9 +690,8 @@ _GLOBAL(enter_rtas)
         std	r6,PACASAVEDMSR(r13)
 
 	/* Setup our real return addr */	
-	SET_REG_TO_LABEL(r4,.rtas_return_loc)
-	SET_REG_TO_CONST(r9,PAGE_OFFSET)
-	sub	r4,r4,r9
+	LOAD_REG_ADDR(r4,.rtas_return_loc)
+	clrldi	r4,r4,2			/* convert to realmode address */
        	mtlr	r4
 
 	li	r0,0
@@ -706,7 +706,7 @@ _GLOBAL(enter_rtas)
 	sync				/* disable interrupts so SRR0/1 */
 	mtmsrd	r0			/* don't get trashed */
 
-	SET_REG_TO_LABEL(r4,rtas)
+	LOAD_REG_ADDR(r4, rtas)
 	ld	r5,RTASENTRY(r4)	/* get the rtas->entry value */
 	ld	r4,RTASBASE(r4)		/* get the rtas->base value */
 	
@@ -718,8 +718,7 @@ _GLOBAL(enter_rtas)
 _STATIC(rtas_return_loc)
 	/* relocation is off at this point */
 	mfspr	r4,SPRN_SPRG3	        /* Get PACA */
-	SET_REG_TO_CONST(r5, PAGE_OFFSET)
-        sub     r4,r4,r5                /* RELOC the PACA base pointer */
+	clrldi	r4,r4,2			/* convert to realmode address */
 
 	mfmsr   r6
 	li	r0,MSR_RI
@@ -728,7 +727,7 @@ _STATIC(rtas_return_loc)
 	mtmsrd  r6
         
         ld	r1,PACAR1(r4)           /* Restore our SP */
-	LOADADDR(r3,.rtas_restore_regs)
+	LOAD_REG_IMMEDIATE(r3,.rtas_restore_regs)
         ld	r4,PACASAVEDMSR(r4)     /* Restore our MSR */
 
 	mtspr	SPRN_SRR0,r3

+ 5 - 5
arch/powerpc/kernel/fpu.S

@@ -39,9 +39,9 @@ _GLOBAL(load_up_fpu)
  * to another.  Instead we call giveup_fpu in switch_to.
  */
 #ifndef CONFIG_SMP
-	LOADBASE(r3, last_task_used_math)
+	LOAD_REG_ADDRBASE(r3, last_task_used_math)
 	toreal(r3)
-	PPC_LL	r4,OFF(last_task_used_math)(r3)
+	PPC_LL	r4,ADDROFF(last_task_used_math)(r3)
 	PPC_LCMPI	0,r4,0
 	beq	1f
 	toreal(r4)
@@ -77,7 +77,7 @@ _GLOBAL(load_up_fpu)
 #ifndef CONFIG_SMP
 	subi	r4,r5,THREAD
 	fromreal(r4)
-	PPC_STL	r4,OFF(last_task_used_math)(r3)
+	PPC_STL	r4,ADDROFF(last_task_used_math)(r3)
 #endif /* CONFIG_SMP */
 	/* restore registers and return */
 	/* we haven't used ctr or xer or lr */
@@ -113,8 +113,8 @@ _GLOBAL(giveup_fpu)
 1:
 #ifndef CONFIG_SMP
 	li	r5,0
-	LOADBASE(r4,last_task_used_math)
-	PPC_STL	r5,OFF(last_task_used_math)(r4)
+	LOAD_REG_ADDRBASE(r4,last_task_used_math)
+	PPC_STL	r5,ADDROFF(last_task_used_math)(r4)
 #endif /* CONFIG_SMP */
 	blr
 

+ 60 - 52
arch/powerpc/kernel/head_64.S

@@ -154,12 +154,12 @@ _GLOBAL(__secondary_hold)
 	bne	100b
 
 #ifdef CONFIG_HMT
-	LOADADDR(r4, .hmt_init)
+	SET_REG_IMMEDIATE(r4, .hmt_init)
 	mtctr	r4
 	bctr
 #else
 #ifdef CONFIG_SMP
-	LOADADDR(r4, .pSeries_secondary_smp_init)
+	LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init)
 	mtctr	r4
 	mr	r3,r24
 	bctr
@@ -205,9 +205,10 @@ exception_marker:
 #define EX_LR		72
 
 /*
- * We're short on space and time in the exception prolog, so we can't use
- * the normal LOADADDR macro. Normally we just need the low halfword of the
- * address, but for Kdump we need the whole low word.
+ * We're short on space and time in the exception prolog, so we can't
+ * use the normal SET_REG_IMMEDIATE macro. Normally we just need the
+ * low halfword of the address, but for Kdump we need the whole low
+ * word.
  */
 #ifdef CONFIG_CRASH_DUMP
 #define LOAD_HANDLER(reg, label)					\
@@ -254,8 +255,9 @@ exception_marker:
 
 #define EXCEPTION_PROLOG_ISERIES_2					\
 	mfmsr	r10;							\
-	ld	r11,PACALPPACA+LPPACASRR0(r13);				\
-	ld	r12,PACALPPACA+LPPACASRR1(r13);				\
+	ld	r12,PACALPPACAPTR(r13);					\
+	ld	r11,LPPACASRR0(r12);					\
+	ld	r12,LPPACASRR1(r12);					\
 	ori	r10,r10,MSR_RI;						\
 	mtmsrd	r10,1
 
@@ -634,7 +636,8 @@ data_access_slb_iSeries:
 	std	r12,PACA_EXSLB+EX_R12(r13)
 	mfspr	r10,SPRN_SPRG1
 	std	r10,PACA_EXSLB+EX_R13(r13)
-	ld	r12,PACALPPACA+LPPACASRR1(r13);
+	ld	r12,PACALPPACAPTR(r13)
+	ld	r12,LPPACASRR1(r12)
 	b	.slb_miss_realmode
 
 	STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
@@ -644,7 +647,8 @@ instruction_access_slb_iSeries:
 	mtspr	SPRN_SPRG1,r13		/* save r13 */
 	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
 	std	r3,PACA_EXSLB+EX_R3(r13)
-	ld	r3,PACALPPACA+LPPACASRR0(r13)	/* get SRR0 value */
+	ld	r3,PACALPPACAPTR(r13)
+	ld	r3,LPPACASRR0(r3)	/* get SRR0 value */
 	std	r9,PACA_EXSLB+EX_R9(r13)
 	mfcr	r9
 #ifdef __DISABLED__
@@ -656,7 +660,8 @@ instruction_access_slb_iSeries:
 	std	r12,PACA_EXSLB+EX_R12(r13)
 	mfspr	r10,SPRN_SPRG1
 	std	r10,PACA_EXSLB+EX_R13(r13)
-	ld	r12,PACALPPACA+LPPACASRR1(r13);
+	ld	r12,PACALPPACAPTR(r13)
+	ld	r12,LPPACASRR1(r12)
 	b	.slb_miss_realmode
 
 #ifdef __DISABLED__
@@ -713,7 +718,7 @@ system_reset_iSeries:
 	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor
 					 * should start */
 	sync
-	LOADADDR(r3,current_set)
+	LOAD_REG_IMMEDIATE(r3,current_set)
 	sldi	r28,r24,3		/* get current_set[cpu#] */
 	ldx	r3,r3,r28
 	addi	r1,r3,THREAD_SIZE
@@ -745,17 +750,19 @@ iSeries_secondary_smp_loop:
 	.globl decrementer_iSeries_masked
 decrementer_iSeries_masked:
 	li	r11,1
-	stb	r11,PACALPPACA+LPPACADECRINT(r13)
-	LOADBASE(r12,tb_ticks_per_jiffy)
-	lwz	r12,OFF(tb_ticks_per_jiffy)(r12)
+	ld	r12,PACALPPACAPTR(r13)
+	stb	r11,LPPACADECRINT(r12)
+	LOAD_REG_ADDRBASE(r12,tb_ticks_per_jiffy)
+	lwz	r12,ADDROFF(tb_ticks_per_jiffy)(r12)
 	mtspr	SPRN_DEC,r12
 	/* fall through */
 
 	.globl hardware_interrupt_iSeries_masked
 hardware_interrupt_iSeries_masked:
 	mtcrf	0x80,r9		/* Restore regs */
-	ld	r11,PACALPPACA+LPPACASRR0(r13)
-	ld	r12,PACALPPACA+LPPACASRR1(r13)
+	ld	r12,PACALPPACAPTR(r13)
+	ld	r11,LPPACASRR0(r12)
+	ld	r12,LPPACASRR1(r12)
 	mtspr	SPRN_SRR0,r11
 	mtspr	SPRN_SRR1,r12
 	ld	r9,PACA_EXGEN+EX_R9(r13)
@@ -994,7 +1001,8 @@ _GLOBAL(slb_miss_realmode)
 	ld	r3,PACA_EXSLB+EX_R3(r13)
 	lwz	r9,PACA_EXSLB+EX_CCR(r13)	/* get saved CR */
 #ifdef CONFIG_PPC_ISERIES
-	ld	r11,PACALPPACA+LPPACASRR0(r13)	/* get SRR0 value */
+	ld	r11,PACALPPACAPTR(r13)
+	ld	r11,LPPACASRR0(r11)		/* get SRR0 value */
 #endif /* CONFIG_PPC_ISERIES */
 
 	mtlr	r10
@@ -1412,7 +1420,7 @@ _GLOBAL(pSeries_secondary_smp_init)
 	 * physical cpu id in r24, we need to search the pacas to find
 	 * which logical id maps to our physical one.
 	 */
-	LOADADDR(r13, paca) 		/* Get base vaddr of paca array	 */
+	LOAD_REG_IMMEDIATE(r13, paca)	/* Get base vaddr of paca array	 */
 	li	r5,0			/* logical cpu id                */
 1:	lhz	r6,PACAHWCPUID(r13)	/* Load HW procid from paca      */
 	cmpw	r6,r24			/* Compare to our id             */
@@ -1446,8 +1454,8 @@ _GLOBAL(pSeries_secondary_smp_init)
 #ifdef CONFIG_PPC_ISERIES
 _STATIC(__start_initialization_iSeries)
 	/* Clear out the BSS */
-	LOADADDR(r11,__bss_stop)
-	LOADADDR(r8,__bss_start)
+	LOAD_REG_IMMEDIATE(r11,__bss_stop)
+	LOAD_REG_IMMEDIATE(r8,__bss_start)
 	sub	r11,r11,r8		/* bss size			*/
 	addi	r11,r11,7		/* round up to an even double word */
 	rldicl. r11,r11,61,3		/* shift right by 3		*/
@@ -1458,17 +1466,17 @@ _STATIC(__start_initialization_iSeries)
 3:	stdu	r0,8(r8)
 	bdnz	3b
 4:
-	LOADADDR(r1,init_thread_union)
+	LOAD_REG_IMMEDIATE(r1,init_thread_union)
 	addi	r1,r1,THREAD_SIZE
 	li	r0,0
 	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
 
-	LOADADDR(r3,cpu_specs)
-	LOADADDR(r4,cur_cpu_spec)
+	LOAD_REG_IMMEDIATE(r3,cpu_specs)
+	LOAD_REG_IMMEDIATE(r4,cur_cpu_spec)
 	li	r5,0
 	bl	.identify_cpu
 
-	LOADADDR(r2,__toc_start)
+	LOAD_REG_IMMEDIATE(r2,__toc_start)
 	addi	r2,r2,0x4000
 	addi	r2,r2,0x4000
 
@@ -1528,7 +1536,7 @@ _GLOBAL(__start_initialization_multiplatform)
 	li	r24,0
 
 	/* Switch off MMU if not already */
-	LOADADDR(r4, .__after_prom_start - KERNELBASE)
+	LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
 	add	r4,r4,r30
 	bl	.__mmu_off
 	b	.__after_prom_start
@@ -1548,7 +1556,7 @@ _STATIC(__boot_from_prom)
 	/* put a relocation offset into r3 */
 	bl	.reloc_offset
 
-	LOADADDR(r2,__toc_start)
+	LOAD_REG_IMMEDIATE(r2,__toc_start)
 	addi	r2,r2,0x4000
 	addi	r2,r2,0x4000
 
@@ -1588,9 +1596,9 @@ _STATIC(__after_prom_start)
  */
 	bl	.reloc_offset
 	mr	r26,r3
-	SET_REG_TO_CONST(r27,KERNELBASE)
+	LOAD_REG_IMMEDIATE(r27, KERNELBASE)
 
-	LOADADDR(r3, PHYSICAL_START)	/* target addr */
+	LOAD_REG_IMMEDIATE(r3, PHYSICAL_START)	/* target addr */
 
 	// XXX FIXME: Use phys returned by OF (r30)
 	add	r4,r27,r26 		/* source addr			 */
@@ -1598,7 +1606,7 @@ _STATIC(__after_prom_start)
 					/*   i.e. where we are running	 */
 					/*	the source addr		 */
 
-	LOADADDR(r5,copy_to_here)	/* # bytes of memory to copy	 */
+	LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */
 	sub	r5,r5,r27
 
 	li	r6,0x100		/* Start offset, the first 0x100 */
@@ -1608,11 +1616,11 @@ _STATIC(__after_prom_start)
 					/* this includes the code being	 */
 					/* executed here.		 */
 
-	LOADADDR(r0, 4f)		/* Jump to the copy of this code */
+	LOAD_REG_IMMEDIATE(r0, 4f)	/* Jump to the copy of this code */
 	mtctr	r0			/* that we just made/relocated	 */
 	bctr
 
-4:	LOADADDR(r5,klimit)
+4:	LOAD_REG_IMMEDIATE(r5,klimit)
 	add	r5,r5,r26
 	ld	r5,0(r5)		/* get the value of klimit */
 	sub	r5,r5,r27
@@ -1694,7 +1702,7 @@ _GLOBAL(pmac_secondary_start)
 	mtmsrd	r3			/* RI on */
 
 	/* Set up a paca value for this processor. */
-	LOADADDR(r4, paca) 		 /* Get base vaddr of paca array	*/
+	LOAD_REG_IMMEDIATE(r4, paca)	/* Get base vaddr of paca array	*/
 	mulli	r13,r24,PACA_SIZE	 /* Calculate vaddr of right paca */
 	add	r13,r13,r4		/* for this processor.		*/
 	mtspr	SPRN_SPRG3,r13		 /* Save vaddr of paca in SPRG3	*/
@@ -1731,7 +1739,7 @@ _GLOBAL(__secondary_start)
 	bl	.early_setup_secondary
 
 	/* Initialize the kernel stack.  Just a repeat for iSeries.	 */
-	LOADADDR(r3,current_set)
+	LOAD_REG_ADDR(r3, current_set)
 	sldi	r28,r24,3		/* get current_set[cpu#]	 */
 	ldx	r1,r3,r28
 	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
@@ -1742,8 +1750,8 @@ _GLOBAL(__secondary_start)
 	mtlr	r7
 
 	/* enable MMU and jump to start_secondary */
-	LOADADDR(r3,.start_secondary_prolog)
-	SET_REG_TO_CONST(r4, MSR_KERNEL)
+	LOAD_REG_ADDR(r3, .start_secondary_prolog)
+	LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
 #ifdef DO_SOFT_DISABLE
 	ori	r4,r4,MSR_EE
 #endif
@@ -1792,8 +1800,8 @@ _STATIC(start_here_multiplatform)
 	 * be detached from the kernel completely. Besides, we need
 	 * to clear it now for kexec-style entry.
 	 */
-	LOADADDR(r11,__bss_stop)
-	LOADADDR(r8,__bss_start)
+	LOAD_REG_IMMEDIATE(r11,__bss_stop)
+	LOAD_REG_IMMEDIATE(r8,__bss_start)
 	sub	r11,r11,r8		/* bss size			*/
 	addi	r11,r11,7		/* round up to an even double word */
 	rldicl. r11,r11,61,3		/* shift right by 3		*/
@@ -1831,7 +1839,7 @@ _STATIC(start_here_multiplatform)
 	/* up the htab.  This is done because we have relocated the  */
 	/* kernel but are still running in real mode. */
 
-	LOADADDR(r3,init_thread_union)
+	LOAD_REG_IMMEDIATE(r3,init_thread_union)
 	add	r3,r3,r26
 
 	/* set up a stack pointer (physical address) */
@@ -1840,14 +1848,14 @@ _STATIC(start_here_multiplatform)
 	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
 
 	/* set up the TOC (physical address) */
-	LOADADDR(r2,__toc_start)
+	LOAD_REG_IMMEDIATE(r2,__toc_start)
 	addi	r2,r2,0x4000
 	addi	r2,r2,0x4000
 	add	r2,r2,r26
 
-	LOADADDR(r3,cpu_specs)
+	LOAD_REG_IMMEDIATE(r3, cpu_specs)
 	add	r3,r3,r26
-	LOADADDR(r4,cur_cpu_spec)
+	LOAD_REG_IMMEDIATE(r4,cur_cpu_spec)
 	add	r4,r4,r26
 	mr	r5,r26
 	bl	.identify_cpu
@@ -1863,11 +1871,11 @@ _STATIC(start_here_multiplatform)
 	 * nowhere it can be initialized differently before we reach this
 	 * code
 	 */
-	LOADADDR(r27, boot_cpuid)
+	LOAD_REG_IMMEDIATE(r27, boot_cpuid)
 	add	r27,r27,r26
 	lwz	r27,0(r27)
 
-	LOADADDR(r24, paca) 		/* Get base vaddr of paca array	 */
+	LOAD_REG_IMMEDIATE(r24, paca) 	/* Get base vaddr of paca array	 */
 	mulli	r13,r27,PACA_SIZE	/* Calculate vaddr of right paca */
 	add	r13,r13,r24		/* for this processor.		 */
 	add	r13,r13,r26		/* convert to physical addr	 */
@@ -1880,8 +1888,8 @@ _STATIC(start_here_multiplatform)
 	mr	r3,r31
  	bl	.early_setup
 
-	LOADADDR(r3,.start_here_common)
-	SET_REG_TO_CONST(r4, MSR_KERNEL)
+	LOAD_REG_IMMEDIATE(r3, .start_here_common)
+	LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
 	mtspr	SPRN_SRR0,r3
 	mtspr	SPRN_SRR1,r4
 	rfid
@@ -1895,7 +1903,7 @@ _STATIC(start_here_common)
 	/* The following code sets up the SP and TOC now that we are */
 	/* running with translation enabled. */
 
-	LOADADDR(r3,init_thread_union)
+	LOAD_REG_IMMEDIATE(r3,init_thread_union)
 
 	/* set up the stack */
 	addi	r1,r3,THREAD_SIZE
@@ -1908,16 +1916,16 @@ _STATIC(start_here_common)
 	li	r3,0
 	bl	.do_cpu_ftr_fixups
 
-	LOADADDR(r26, boot_cpuid)
+	LOAD_REG_IMMEDIATE(r26, boot_cpuid)
 	lwz	r26,0(r26)
 
-	LOADADDR(r24, paca) 		/* Get base vaddr of paca array  */
+	LOAD_REG_IMMEDIATE(r24, paca)	/* Get base vaddr of paca array  */
 	mulli	r13,r26,PACA_SIZE	/* Calculate vaddr of right paca */
 	add	r13,r13,r24		/* for this processor.		 */
 	mtspr	SPRN_SPRG3,r13
 
 	/* ptr to current */
-	LOADADDR(r4,init_task)
+	LOAD_REG_IMMEDIATE(r4, init_task)
 	std	r4,PACACURRENT(r13)
 
 	/* Load the TOC */
@@ -1940,7 +1948,7 @@ _STATIC(start_here_common)
 
 _GLOBAL(hmt_init)
 #ifdef CONFIG_HMT
-	LOADADDR(r5, hmt_thread_data)
+	LOAD_REG_IMMEDIATE(r5, hmt_thread_data)
 	mfspr	r7,SPRN_PVR
 	srwi	r7,r7,16
 	cmpwi	r7,0x34			/* Pulsar  */
@@ -1961,7 +1969,7 @@ _GLOBAL(hmt_init)
 	b	101f
 
 __hmt_secondary_hold:
-	LOADADDR(r5, hmt_thread_data)
+	LOAD_REG_IMMEDIATE(r5, hmt_thread_data)
 	clrldi	r5,r5,4
 	li	r7,0
 	mfspr	r6,SPRN_PIR
@@ -1989,7 +1997,7 @@ __hmt_secondary_hold:
 
 #ifdef CONFIG_HMT
 _GLOBAL(hmt_start_secondary)
-	LOADADDR(r4,__hmt_secondary_hold)
+	LOAD_REG_IMMEDIATE(r4,__hmt_secondary_hold)
 	clrldi	r4,r4,4
 	mtspr	SPRN_NIADORM, r4
 	mfspr	r4, SPRN_MSRDORM

+ 4 - 4
arch/powerpc/kernel/idle_power4.S

@@ -38,14 +38,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
 	/* We must dynamically check for the NAP feature as it
 	 * can be cleared by CPU init after the fixups are done
 	 */
-	LOADBASE(r3,cur_cpu_spec)
-	ld	r4,OFF(cur_cpu_spec)(r3)
+	LOAD_REG_ADDRBASE(r3,cur_cpu_spec)
+	ld	r4,ADDROFF(cur_cpu_spec)(r3)
 	ld	r4,CPU_SPEC_FEATURES(r4)
 	andi.	r0,r4,CPU_FTR_CAN_NAP
 	beqlr
 	/* Now check if user or arch enabled NAP mode */
-	LOADBASE(r3,powersave_nap)
-	lwz	r4,OFF(powersave_nap)(r3)
+	LOAD_REG_ADDRBASE(r3,powersave_nap)
+	lwz	r4,ADDROFF(powersave_nap)(r3)
 	cmpwi	0,r4,0
 	beqlr
 

+ 4 - 8
arch/powerpc/kernel/irq.c

@@ -238,14 +238,10 @@ void do_IRQ(struct pt_regs *regs)
         irq_exit();
 
 #ifdef CONFIG_PPC_ISERIES
-	{
-		struct paca_struct *lpaca = get_paca();
-
-		if (lpaca->lppaca.int_dword.fields.decr_int) {
-			lpaca->lppaca.int_dword.fields.decr_int = 0;
-			/* Signal a fake decrementer interrupt */
-			timer_interrupt(regs);
-		}
+	if (get_lppaca()->int_dword.fields.decr_int) {
+		get_lppaca()->int_dword.fields.decr_int = 0;
+		/* Signal a fake decrementer interrupt */
+		timer_interrupt(regs);
 	}
 #endif
 }

+ 5 - 8
arch/powerpc/kernel/lparcfg.c

@@ -55,15 +55,13 @@ static unsigned long get_purr(void)
 {
 	unsigned long sum_purr = 0;
 	int cpu;
-	struct paca_struct *lpaca;
 
 	for_each_cpu(cpu) {
-		lpaca = paca + cpu;
-		sum_purr += lpaca->lppaca.emulated_time_base;
+		sum_purr += lppaca[cpu].emulated_time_base;
 
 #ifdef PURR_DEBUG
 		printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n",
-			cpu, lpaca->lppaca.emulated_time_base);
+			cpu, lppaca[cpu].emulated_time_base);
 #endif
 	}
 	return sum_purr;
@@ -79,12 +77,11 @@ static int lparcfg_data(struct seq_file *m, void *v)
 	unsigned long pool_id, lp_index;
 	int shared, entitled_capacity, max_entitled_capacity;
 	int processors, max_processors;
-	struct paca_struct *lpaca = get_paca();
 	unsigned long purr = get_purr();
 
 	seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
 
-	shared = (int)(lpaca->lppaca_ptr->shared_proc);
+	shared = (int)(get_lppaca()->shared_proc);
 	seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n",
 		   e2a(xItExtVpdPanel.mfgID[2]),
 		   e2a(xItExtVpdPanel.mfgID[3]),
@@ -402,7 +399,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
 			   (h_resource >> 0 * 8) & 0xffff);
 
 		/* pool related entries are apropriate for shared configs */
-		if (paca[0].lppaca.shared_proc) {
+		if (lppaca[0].shared_proc) {
 
 			h_pic(&pool_idle_time, &pool_procs);
 
@@ -451,7 +448,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
 	seq_printf(m, "partition_potential_processors=%d\n",
 		   partition_potential_processors);
 
-	seq_printf(m, "shared_processor_mode=%d\n", paca[0].lppaca.shared_proc);
+	seq_printf(m, "shared_processor_mode=%d\n", lppaca[0].shared_proc);
 
 	return 0;
 }

+ 2 - 2
arch/powerpc/kernel/misc_32.S

@@ -68,7 +68,7 @@ _GLOBAL(reloc_offset)
 	mflr	r0
 	bl	1f
 1:	mflr	r3
-	LOADADDR(r4,1b)
+	LOAD_REG_IMMEDIATE(r4,1b)
 	subf	r3,r4,r3
 	mtlr	r0
 	blr
@@ -80,7 +80,7 @@ _GLOBAL(add_reloc_offset)
 	mflr	r0
 	bl	1f
 1:	mflr	r5
-	LOADADDR(r4,1b)
+	LOAD_REG_IMMEDIATE(r4,1b)
 	subf	r5,r4,r5
 	add	r3,r3,r5
 	mtlr	r0

+ 5 - 5
arch/powerpc/kernel/misc_64.S

@@ -39,7 +39,7 @@ _GLOBAL(reloc_offset)
 	mflr	r0
 	bl	1f
 1:	mflr	r3
-	LOADADDR(r4,1b)
+	LOAD_REG_IMMEDIATE(r4,1b)
 	subf	r3,r4,r3
 	mtlr	r0
 	blr
@@ -51,7 +51,7 @@ _GLOBAL(add_reloc_offset)
 	mflr	r0
 	bl	1f
 1:	mflr	r5
-	LOADADDR(r4,1b)
+	LOAD_REG_IMMEDIATE(r4,1b)
 	subf	r5,r4,r5
 	add	r3,r3,r5
 	mtlr	r0
@@ -498,15 +498,15 @@ _GLOBAL(identify_cpu)
  */
 _GLOBAL(do_cpu_ftr_fixups)
 	/* Get CPU 0 features */
-	LOADADDR(r6,cur_cpu_spec)
+	LOAD_REG_IMMEDIATE(r6,cur_cpu_spec)
 	sub	r6,r6,r3
 	ld	r4,0(r6)
 	sub	r4,r4,r3
 	ld	r4,CPU_SPEC_FEATURES(r4)
 	/* Get the fixup table */
-	LOADADDR(r6,__start___ftr_fixup)
+	LOAD_REG_IMMEDIATE(r6,__start___ftr_fixup)
 	sub	r6,r6,r3
-	LOADADDR(r7,__stop___ftr_fixup)
+	LOAD_REG_IMMEDIATE(r7,__stop___ftr_fixup)
 	sub	r7,r7,r3
 	/* Do the fixup */
 1:	cmpld	r6,r7

+ 24 - 12
arch/powerpc/kernel/paca.c

@@ -25,6 +25,28 @@
  * field correctly */
 extern unsigned long __toc_start;
 
+/*
+ * iSeries structure which the hypervisor knows about - this structure
+ * should not cross a page boundary.  The vpa_init/register_vpa call
+ * is now known to fail if the lppaca structure crosses a page
+ * boundary.  The lppaca is also used on POWER5 pSeries boxes.  The
+ * lppaca is 640 bytes long, and cannot readily change since the
+ * hypervisor knows its layout, so a 1kB alignment will suffice to
+ * ensure that it doesn't cross a page boundary.
+ */
+struct lppaca lppaca[] = {
+	[0 ... (NR_CPUS-1)] = {
+		.desc = 0xd397d781,	/* "LpPa" */
+		.size = sizeof(struct lppaca),
+		.dyn_proc_status = 2,
+		.decr_val = 0x00ff0000,
+		.fpregs_in_use = 1,
+		.end_of_quantum = 0xfffffffffffffffful,
+		.slb_count = 64,
+		.vmxregs_in_use = 0,
+	},
+};
+
 /* The Paca is an array with one entry per processor.  Each contains an
  * lppaca, which contains the information shared between the
  * hypervisor and Linux.
@@ -35,27 +57,17 @@ extern unsigned long __toc_start;
  * processor (not thread).
  */
 #define PACA_INIT_COMMON(number, start, asrr, asrv)			    \
+	.lppaca_ptr = &lppaca[number],					    \
 	.lock_token = 0x8000,						    \
 	.paca_index = (number),		/* Paca Index */		    \
 	.kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL,		    \
 	.stab_real = (asrr), 		/* Real pointer to segment table */ \
 	.stab_addr = (asrv),		/* Virt pointer to segment table */ \
 	.cpu_start = (start),		/* Processor start */		    \
-	.hw_cpu_id = 0xffff,						    \
-	.lppaca = {							    \
-		.desc = 0xd397d781,	/* "LpPa" */			    \
-		.size = sizeof(struct lppaca),				    \
-		.dyn_proc_status = 2,					    \
-		.decr_val = 0x00ff0000,					    \
-		.fpregs_in_use = 1,					    \
-		.end_of_quantum = 0xfffffffffffffffful,			    \
-		.slb_count = 64,					    \
-		.vmxregs_in_use = 0,					    \
-	},								    \
+	.hw_cpu_id = 0xffff,
 
 #ifdef CONFIG_PPC_ISERIES
 #define PACA_INIT_ISERIES(number)					    \
-	.lppaca_ptr = &paca[number].lppaca,				    \
 	.reg_save_ptr = &iseries_reg_save[number],
 
 #define PACA_INIT(number)						    \

+ 1 - 2
arch/powerpc/kernel/ppc_ksyms.c

@@ -230,8 +230,7 @@ EXPORT_SYMBOL(__down_interruptible);
 EXPORT_SYMBOL(cpm_install_handler);
 EXPORT_SYMBOL(cpm_free_handler);
 #endif /* CONFIG_8xx */
-#if defined(CONFIG_8xx) || defined(CONFIG_40x) || defined(CONFIG_85xx) ||\
-	defined(CONFIG_83xx)
+#if defined(CONFIG_8xx) || defined(CONFIG_40x)
 EXPORT_SYMBOL(__res);
 #endif
 

+ 101 - 8
arch/powerpc/kernel/prom.c

@@ -1627,6 +1627,11 @@ static void of_node_release(struct kref *kref)
 		kfree(prop->value);
 		kfree(prop);
 		prop = next;
+
+		if (!prop) {
+			prop = node->deadprops;
+			node->deadprops = NULL;
+		}
 	}
 	kfree(node->intrs);
 	kfree(node->full_name);
@@ -1774,22 +1779,32 @@ static int __init prom_reconfig_setup(void)
 __initcall(prom_reconfig_setup);
 #endif
 
-/*
- * Find a property with a given name for a given node
- * and return the value.
- */
-unsigned char *get_property(struct device_node *np, const char *name,
-			    int *lenp)
+struct property *of_find_property(struct device_node *np, const char *name,
+				  int *lenp)
 {
 	struct property *pp;
 
+	read_lock(&devtree_lock);
 	for (pp = np->properties; pp != 0; pp = pp->next)
 		if (strcmp(pp->name, name) == 0) {
 			if (lenp != 0)
 				*lenp = pp->length;
-			return pp->value;
+			break;
 		}
-	return NULL;
+	read_unlock(&devtree_lock);
+
+	return pp;
+}
+
+/*
+ * Find a property with a given name for a given node
+ * and return the value.
+ */
+unsigned char *get_property(struct device_node *np, const char *name,
+			    int *lenp)
+{
+	struct property *pp = of_find_property(np,name,lenp);
+	return pp ? pp->value : NULL;
 }
 EXPORT_SYMBOL(get_property);
 
@@ -1823,4 +1838,82 @@ int prom_add_property(struct device_node* np, struct property* prop)
 	return 0;
 }
 
+/*
+ * Remove a property from a node.  Note that we don't actually
+ * remove it, since we have given out who-knows-how-many pointers
+ * to the data using get-property.  Instead we just move the property
+ * to the "dead properties" list, so it won't be found any more.
+ */
+int prom_remove_property(struct device_node *np, struct property *prop)
+{
+	struct property **next;
+	int found = 0;
 
+	write_lock(&devtree_lock);
+	next = &np->properties;
+	while (*next) {
+		if (*next == prop) {
+			/* found the node */
+			*next = prop->next;
+			prop->next = np->deadprops;
+			np->deadprops = prop;
+			found = 1;
+			break;
+		}
+		next = &(*next)->next;
+	}
+	write_unlock(&devtree_lock);
+
+	if (!found)
+		return -ENODEV;
+
+#ifdef CONFIG_PROC_DEVICETREE
+	/* try to remove the proc node as well */
+	if (np->pde)
+		proc_device_tree_remove_prop(np->pde, prop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+	return 0;
+}
+
+/*
+ * Update a property in a node.  Note that we don't actually
+ * remove it, since we have given out who-knows-how-many pointers
+ * to the data using get-property.  Instead we just move the property
+ * to the "dead properties" list, and add the new property to the
+ * property list
+ */
+int prom_update_property(struct device_node *np,
+			 struct property *newprop,
+			 struct property *oldprop)
+{
+	struct property **next;
+	int found = 0;
+
+	write_lock(&devtree_lock);
+	next = &np->properties;
+	while (*next) {
+		if (*next == oldprop) {
+			/* found the node */
+			newprop->next = oldprop->next;
+			*next = newprop;
+			oldprop->next = np->deadprops;
+			np->deadprops = oldprop;
+			found = 1;
+			break;
+		}
+		next = &(*next)->next;
+	}
+	write_unlock(&devtree_lock);
+
+	if (!found)
+		return -ENODEV;
+
+#ifdef CONFIG_PROC_DEVICETREE
+	/* try to add to proc as well if it was initialized */
+	if (np->pde)
+		proc_device_tree_update_prop(np->pde, newprop, oldprop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+	return 0;
+}

+ 2 - 1
arch/powerpc/kernel/prom_parse.c

@@ -113,7 +113,8 @@ static unsigned int of_bus_default_get_flags(u32 *addr)
 
 static int of_bus_pci_match(struct device_node *np)
 {
-	return !strcmp(np->type, "pci");
+	/* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
+	return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
 }
 
 static void of_bus_pci_count_cells(struct device_node *np,

+ 95 - 1
arch/powerpc/kernel/rtas.c

@@ -36,6 +36,11 @@ struct rtas_t rtas = {
 	.lock = SPIN_LOCK_UNLOCKED
 };
 
+struct rtas_suspend_me_data {
+	long waiting;
+	struct rtas_args *args;
+};
+
 EXPORT_SYMBOL(rtas);
 
 DEFINE_SPINLOCK(rtas_data_buf_lock);
@@ -556,6 +561,80 @@ void rtas_os_term(char *str)
 	} while (status == RTAS_BUSY);
 }
 
+static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
+#ifdef CONFIG_PPC_PSERIES
+static void rtas_percpu_suspend_me(void *info)
+{
+	long rc;
+	long flags;
+	struct rtas_suspend_me_data *data =
+		(struct rtas_suspend_me_data *)info;
+
+	/*
+	 * We use "waiting" to indicate our state.  As long
+	 * as it is >0, we are still trying to all join up.
+	 * If it goes to 0, we have successfully joined up and
+	 * one thread got H_Continue.  If any error happens,
+	 * we set it to <0.
+	 */
+	local_irq_save(flags);
+	do {
+		rc = plpar_hcall_norets(H_JOIN);
+		smp_rmb();
+	} while (rc == H_Success && data->waiting > 0);
+	if (rc == H_Success)
+		goto out;
+
+	if (rc == H_Continue) {
+		data->waiting = 0;
+		rtas_call(ibm_suspend_me_token, 0, 1,
+			  data->args->args);
+	} else {
+		data->waiting = -EBUSY;
+		printk(KERN_ERR "Error on H_Join hypervisor call\n");
+	}
+
+out:
+	/* before we restore interrupts, make sure we don't
+	 * generate a spurious soft lockup errors
+	 */
+	touch_softlockup_watchdog();
+	local_irq_restore(flags);
+	return;
+}
+
+static int rtas_ibm_suspend_me(struct rtas_args *args)
+{
+	int i;
+
+	struct rtas_suspend_me_data data;
+
+	data.waiting = 1;
+	data.args = args;
+
+	/* Call function on all CPUs.  One of us will make the
+	 * rtas call
+	 */
+	if (on_each_cpu(rtas_percpu_suspend_me, &data, 1, 0))
+		data.waiting = -EINVAL;
+
+	if (data.waiting != 0)
+		printk(KERN_ERR "Error doing global join\n");
+
+	/* Prod each CPU.  This won't hurt, and will wake
+	 * anyone we successfully put to sleep with H_Join
+	 */
+	for_each_cpu(i)
+		plpar_hcall_norets(H_PROD, i);
+
+	return data.waiting;
+}
+#else /* CONFIG_PPC_PSERIES */
+static int rtas_ibm_suspend_me(struct rtas_args *args)
+{
+	return -ENOSYS;
+}
+#endif
 
 asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
 {
@@ -563,6 +642,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
 	unsigned long flags;
 	char *buff_copy, *errbuf = NULL;
 	int nargs;
+	int rc;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -581,6 +661,17 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
 			   nargs * sizeof(rtas_arg_t)) != 0)
 		return -EFAULT;
 
+	if (args.token == RTAS_UNKNOWN_SERVICE)
+		return -EINVAL;
+
+	/* Need to handle ibm,suspend_me call specially */
+	if (args.token == ibm_suspend_me_token) {
+		rc = rtas_ibm_suspend_me(&args);
+		if (rc)
+			return rc;
+		goto copy_return;
+	}
+
 	buff_copy = get_errorlog_buffer();
 
 	spin_lock_irqsave(&rtas.lock, flags);
@@ -604,6 +695,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
 		kfree(buff_copy);
 	}
 
+ copy_return:
 	/* Copy out args. */
 	if (copy_to_user(uargs->args + nargs,
 			 args.args + nargs,
@@ -675,8 +767,10 @@ void __init rtas_initialize(void)
 	 * the stop-self token if any
 	 */
 #ifdef CONFIG_PPC64
-	if (_machine == PLATFORM_PSERIES_LPAR)
+	if (_machine == PLATFORM_PSERIES_LPAR) {
 		rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
+		ibm_suspend_me_token = rtas_token("ibm,suspend-me");
+	}
 #endif
 	rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region);
 

+ 6 - 3
arch/powerpc/kernel/setup-common.c

@@ -100,7 +100,8 @@ void machine_shutdown(void)
 void machine_restart(char *cmd)
 {
 	machine_shutdown();
-	ppc_md.restart(cmd);
+	if (ppc_md.restart)
+		ppc_md.restart(cmd);
 #ifdef CONFIG_SMP
 	smp_send_stop();
 #endif
@@ -112,7 +113,8 @@ void machine_restart(char *cmd)
 void machine_power_off(void)
 {
 	machine_shutdown();
-	ppc_md.power_off();
+	if (ppc_md.power_off)
+		ppc_md.power_off();
 #ifdef CONFIG_SMP
 	smp_send_stop();
 #endif
@@ -129,7 +131,8 @@ EXPORT_SYMBOL_GPL(pm_power_off);
 void machine_halt(void)
 {
 	machine_shutdown();
-	ppc_md.halt();
+	if (ppc_md.halt)
+		ppc_md.halt();
 #ifdef CONFIG_SMP
 	smp_send_stop();
 #endif

+ 1 - 1
arch/powerpc/kernel/time.c

@@ -431,7 +431,7 @@ void timer_interrupt(struct pt_regs * regs)
 	profile_tick(CPU_PROFILING, regs);
 
 #ifdef CONFIG_PPC_ISERIES
-	get_paca()->lppaca.int_dword.fields.decr_int = 0;
+	get_lppaca()->int_dword.fields.decr_int = 0;
 #endif
 
 	while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu)))

+ 2 - 6
arch/powerpc/lib/locks.c

@@ -28,15 +28,13 @@
 void __spin_yield(raw_spinlock_t *lock)
 {
 	unsigned int lock_value, holder_cpu, yield_count;
-	struct paca_struct *holder_paca;
 
 	lock_value = lock->slock;
 	if (lock_value == 0)
 		return;
 	holder_cpu = lock_value & 0xffff;
 	BUG_ON(holder_cpu >= NR_CPUS);
-	holder_paca = &paca[holder_cpu];
-	yield_count = holder_paca->lppaca.yield_count;
+	yield_count = lppaca[holder_cpu].yield_count;
 	if ((yield_count & 1) == 0)
 		return;		/* virtual cpu is currently running */
 	rmb();
@@ -60,15 +58,13 @@ void __rw_yield(raw_rwlock_t *rw)
 {
 	int lock_value;
 	unsigned int holder_cpu, yield_count;
-	struct paca_struct *holder_paca;
 
 	lock_value = rw->lock;
 	if (lock_value >= 0)
 		return;		/* no write lock at present */
 	holder_cpu = lock_value & 0xffff;
 	BUG_ON(holder_cpu >= NR_CPUS);
-	holder_paca = &paca[holder_cpu];
-	yield_count = holder_paca->lppaca.yield_count;
+	yield_count = lppaca[holder_cpu].yield_count;
 	if ((yield_count & 1) == 0)
 		return;		/* virtual cpu is currently running */
 	rmb();

+ 4 - 4
arch/powerpc/oprofile/common.c

@@ -140,19 +140,19 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
 
 	switch (cur_cpu_spec->oprofile_type) {
 #ifdef CONFIG_PPC64
-		case RS64:
+		case PPC_OPROFILE_RS64:
 			model = &op_model_rs64;
 			break;
-		case POWER4:
+		case PPC_OPROFILE_POWER4:
 			model = &op_model_power4;
 			break;
 #else
-		case G4:
+		case PPC_OPROFILE_G4:
 			model = &op_model_7450;
 			break;
 #endif
 #ifdef CONFIG_FSL_BOOKE
-		case BOOKE:
+		case PPC_OPROFILE_BOOKE:
 			model = &op_model_fsl_booke;
 			break;
 #endif

+ 1 - 0
arch/powerpc/platforms/83xx/Kconfig

@@ -7,6 +7,7 @@ choice
 
 config MPC834x_SYS
 	bool "Freescale MPC834x SYS"
+	select DEFAULT_UIMAGE
 	help
 	  This option enables support for the MPC 834x SYS evaluation board.
 

+ 243 - 0
arch/powerpc/platforms/83xx/mpc834x_sys.c

@@ -0,0 +1,243 @@
+/*
+ * arch/powerpc/platforms/83xx/mpc834x_sys.c
+ *
+ * MPC834x SYS board specific routines
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/module.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ipic.h>
+#include <asm/bootinfo.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc83xx.h>
+#include <asm/irq.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <sysdev/fsl_soc.h>
+
+#include "mpc83xx.h"
+
+#ifndef CONFIG_PCI
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+#endif
+
+#ifdef CONFIG_PCI
+extern int mpc83xx_pci2_busno;
+
+static int
+mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	    /*
+	     *      PCI IDSEL/INTPIN->INTLINE
+	     *       A      B      C      D
+	     */
+	{
+		{PIRQA, PIRQB, PIRQC, PIRQD},	/* idsel 0x11 */
+		{PIRQC, PIRQD, PIRQA, PIRQB},	/* idsel 0x12 */
+		{PIRQD, PIRQA, PIRQB, PIRQC},	/* idsel 0x13 */
+		{0, 0, 0, 0},
+		{PIRQA, PIRQB, PIRQC, PIRQD},	/* idsel 0x15 */
+		{PIRQD, PIRQA, PIRQB, PIRQC},	/* idsel 0x16 */
+		{PIRQC, PIRQD, PIRQA, PIRQB},	/* idsel 0x17 */
+		{PIRQB, PIRQC, PIRQD, PIRQA},	/* idsel 0x18 */
+		{0, 0, 0, 0},			/* idsel 0x19 */
+		{0, 0, 0, 0},			/* idsel 0x20 */
+	};
+
+	const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+static int
+mpc83xx_exclude_device(u_char bus, u_char devfn)
+{
+	if (bus == 0 && PCI_SLOT(devfn) == 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	if (mpc83xx_pci2_busno)
+		if (bus == (mpc83xx_pci2_busno) && PCI_SLOT(devfn) == 0)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+	return PCIBIOS_SUCCESSFUL;
+}
+#endif /* CONFIG_PCI */
+
+/* ************************************************************************
+ *
+ * Setup the architecture
+ *
+ */
+static void __init
+mpc834x_sys_setup_arch(void)
+{
+	struct device_node *np;
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc834x_sys_setup_arch()", 0);
+
+	np = of_find_node_by_type(NULL, "cpu");
+	if (np != 0) {
+		unsigned int *fp = (int *) get_property(np, "clock-frequency", NULL);
+		if (fp != 0)
+			loops_per_jiffy = *fp / HZ;
+		else
+			loops_per_jiffy = 50000000 / HZ;
+		of_node_put(np);
+	}
+
+#ifdef CONFIG_PCI
+	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+		add_bridge(np);
+
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_map_irq = mpc83xx_map_irq;
+	ppc_md.pci_exclude_device = mpc83xx_exclude_device;
+#endif
+
+#ifdef  CONFIG_ROOT_NFS
+		ROOT_DEV = Root_NFS;
+#else
+		ROOT_DEV = Root_HDA1;
+#endif
+}
+
+void __init
+mpc834x_sys_init_IRQ(void)
+{
+	u8 senses[8] = {
+		0,			/* EXT 0 */
+		IRQ_SENSE_LEVEL,	/* EXT 1 */
+		IRQ_SENSE_LEVEL,	/* EXT 2 */
+		0,			/* EXT 3 */
+#ifdef CONFIG_PCI
+		IRQ_SENSE_LEVEL,	/* EXT 4 */
+		IRQ_SENSE_LEVEL,	/* EXT 5 */
+		IRQ_SENSE_LEVEL,	/* EXT 6 */
+		IRQ_SENSE_LEVEL,	/* EXT 7 */
+#else
+		0,			/* EXT 4 */
+		0,			/* EXT 5 */
+		0,			/* EXT 6 */
+		0,			/* EXT 7 */
+#endif
+	};
+
+	ipic_init(get_immrbase() + 0x00700, 0, 0, senses, 8);
+
+	/* Initialize the default interrupt mapping priorities,
+	 * in case the boot rom changed something on us.
+	 */
+	ipic_set_default_priority();
+}
+
+#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
+extern ulong	ds1374_get_rtc_time(void);
+extern int	ds1374_set_rtc_time(ulong);
+
+static int __init
+mpc834x_rtc_hookup(void)
+{
+	struct timespec	tv;
+
+	ppc_md.get_rtc_time = ds1374_get_rtc_time;
+	ppc_md.set_rtc_time = ds1374_set_rtc_time;
+
+	tv.tv_nsec = 0;
+	tv.tv_sec = (ppc_md.get_rtc_time)();
+	do_settimeofday(&tv);
+
+	return 0;
+}
+late_initcall(mpc834x_rtc_hookup);
+#endif
+
+static void
+mpc83xx_restart(char *cmd)
+{
+#define RST_OFFSET	0x00000900
+#define RST_PROT_REG	0x00000018
+#define RST_CTRL_REG	0x0000001c
+	__be32 __iomem *reg;
+
+	// map reset register space
+	reg = ioremap(get_immrbase() + 0x900, 0xff);
+
+	local_irq_disable();
+
+	/* enable software reset "RSTE" */
+	out_be32(reg + (RST_PROT_REG >> 2), 0x52535445);
+
+	/* set software hard reset */
+	out_be32(reg + (RST_CTRL_REG >> 2), 0x52535445);
+	for(;;);
+}
+
+static long __init
+mpc83xx_time_init(void)
+{
+#define SPCR_OFFSET	0x00000110
+#define SPCR_TBEN	0x00400000
+	__be32 __iomem *spcr = ioremap(get_immrbase() + SPCR_OFFSET, 4);
+	__be32 tmp;
+
+	tmp = in_be32(spcr);
+	out_be32(spcr, tmp|SPCR_TBEN);
+
+	iounmap(spcr);
+
+	return 0;
+}
+void __init
+platform_init(void)
+{
+	/* setup the PowerPC module struct */
+	ppc_md.setup_arch = mpc834x_sys_setup_arch;
+
+	ppc_md.init_IRQ = mpc834x_sys_init_IRQ;
+	ppc_md.get_irq = ipic_get_irq;
+
+	ppc_md.restart = mpc83xx_restart;
+
+	ppc_md.time_init = mpc83xx_time_init;
+	ppc_md.set_rtc_time = NULL;
+	ppc_md.get_rtc_time = NULL;
+	ppc_md.calibrate_decr = generic_calibrate_decr;
+
+	ppc_md.progress = udbg_progress;
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc834x_sys_init(): exit", 0);
+
+	return;
+}
+
+

+ 23 - 0
arch/powerpc/platforms/83xx/mpc834x_sys.h

@@ -0,0 +1,23 @@
+/*
+ * arch/powerppc/platforms/83xx/mpc834x_sys.h
+ *
+ * MPC834X SYS common board definitions
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __MACH_MPC83XX_SYS_H__
+#define __MACH_MPC83XX_SYS_H__
+
+#define PIRQA	MPC83xx_IRQ_EXT4
+#define PIRQB	MPC83xx_IRQ_EXT5
+#define PIRQC	MPC83xx_IRQ_EXT6
+#define PIRQD	MPC83xx_IRQ_EXT7
+
+#endif                /* __MACH_MPC83XX_SYS_H__ */

+ 14 - 0
arch/powerpc/platforms/83xx/mpc83xx.h

@@ -0,0 +1,14 @@
+#ifndef __MPC83XX_H__
+#define __MPC83XX_H__
+
+#include <linux/init.h>
+#include <linux/device.h>
+
+/*
+ * Declaration for the various functions exported by the
+ * mpc83xx_* files. Mostly for use by mpc83xx_setup
+ */
+
+extern int add_bridge(struct device_node *dev);
+
+#endif /* __MPC83XX_H__ */

+ 99 - 0
arch/powerpc/platforms/83xx/pci.c

@@ -0,0 +1,99 @@
+/*
+ * FSL SoC setup code
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+#include <asm/prom.h>
+#include <sysdev/fsl_soc.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+int mpc83xx_pci2_busno;
+
+#ifdef CONFIG_PCI
+int __init add_bridge(struct device_node *dev)
+{
+	int len;
+	struct pci_controller *hose;
+	struct resource rsrc;
+	int *bus_range;
+	int primary = 1, has_address = 0;
+	phys_addr_t immr = get_immrbase();
+
+	DBG("Adding PCI host bridge %s\n", dev->full_name);
+
+	/* Fetch host bridge registers address */
+	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
+
+	/* Get bus range if any */
+	bus_range = (int *) get_property(dev, "bus-range", &len);
+	if (bus_range == NULL || len < 2 * sizeof(int)) {
+		printk(KERN_WARNING "Can't get bus-range for %s, assume"
+		       " bus 0\n", dev->full_name);
+	}
+
+	hose = pcibios_alloc_controller();
+	if (!hose)
+		return -ENOMEM;
+	hose->arch_data = dev;
+	hose->set_cfg_type = 1;
+
+	hose->first_busno = bus_range ? bus_range[0] : 0;
+	hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+	/* MPC83xx supports up to two host controllers one at 0x8500 from immrbar
+	 * the other at 0x8600, we consider the 0x8500 the primary controller
+	 */
+	/* PCI 1 */
+	if ((rsrc.start & 0xfffff) == 0x8500) {
+		setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304);
+	}
+	/* PCI 2*/
+	if ((rsrc.start & 0xfffff) == 0x8600) {
+		setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384);
+		primary = 0;
+		hose->bus_offset = hose->first_busno;
+		mpc83xx_pci2_busno = hose->first_busno;
+	}
+
+	printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%08lx. "
+	       "Firmware bus number: %d->%d\n",
+		rsrc.start, hose->first_busno, hose->last_busno);
+
+	DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
+		hose, hose->cfg_addr, hose->cfg_data);
+
+	/* Interpret the "ranges" property */
+	/* This also maps the I/O region and sets isa_io/mem_base */
+	pci_process_bridge_OF_ranges(hose, dev, primary);
+
+	return 0;
+}
+
+#endif

+ 17 - 10
arch/powerpc/platforms/chrp/pci.c

@@ -135,12 +135,13 @@ int __init
 hydra_init(void)
 {
 	struct device_node *np;
+	struct resource r;
 
 	np = find_devices("mac-io");
-	if (np == NULL || np->n_addrs == 0)
+	if (np == NULL || of_address_to_resource(np, 0, &r))
 		return 0;
-	Hydra = ioremap(np->addrs[0].address, np->addrs[0].size);
-	printk("Hydra Mac I/O at %lx\n", np->addrs[0].address);
+	Hydra = ioremap(r.start, r.end-r.start);
+	printk("Hydra Mac I/O at %lx\n", r.start);
 	printk("Hydra Feature_Control was %x",
 	       in_le32(&Hydra->Feature_Control));
 	out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN |
@@ -177,18 +178,24 @@ setup_python(struct pci_controller *hose, struct device_node *dev)
 {
 	u32 __iomem *reg;
 	u32 val;
-	unsigned long addr = dev->addrs[0].address;
+	struct resource r;
 
-	setup_indirect_pci(hose, addr + 0xf8000, addr + 0xf8010);
+	if (of_address_to_resource(dev, 0, &r)) {
+		printk(KERN_ERR "No address for Python PCI controller\n");
+		return;
+	}
 
 	/* Clear the magic go-slow bit */
-	reg = ioremap(dev->addrs[0].address + 0xf6000, 0x40);
+	reg = ioremap(r.start + 0xf6000, 0x40);
+	BUG_ON(!reg); 
 	val = in_be32(&reg[12]);
 	if (val & PRG_CL_RESET_VALID) {
 		out_be32(&reg[12], val & ~PRG_CL_RESET_VALID);
 		in_be32(&reg[12]);
 	}
 	iounmap(reg);
+
+	setup_indirect_pci(hose, r.start + 0xf8000, r.start + 0xf8010);
 }
 
 /* Marvell Discovery II based Pegasos 2 */
@@ -218,7 +225,7 @@ chrp_find_bridges(void)
 	char *model, *machine;
 	int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
 	struct device_node *root = find_path_device("/");
-
+	struct resource r;
 	/*
 	 * The PCI host bridge nodes on some machines don't have
 	 * properties to adequately identify them, so we have to
@@ -238,7 +245,7 @@ chrp_find_bridges(void)
 			continue;
 		++index;
 		/* The GG2 bridge on the LongTrail doesn't have an address */
-		if (dev->n_addrs < 1 && !is_longtrail) {
+		if (of_address_to_resource(dev, 0, &r) && !is_longtrail) {
 			printk(KERN_WARNING "Can't use %s: no address\n",
 			       dev->full_name);
 			continue;
@@ -255,8 +262,8 @@ chrp_find_bridges(void)
 			printk(KERN_INFO "PCI buses %d..%d",
 			       bus_range[0], bus_range[1]);
 		printk(" controlled by %s", dev->type);
-		if (dev->n_addrs > 0)
-			printk(" at %lx", dev->addrs[0].address);
+		if (!is_longtrail)
+			printk(" at %lx", r.start);
 		printk("\n");
 
 		hose = pcibios_alloc_controller();

+ 4 - 3
arch/powerpc/platforms/chrp/setup.c

@@ -352,9 +352,10 @@ static void __init chrp_find_openpic(void)
 		opaddr = opprop[na-1];	/* assume 32-bit */
 		oplen /= na * sizeof(unsigned int);
 	} else {
-		if (np->n_addrs == 0)
+		struct resource r;
+		if (of_address_to_resource(np, 0, &r))
 			return;
-		opaddr = np->addrs[0].address;
+		opaddr = r.start;
 		oplen = 0;
 	}
 
@@ -377,7 +378,7 @@ static void __init chrp_find_openpic(void)
 	 */
 	if (oplen < len) {
 		printk(KERN_ERR "Insufficient addresses for distributed"
-		       " OpenPIC (%d < %d)\n", np->n_addrs, len);
+		       " OpenPIC (%d < %d)\n", oplen, len);
 		len = oplen;
 	}
 

+ 5 - 2
arch/powerpc/platforms/chrp/time.c

@@ -21,6 +21,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/init.h>
 #include <linux/bcd.h>
+#include <linux/ioport.h>
 
 #include <asm/io.h>
 #include <asm/nvram.h>
@@ -37,14 +38,16 @@ static int nvram_data = NVRAM_DATA;
 long __init chrp_time_init(void)
 {
 	struct device_node *rtcs;
+	struct resource r;
 	int base;
 
 	rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
 	if (rtcs == NULL)
 		rtcs = find_compatible_devices("rtc", "ds1385-rtc");
-	if (rtcs == NULL || rtcs->addrs == NULL)
+	if (rtcs == NULL || of_address_to_resource(rtcs, 0, &r))
 		return 0;
-	base = rtcs->addrs[0].address;
+	
+	base = r.start;
 	nvram_as1 = 0;
 	nvram_as0 = base;
 	nvram_data = base + 1;

+ 2 - 4
arch/powerpc/platforms/iseries/irq.c

@@ -334,14 +334,12 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus,
  */
 int iSeries_get_irq(struct pt_regs *regs)
 {
-	struct paca_struct *lpaca;
 	/* -2 means ignore this interrupt */
 	int irq = -2;
 
-	lpaca = get_paca();
 #ifdef CONFIG_SMP
-	if (lpaca->lppaca.int_dword.fields.ipi_cnt) {
-		lpaca->lppaca.int_dword.fields.ipi_cnt = 0;
+	if (get_lppaca()->int_dword.fields.ipi_cnt) {
+		get_lppaca()->int_dword.fields.ipi_cnt = 0;
 		iSeries_smp_message_recv(regs);
 	}
 #endif /* CONFIG_SMP */

+ 2 - 1
arch/powerpc/platforms/iseries/misc.S

@@ -44,7 +44,8 @@ _GLOBAL(local_irq_restore)
 	/* Check pending interrupts */
 	/*   A decrementer, IPI or PMC interrupt may have occurred
 	 *   while we were in the hypervisor (which enables) */
-	ld	r4,PACALPPACA+LPPACAANYINT(r13)
+	ld	r4,PACALPPACAPTR(r13)
+	ld	r4,LPPACAANYINT(r4)
 	cmpdi	r4,0
 	beqlr
 

+ 4 - 4
arch/powerpc/platforms/iseries/setup.c

@@ -538,7 +538,7 @@ static unsigned long __init build_iSeries_Memory_Map(void)
  */
 static void __init iSeries_setup_arch(void)
 {
-	if (get_paca()->lppaca.shared_proc) {
+	if (get_lppaca()->shared_proc) {
 		ppc_md.idle_loop = iseries_shared_idle;
 		printk(KERN_INFO "Using shared processor idle loop\n");
 	} else {
@@ -647,7 +647,7 @@ static void yield_shared_processor(void)
 	 * The decrementer stops during the yield.  Force a fake decrementer
 	 * here and let the timer_interrupt code sort out the actual time.
 	 */
-	get_paca()->lppaca.int_dword.fields.decr_int = 1;
+	get_lppaca()->int_dword.fields.decr_int = 1;
 	process_iSeries_events();
 }
 
@@ -883,7 +883,7 @@ void dt_cpus(struct iseries_flat_dt *dt)
 	pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE);
 
 	for (i = 0; i < NR_CPUS; i++) {
-		if (paca[i].lppaca.dyn_proc_status >= 2)
+		if (lppaca[i].dyn_proc_status >= 2)
 			continue;
 
 		snprintf(p, 32 - (p - buf), "@%d", i);
@@ -891,7 +891,7 @@ void dt_cpus(struct iseries_flat_dt *dt)
 
 		dt_prop_str(dt, "device_type", "cpu");
 
-		index = paca[i].lppaca.dyn_hv_phys_proc_index;
+		index = lppaca[i].dyn_hv_phys_proc_index;
 		d = &xIoHriProcessorVpd[index];
 
 		dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);

+ 1 - 1
arch/powerpc/platforms/iseries/smp.c

@@ -91,7 +91,7 @@ static void smp_iSeries_kick_cpu(int nr)
 	BUG_ON((nr < 0) || (nr >= NR_CPUS));
 
 	/* Verify that our partition has a processor nr */
-	if (paca[nr].lppaca.dyn_proc_status >= 2)
+	if (lppaca[nr].dyn_proc_status >= 2)
 		return;
 
 	/* The processor is currently spinning, waiting

+ 2 - 2
arch/powerpc/platforms/pseries/lpar.c

@@ -254,11 +254,11 @@ out:
 void vpa_init(int cpu)
 {
 	int hwcpu = get_hard_smp_processor_id(cpu);
-	unsigned long vpa = __pa(&paca[cpu].lppaca);
+	unsigned long vpa = __pa(&lppaca[cpu]);
 	long ret;
 
 	if (cpu_has_feature(CPU_FTR_ALTIVEC))
-		paca[cpu].lppaca.vmxregs_in_use = 1;
+		lppaca[cpu].vmxregs_in_use = 1;
 
 	ret = register_vpa(hwcpu, vpa);
 

+ 100 - 0
arch/powerpc/platforms/pseries/reconfig.c

@@ -350,6 +350,100 @@ static int do_remove_node(char *buf)
 	return rv;
 }
 
+static char *parse_node(char *buf, size_t bufsize, struct device_node **npp)
+{
+	char *handle_str;
+	phandle handle;
+	*npp = NULL;
+
+	handle_str = buf;
+
+	buf = strchr(buf, ' ');
+	if (!buf)
+		return NULL;
+	*buf = '\0';
+	buf++;
+
+	handle = simple_strtoul(handle_str, NULL, 10);
+
+	*npp = of_find_node_by_phandle(handle);
+	return buf;
+}
+
+static int do_add_property(char *buf, size_t bufsize)
+{
+	struct property *prop = NULL;
+	struct device_node *np;
+	unsigned char *value;
+	char *name, *end;
+	int length;
+	end = buf + bufsize;
+	buf = parse_node(buf, bufsize, &np);
+
+	if (!np)
+		return -ENODEV;
+
+	if (parse_next_property(buf, end, &name, &length, &value) == NULL)
+		return -EINVAL;
+
+	prop = new_property(name, length, value, NULL);
+	if (!prop)
+		return -ENOMEM;
+
+	prom_add_property(np, prop);
+
+	return 0;
+}
+
+static int do_remove_property(char *buf, size_t bufsize)
+{
+	struct device_node *np;
+	char *tmp;
+	struct property *prop;
+	buf = parse_node(buf, bufsize, &np);
+
+	if (!np)
+		return -ENODEV;
+
+	tmp = strchr(buf,' ');
+	if (tmp)
+		*tmp = '\0';
+
+	if (strlen(buf) == 0)
+		return -EINVAL;
+
+	prop = of_find_property(np, buf, NULL);
+
+	return prom_remove_property(np, prop);
+}
+
+static int do_update_property(char *buf, size_t bufsize)
+{
+	struct device_node *np;
+	unsigned char *value;
+	char *name, *end;
+	int length;
+	struct property *newprop, *oldprop;
+	buf = parse_node(buf, bufsize, &np);
+	end = buf + bufsize;
+
+	if (!np)
+		return -ENODEV;
+
+	if (parse_next_property(buf, end, &name, &length, &value) == NULL)
+		return -EINVAL;
+
+	newprop = new_property(name, length, value, NULL);
+	if (!newprop)
+		return -ENOMEM;
+
+	oldprop = of_find_property(np, name,NULL);
+	if (!oldprop)
+		return -ENODEV;
+
+	return prom_update_property(np, newprop, oldprop);
+}
+
 /**
  * ofdt_write - perform operations on the Open Firmware device tree
  *
@@ -392,6 +486,12 @@ static ssize_t ofdt_write(struct file *file, const char __user *buf, size_t coun
 		rv = do_add_node(tmp, count - (tmp - kbuf));
 	else if (!strcmp(kbuf, "remove_node"))
 		rv = do_remove_node(tmp);
+	else if (!strcmp(kbuf, "add_property"))
+		rv = do_add_property(tmp, count - (tmp - kbuf));
+	else if (!strcmp(kbuf, "remove_property"))
+		rv = do_remove_property(tmp, count - (tmp - kbuf));
+	else if (!strcmp(kbuf, "update_property"))
+		rv = do_update_property(tmp, count - (tmp - kbuf));
 	else
 		rv = -EINVAL;
 out:

+ 9 - 11
arch/powerpc/platforms/pseries/setup.c

@@ -190,7 +190,7 @@ static void pseries_lpar_enable_pmcs(void)
 
 	/* instruct hypervisor to maintain PMCs */
 	if (firmware_has_feature(FW_FEATURE_SPLPAR))
-		get_paca()->lppaca.pmcregs_in_use = 1;
+		get_lppaca()->pmcregs_in_use = 1;
 }
 
 static void __init pSeries_setup_arch(void)
@@ -234,7 +234,7 @@ static void __init pSeries_setup_arch(void)
 	/* Choose an idle loop */
 	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
 		vpa_init(boot_cpuid);
-		if (get_paca()->lppaca.shared_proc) {
+		if (get_lppaca()->shared_proc) {
 			printk(KERN_INFO "Using shared processor idle loop\n");
 			ppc_md.idle_loop = pseries_shared_idle;
 		} else {
@@ -444,10 +444,10 @@ DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
 
 static inline void dedicated_idle_sleep(unsigned int cpu)
 {
-	struct paca_struct *ppaca = &paca[cpu ^ 1];
+	struct lppaca *plppaca = &lppaca[cpu ^ 1];
 
 	/* Only sleep if the other thread is not idle */
-	if (!(ppaca->lppaca.idle)) {
+	if (!(plppaca->idle)) {
 		local_irq_disable();
 
 		/*
@@ -480,7 +480,6 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
 
 static void pseries_dedicated_idle(void)
 { 
-	struct paca_struct *lpaca = get_paca();
 	unsigned int cpu = smp_processor_id();
 	unsigned long start_snooze;
 	unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
@@ -491,7 +490,7 @@ static void pseries_dedicated_idle(void)
 		 * Indicate to the HV that we are idle. Now would be
 		 * a good time to find other work to dispatch.
 		 */
-		lpaca->lppaca.idle = 1;
+		get_lppaca()->idle = 1;
 
 		if (!need_resched()) {
 			start_snooze = get_tb() +
@@ -518,7 +517,7 @@ static void pseries_dedicated_idle(void)
 			HMT_medium();
 		}
 
-		lpaca->lppaca.idle = 0;
+		get_lppaca()->idle = 0;
 		ppc64_runlatch_on();
 
 		preempt_enable_no_resched();
@@ -532,7 +531,6 @@ static void pseries_dedicated_idle(void)
 
 static void pseries_shared_idle(void)
 {
-	struct paca_struct *lpaca = get_paca();
 	unsigned int cpu = smp_processor_id();
 
 	while (1) {
@@ -540,7 +538,7 @@ static void pseries_shared_idle(void)
 		 * Indicate to the HV that we are idle. Now would be
 		 * a good time to find other work to dispatch.
 		 */
-		lpaca->lppaca.idle = 1;
+		get_lppaca()->idle = 1;
 
 		while (!need_resched() && !cpu_is_offline(cpu)) {
 			local_irq_disable();
@@ -564,7 +562,7 @@ static void pseries_shared_idle(void)
 			HMT_medium();
 		}
 
-		lpaca->lppaca.idle = 0;
+		get_lppaca()->idle = 0;
 		ppc64_runlatch_on();
 
 		preempt_enable_no_resched();
@@ -588,7 +586,7 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
 {
 	/* Don't risk a hypervisor call if we're crashing */
 	if (!crash_shutdown) {
-		unsigned long vpa = __pa(&get_paca()->lppaca);
+		unsigned long vpa = __pa(get_lppaca());
 
 		if (unregister_vpa(hard_smp_processor_id(), vpa)) {
 			printk("VPA deregistration of cpu %u (hw_cpu_id %d) "

+ 1 - 0
arch/powerpc/sysdev/Makefile

@@ -7,3 +7,4 @@ obj-$(CONFIG_40x)		+= dcr.o
 obj-$(CONFIG_U3_DART)		+= dart_iommu.o
 obj-$(CONFIG_MMIO_NVRAM)	+= mmio_nvram.o
 obj-$(CONFIG_PPC_83xx)		+= ipic.o
+obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o

+ 317 - 0
arch/powerpc/sysdev/fsl_soc.c

@@ -0,0 +1,317 @@
+/*
+ * FSL SoC setup code
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <sysdev/fsl_soc.h>
+#include <mm/mmu_decl.h>
+
+static phys_addr_t immrbase = -1;
+
+phys_addr_t get_immrbase(void)
+{
+	struct device_node *soc;
+
+	if (immrbase != -1)
+		return immrbase;
+
+	soc = of_find_node_by_type(NULL, "soc");
+	if (soc != 0) {
+		unsigned int size;
+		void *prop = get_property(soc, "reg", &size);
+		immrbase = of_translate_address(soc, prop);
+		of_node_put(soc);
+	};
+
+	return immrbase;
+}
+EXPORT_SYMBOL(get_immrbase);
+
+static const char * gfar_tx_intr = "tx";
+static const char * gfar_rx_intr = "rx";
+static const char * gfar_err_intr = "error";
+
+static int __init gfar_of_init(void)
+{
+	struct device_node *np;
+	unsigned int i;
+	struct platform_device *mdio_dev, *gfar_dev;
+	struct resource res;
+	int ret;
+
+	for (np = NULL, i = 0; (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL; i++) {
+		int k;
+		struct device_node *child = NULL;
+		struct gianfar_mdio_data mdio_data;
+
+		memset(&res, 0, sizeof(res));
+		memset(&mdio_data, 0, sizeof(mdio_data));
+
+		ret = of_address_to_resource(np, 0, &res);
+		if (ret)
+			goto mdio_err;
+
+		mdio_dev = platform_device_register_simple("fsl-gianfar_mdio", res.start, &res, 1);
+		if (IS_ERR(mdio_dev)) {
+			ret = PTR_ERR(mdio_dev);
+			goto mdio_err;
+		}
+
+		for (k = 0; k < 32; k++)
+			mdio_data.irq[k] = -1;
+
+		while ((child = of_get_next_child(np, child)) != NULL) {
+			if (child->n_intrs) {
+				u32 *id = (u32 *) get_property(child, "reg", NULL);
+				mdio_data.irq[*id] = child->intrs[0].line;
+			}
+		}
+
+		ret = platform_device_add_data(mdio_dev, &mdio_data, sizeof(struct gianfar_mdio_data));
+		if (ret)
+			goto mdio_unreg;
+	}
+
+	for (np = NULL, i = 0; (np = of_find_compatible_node(np, "network", "gianfar")) != NULL; i++) {
+		struct resource r[4];
+		struct device_node *phy, *mdio;
+		struct gianfar_platform_data gfar_data;
+		unsigned int *id;
+		char *model;
+		void *mac_addr;
+		phandle *ph;
+
+		memset(r, 0, sizeof(r));
+		memset(&gfar_data, 0, sizeof(gfar_data));
+
+		ret = of_address_to_resource(np, 0, &r[0]);
+		if (ret)
+			goto gfar_err;
+
+		r[1].start = np->intrs[0].line;
+		r[1].end = np->intrs[0].line;
+		r[1].flags = IORESOURCE_IRQ;
+
+		model = get_property(np, "model", NULL);
+
+		/* If we aren't the FEC we have multiple interrupts */
+		if (model && strcasecmp(model, "FEC")) {
+			r[1].name = gfar_tx_intr;
+
+			r[2].name = gfar_rx_intr;
+			r[2].start = np->intrs[1].line;
+			r[2].end = np->intrs[1].line;
+			r[2].flags = IORESOURCE_IRQ;
+
+			r[3].name = gfar_err_intr;
+			r[3].start = np->intrs[2].line;
+			r[3].end = np->intrs[2].line;
+			r[3].flags = IORESOURCE_IRQ;
+		}
+
+		gfar_dev = platform_device_register_simple("fsl-gianfar", i, &r[0], np->n_intrs + 1);
+
+		if (IS_ERR(gfar_dev)) {
+			ret = PTR_ERR(gfar_dev);
+			goto gfar_err;
+		}
+
+		mac_addr = get_property(np, "address", NULL);
+		memcpy(gfar_data.mac_addr, mac_addr, 6);
+
+		if (model && !strcasecmp(model, "TSEC"))
+			gfar_data.device_flags =
+				FSL_GIANFAR_DEV_HAS_GIGABIT |
+				FSL_GIANFAR_DEV_HAS_COALESCE |
+				FSL_GIANFAR_DEV_HAS_RMON |
+				FSL_GIANFAR_DEV_HAS_MULTI_INTR;
+		if (model && !strcasecmp(model, "eTSEC"))
+			gfar_data.device_flags =
+				FSL_GIANFAR_DEV_HAS_GIGABIT |
+				FSL_GIANFAR_DEV_HAS_COALESCE |
+				FSL_GIANFAR_DEV_HAS_RMON |
+				FSL_GIANFAR_DEV_HAS_MULTI_INTR |
+				FSL_GIANFAR_DEV_HAS_CSUM |
+				FSL_GIANFAR_DEV_HAS_VLAN |
+				FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
+
+		ph = (phandle *) get_property(np, "phy-handle", NULL);
+		phy = of_find_node_by_phandle(*ph);
+
+		if (phy == NULL) {
+			ret = -ENODEV;
+			goto gfar_unreg;
+		}
+
+		mdio = of_get_parent(phy);
+
+		id = (u32 *) get_property(phy, "reg", NULL);
+		ret = of_address_to_resource(mdio, 0, &res);
+		if (ret) {
+			of_node_put(phy);
+			of_node_put(mdio);
+			goto gfar_unreg;
+		}
+
+		gfar_data.phy_id = *id;
+		gfar_data.bus_id = res.start;
+
+		of_node_put(phy);
+		of_node_put(mdio);
+
+		ret = platform_device_add_data(gfar_dev, &gfar_data, sizeof(struct gianfar_platform_data));
+		if (ret)
+			goto gfar_unreg;
+	}
+
+	return 0;
+
+mdio_unreg:
+	platform_device_unregister(mdio_dev);
+mdio_err:
+	return ret;
+
+gfar_unreg:
+	platform_device_unregister(gfar_dev);
+gfar_err:
+	return ret;
+}
+arch_initcall(gfar_of_init);
+
+static int __init fsl_i2c_of_init(void)
+{
+	struct device_node *np;
+	unsigned int i;
+	struct platform_device *i2c_dev;
+	int ret;
+
+	for (np = NULL, i = 0; (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL; i++) {
+		struct resource r[2];
+		struct fsl_i2c_platform_data i2c_data;
+		unsigned char * flags = NULL;
+
+		memset(&r, 0, sizeof(r));
+		memset(&i2c_data, 0, sizeof(i2c_data));
+
+		ret = of_address_to_resource(np, 0, &r[0]);
+		if (ret)
+			goto i2c_err;
+
+		r[1].start = np->intrs[0].line;
+		r[1].end = np->intrs[0].line;
+		r[1].flags = IORESOURCE_IRQ;
+
+		i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
+		if (IS_ERR(i2c_dev)) {
+			ret = PTR_ERR(i2c_dev);
+			goto i2c_err;
+		}
+
+		i2c_data.device_flags = 0;
+		flags = get_property(np, "dfsrr", NULL);
+		if (flags)
+			i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
+
+		flags = get_property(np, "fsl5200-clocking", NULL);
+		if (flags)
+			i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
+
+		ret = platform_device_add_data(i2c_dev, &i2c_data, sizeof(struct fsl_i2c_platform_data));
+		if (ret)
+			goto i2c_unreg;
+	}
+
+	return 0;
+
+i2c_unreg:
+	platform_device_unregister(i2c_dev);
+i2c_err:
+	return ret;
+}
+arch_initcall(fsl_i2c_of_init);
+
+#ifdef CONFIG_PPC_83xx
+static int __init mpc83xx_wdt_init(void)
+{
+	struct resource r;
+	struct device_node *soc, *np;
+	struct platform_device *dev;
+	unsigned int *freq;
+	int ret;
+
+	np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt");
+
+	if (!np) {
+		ret = -ENODEV;
+		goto mpc83xx_wdt_nodev;
+	}
+
+	soc = of_find_node_by_type(NULL, "soc");
+
+	if (!soc) {
+		ret = -ENODEV;
+		goto mpc83xx_wdt_nosoc;
+	}
+
+	freq = (unsigned int *)get_property(soc, "bus-frequency", NULL);
+	if (!freq) {
+		ret = -ENODEV;
+		goto mpc83xx_wdt_err;
+	}
+
+	memset(&r, 0, sizeof(r));
+
+	ret = of_address_to_resource(np, 0, &r);
+	if (ret)
+		goto mpc83xx_wdt_err;
+
+	dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1);
+	if (IS_ERR(dev)) {
+		ret = PTR_ERR(dev);
+		goto mpc83xx_wdt_err;
+	}
+
+	ret = platform_device_add_data(dev, freq, sizeof(int));
+	if (ret)
+		goto mpc83xx_wdt_unreg;
+
+	of_node_put(soc);
+	of_node_put(np);
+
+	return 0;
+
+mpc83xx_wdt_unreg:
+	platform_device_unregister(dev);
+mpc83xx_wdt_err:
+	of_node_put(soc);
+mpc83xx_wdt_nosoc:
+	of_node_put(np);
+mpc83xx_wdt_nodev:
+	return ret;
+}
+arch_initcall(mpc83xx_wdt_init);
+#endif

+ 8 - 0
arch/powerpc/sysdev/fsl_soc.h

@@ -0,0 +1,8 @@
+#ifndef __PPC_FSL_SOC_H
+#define __PPC_FSL_SOC_H
+#ifdef __KERNEL__
+
+extern phys_addr_t get_immrbase(void);
+
+#endif
+#endif

+ 77 - 0
arch/ppc/kernel/head_8xx.S

@@ -375,6 +375,8 @@ DataStoreTLBMiss:
 	lis	r11, swapper_pg_dir@h
 	ori	r11, r11, swapper_pg_dir@l
 	rlwimi	r10, r11, 0, 2, 19
+	stw	r12, 16(r0)
+	b LoadLargeDTLB
 3:
 	lwz	r11, 0(r10)	/* Get the level 1 entry */
 	rlwinm.	r10, r11,0,0,19	/* Extract page descriptor page address */
@@ -430,6 +432,81 @@ DataStoreTLBMiss:
 InstructionTLBError:
 	b	InstructionAccess
 
+LoadLargeDTLB:
+	li	r12, 0
+	lwz	r11, 0(r10)	/* Get the level 1 entry */
+	rlwinm.	r10, r11,0,0,19	/* Extract page descriptor page address */
+	beq	3f		/* If zero, don't try to find a pte */
+
+	/* We have a pte table, so load fetch the pte from the table.
+	 */
+	ori	r11, r11, 1	/* Set valid bit in physical L2 page */
+	DO_8xx_CPU6(0x3b80, r3)
+	mtspr	SPRN_MD_TWC, r11	/* Load pte table base address */
+	mfspr	r10, SPRN_MD_TWC	/* ....and get the pte address */
+	lwz	r10, 0(r10)	/* Get the pte */
+
+	/* Insert the Guarded flag into the TWC from the Linux PTE.
+	 * It is bit 27 of both the Linux PTE and the TWC (at least
+	 * I got that right :-).  It will be better when we can put
+	 * this into the Linux pgd/pmd and load it in the operation
+	 * above.
+	 */
+	rlwimi	r11, r10, 0, 27, 27
+
+	rlwimi  r12, r10, 0, 0, 9	/* extract phys. addr */
+	mfspr	r3, SPRN_MD_EPN
+	rlwinm	r3, r3, 0, 0, 9		/* extract virtual address */
+	tophys(r3, r3)
+	cmpw	r3, r12			/* only use 8M page if it is a direct 
+					   kernel mapping */
+	bne	1f
+	ori     r11, r11, MD_PS8MEG
+	li	r12, 1
+	b	2f
+1:
+	li	r12, 0		/* can't use 8MB TLB, so zero r12. */
+2:
+	DO_8xx_CPU6(0x3b80, r3)
+	mtspr	SPRN_MD_TWC, r11
+
+	/* The Linux PTE won't go exactly into the MMU TLB.
+	 * Software indicator bits 21, 22 and 28 must be clear.
+	 * Software indicator bits 24, 25, 26, and 27 must be
+	 * set.  All other Linux PTE bits control the behavior
+	 * of the MMU.
+	 */
+3:	li	r11, 0x00f0
+	rlwimi	r10, r11, 0, 24, 28	/* Set 24-27, clear 28 */
+	cmpwi   r12, 1
+	bne 4f
+	ori     r10, r10, 0x8
+
+	mfspr	r12, SPRN_MD_EPN
+	lis	r3, 0xff80		/* 10-19 must be clear for 8MB TLB */
+	ori	r3, r3, 0x0fff
+	and	r12, r3, r12
+	DO_8xx_CPU6(0x3780, r3)
+	mtspr	SPRN_MD_EPN, r12
+
+	lis	r3, 0xff80		/* 10-19 must be clear for 8MB TLB */
+	ori	r3, r3, 0x0fff
+	and	r10, r3, r10
+4:
+	DO_8xx_CPU6(0x3d80, r3)
+	mtspr	SPRN_MD_RPN, r10	/* Update TLB entry */
+
+	mfspr	r10, SPRN_M_TW	/* Restore registers */
+	lwz	r11, 0(r0)
+	mtcr	r11
+	lwz	r11, 4(r0)
+
+	lwz	r12, 16(r0)
+#ifdef CONFIG_8xx_CPU6
+	lwz	r3, 8(r0)
+#endif
+	rfi
+
 /* This is the data TLB error on the MPC8xx.  This could be due to
  * many reasons, including a dirty update to a pte.  We can catch that
  * one here, but anything else is an error.  First, we track down the

+ 0 - 1
arch/ppc/kernel/ppc_ksyms.c

@@ -270,7 +270,6 @@ EXPORT_SYMBOL(__delay);
 EXPORT_SYMBOL(timer_interrupt);
 EXPORT_SYMBOL(irq_desc);
 EXPORT_SYMBOL(tb_ticks_per_jiffy);
-EXPORT_SYMBOL(get_wchan);
 EXPORT_SYMBOL(console_drivers);
 #ifdef CONFIG_XMON
 EXPORT_SYMBOL(xmon);

+ 4 - 6
arch/ppc/platforms/83xx/mpc834x_sys.c

@@ -51,9 +51,6 @@
 
 #include <syslib/ppc83xx_setup.h>
 
-static const char *GFAR_PHY_0 = "phy0:0";
-static const char *GFAR_PHY_1 = "phy0:1";
-
 #ifndef CONFIG_PCI
 unsigned long isa_io_base = 0;
 unsigned long isa_mem_base = 0;
@@ -129,20 +126,21 @@ mpc834x_sys_setup_arch(void)
 	mdata->irq[1] = MPC83xx_IRQ_EXT2;
 	mdata->irq[2] = -1;
 	mdata->irq[31] = -1;
-	mdata->paddr += binfo->bi_immr_base;
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_0;
+		pdata->bus_id = 0;
+		pdata->phy_id = 0;
 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
 	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_1;
+		pdata->bus_id = 0;
+		pdata->phy_id = 1;
 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
 	}
 

+ 6 - 8
arch/ppc/platforms/85xx/mpc8540_ads.c

@@ -52,10 +52,6 @@
 
 #include <syslib/ppc85xx_setup.h>
 
-static const char *GFAR_PHY_0 = "phy0:0";
-static const char *GFAR_PHY_1 = "phy0:1";
-static const char *GFAR_PHY_3 = "phy0:3";
-
 /* ************************************************************************
  *
  * Setup the architecture
@@ -102,27 +98,29 @@ mpc8540ads_setup_arch(void)
 	mdata->irq[2] = -1;
 	mdata->irq[3] = MPC85xx_IRQ_EXT5;
 	mdata->irq[31] = -1;
-	mdata->paddr += binfo->bi_immr_base;
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_0;
+		pdata->bus_id = 0;
+		pdata->phy_id = 0;
 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
 	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_1;
+		pdata->bus_id = 0;
+		pdata->phy_id = 1;
 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
 	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
 	if (pdata) {
 		pdata->board_flags = 0;
-		pdata->bus_id = GFAR_PHY_3;
+		pdata->bus_id = 0;
+		pdata->phy_id = 3;
 		memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
 	}
 

+ 4 - 7
arch/ppc/platforms/85xx/mpc8560_ads.c

@@ -56,10 +56,6 @@
 #include <syslib/ppc85xx_setup.h>
 
 
-static const char *GFAR_PHY_0 = "phy0:0";
-static const char *GFAR_PHY_1 = "phy0:1";
-static const char *GFAR_PHY_3 = "phy0:3";
-
 /* ************************************************************************
  *
  * Setup the architecture
@@ -99,20 +95,21 @@ mpc8560ads_setup_arch(void)
 	mdata->irq[2] = -1;
 	mdata->irq[3] = MPC85xx_IRQ_EXT5;
 	mdata->irq[31] = -1;
-	mdata->paddr += binfo->bi_immr_base;
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_0;
+		pdata->bus_id = 0;
+		pdata->phy_id = 0;
 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
 	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_1;
+		pdata->bus_id = 0;
+		pdata->phy_id = 1;
 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
 	}
 

+ 8 - 8
arch/ppc/platforms/85xx/mpc85xx_cds_common.c

@@ -395,9 +395,6 @@ mpc85xx_cds_pcibios_fixup(void)
 
 TODC_ALLOC();
 
-static const char *GFAR_PHY_0 = "phy0:0";
-static const char *GFAR_PHY_1 = "phy0:1";
-
 /* ************************************************************************
  *
  * Setup the architecture
@@ -461,34 +458,37 @@ mpc85xx_cds_setup_arch(void)
 	mdata->irq[2] = -1;
 	mdata->irq[3] = -1;
 	mdata->irq[31] = -1;
-	mdata->paddr += binfo->bi_immr_base;
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_0;
+		pdata->bus_id = 0;
+		pdata->phy_id = 0;
 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
 	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_1;
+		pdata->bus_id = 0;
+		pdata->phy_id = 1;
 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
 	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC1);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_0;
+		pdata->bus_id = 0;
+		pdata->phy_id = 0;
 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
 	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC2);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_1;
+		pdata->bus_id = 0;
+		pdata->phy_id = 1;
 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
 	}
 

+ 4 - 6
arch/ppc/platforms/85xx/sbc8560.c

@@ -91,9 +91,6 @@ sbc8560_early_serial_map(void)
 }
 #endif
 
-static const char *GFAR_PHY_25 = "phy0:25";
-static const char *GFAR_PHY_26 = "phy0:26";
-
 /* ************************************************************************
  *
  * Setup the architecture
@@ -136,20 +133,21 @@ sbc8560_setup_arch(void)
 	mdata->irq[25] = MPC85xx_IRQ_EXT6;
 	mdata->irq[26] = MPC85xx_IRQ_EXT7;
 	mdata->irq[31] = -1;
-	mdata->paddr += binfo->bi_immr_base;
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_25;
+		pdata->bus_id = 0;
+		pdata->phy_id = 25;
 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
 	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_26;
+		pdata->bus_id = 0;
+		pdata->phy_id = 26;
 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
 	}
 

+ 4 - 6
arch/ppc/platforms/85xx/stx_gp3.c

@@ -93,9 +93,6 @@ static u8 gp3_openpic_initsenses[] __initdata = {
 	0x0,				/* External 11: */
 };
 
-static const char *GFAR_PHY_2 = "phy0:2";
-static const char *GFAR_PHY_4 = "phy0:4";
-
 /*
  * Setup the architecture
  */
@@ -130,20 +127,21 @@ gp3_setup_arch(void)
 	mdata->irq[2] = MPC85xx_IRQ_EXT5;
 	mdata->irq[4] = MPC85xx_IRQ_EXT5;
 	mdata->irq[31] = -1;
-	mdata->paddr += binfo->bi_immr_base;
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
 	if (pdata) {
 	/*	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
-		pdata->bus_id = GFAR_PHY_2;
+		pdata->bus_id = 0;
+		pdata->phy_id = 2;
 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
 	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
 	if (pdata) {
 	/*	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
-		pdata->bus_id = GFAR_PHY_4;
+		pdata->bus_id = 0;
+		pdata->phy_id = 4;
 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
 	}
 

+ 6 - 10
arch/ppc/platforms/85xx/tqm85xx.c

@@ -91,12 +91,6 @@ static u_char tqm85xx_openpic_initsenses[] __initdata = {
 	0x0,				/* External 11: */
 };
 
-static const char *GFAR_PHY_0 = "phy0:2";
-static const char *GFAR_PHY_1 = "phy0:1";
-#ifdef CONFIG_MPC8540
-static const char *GFAR_PHY_3 = "phy0:3";
-#endif
-
 /* ************************************************************************
  *
  * Setup the architecture
@@ -149,20 +143,21 @@ tqm85xx_setup_arch(void)
 	mdata->irq[2] = -1;
 	mdata->irq[3] = MPC85xx_IRQ_EXT8;
 	mdata->irq[31] = -1;
-	mdata->paddr += binfo->bi_immr_base;
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_0;
+		pdata->bus_id = 0;
+		pdata->phy_id = 2;
 		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
 	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
 	if (pdata) {
 		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-		pdata->bus_id = GFAR_PHY_1;
+		pdata->bus_id = 0;
+		pdata->phy_id = 1;
 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
 	}
 
@@ -170,7 +165,8 @@ tqm85xx_setup_arch(void)
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
 	if (pdata) {
 		pdata->board_flags = 0;
-		pdata->bus_id = GFAR_PHY_3;
+		pdata->bus_id = 0;
+		pdata->phy_id = 3;
 		memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
 	}
 #endif

+ 8 - 2
arch/ppc/syslib/mpc83xx_devices.c

@@ -28,7 +28,6 @@
  */
 
 struct gianfar_mdio_data mpc83xx_mdio_pdata = {
-	.paddr = 0x24520,
 };
 
 static struct gianfar_platform_data mpc83xx_tsec1_pdata = {
@@ -226,7 +225,14 @@ struct platform_device ppc_sys_platform_devices[] = {
 		.name = "fsl-gianfar_mdio",
 		.id = 0,
 		.dev.platform_data = &mpc83xx_mdio_pdata,
-		.num_resources = 0,
+		.num_resources = 1,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x24520,
+				.end	= 0x2453f,
+				.flags	= IORESOURCE_MEM,
+			},
+		},
 	},
 };
 

+ 8 - 2
arch/ppc/syslib/mpc85xx_devices.c

@@ -26,7 +26,6 @@
  * what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup
  */
 struct gianfar_mdio_data mpc85xx_mdio_pdata = {
-	.paddr = MPC85xx_MIIM_OFFSET,
 };
 
 static struct gianfar_platform_data mpc85xx_tsec1_pdata = {
@@ -720,7 +719,14 @@ struct platform_device ppc_sys_platform_devices[] = {
 		.name = "fsl-gianfar_mdio",
 		.id = 0,
 		.dev.platform_data = &mpc85xx_mdio_pdata,
-		.num_resources = 0,
+		.num_resources = 1,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x24520,
+				.end	= 0x2453f,
+				.flags	= IORESOURCE_MEM,
+			},
+		},
 	},
 };
 

+ 8 - 5
drivers/macintosh/macio-adb.c

@@ -17,6 +17,7 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 
 struct preg {
 	unsigned char r;
@@ -88,24 +89,26 @@ int macio_probe(void)
 int macio_init(void)
 {
 	struct device_node *adbs;
+	struct resource r;
 
 	adbs = find_compatible_devices("adb", "chrp,adb0");
 	if (adbs == 0)
 		return -ENXIO;
 
 #if 0
-	{ int i;
+	{ int i = 0;
 
 	printk("macio_adb_init: node = %p, addrs =", adbs->node);
-	for (i = 0; i < adbs->n_addrs; ++i)
-		printk(" %x(%x)", adbs->addrs[i].address, adbs->addrs[i].size);
+	while(!of_address_to_resource(adbs, i, &r))
+		printk(" %x(%x)", r.start, r.end - r.start);
 	printk(", intrs =");
 	for (i = 0; i < adbs->n_intrs; ++i)
 		printk(" %x", adbs->intrs[i].line);
 	printk("\n"); }
 #endif
-	
-	adb = ioremap(adbs->addrs->address, sizeof(struct adb_regs));
+	if (of_address_to_resource(adbs, 0, &r))
+		return -ENXIO;
+	adb = ioremap(r.start, sizeof(struct adb_regs));
 
 	out_8(&adb->ctrl.r, 0);
 	out_8(&adb->intr.r, 0);

+ 24 - 0
fs/proc/proc_devtree.c

@@ -81,6 +81,30 @@ void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop
 	__proc_device_tree_add_prop(pde, prop);
 }
 
+void proc_device_tree_remove_prop(struct proc_dir_entry *pde,
+				  struct property *prop)
+{
+	remove_proc_entry(prop->name, pde);
+}
+
+void proc_device_tree_update_prop(struct proc_dir_entry *pde,
+				  struct property *newprop,
+				  struct property *oldprop)
+{
+	struct proc_dir_entry *ent;
+
+	for (ent = pde->subdir; ent != NULL; ent = ent->next)
+		if (ent->data == oldprop)
+			break;
+	if (ent == NULL) {
+		printk(KERN_WARNING "device-tree: property \"%s\" "
+		       " does not exist\n", oldprop->name);
+	} else {
+		ent->data = newprop;
+		ent->size = newprop->length;
+	}
+}
+
 /*
  * Process a node, adding entries for its children and its properties.
  */

+ 23 - 23
include/asm-powerpc/atomic.h

@@ -36,7 +36,7 @@ static __inline__ int atomic_add_return(int a, atomic_t *v)
 	int t;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	lwarx	%0,0,%2		# atomic_add_return\n\
 	add	%0,%1,%0\n"
 	PPC405_ERR77(0,%2)
@@ -72,7 +72,7 @@ static __inline__ int atomic_sub_return(int a, atomic_t *v)
 	int t;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	lwarx	%0,0,%2		# atomic_sub_return\n\
 	subf	%0,%1,%0\n"
 	PPC405_ERR77(0,%2)
@@ -106,7 +106,7 @@ static __inline__ int atomic_inc_return(atomic_t *v)
 	int t;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	lwarx	%0,0,%1		# atomic_inc_return\n\
 	addic	%0,%0,1\n"
 	PPC405_ERR77(0,%1)
@@ -150,7 +150,7 @@ static __inline__ int atomic_dec_return(atomic_t *v)
 	int t;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	lwarx	%0,0,%1		# atomic_dec_return\n\
 	addic	%0,%0,-1\n"
 	PPC405_ERR77(0,%1)
@@ -176,19 +176,19 @@ static __inline__ int atomic_dec_return(atomic_t *v)
  * Atomically adds @a to @v, so long as it was not @u.
  * Returns non-zero if @v was not @u, and zero otherwise.
  */
-#define atomic_add_unless(v, a, u)							 \
-({															 \
-	   int c, old;											 \
-	   c = atomic_read(v);									 \
-	   for (;;) {											  \
-			   if (unlikely(c == (u)))						 \
-					   break;								  \
-			   old = atomic_cmpxchg((v), c, c + (a));		  \
-			   if (likely(old == c))						   \
-					   break;								  \
-			   c = old;										\
-	   }													   \
-	   c != (u);											   \
+#define atomic_add_unless(v, a, u)			\
+({							\
+	int c, old;					\
+	c = atomic_read(v);				\
+	for (;;) {					\
+		if (unlikely(c == (u)))			\
+			break;				\
+		old = atomic_cmpxchg((v), c, c + (a));	\
+		if (likely(old == c))			\
+			break;				\
+		c = old;				\
+	}						\
+	c != (u);					\
 })
 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
@@ -204,7 +204,7 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
 	int t;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	lwarx	%0,0,%1		# atomic_dec_if_positive\n\
 	addic.	%0,%0,-1\n\
 	blt-	2f\n"
@@ -253,7 +253,7 @@ static __inline__ long atomic64_add_return(long a, atomic64_t *v)
 	long t;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	ldarx	%0,0,%2		# atomic64_add_return\n\
 	add	%0,%1,%0\n\
 	stdcx.	%0,0,%2 \n\
@@ -287,7 +287,7 @@ static __inline__ long atomic64_sub_return(long a, atomic64_t *v)
 	long t;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	ldarx	%0,0,%2		# atomic64_sub_return\n\
 	subf	%0,%1,%0\n\
 	stdcx.	%0,0,%2 \n\
@@ -319,7 +319,7 @@ static __inline__ long atomic64_inc_return(atomic64_t *v)
 	long t;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	ldarx	%0,0,%1		# atomic64_inc_return\n\
 	addic	%0,%0,1\n\
 	stdcx.	%0,0,%1 \n\
@@ -361,7 +361,7 @@ static __inline__ long atomic64_dec_return(atomic64_t *v)
 	long t;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	ldarx	%0,0,%1		# atomic64_dec_return\n\
 	addic	%0,%0,-1\n\
 	stdcx.	%0,0,%1\n\
@@ -386,7 +386,7 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
 	long t;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	ldarx	%0,0,%1		# atomic64_dec_if_positive\n\
 	addic.	%0,%0,-1\n\
 	blt-	2f\n\

+ 3 - 3
include/asm-powerpc/bitops.h

@@ -112,7 +112,7 @@ static __inline__ int test_and_set_bit(unsigned long nr,
 	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:"	PPC_LLARX "%0,0,%3		# test_and_set_bit\n"
 	"or	%1,%0,%2 \n"
 	PPC405_ERR77(0,%3)
@@ -134,7 +134,7 @@ static __inline__ int test_and_clear_bit(unsigned long nr,
 	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:"	PPC_LLARX "%0,0,%3		# test_and_clear_bit\n"
 	"andc	%1,%0,%2 \n"
 	PPC405_ERR77(0,%3)
@@ -156,7 +156,7 @@ static __inline__ int test_and_change_bit(unsigned long nr,
 	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:"	PPC_LLARX "%0,0,%3		# test_and_change_bit\n"
 	"xor	%1,%0,%2 \n"
 	PPC405_ERR77(0,%3)

+ 9 - 5
include/asm-powerpc/cputable.h

@@ -19,6 +19,7 @@
 #define PPC_FEATURE_POWER5		0x00040000
 #define PPC_FEATURE_POWER5_PLUS		0x00020000
 #define PPC_FEATURE_CELL		0x00010000
+#define PPC_FEATURE_BOOKE		0x00008000
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
@@ -31,11 +32,11 @@ struct cpu_spec;
 typedef	void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec);
 
 enum powerpc_oprofile_type {
-	INVALID = 0,
-	RS64 = 1,
-	POWER4 = 2,
-	G4 = 3,
-	BOOKE = 4,
+	PPC_OPROFILE_INVALID = 0,
+	PPC_OPROFILE_RS64 = 1,
+	PPC_OPROFILE_POWER4 = 2,
+	PPC_OPROFILE_G4 = 3,
+	PPC_OPROFILE_BOOKE = 4,
 };
 
 struct cpu_spec {
@@ -64,6 +65,9 @@ struct cpu_spec {
 
 	/* Processor specific oprofile operations */
 	enum powerpc_oprofile_type oprofile_type;
+
+	/* Name of processor class, for the ELF AT_PLATFORM entry */
+	char		*platform;
 };
 
 extern struct cpu_spec		*cur_cpu_spec;

+ 7 - 9
include/asm-powerpc/elf.h

@@ -221,20 +221,18 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
    instruction set this cpu supports.  This could be done in userspace,
    but it's not easy, and we've already done it here.  */
 # define ELF_HWCAP	(cur_cpu_spec->cpu_user_features)
-#ifdef __powerpc64__
-# define ELF_PLAT_INIT(_r, load_addr)	do {	\
-	_r->gpr[2] = load_addr; 		\
-} while (0)
-#endif /* __powerpc64__ */
 
 /* This yields a string that ld.so will use to load implementation
    specific libraries for optimization.  This is more specific in
-   intent than poking at uname or /proc/cpuinfo.
+   intent than poking at uname or /proc/cpuinfo.  */
 
-   For the moment, we have only optimizations for the Intel generations,
-   but that could change... */
+#define ELF_PLATFORM	(cur_cpu_spec->platform)
 
-#define ELF_PLATFORM	(NULL)
+#ifdef __powerpc64__
+# define ELF_PLAT_INIT(_r, load_addr)	do {	\
+	_r->gpr[2] = load_addr; 		\
+} while (0)
+#endif /* __powerpc64__ */
 
 #ifdef __KERNEL__
 

+ 1 - 1
include/asm-powerpc/futex.h

@@ -11,7 +11,7 @@
 
 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
   __asm__ __volatile ( \
-	SYNC_ON_SMP \
+	LWSYNC_ON_SMP \
 "1:	lwarx	%0,0,%2\n" \
 	insn \
 	PPC405_ERR77(0, %2) \

+ 5 - 0
include/asm-powerpc/hvcall.h

@@ -6,7 +6,10 @@
 
 #define H_Success	0
 #define H_Busy		1	/* Hardware busy -- retry later */
+#define H_Closed	2	/* Resource closed */
 #define H_Constrained	4	/* Resource request constrained to max allowed */
+#define H_InProgress   14	/* Kind of like busy */
+#define H_Continue     18	/* Returned from H_Join on success */
 #define H_LongBusyStartRange   9900  /* Start of long busy range */
 #define H_LongBusyOrder1msec   9900  /* Long busy, hint that 1msec is a good time to retry */
 #define H_LongBusyOrder10msec  9901  /* Long busy, hint that 10msec is a good time to retry */
@@ -114,6 +117,8 @@
 #define H_REGISTER_VTERM	0x154
 #define H_FREE_VTERM		0x158
 #define H_POLL_PENDING	        0x1D8
+#define H_JOIN			0x298
+#define H_ENABLE_CRQ		0x2B0
 
 #ifndef __ASSEMBLY__
 

+ 5 - 1
include/asm-powerpc/lppaca.h

@@ -29,7 +29,9 @@
 //----------------------------------------------------------------------------
 #include <asm/types.h>
 
-struct lppaca {
+/* The Hypervisor barfs if the lppaca crosses a page boundary.  A 1k
+ * alignment is sufficient to prevent this */
+struct __attribute__((__aligned__(0x400))) lppaca {
 //=============================================================================
 // CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
 // NOTE: The xDynXyz fields are fields that will be dynamically changed by
@@ -129,5 +131,7 @@ struct lppaca {
 	u8	pmc_save_area[256];	// PMC interrupt Area           x00-xFF
 };
 
+extern struct lppaca lppaca[];
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_LPPACA_H */

+ 1 - 13
include/asm-powerpc/paca.h

@@ -23,6 +23,7 @@
 
 register struct paca_struct *local_paca asm("r13");
 #define get_paca()	local_paca
+#define get_lppaca()	(get_paca()->lppaca_ptr)
 
 struct task_struct;
 
@@ -95,19 +96,6 @@ struct paca_struct {
 	u64 saved_r1;			/* r1 save for RTAS calls */
 	u64 saved_msr;			/* MSR saved here by enter_rtas */
 	u8 proc_enabled;		/* irq soft-enable flag */
-
-	/*
-	 * iSeries structure which the hypervisor knows about -
-	 * this structure should not cross a page boundary.
-	 * The vpa_init/register_vpa call is now known to fail if the
-	 * lppaca structure crosses a page boundary.
-	 * The lppaca is also used on POWER5 pSeries boxes.
-	 * The lppaca is 640 bytes long, and cannot readily change
-	 * since the hypervisor knows its layout, so a 1kB
-	 * alignment will suffice to ensure that it doesn't
-	 * cross a page boundary.
-	 */
-	struct lppaca lppaca __attribute__((__aligned__(0x400)));
 };
 
 extern struct paca_struct paca[];

+ 40 - 36
include/asm-powerpc/ppc_asm.h

@@ -156,52 +156,56 @@ n:
 #endif
 
 /* 
- * LOADADDR( rn, name )
- *   loads the address of 'name' into 'rn'
+ * LOAD_REG_IMMEDIATE(rn, expr)
+ *   Loads the value of the constant expression 'expr' into register 'rn'
+ *   using immediate instructions only.  Use this when it's important not
+ *   to reference other data (i.e. on ppc64 when the TOC pointer is not
+ *   valid).
  *
- * LOADBASE( rn, name )
- *   loads the address (possibly without the low 16 bits) of 'name' into 'rn'
- *   suitable for base+disp addressing
+ * LOAD_REG_ADDR(rn, name)
+ *   Loads the address of label 'name' into register 'rn'.  Use this when
+ *   you don't particularly need immediate instructions only, but you need
+ *   the whole address in one register (e.g. it's a structure address and
+ *   you want to access various offsets within it).  On ppc32 this is
+ *   identical to LOAD_REG_IMMEDIATE.
+ *
+ * LOAD_REG_ADDRBASE(rn, name)
+ * ADDROFF(name)
+ *   LOAD_REG_ADDRBASE loads part of the address of label 'name' into
+ *   register 'rn'.  ADDROFF(name) returns the remainder of the address as
+ *   a constant expression.  ADDROFF(name) is a signed expression < 16 bits
+ *   in size, so is suitable for use directly as an offset in load and store
+ *   instructions.  Use this when loading/storing a single word or less as:
+ *      LOAD_REG_ADDRBASE(rX, name)
+ *      ld	rY,ADDROFF(name)(rX)
  */
 #ifdef __powerpc64__
-#define LOADADDR(rn,name) \
-	lis	rn,name##@highest;	\
-	ori	rn,rn,name##@higher;	\
-	rldicr	rn,rn,32,31;		\
-	oris	rn,rn,name##@h;		\
-	ori	rn,rn,name##@l
-
-#define LOADBASE(rn,name)		\
-	ld	rn,name@got(r2)
-
-#define OFF(name)	0
-
-#define SET_REG_TO_CONST(reg, value)	         	\
-	lis     reg,(((value)>>48)&0xFFFF);             \
-	ori     reg,reg,(((value)>>32)&0xFFFF);         \
-	rldicr  reg,reg,32,31;                          \
-	oris    reg,reg,(((value)>>16)&0xFFFF);         \
-	ori     reg,reg,((value)&0xFFFF);
-
-#define SET_REG_TO_LABEL(reg, label)	         	\
-	lis     reg,(label)@highest;                    \
-	ori     reg,reg,(label)@higher;                 \
-	rldicr  reg,reg,32,31;                          \
-	oris    reg,reg,(label)@h;                      \
-	ori     reg,reg,(label)@l;
+#define LOAD_REG_IMMEDIATE(reg,expr)		\
+	lis     (reg),(expr)@highest;		\
+	ori     (reg),(reg),(expr)@higher;	\
+	rldicr  (reg),(reg),32,31;		\
+	oris    (reg),(reg),(expr)@h;		\
+	ori     (reg),(reg),(expr)@l;
+
+#define LOAD_REG_ADDR(reg,name)			\
+	ld	(reg),name@got(r2)
+
+#define LOAD_REG_ADDRBASE(reg,name)	LOAD_REG_ADDR(reg,name)
+#define ADDROFF(name)			0
 
 /* offsets for stack frame layout */
 #define LRSAVE	16
 
 #else /* 32-bit */
-#define LOADADDR(rn,name) \
-	lis	rn,name@ha;	\
-	addi	rn,rn,name@l
 
-#define LOADBASE(rn,name)	\
-	lis	rn,name@ha
+#define LOAD_REG_IMMEDIATE(reg,expr)		\
+	lis	(reg),(expr)@ha;		\
+	addi	(reg),(reg),(expr)@l;
+
+#define LOAD_REG_ADDR(reg,name)		LOAD_REG_IMMEDIATE(reg, name)
 
-#define OFF(name)	name@l
+#define LOAD_REG_ADDRBASE(reg, name)	lis	(reg),name@ha
+#define ADDROFF(name)			name@l
 
 /* offsets for stack frame layout */
 #define LRSAVE	4

+ 8 - 0
include/asm-powerpc/prom.h

@@ -87,6 +87,7 @@ struct device_node {
 	char	*full_name;
 
 	struct	property *properties;
+	struct  property *deadprops; /* removed properties */
 	struct	device_node *parent;
 	struct	device_node *child;
 	struct	device_node *sibling;
@@ -135,6 +136,9 @@ extern struct device_node *of_find_all_nodes(struct device_node *prev);
 extern struct device_node *of_get_parent(const struct device_node *node);
 extern struct device_node *of_get_next_child(const struct device_node *node,
 					     struct device_node *prev);
+extern struct property *of_find_property(struct device_node *np,
+					 const char *name,
+					 int *lenp);
 extern struct device_node *of_node_get(struct device_node *node);
 extern void of_node_put(struct device_node *node);
 
@@ -164,6 +168,10 @@ extern int prom_n_size_cells(struct device_node* np);
 extern int prom_n_intr_cells(struct device_node* np);
 extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
 extern int prom_add_property(struct device_node* np, struct property* prop);
+extern int prom_remove_property(struct device_node *np, struct property *prop);
+extern int prom_update_property(struct device_node *np,
+				struct property *newprop,
+				struct property *oldprop);
 
 #ifdef CONFIG_PPC32
 /*

+ 11 - 10
include/asm-powerpc/spinlock.h

@@ -46,7 +46,7 @@ static __inline__ unsigned long __spin_trylock(raw_spinlock_t *lock)
 
 	token = LOCK_TOKEN;
 	__asm__ __volatile__(
-"1:	lwarx		%0,0,%2		# __spin_trylock\n\
+"1:	lwarx		%0,0,%2\n\
 	cmpwi		0,%0,0\n\
 	bne-		2f\n\
 	stwcx.		%1,0,%2\n\
@@ -80,7 +80,7 @@ static int __inline__ __raw_spin_trylock(raw_spinlock_t *lock)
 
 #if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES)
 /* We only yield to the hypervisor if we are in shared processor mode */
-#define SHARED_PROCESSOR (get_paca()->lppaca.shared_proc)
+#define SHARED_PROCESSOR (get_lppaca()->shared_proc)
 extern void __spin_yield(raw_spinlock_t *lock);
 extern void __rw_yield(raw_rwlock_t *lock);
 #else /* SPLPAR || ISERIES */
@@ -124,8 +124,8 @@ static void __inline__ __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long
 
 static __inline__ void __raw_spin_unlock(raw_spinlock_t *lock)
 {
-	__asm__ __volatile__(SYNC_ON_SMP"	# __raw_spin_unlock"
-			     : : :"memory");
+	__asm__ __volatile__("# __raw_spin_unlock\n\t"
+				LWSYNC_ON_SMP: : :"memory");
 	lock->slock = 0;
 }
 
@@ -167,7 +167,7 @@ static long __inline__ __read_trylock(raw_rwlock_t *rw)
 	long tmp;
 
 	__asm__ __volatile__(
-"1:	lwarx		%0,0,%1		# read_trylock\n"
+"1:	lwarx		%0,0,%1\n"
 	__DO_SIGN_EXTEND
 "	addic.		%0,%0,1\n\
 	ble-		2f\n"
@@ -192,7 +192,7 @@ static __inline__ long __write_trylock(raw_rwlock_t *rw)
 
 	token = WRLOCK_TOKEN;
 	__asm__ __volatile__(
-"1:	lwarx		%0,0,%2	# write_trylock\n\
+"1:	lwarx		%0,0,%2\n\
 	cmpwi		0,%0,0\n\
 	bne-		2f\n"
 	PPC405_ERR77(0,%1)
@@ -249,8 +249,9 @@ static void __inline__ __raw_read_unlock(raw_rwlock_t *rw)
 	long tmp;
 
 	__asm__ __volatile__(
-	"eieio				# read_unlock\n\
-1:	lwarx		%0,0,%1\n\
+	"# read_unlock\n\t"
+	LWSYNC_ON_SMP
+"1:	lwarx		%0,0,%1\n\
 	addic		%0,%0,-1\n"
 	PPC405_ERR77(0,%1)
 "	stwcx.		%0,0,%1\n\
@@ -262,8 +263,8 @@ static void __inline__ __raw_read_unlock(raw_rwlock_t *rw)
 
 static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
 {
-	__asm__ __volatile__(SYNC_ON_SMP"	# write_unlock"
-			     : : :"memory");
+	__asm__ __volatile__("# write_unlock\n\t"
+				LWSYNC_ON_SMP: : :"memory");
 	rw->lock = 0;
 }
 

+ 4 - 19
include/asm-powerpc/synch.h

@@ -2,6 +2,8 @@
 #define _ASM_POWERPC_SYNCH_H 
 #ifdef __KERNEL__
 
+#include <linux/stringify.h>
+
 #ifdef __powerpc64__
 #define __SUBARCH_HAS_LWSYNC
 #endif
@@ -12,20 +14,12 @@
 #    define LWSYNC	sync
 #endif
 
-
-/*
- * Arguably the bitops and *xchg operations don't imply any memory barrier
- * or SMP ordering, but in fact a lot of drivers expect them to imply
- * both, since they do on x86 cpus.
- */
 #ifdef CONFIG_SMP
-#define EIEIO_ON_SMP	"eieio\n"
 #define ISYNC_ON_SMP	"\n\tisync"
-#define SYNC_ON_SMP	__stringify(LWSYNC) "\n"
+#define LWSYNC_ON_SMP	__stringify(LWSYNC) "\n"
 #else
-#define EIEIO_ON_SMP
 #define ISYNC_ON_SMP
-#define SYNC_ON_SMP
+#define LWSYNC_ON_SMP
 #endif
 
 static inline void eieio(void)
@@ -38,14 +32,5 @@ static inline void isync(void)
 	__asm__ __volatile__ ("isync" : : : "memory");
 }
 
-#ifdef CONFIG_SMP
-#define eieio_on_smp()	eieio()
-#define isync_on_smp()	isync()
-#else
-#define eieio_on_smp()	__asm__ __volatile__("": : :"memory")
-#define isync_on_smp()	__asm__ __volatile__("": : :"memory")
-#endif
-
 #endif /* __KERNEL__ */
 #endif	/* _ASM_POWERPC_SYNCH_H */
-

+ 4 - 4
include/asm-powerpc/system.h

@@ -212,7 +212,7 @@ __xchg_u32(volatile void *p, unsigned long val)
 	unsigned long prev;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	lwarx	%0,0,%2 \n"
 	PPC405_ERR77(0,%2)
 "	stwcx.	%3,0,%2 \n\
@@ -232,7 +232,7 @@ __xchg_u64(volatile void *p, unsigned long val)
 	unsigned long prev;
 
 	__asm__ __volatile__(
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	ldarx	%0,0,%2 \n"
 	PPC405_ERR77(0,%2)
 "	stdcx.	%3,0,%2 \n\
@@ -287,7 +287,7 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
 	unsigned int prev;
 
 	__asm__ __volatile__ (
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	lwarx	%0,0,%2		# __cmpxchg_u32\n\
 	cmpw	0,%0,%3\n\
 	bne-	2f\n"
@@ -311,7 +311,7 @@ __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
 	unsigned long prev;
 
 	__asm__ __volatile__ (
-	EIEIO_ON_SMP
+	LWSYNC_ON_SMP
 "1:	ldarx	%0,0,%2		# __cmpxchg_u64\n\
 	cmpd	0,%0,%3\n\
 	bne-	2f\n\

+ 2 - 3
include/asm-powerpc/time.h

@@ -175,11 +175,10 @@ static inline void set_dec(int val)
 	set_dec_cpu6(val);
 #else
 #ifdef CONFIG_PPC_ISERIES
-	struct paca_struct *lpaca = get_paca();
 	int cur_dec;
 
-	if (lpaca->lppaca.shared_proc) {
-		lpaca->lppaca.virtual_decr = val;
+	if (get_lppaca()->shared_proc) {
+		get_lppaca()->virtual_decr = val;
 		cur_dec = get_dec();
 		if (cur_dec > val)
 			HvCall_setVirtualDecr();

+ 5 - 0
include/linux/proc_fs.h

@@ -146,6 +146,11 @@ struct property;
 extern void proc_device_tree_init(void);
 extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *);
 extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop);
+extern void proc_device_tree_remove_prop(struct proc_dir_entry *pde,
+					 struct property *prop);
+extern void proc_device_tree_update_prop(struct proc_dir_entry *pde,
+					 struct property *newprop,
+					 struct property *oldprop);
 #endif /* CONFIG_PROC_DEVICETREE */
 
 extern struct proc_dir_entry *proc_symlink(const char *,