summary refs log tree commit diff
path: root/arch/parisc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc')
-rw-r--r--arch/parisc/Kconfig9
-rw-r--r--arch/parisc/Makefile8
-rw-r--r--arch/parisc/hpux/entry_hpux.S10
-rw-r--r--arch/parisc/hpux/fs.c26
-rw-r--r--arch/parisc/hpux/gate.S23
-rw-r--r--arch/parisc/hpux/sys_hpux.c32
-rw-r--r--arch/parisc/hpux/wrappers.S45
-rw-r--r--arch/parisc/kernel/asm-offsets.c2
-rw-r--r--arch/parisc/kernel/cache.c188
-rw-r--r--arch/parisc/kernel/drivers.c19
-rw-r--r--arch/parisc/kernel/entry.S241
-rw-r--r--arch/parisc/kernel/firmware.c26
-rw-r--r--arch/parisc/kernel/head.S15
-rw-r--r--arch/parisc/kernel/hpmc.S16
-rw-r--r--arch/parisc/kernel/inventory.c10
-rw-r--r--arch/parisc/kernel/irq.c6
-rw-r--r--arch/parisc/kernel/module.c23
-rw-r--r--arch/parisc/kernel/pacache.S89
-rw-r--r--arch/parisc/kernel/parisc_ksyms.c10
-rw-r--r--arch/parisc/kernel/pci-dma.c2
-rw-r--r--arch/parisc/kernel/pci.c4
-rw-r--r--arch/parisc/kernel/perf_asm.S26
-rw-r--r--arch/parisc/kernel/process.c8
-rw-r--r--arch/parisc/kernel/processor.c11
-rw-r--r--arch/parisc/kernel/ptrace.c10
-rw-r--r--arch/parisc/kernel/real2.S16
-rw-r--r--arch/parisc/kernel/setup.c6
-rw-r--r--arch/parisc/kernel/signal.c273
-rw-r--r--arch/parisc/kernel/signal32.c42
-rw-r--r--arch/parisc/kernel/smp.c178
-rw-r--r--arch/parisc/kernel/syscall.S71
-rw-r--r--arch/parisc/kernel/syscall_table.S16
-rw-r--r--arch/parisc/kernel/time.c146
-rw-r--r--arch/parisc/kernel/traps.c153
-rw-r--r--arch/parisc/kernel/unaligned.c115
-rw-r--r--arch/parisc/kernel/unwind.c1
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S2
-rw-r--r--arch/parisc/lib/bitops.c4
-rw-r--r--arch/parisc/lib/fixup.S20
-rw-r--r--arch/parisc/lib/lusercopy.S37
-rw-r--r--arch/parisc/lib/memcpy.c38
-rw-r--r--arch/parisc/mm/fault.c4
-rw-r--r--arch/parisc/mm/init.c72
-rw-r--r--arch/parisc/mm/ioremap.c6
-rw-r--r--arch/parisc/mm/kmap.c166
-rw-r--r--arch/parisc/oprofile/init.c2
46 files changed, 957 insertions, 1270 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 28da4e71c443..3d73545e8c48 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -37,6 +37,11 @@ config GENERIC_FIND_NEXT_BIT
 	bool
 	default y
 
+config GENERIC_BUG
+	bool
+	default y
+	depends on BUG
+
 config GENERIC_HWEIGHT
 	bool
 	default y
@@ -45,6 +50,10 @@ config GENERIC_CALIBRATE_DELAY
 	bool
 	default y
 
+config GENERIC_TIME
+	bool
+	default y
+
 config TIME_LOW_RES
 	bool
 	depends on SMP
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 9b7e42490dd1..760567a9ba16 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -35,12 +35,8 @@ FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align
 
 OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
 
-GCC_VERSION     := $(call cc-version)
-ifneq ($(shell if [ -z $(GCC_VERSION) ] ; then echo "bad"; fi ;),)
-$(error Sorry, couldn't find ($(cc-version)).)
-endif
-ifneq ($(shell if [ $(GCC_VERSION) -lt 0303 ] ; then echo "bad"; fi ;),)
-$(error Sorry, your compiler is too old ($(GCC_VERSION)).  GCC v3.3 or above is required.)
+ifneq ($(call cc-ifversion, -lt, 0303, "bad"),)
+$(error Sorry, GCC v3.3 or above is required.)
 endif
 
 cflags-y	:= -pipe
diff --git a/arch/parisc/hpux/entry_hpux.S b/arch/parisc/hpux/entry_hpux.S
index 31c8cccfba31..d15a413572f0 100644
--- a/arch/parisc/hpux/entry_hpux.S
+++ b/arch/parisc/hpux/entry_hpux.S
@@ -18,17 +18,16 @@
  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <asm/unistd.h>
+#include <asm/assembly.h>
 #include <linux/sys.h>
 #include <linux/linkage.h>
-#include <asm/unistd.h>
 
-#define ENTRY_NAME(_name_) .word _name_
+#define ENTRY_NAME(_name_) ASM_ULONG_INSN _name_
 
 	.section .rodata,"a"
-	.align 4
-	.export hpux_call_table
 	.import hpux_unimplemented_wrapper
-hpux_call_table:
+ENTRY(hpux_call_table)
 	ENTRY_NAME(sys_ni_syscall)	/* 0 */
 	ENTRY_NAME(sys_exit)
 	ENTRY_NAME(hpux_fork_wrapper)
@@ -542,5 +541,6 @@ hpux_call_table:
 	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 510 */
 	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_unimplemented_wrapper)
+END(hpux_call_table)
 .end
 
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
index 4204cd1f3cf9..c7a81a2c014c 100644
--- a/arch/parisc/hpux/fs.c
+++ b/arch/parisc/hpux/fs.c
@@ -35,13 +35,13 @@ int hpux_execve(struct pt_regs *regs)
 	int error;
 	char *filename;
 
-	filename = getname((char *) regs->gr[26]);
+	filename = getname((char __user *) regs->gr[26]);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
 		goto out;
 
-	error = do_execve(filename, (char **) regs->gr[25],
-		(char **)regs->gr[24], regs);
+	error = do_execve(filename, (char __user * __user *) regs->gr[25],
+		(char __user * __user *) regs->gr[24], regs);
 
 	if (error == 0) {
 		task_lock(current);
@@ -63,19 +63,19 @@ struct hpux_dirent {
 };
 
 struct getdents_callback {
-	struct hpux_dirent *current_dir;
-	struct hpux_dirent *previous;
+	struct hpux_dirent __user *current_dir;
+	struct hpux_dirent __user *previous;
 	int count;
 	int error;
 };
 
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
 #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
 
 static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
 		u64 ino, unsigned d_type)
 {
-	struct hpux_dirent * dirent;
+	struct hpux_dirent __user * dirent;
 	struct getdents_callback * buf = (struct getdents_callback *) __buf;
 	ino_t d_ino;
 	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
@@ -105,10 +105,10 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
 #undef NAME_OFFSET
 #undef ROUND_UP
 
-int hpux_getdents(unsigned int fd, struct hpux_dirent *dirent, unsigned int count)
+int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count)
 {
 	struct file * file;
-	struct hpux_dirent * lastdirent;
+	struct hpux_dirent __user * lastdirent;
 	struct getdents_callback buf;
 	int error = -EBADF;
 
@@ -143,7 +143,7 @@ int hpux_mount(const char *fs, const char *path, int mflag,
 	return -ENOSYS;
 }
 
-static int cp_hpux_stat(struct kstat *stat, struct hpux_stat64 *statbuf)
+static int cp_hpux_stat(struct kstat *stat, struct hpux_stat64 __user *statbuf)
 {
 	struct hpux_stat64 tmp;
 
@@ -169,7 +169,7 @@ static int cp_hpux_stat(struct kstat *stat, struct hpux_stat64 *statbuf)
 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
 }
 
-long hpux_stat64(char *filename, struct hpux_stat64 *statbuf)
+long hpux_stat64(char __user *filename, struct hpux_stat64 __user *statbuf)
 {
 	struct kstat stat;
 	int error = vfs_stat(filename, &stat);
@@ -180,7 +180,7 @@ long hpux_stat64(char *filename, struct hpux_stat64 *statbuf)
 	return error;
 }
 
-long hpux_fstat64(unsigned int fd, struct hpux_stat64 *statbuf)
+long hpux_fstat64(unsigned int fd, struct hpux_stat64 __user *statbuf)
 {
 	struct kstat stat;
 	int error = vfs_fstat(fd, &stat);
@@ -191,7 +191,7 @@ long hpux_fstat64(unsigned int fd, struct hpux_stat64 *statbuf)
 	return error;
 }
 
-long hpux_lstat64(char *filename, struct hpux_stat64 *statbuf)
+long hpux_lstat64(char __user *filename, struct hpux_stat64 __user *statbuf)
 {
 	struct kstat stat;
 	int error = vfs_lstat(filename, &stat);
diff --git a/arch/parisc/hpux/gate.S b/arch/parisc/hpux/gate.S
index aaaf3306c05a..0b9d5b1e4b37 100644
--- a/arch/parisc/hpux/gate.S
+++ b/arch/parisc/hpux/gate.S
@@ -12,27 +12,18 @@
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
 #include <asm/errno.h>
+#include <linux/linkage.h>
 
-#ifdef __LP64__
-	.level          2.0w
-#else
-	.level		1.1
-#endif
+	.level	LEVEL
 	.text
 
-#ifdef __LP64__
-#define FRAME_SIZE	128
-#else
-#define FRAME_SIZE	64
-#endif
 	.import hpux_call_table
 	.import hpux_syscall_exit,code
-	.export hpux_gateway_page
 
 	.align 4096
-hpux_gateway_page:
+ENTRY(hpux_gateway_page)
 	nop
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #warning NEEDS WORK for 64-bit
 #endif
 	ldw     -64(%r30), %r29                 ;! 8th argument
@@ -101,7 +92,7 @@ hpux_gateway_page:
 	ldo	R%hpux_call_table(%r21), %r21
 	comiclr,>>=	__NR_HPUX_syscalls, %r22, %r0
 	b,n	syscall_nosys
-	ldwx,s	%r22(%r21), %r21
+	LDREGX	%r22(%r21), %r21
 	ldil	L%hpux_syscall_exit,%r2
 	be	0(%sr7,%r21)
 	ldo	R%hpux_syscall_exit(%r2),%r2
@@ -110,7 +101,7 @@ syscall_nosys:
 	ldil	L%hpux_syscall_exit,%r1
 	be	R%hpux_syscall_exit(%sr7,%r1)
 	ldo	-ENOSYS(%r0),%r28
+ENDPROC(hpux_gateway_page)
 
 	.align 4096
-	.export end_hpux_gateway_page
-end_hpux_gateway_page:
+ENTRY(end_hpux_gateway_page)
diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
index 04c2ff444396..3e025df2dc86 100644
--- a/arch/parisc/hpux/sys_hpux.c
+++ b/arch/parisc/hpux/sys_hpux.c
@@ -61,7 +61,7 @@ int hpux_ptrace(void)
 	return -ENOSYS;
 }
 
-int hpux_wait(int *stat_loc)
+int hpux_wait(int __user *stat_loc)
 {
 	return sys_waitpid(-1, stat_loc, 0);
 }
@@ -255,7 +255,7 @@ asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf)
 /*  TODO: Are these put_user calls OK?  Should they pass an int?
  *        (I copied it from sys_i386.c like this.)
  */
-static int hpux_uname(struct hpux_utsname *name)
+static int hpux_uname(struct hpux_utsname __user *name)
 {
 	int error;
 
@@ -300,14 +300,14 @@ static int hpux_uname(struct hpux_utsname *name)
 /*  Note: HP-UX just uses the old suser() function to check perms
  *  in this system call.  We'll use capable(CAP_SYS_ADMIN).
  */
-int hpux_utssys(char *ubuf, int n, int type)
+int hpux_utssys(char __user *ubuf, int n, int type)
 {
 	int len;
 	int error;
 	switch( type ) {
 	case 0:
 		/*  uname():  */
-		return( hpux_uname( (struct hpux_utsname *)ubuf ) );
+		return hpux_uname((struct hpux_utsname __user *)ubuf);
 		break ;
 	case 1:
 		/*  Obsolete (used to be umask().)  */
@@ -315,8 +315,9 @@ int hpux_utssys(char *ubuf, int n, int type)
 		break ;
 	case 2:
 		/*  ustat():  */
-		return( hpux_ustat(new_decode_dev(n), (struct hpux_ustat *)ubuf) );
-		break ;
+		return hpux_ustat(new_decode_dev(n),
+				  (struct hpux_ustat __user *)ubuf);
+		break;
 	case 3:
 		/*  setuname():
 		 *
@@ -332,7 +333,7 @@ int hpux_utssys(char *ubuf, int n, int type)
 			return -EINVAL ;
 		/*  Unlike Linux, HP-UX truncates it if n is too big:  */
 		len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
-		return( sys_sethostname(ubuf, len) );
+		return sys_sethostname(ubuf, len);
 		break ;
 	case 4:
 		/*  sethostname():
@@ -346,7 +347,7 @@ int hpux_utssys(char *ubuf, int n, int type)
 			return -EINVAL ;
 		/*  Unlike Linux, HP-UX truncates it if n is too big:  */
 		len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
-		return( sys_sethostname(ubuf, len) );
+		return sys_sethostname(ubuf, len);
 		break ;
 	case 5:
 		/*  gethostname():
@@ -356,7 +357,7 @@ int hpux_utssys(char *ubuf, int n, int type)
 		/*  Unlike Linux, HP-UX returns an error if n==0:  */
 		if ( n <= 0 )
 			return -EINVAL ;
-		return( sys_gethostname(ubuf, n) );
+		return sys_gethostname(ubuf, n);
 		break ;
 	case 6:
 		/*  Supposedly called from setuname() in libc.
@@ -420,7 +421,7 @@ int hpux_utssys(char *ubuf, int n, int type)
 	}
 }
 
-int hpux_getdomainname(char *name, int len)
+int hpux_getdomainname(char __user *name, int len)
 {
  	int nlen;
  	int err = -EFAULT;
@@ -471,17 +472,18 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
 	printk(KERN_DEBUG "hpux_sysfs called with arg1='%lx'\n", arg1);
 
 	if ( opcode == 1 ) { /* GETFSIND */	
-		len = strlen_user((char *)arg1);
+		char __user *user_fsname = (char __user *)arg1;
+		len = strlen_user(user_fsname);
 		printk(KERN_DEBUG "len of arg1 = %d\n", len);
 		if (len == 0)
 			return 0;
 		fsname = kmalloc(len, GFP_KERNEL);
-		if ( !fsname ) {
+		if (!fsname) {
 			printk(KERN_DEBUG "failed to kmalloc fsname\n");
 			return 0;
 		}
 
-		if ( copy_from_user(fsname, (char *)arg1, len) ) {
+		if (copy_from_user(fsname, user_fsname, len)) {
 			printk(KERN_DEBUG "failed to copy_from_user fsname\n");
 			kfree(fsname);
 			return 0;
@@ -495,7 +497,7 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
 			fstype = 0;
 		} else {
 			fstype = 0;
-		};
+		}
 
 		kfree(fsname);
 
@@ -509,7 +511,7 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
 
 
 /* Table of syscall names and handle for unimplemented routines */
-static const char *syscall_names[] = {
+static const char * const syscall_names[] = {
 	"nosys",                  /* 0 */
 	"exit",                  
 	"fork",                  
diff --git a/arch/parisc/hpux/wrappers.S b/arch/parisc/hpux/wrappers.S
index 0b0c3a66b1be..58c53c879c02 100644
--- a/arch/parisc/hpux/wrappers.S
+++ b/arch/parisc/hpux/wrappers.S
@@ -20,19 +20,16 @@
  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #warning PA64 support needs more work...did first cut
 #endif
 
 #include <asm/asm-offsets.h>
 #include <asm/assembly.h>
 #include <asm/signal.h>
+#include <linux/linkage.h>
 
-#ifdef __LP64__
-	.level          2.0w
-#else
-	.level		1.1
-#endif
+	.level	LEVEL
 	.text
 
 	/* These should probably go in a header file somewhere.
@@ -41,7 +38,7 @@
 	 * register save/restore macros.
 	 */
 	.macro	reg_save regs
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #warning NEEDS WORK for 64-bit
 #endif
 	STREG	%r3, PT_GR3(\regs)
@@ -82,11 +79,9 @@
 	.endm
 
 
-	.export hpux_fork_wrapper
-	.export hpux_child_return
 	.import sys_fork
 
-hpux_fork_wrapper:
+ENTRY(hpux_fork_wrapper)
 	ldo	TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1	    ;! get pt regs
 							    ;! pointer in task
 	reg_save %r1
@@ -128,27 +123,26 @@ fork_return:
 fork_exit:
 	bv	%r0(%r2)
 	nop
+ENDPROC(hpux_fork_wrapper)
 
 	/* Set the return value for the child */
 
-hpux_child_return:
+ENTRY(hpux_child_return)
 #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
-	bl	schedule_tail, %r2
-	nop
+	bl,n	schedule_tail, %r2
 #endif
 
 	LDREG	TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
 	b fork_return
 	copy %r0,%r28
+ENDPROC(hpux_child_return)
 
-	.export hpux_execve_wrapper
-	.export hpux_execv_wrapper
 	.import hpux_execve
 
-hpux_execv_wrapper:
+ENTRY(hpux_execv_wrapper)
 	copy %r0,%r24  /* NULL environment */
 
-hpux_execve_wrapper:
+ENTRY(hpux_execve_wrapper)
 
 	ldo	TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1	    ;! get pt regs
 
@@ -187,13 +181,13 @@ hpux_execve_wrapper:
 exec_error:
 	bv %r0(%r19)
 	nop
+ENDPROC(hpux_execv_wrapper)
 
-	.export hpux_pipe_wrapper
 	.import hpux_pipe
 
 	/* HP-UX expects pipefd's returned in r28 & r29 */
 
-hpux_pipe_wrapper:
+ENTRY(hpux_pipe_wrapper)
 	STREG %r2,-20(%r30)
 	ldo 64(%r30),%r30
 	bl hpux_pipe,%r2
@@ -212,12 +206,11 @@ hpux_pipe_wrapper:
 pipe_exit:
 	bv %r0(%r2)
 	ldo -64(%r30),%r30
+ENDPROC(hpux_pipe_wrapper)
 
-	.export hpux_syscall_exit
 	.import syscall_exit
 
-hpux_syscall_exit:
-
+ENTRY(hpux_syscall_exit)
 	/*
 	 *
 	 * HP-UX call return conventions:
@@ -246,12 +239,12 @@ hpux_syscall_exit:
 	ldo 1(%r0),%r22
 
 no_error:
-	b syscall_exit
-	nop
+	b,n syscall_exit
+ENDPROC(hpux_syscall_exit)
 
-	.export hpux_unimplemented_wrapper
 	.import hpux_unimplemented
 
-hpux_unimplemented_wrapper:
+ENTRY(hpux_unimplemented_wrapper)
 	b hpux_unimplemented
 	STREG %r22,-64(%r30)  /* overwrite arg8 with syscall number */
+ENDPROC(hpux_unimplemented_wrapper)
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index c11a5bc7c067..54fdb959149c 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -44,7 +44,7 @@
 
 #define BLANK() asm volatile("\n->" : : )
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #define FRAME_SIZE	128
 #else
 #define FRAME_SIZE	64
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 0be51e92a2fc..0dc924ccceb5 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -68,16 +68,6 @@ flush_cache_all_local(void)
 }
 EXPORT_SYMBOL(flush_cache_all_local);
 
-/* flushes EVERYTHING (tlb & cache) */
-
-void
-flush_all_caches(void)
-{
-	flush_cache_all();
-	flush_tlb_all();
-}
-EXPORT_SYMBOL(flush_all_caches);
-
 void
 update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
@@ -99,7 +89,7 @@ show_cache_info(struct seq_file *m)
 
 	seq_printf(m, "I-cache\t\t: %ld KB\n", 
 		cache_info.ic_size/1024 );
-	if (cache_info.dc_loop == 1)
+	if (cache_info.dc_loop != 1)
 		snprintf(buf, 32, "%lu-way associative", cache_info.dc_loop);
 	seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %s)\n",
 		cache_info.dc_size/1024,
@@ -270,6 +260,83 @@ void disable_sr_hashing(void)
 		panic("SpaceID hashing is still on!\n");
 }
 
+/* Simple function to work out if we have an existing address translation
+ * for a user space vma. */
+static inline int translation_exists(struct vm_area_struct *vma,
+				unsigned long addr, unsigned long pfn)
+{
+	pgd_t *pgd = pgd_offset(vma->vm_mm, addr);
+	pmd_t *pmd;
+	pte_t pte;
+
+	if(pgd_none(*pgd))
+		return 0;
+
+	pmd = pmd_offset(pgd, addr);
+	if(pmd_none(*pmd) || pmd_bad(*pmd))
+		return 0;
+
+	/* We cannot take the pte lock here: flush_cache_page is usually
+	 * called with pte lock already held.  Whereas flush_dcache_page
+	 * takes flush_dcache_mmap_lock, which is lower in the hierarchy:
+	 * the vma itself is secure, but the pte might come or go racily.
+	 */
+	pte = *pte_offset_map(pmd, addr);
+	/* But pte_unmap() does nothing on this architecture */
+
+	/* Filter out coincidental file entries and swap entries */
+	if (!(pte_val(pte) & (_PAGE_FLUSH|_PAGE_PRESENT)))
+		return 0;
+
+	return pte_pfn(pte) == pfn;
+}
+
+/* Private function to flush a page from the cache of a non-current
+ * process.  cr25 contains the Page Directory of the current user
+ * process; we're going to hijack both it and the user space %sr3 to
+ * temporarily make the non-current process current.  We have to do
+ * this because cache flushing may cause a non-access tlb miss which
+ * the handlers have to fill in from the pgd of the non-current
+ * process. */
+static inline void
+flush_user_cache_page_non_current(struct vm_area_struct *vma,
+				  unsigned long vmaddr)
+{
+	/* save the current process space and pgd */
+	unsigned long space = mfsp(3), pgd = mfctl(25);
+
+	/* we don't mind taking interrups since they may not
+	 * do anything with user space, but we can't
+	 * be preempted here */
+	preempt_disable();
+
+	/* make us current */
+	mtctl(__pa(vma->vm_mm->pgd), 25);
+	mtsp(vma->vm_mm->context, 3);
+
+	flush_user_dcache_page(vmaddr);
+	if(vma->vm_flags & VM_EXEC)
+		flush_user_icache_page(vmaddr);
+
+	/* put the old current process back */
+	mtsp(space, 3);
+	mtctl(pgd, 25);
+	preempt_enable();
+}
+
+
+static inline void
+__flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr)
+{
+	if (likely(vma->vm_mm->context == mfsp(3))) {
+		flush_user_dcache_page(vmaddr);
+		if (vma->vm_flags & VM_EXEC)
+			flush_user_icache_page(vmaddr);
+	} else {
+		flush_user_cache_page_non_current(vma, vmaddr);
+	}
+}
+
 void flush_dcache_page(struct page *page)
 {
 	struct address_space *mapping = page_mapping(page);
@@ -342,7 +409,7 @@ void clear_user_page_asm(void *page, unsigned long vaddr)
 #define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
 int parisc_cache_flush_threshold __read_mostly = FLUSH_THRESHOLD;
 
-void parisc_setup_cache_timing(void)
+void __init parisc_setup_cache_timing(void)
 {
 	unsigned long rangetime, alltime;
 	unsigned long size;
@@ -366,6 +433,9 @@ void parisc_setup_cache_timing(void)
 	if (!parisc_cache_flush_threshold)
 		parisc_cache_flush_threshold = FLUSH_THRESHOLD;
 
+	if (parisc_cache_flush_threshold > cache_info.dc_size)
+		parisc_cache_flush_threshold = cache_info.dc_size;
+
 	printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus());
 }
 
@@ -410,3 +480,97 @@ void kunmap_parisc(void *addr)
 }
 EXPORT_SYMBOL(kunmap_parisc);
 #endif
+
+void __flush_tlb_range(unsigned long sid, unsigned long start,
+		       unsigned long end)
+{
+	unsigned long npages;
+
+	npages = ((end - (start & PAGE_MASK)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+	if (npages >= 512)  /* 2MB of space: arbitrary, should be tuned */
+		flush_tlb_all();
+	else {
+		mtsp(sid, 1);
+		purge_tlb_start();
+		if (split_tlb) {
+			while (npages--) {
+				pdtlb(start);
+				pitlb(start);
+				start += PAGE_SIZE;
+			}
+		} else {
+			while (npages--) {
+				pdtlb(start);
+				start += PAGE_SIZE;
+			}
+		}
+		purge_tlb_end();
+	}
+}
+
+static void cacheflush_h_tmp_function(void *dummy)
+{
+	flush_cache_all_local();
+}
+
+void flush_cache_all(void)
+{
+	on_each_cpu(cacheflush_h_tmp_function, NULL, 1, 1);
+}
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+#ifdef CONFIG_SMP
+	flush_cache_all();
+#else
+	flush_cache_all_local();
+#endif
+}
+
+void
+flush_user_dcache_range(unsigned long start, unsigned long end)
+{
+	if ((end - start) < parisc_cache_flush_threshold)
+		flush_user_dcache_range_asm(start,end);
+	else
+		flush_data_cache();
+}
+
+void
+flush_user_icache_range(unsigned long start, unsigned long end)
+{
+	if ((end - start) < parisc_cache_flush_threshold)
+		flush_user_icache_range_asm(start,end);
+	else
+		flush_instruction_cache();
+}
+
+
+void flush_cache_range(struct vm_area_struct *vma,
+		unsigned long start, unsigned long end)
+{
+	int sr3;
+
+	if (!vma->vm_mm->context) {
+		BUG();
+		return;
+	}
+
+	sr3 = mfsp(3);
+	if (vma->vm_mm->context == sr3) {
+		flush_user_dcache_range(start,end);
+		flush_user_icache_range(start,end);
+	} else {
+		flush_cache_all();
+	}
+}
+
+void
+flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
+{
+	BUG_ON(!vma->vm_mm->context);
+
+	if (likely(translation_exists(vma, vmaddr, pfn)))
+		__flush_cache_page(vma, vmaddr);
+
+}
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index d6c486e9501c..2ca654bd6322 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -562,12 +562,23 @@ pa_dev_attr(rev, id.hversion_rev, "0x%x\n");
 pa_dev_attr_id(hversion, "0x%03x\n");
 pa_dev_attr_id(sversion, "0x%05x\n");
 
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct parisc_device *padev = to_parisc_device(dev);
+	struct parisc_device_id *id = &padev->id;
+
+	return sprintf(buf, "parisc:t%02Xhv%04Xrev%02Xsv%08X\n",
+		(u8)id->hw_type, (u16)id->hversion, (u8)id->hversion_rev,
+		(u32)id->sversion);
+}
+
 static struct device_attribute parisc_device_attrs[] = {
 	__ATTR_RO(irq),
 	__ATTR_RO(hw_type),
 	__ATTR_RO(rev),
 	__ATTR_RO(hversion),
 	__ATTR_RO(sversion),
+	__ATTR_RO(modalias),
 	__ATTR_NULL,
 };
 
@@ -689,7 +700,9 @@ parse_tree_node(struct device *parent, int index, struct hardware_path *modpath)
 		.fn	= check_parent,
 	};
 
-	device_for_each_child(parent, &recurse_data, descend_children);
+	if (device_for_each_child(parent, &recurse_data, descend_children))
+		/* nothing */;
+
 	return d.dev;
 }
 
@@ -835,8 +848,8 @@ static void print_parisc_device(struct parisc_device *dev)
 	static int count;
 
 	print_pa_hwpath(dev, hw_path);
-	printk(KERN_INFO "%d. %s at 0x%lx [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
-		++count, dev->name, dev->hpa.start, hw_path, dev->id.hw_type,
+	printk(KERN_INFO "%d. %s at 0x%p [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
+		++count, dev->name, (void*) dev->hpa.start, hw_path, dev->id.hw_type,
 		dev->id.hversion_rev, dev->id.hversion, dev->id.sversion);
 
 	if (dev->num_addrs) {
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 340b5e8d67ba..8474f9e5ca10 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -37,6 +37,8 @@
 #include <asm/unistd.h>
 #include <asm/thread_info.h>
 
+#include <linux/linkage.h>
+
 #ifdef CONFIG_64BIT
 #define CMPIB           cmpib,*
 #define CMPB            cmpb,*
@@ -648,13 +650,11 @@
 	 * the static part of the kernel address space.
 	 */
 
-	.export fault_vector_20
-
 	.text
 
 	.align 4096
 
-fault_vector_20:
+ENTRY(fault_vector_20)
 	/* First vector is invalid (0) */
 	.ascii	"cows can fly"
 	.byte 0
@@ -695,14 +695,13 @@ fault_vector_20:
 	def		29
 	def		30
 	def		31
+END(fault_vector_20)
 
 #ifndef CONFIG_64BIT
 
-	.export fault_vector_11
-	
 	.align 2048
 
-fault_vector_11:
+ENTRY(fault_vector_11)
 	/* First vector is invalid (0) */
 	.ascii	"cows can fly"
 	.byte 0
@@ -743,6 +742,7 @@ fault_vector_11:
 	def		29
 	def		30
 	def		31
+END(fault_vector_11)
 
 #endif
 
@@ -762,9 +762,8 @@ fault_vector_11:
 #define CLONE_VM 0x100	/* Must agree with <linux/sched.h> */
 #define CLONE_UNTRACED 0x00800000
 
-	.export __kernel_thread, code
 	.import do_fork
-__kernel_thread:
+ENTRY(__kernel_thread)
 	STREG	%r2, -RP_OFFSET(%r30)
 
 	copy	%r30, %r1
@@ -797,6 +796,7 @@ __kernel_thread:
 	ldo	-PT_SZ_ALGN(%r30), %r30
 	bv	%r0(%r2)
 	nop
+ENDPROC(__kernel_thread)
 
 	/*
 	 * Child Returns here
@@ -805,8 +805,7 @@ __kernel_thread:
 	 * into task save area.
 	 */
 
-	.export	ret_from_kernel_thread
-ret_from_kernel_thread:
+ENTRY(ret_from_kernel_thread)
 
 	/* Call schedule_tail first though */
 	BL	schedule_tail, %r2
@@ -833,10 +832,10 @@ ret_from_kernel_thread:
 	bv	%r0(%r1)
 #endif
 	ldi	0, %r26
+ENDPROC(ret_from_kernel_thread)
 
 	.import	sys_execve, code
-	.export	__execve, code
-__execve:
+ENTRY(__execve)
 	copy	%r2, %r15
 	copy	%r30, %r16
 	ldo	PT_SZ_ALGN(%r30), %r30
@@ -856,16 +855,15 @@ __execve:
 	copy	%r16, %r30
 	bv	%r0(%r2)
 	nop
+ENDPROC(__execve)
 
-	.align 4
 
 	/*
 	 * struct task_struct *_switch_to(struct task_struct *prev,
 	 *	struct task_struct *next)
 	 *
 	 * switch kernel stacks and return prev */
-	.export	_switch_to, code
-_switch_to:
+ENTRY(_switch_to)
 	STREG	 %r2, -RP_OFFSET(%r30)
 
 	callee_save_float
@@ -890,6 +888,7 @@ _switch_to_ret:
 	LDREG	-RP_OFFSET(%r30), %r2
 	bv	%r0(%r2)
 	copy	%r26, %r28
+ENDPROC(_switch_to)
 
 	/*
 	 * Common rfi return path for interruptions, kernel execve, and
@@ -907,8 +906,7 @@ _switch_to_ret:
 
 	.align 4096
 
-	.export	syscall_exit_rfi
-syscall_exit_rfi:
+ENTRY(syscall_exit_rfi)
 	mfctl   %cr30,%r16
 	LDREG	TI_TASK(%r16), %r16	/* thread_info -> task_struct */
 	ldo	TASK_REGS(%r16),%r16
@@ -978,11 +976,36 @@ intr_check_resched:
 	LDREG   TI_FLAGS(%r1),%r19	/* sched.h: TIF_NEED_RESCHED */
 	bb,<,n	%r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
 
+	.import do_notify_resume,code
 intr_check_sig:
 	/* As above */
 	mfctl   %cr30,%r1
-	LDREG	TI_FLAGS(%r1),%r19	/* sched.h: TIF_SIGPENDING */
-	bb,<,n %r19, 31-TIF_SIGPENDING, intr_do_signal /* forward */
+	LDREG	TI_FLAGS(%r1),%r19
+	ldi	(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r20
+	and,COND(<>)	%r19, %r20, %r0
+	b,n	intr_restore	/* skip past if we've nothing to do */
+
+	/* This check is critical to having LWS
+	 * working. The IASQ is zero on the gateway
+	 * page and we cannot deliver any signals until
+	 * we get off the gateway page.
+	 *
+	 * Only do signals if we are returning to user space
+	 */
+	LDREG	PT_IASQ0(%r16), %r20
+	CMPIB=,n 0,%r20,intr_restore /* backward */
+	LDREG	PT_IASQ1(%r16), %r20
+	CMPIB=,n 0,%r20,intr_restore /* backward */
+
+	copy	%r0, %r25			/* long in_syscall = 0 */
+#ifdef CONFIG_64BIT
+	ldo	-16(%r30),%r29			/* Reference param save area */
+#endif
+
+	BL	do_notify_resume,%r2
+	copy	%r16, %r26			/* struct pt_regs *regs */
+
+	b,n	intr_check_sig
 
 intr_restore:
 	copy            %r16,%r29
@@ -1072,35 +1095,6 @@ intr_do_preempt:
 	b,n	intr_restore		/* ssm PSW_SM_I done by intr_restore */
 #endif /* CONFIG_PREEMPT */
 
-	.import do_signal,code
-intr_do_signal:
-	/* 
-		This check is critical to having LWS
-		working. The IASQ is zero on the gateway
-		page and we cannot deliver any signals until
-		we get off the gateway page.
-
-		Only do signals if we are returning to user space 
-	*/
-	LDREG	PT_IASQ0(%r16), %r20
-	CMPIB= 0,%r20,intr_restore /* backward */
-	nop
-	LDREG	PT_IASQ1(%r16), %r20
-	CMPIB= 0,%r20,intr_restore /* backward */
-	nop
-
-	copy	%r0, %r24			/* unsigned long in_syscall */
-	copy	%r16, %r25			/* struct pt_regs *regs */
-#ifdef CONFIG_64BIT
-	ldo	-16(%r30),%r29			/* Reference param save area */
-#endif
-
-	BL	do_signal,%r2
-	copy	%r0, %r26			/* sigset_t *oldset = NULL */
-
-	b	intr_check_sig
-	nop
-
 	/*
 	 * External interrupts.
 	 */
@@ -1115,11 +1109,7 @@ intr_extint:
 	mfctl	%cr31,%r1
 	copy	%r30,%r17
 	/* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
-#ifdef CONFIG_64BIT
-	depdi	0,63,15,%r17
-#else
-	depi	0,31,15,%r17
-#endif
+	DEPI	0,31,15,%r17
 	CMPB=,n	%r1,%r17,2f
 	get_stack_use_cr31
 	b,n 3f
@@ -1148,13 +1138,12 @@ intr_extint:
 
 	b	do_cpu_irq_mask
 	ldo	R%intr_return(%r2), %r2	/* return to intr_return, not here */
+ENDPROC(syscall_exit_rfi)
 
 
 	/* Generic interruptions (illegal insn, unaligned, page fault, etc) */
 
-	.export         intr_save, code /* for os_hpmc */
-
-intr_save:
+ENTRY(intr_save)		/* for os_hpmc */
 	mfsp    %sr7,%r16
 	CMPIB=,n 0,%r16,1f
 	get_stack_use_cr30
@@ -1229,6 +1218,7 @@ skip_save_ior:
 
 	b		handle_interruption
 	ldo		R%intr_check_sig(%r2), %r2
+ENDPROC(intr_save)
 
 
 	/*
@@ -1814,9 +1804,7 @@ dtlb_fault:
 	LDREG   PT_GR18(\regs),%r18
 	.endm
 
-	.export sys_fork_wrapper
-	.export child_return
-sys_fork_wrapper:
+ENTRY(sys_fork_wrapper)
 	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
 	ldo	TASK_REGS(%r1),%r1
 	reg_save %r1
@@ -1853,9 +1841,10 @@ wrapper_exit:
 	ldi	__NR_fork,%r20
 	bv %r0(%r2)
 	STREG	%r20,PT_GR20(%r1)
+ENDPROC(sys_fork_wrapper)
 
 	/* Set the return value for the child */
-child_return:
+ENTRY(child_return)
 	BL	schedule_tail, %r2
 	nop
 
@@ -1863,10 +1852,10 @@ child_return:
 	LDREG	TASK_PT_GR19(%r1),%r2
 	b	wrapper_exit
 	copy	%r0,%r28
+ENDPROC(child_return)
 
-	
-	.export sys_clone_wrapper
-sys_clone_wrapper:
+
+ENTRY(sys_clone_wrapper)
 	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
 	ldo	TASK_REGS(%r1),%r1	/* get pt regs */
 	reg_save %r1
@@ -1887,9 +1876,10 @@ sys_clone_wrapper:
 
 	b	wrapper_exit
 	LDREG	-RP_OFFSET-FRAME_SIZE(%r30),%r2
+ENDPROC(sys_clone_wrapper)
+
 
-	.export sys_vfork_wrapper
-sys_vfork_wrapper:
+ENTRY(sys_vfork_wrapper)
 	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
 	ldo	TASK_REGS(%r1),%r1	/* get pt regs */
 	reg_save %r1
@@ -1910,6 +1900,7 @@ sys_vfork_wrapper:
 
 	b	wrapper_exit
 	LDREG	-RP_OFFSET-FRAME_SIZE(%r30),%r2
+ENDPROC(sys_vfork_wrapper)
 
 	
 	.macro  execve_wrapper execve
@@ -1946,22 +1937,19 @@ error_\execve:
 	nop
 	.endm
 
-	.export sys_execve_wrapper
 	.import sys_execve
-
-sys_execve_wrapper:
+ENTRY(sys_execve_wrapper)
 	execve_wrapper sys_execve
+ENDPROC(sys_execve_wrapper)
 
 #ifdef CONFIG_64BIT
-	.export sys32_execve_wrapper
 	.import sys32_execve
-
-sys32_execve_wrapper:
+ENTRY(sys32_execve_wrapper)
 	execve_wrapper sys32_execve
+ENDPROC(sys32_execve_wrapper)
 #endif
 
-	.export sys_rt_sigreturn_wrapper
-sys_rt_sigreturn_wrapper:
+ENTRY(sys_rt_sigreturn_wrapper)
 	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
 	ldo	TASK_REGS(%r26),%r26	/* get pt regs */
 	/* Don't save regs, we are going to restore them from sigcontext. */
@@ -1989,9 +1977,9 @@ sys_rt_sigreturn_wrapper:
 	 */
 	bv	%r0(%r2)
 	LDREG	PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */
+ENDPROC(sys_rt_sigreturn_wrapper)
 
-	.export sys_sigaltstack_wrapper
-sys_sigaltstack_wrapper:
+ENTRY(sys_sigaltstack_wrapper)
 	/* Get the user stack pointer */
 	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
 	ldo	TASK_REGS(%r1),%r24	/* get pt regs */
@@ -1999,10 +1987,10 @@ sys_sigaltstack_wrapper:
 	STREG	%r2, -RP_OFFSET(%r30)
 #ifdef CONFIG_64BIT
 	ldo	FRAME_SIZE(%r30), %r30
-	b,l	do_sigaltstack,%r2
+	BL	do_sigaltstack,%r2
 	ldo	-16(%r30),%r29		/* Reference param save area */
 #else
-	bl	do_sigaltstack,%r2
+	BL	do_sigaltstack,%r2
 	ldo	FRAME_SIZE(%r30), %r30
 #endif
 
@@ -2010,53 +1998,26 @@ sys_sigaltstack_wrapper:
 	LDREG	-RP_OFFSET(%r30), %r2
 	bv	%r0(%r2)
 	nop
+ENDPROC(sys_sigaltstack_wrapper)
 
 #ifdef CONFIG_64BIT
-	.export sys32_sigaltstack_wrapper
-sys32_sigaltstack_wrapper:
+ENTRY(sys32_sigaltstack_wrapper)
 	/* Get the user stack pointer */
 	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24
 	LDREG	TASK_PT_GR30(%r24),%r24
 	STREG	%r2, -RP_OFFSET(%r30)
 	ldo	FRAME_SIZE(%r30), %r30
-	b,l	do_sigaltstack32,%r2
+	BL	do_sigaltstack32,%r2
 	ldo	-16(%r30),%r29		/* Reference param save area */
 
 	ldo	-FRAME_SIZE(%r30), %r30
 	LDREG	-RP_OFFSET(%r30), %r2
 	bv	%r0(%r2)
 	nop
+ENDPROC(sys32_sigaltstack_wrapper)
 #endif
 
-	.export sys_rt_sigsuspend_wrapper
-sys_rt_sigsuspend_wrapper:
-	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
-	ldo	TASK_REGS(%r1),%r24
-	reg_save %r24
-
-	STREG	%r2, -RP_OFFSET(%r30)
-#ifdef CONFIG_64BIT
-	ldo	FRAME_SIZE(%r30), %r30
-	b,l	sys_rt_sigsuspend,%r2
-	ldo	-16(%r30),%r29		/* Reference param save area */
-#else
-	bl	sys_rt_sigsuspend,%r2
-	ldo	FRAME_SIZE(%r30), %r30
-#endif
-
-	ldo	-FRAME_SIZE(%r30), %r30
-	LDREG	-RP_OFFSET(%r30), %r2
-
-	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
-	ldo	TASK_REGS(%r1),%r1
-	reg_restore %r1
-
-	bv	%r0(%r2)
-	nop
-
-	.export syscall_exit
-syscall_exit:
-
+ENTRY(syscall_exit)
 	/* NOTE: HP-UX syscalls also come through here
 	 * after hpux_syscall_exit fixes up return
 	 * values. */
@@ -2119,9 +2080,35 @@ syscall_check_resched:
 	LDREG	TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19	/* long */
 	bb,<,n	%r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
 
+	.import do_signal,code
 syscall_check_sig:
-	LDREG	TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19    /* get ti flags */
-	bb,<,n	%r19, 31-TIF_SIGPENDING, syscall_do_signal /* forward */
+	LDREG	TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
+	ldi	(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r26
+	and,COND(<>)	%r19, %r26, %r0
+	b,n	syscall_restore	/* skip past if we've nothing to do */
+
+syscall_do_signal:
+	/* Save callee-save registers (for sigcontext).
+	 * FIXME: After this point the process structure should be
+	 * consistent with all the relevant state of the process
+	 * before the syscall.  We need to verify this.
+	 */
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+	ldo	TASK_REGS(%r1), %r26		/* struct pt_regs *regs */
+	reg_save %r26
+
+#ifdef CONFIG_64BIT
+	ldo	-16(%r30),%r29			/* Reference param save area */
+#endif
+
+	BL	do_notify_resume,%r2
+	ldi	1, %r25				/* long in_syscall = 1 */
+
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+	ldo	TASK_REGS(%r1), %r20		/* reload pt_regs */
+	reg_restore %r20
+
+	b,n     syscall_check_sig
 
 syscall_restore:
 	/* Are we being ptraced? */
@@ -2259,31 +2246,10 @@ syscall_do_resched:
 #endif
 	b       syscall_check_bh  /* if resched, we start over again */
 	nop
+ENDPROC(syscall_exit)
 
-	.import do_signal,code
-syscall_do_signal:
-	/* Save callee-save registers (for sigcontext).
-	   FIXME: After this point the process structure should be
-	   consistent with all the relevant state of the process
-	   before the syscall.  We need to verify this. */
-	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 
-	ldo	TASK_REGS(%r1), %r25		/* struct pt_regs *regs */
-	reg_save %r25
-
-	ldi	1, %r24				/* unsigned long in_syscall */
-
-#ifdef CONFIG_64BIT
-	ldo	-16(%r30),%r29			/* Reference param save area */
-#endif
-	BL	do_signal,%r2
-	copy	%r0, %r26			/* sigset_t *oldset = NULL */
-
-	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
-	ldo	TASK_REGS(%r1), %r20		/* reload pt_regs */
-	reg_restore %r20
-
-	b,n     syscall_check_sig
 
+get_register:
 	/*
 	 * get_register is used by the non access tlb miss handlers to
 	 * copy the value of the general register specified in r8 into
@@ -2294,8 +2260,6 @@ syscall_do_signal:
 	 * a -1 in it, but that is OK, it just means that we will have
 	 * to use the slow path instead).
 	 */
-
-get_register:
 	blr     %r8,%r0
 	nop
 	bv      %r0(%r25)    /* r0 */
@@ -2363,13 +2327,13 @@ get_register:
 	bv      %r0(%r25)    /* r31 */
 	copy    %r31,%r1
 
+
+set_register:
 	/*
 	 * set_register is used by the non access tlb miss handlers to
 	 * copy the value of r1 into the general register specified in
 	 * r8.
 	 */
-
-set_register:
 	blr     %r8,%r0
 	nop
 	bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
@@ -2436,3 +2400,4 @@ set_register:
 	copy    %r1,%r30
 	bv      %r0(%r25)    /* r31 */
 	copy    %r1,%r31
+
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 9158b707c0dd..39dc835bf89e 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -74,7 +74,7 @@ static DEFINE_SPINLOCK(pdc_lock);
 static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
 static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #define WIDE_FIRMWARE 0x1
 #define NARROW_FIRMWARE 0x2
 
@@ -94,12 +94,12 @@ int parisc_narrow_firmware __read_mostly = 1;
  * when running a 64-bit kernel on such boxes (e.g. C200 or C360).
  */
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 long real64_call(unsigned long function, ...);
 #endif
 long real32_call(unsigned long function, ...);
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #   define MEM_PDC (unsigned long)(PAGE0->mem_pdc_hi) << 32 | PAGE0->mem_pdc
 #   define mem_pdc_call(args...) unlikely(parisc_narrow_firmware) ? real32_call(MEM_PDC, args) : real64_call(MEM_PDC, args)
 #else
@@ -117,7 +117,7 @@ long real32_call(unsigned long function, ...);
  */
 static unsigned long f_extend(unsigned long address)
 {
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	if(unlikely(parisc_narrow_firmware)) {
 		if((address & 0xff000000) == 0xf0000000)
 			return 0xf0f0f0f000000000UL | (u32)address;
@@ -139,7 +139,7 @@ static unsigned long f_extend(unsigned long address)
  */
 static void convert_to_wide(unsigned long *addr)
 {
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	int i;
 	unsigned int *p = (unsigned int *)addr;
 
@@ -158,7 +158,7 @@ static void convert_to_wide(unsigned long *addr)
  */
 void __init set_firmware_width(void)
 {
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	int retval;
 	unsigned long flags;
 
@@ -238,7 +238,7 @@ int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_inf
  * 
  * Must be correctly formatted or expect system crash
  */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 int pdc_pat_chassis_send_log(unsigned long state, unsigned long data)
 {
 	int retval = 0;
@@ -949,7 +949,7 @@ int pdc_tod_set(unsigned long sec, unsigned long usec)
 }
 EXPORT_SYMBOL(pdc_tod_set);
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
 		struct pdc_memory_table *tbl, unsigned long entries)
 {
@@ -965,7 +965,7 @@ int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
 
 	return retval;
 }
-#endif /* __LP64__ */
+#endif /* CONFIG_64BIT */
 
 /* FIXME: Is this pdc used?  I could not find type reference to ftc_bitmap
  * so I guessed at unsigned long.  Someone who knows what this does, can fix
@@ -1204,7 +1204,7 @@ int pdc_sti_call(unsigned long func, unsigned long flags,
 }
 EXPORT_SYMBOL(pdc_sti_call);
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 /**
  * pdc_pat_cell_get_number - Returns the cell number.
  * @cell_info: The return buffer.
@@ -1387,7 +1387,7 @@ int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val)
 
 	return retval;
 }
-#endif /* __LP64__ */
+#endif /* CONFIG_64BIT */
 
 
 /***************** 32-bit real-mode calls ***********/
@@ -1445,7 +1445,7 @@ long real32_call(unsigned long fn, ...)
 	return real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
 }
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 /***************** 64-bit real-mode calls ***********/
 
 struct wide_stack {
@@ -1496,5 +1496,5 @@ long real64_call(unsigned long fn, ...)
 	return real64_call_asm(&real64_stack.sp, &real64_stack.arg0, fn);
 }
 
-#endif /* __LP64__ */
+#endif /* CONFIG_64BIT */
 
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index eaad2328fea1..9676c486bb63 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -2,7 +2,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1999 by Helge Deller
+ * Copyright (C) 1999-2007 by Helge Deller <deller@gmx.de>
  * Copyright 1999 SuSE GmbH (Philipp Rumpf)
  * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
  * Copyright 2000 Hewlett Packard (Paul Bame, bame@puffin.external.hp.com)
@@ -19,16 +19,17 @@
 #include <asm/assembly.h>
 #include <asm/pgtable.h>
 
+#include <linux/linkage.h>
+
 	.level	LEVEL
 
 	.data
-
-	.export boot_args
-boot_args:
+ENTRY(boot_args)
 	.word 0 /* arg0 */
 	.word 0 /* arg1 */
 	.word 0 /* arg2 */
 	.word 0 /* arg3 */
+END(boot_args)
 
 	.text
 	.align	4
@@ -38,10 +39,9 @@ boot_args:
         .import fault_vector_11,code    /* IVA parisc 1.1 32 bit */
 	.import	$global$		/* forward declaration */
 #endif /*!CONFIG_64BIT*/
-	.export stext
 	.export _stext,data		/* Kernel want it this way! */
 _stext:
-stext:
+ENTRY(stext)
 	.proc
 	.callinfo
 
@@ -343,6 +343,9 @@ smp_slave_stext:
 
 	.procend
 #endif /* CONFIG_SMP */
+
+ENDPROC(stext)
+
 #ifndef CONFIG_64BIT
 	.data
 
diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S
index c412c0adc4a9..d8baa158d8a0 100644
--- a/arch/parisc/kernel/hpmc.S
+++ b/arch/parisc/kernel/hpmc.S
@@ -46,6 +46,8 @@
 #include <asm/assembly.h>
 #include <asm/pdc.h>
 
+#include <linux/linkage.h>
+
 	/*
 	 * stack for os_hpmc, the HPMC handler.
 	 * buffer for IODC procedures (for the HPMC handler).
@@ -69,17 +71,15 @@ hpmc_raddr:
 
 #define HPMC_PIM_DATA_SIZE 896 /* Enough to hold all architected 2.0 state */
 
-	.export hpmc_pim_data, data
 	.align 8
-hpmc_pim_data:
+ENTRY(hpmc_pim_data)
 	.block HPMC_PIM_DATA_SIZE
+END(hpmc_pim_data)
 
 	.text
 
-	.export os_hpmc, code
 	.import intr_save, code
-
-os_hpmc:
+ENTRY(os_hpmc)
 
 	/*
 	 * registers modified:
@@ -294,11 +294,9 @@ os_hpmc_6:
 
 	b .
 	nop
+ENDPROC(os_hpmc)
 
 	/* this label used to compute os_hpmc checksum */
-
-	.export os_hpmc_end, code
-
-os_hpmc_end:
+ENTRY(os_hpmc_end)
 
 	nop
diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
index 4e847ba53180..4845a6444633 100644
--- a/arch/parisc/kernel/inventory.c
+++ b/arch/parisc/kernel/inventory.c
@@ -47,7 +47,7 @@ void __init setup_pdc(void)
 	struct pdc_system_map_mod_info module_result;
 	struct pdc_module_path module_path;
 	struct pdc_model model;
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	struct pdc_pat_cell_num cell_info;
 #endif
 
@@ -73,7 +73,7 @@ void __init setup_pdc(void)
 	 * clearer message.
 	 */
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	status = pdc_pat_cell_get_number(&cell_info);
 	if (status == PDC_OK) {
 		pdc_type = PDC_TYPE_PAT;
@@ -152,7 +152,7 @@ static void __init pagezero_memconfig(void)
 	npmem_ranges = 1;
 }
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 
 /* All of the PDC PAT specific code is 64-bit only */
 
@@ -408,13 +408,13 @@ static void __init sprockets_memconfig(void)
 	}
 }
 
-#else   /* !__LP64__ */
+#else   /* !CONFIG_64BIT */
 
 #define pat_inventory() do { } while (0)
 #define pat_memconfig() do { } while (0)
 #define sprockets_memconfig() pagezero_memconfig()
 
-#endif	/* !__LP64__ */
+#endif	/* !CONFIG_64BIT */
 
 
 #ifndef CONFIG_PA20
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index b39c5b9aff46..e9d09b020e86 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -336,11 +336,7 @@ unsigned int txn_alloc_data(unsigned int virt_irq)
 
 static inline int eirr_to_irq(unsigned long eirr)
 {
-#ifdef CONFIG_64BIT
-	int bit = fls64(eirr);
-#else
-	int bit = fls(eirr);
-#endif
+	int bit = fls_long(eirr);
 	return (BITS_PER_LONG - bit) + TIMER_IRQ;
 }
 
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index f50b982b0834..fdacdd4341c9 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -46,6 +46,7 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/bug.h>
 
 #include <asm/unwind.h>
 
@@ -96,7 +97,7 @@ static inline int in_local_section(struct module *me, void *loc, void *dot)
 }
 
 
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
 struct got_entry {
 	Elf32_Addr addr;
 };
@@ -176,7 +177,7 @@ void *module_alloc(unsigned long size)
 	return vmalloc(size);
 }
 
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
 static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
 {
 	return 0;
@@ -319,7 +320,7 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
 	return 0;
 }
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
 {
 	unsigned int i;
@@ -342,9 +343,9 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
 	       value);
 	return i * sizeof(struct got_entry);
 }
-#endif /* __LP64__ */
+#endif /* CONFIG_64BIT */
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
 {
 	Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
@@ -368,7 +369,7 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value)
 	fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
 	return (Elf_Addr)fdesc;
 }
-#endif /* __LP64__ */
+#endif /* CONFIG_64BIT */
 
 enum elf_stub_type {
 	ELF_STUB_GOT,
@@ -394,7 +395,7 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
 			i * sizeof(struct stub_entry);
 	}
 
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
 /* for 32-bit the stub looks like this:
  * 	ldil L'XXX,%r1
  * 	be,n R'XXX(%sr4,%r1)
@@ -472,7 +473,7 @@ int apply_relocate(Elf_Shdr *sechdrs,
 	return -ENOEXEC;
 }
 
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
 int apply_relocate_add(Elf_Shdr *sechdrs,
 		       const char *strtab,
 		       unsigned int symindex,
@@ -822,7 +823,8 @@ int module_finalize(const Elf_Ehdr *hdr,
 	       me->name, strtab, symhdr);
 
 	if(me->arch.got_count > MAX_GOTS) {
-		printk(KERN_ERR "%s: Global Offset Table overflow (used %ld, allowed %d\n", me->name, me->arch.got_count, MAX_GOTS);
+		printk(KERN_ERR "%s: Global Offset Table overflow (used %ld, allowed %d)\n",
+				me->name, me->arch.got_count, MAX_GOTS);
 		return -EINVAL;
 	}
 	
@@ -850,10 +852,11 @@ int module_finalize(const Elf_Ehdr *hdr,
 	nsyms = newptr - (Elf_Sym *)symhdr->sh_addr;
 	DEBUGP("NEW num_symtab %lu\n", nsyms);
 	symhdr->sh_size = nsyms * sizeof(Elf_Sym);
-	return 0;
+	return module_bug_finalize(hdr, sechdrs, me);
 }
 
 void module_arch_cleanup(struct module *mod)
 {
 	deregister_unwind_table(mod);
+	module_bug_cleanup(mod);
 }
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index e81c9937d10a..90b240878520 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -27,31 +27,21 @@
  */
 
 #ifdef CONFIG_64BIT
-#define ADDIB	addib,*
-#define CMPB	cmpb,*
-#define ANDCM	andcm,*
-
 	.level	2.0w
 #else
-#define ADDIB	addib,
-#define CMPB	cmpb,
-#define ANDCM	andcm
-
 	.level	2.0
 #endif
 
-
 #include <asm/psw.h>
 #include <asm/assembly.h>
 #include <asm/pgtable.h>
 #include <asm/cache.h>
+#include <linux/linkage.h>
 
 	.text
 	.align	128
 
-	.export flush_tlb_all_local,code
-
-flush_tlb_all_local:
+ENTRY(flush_tlb_all_local)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -200,11 +190,11 @@ fdtdone:
 
 	.exit
 	.procend
+ENDPROC(flush_tlb_all_local)
 
-	.export flush_instruction_cache_local,code
 	.import cache_info,data
 
-flush_instruction_cache_local:
+ENTRY(flush_instruction_cache_local)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -241,11 +231,11 @@ fisync:
 	.exit
 
 	.procend
+ENDPROC(flush_instruction_cache_local)
 
-	.export flush_data_cache_local, code
-	.import cache_info, data
 
-flush_data_cache_local:
+	.import cache_info, data
+ENTRY(flush_data_cache_local)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -283,11 +273,11 @@ fdsync:
 	.exit
 
 	.procend
+ENDPROC(flush_data_cache_local)
 
-	.export copy_user_page_asm,code
 	.align	16
 
-copy_user_page_asm:
+ENTRY(copy_user_page_asm)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -409,6 +399,7 @@ copy_user_page_asm:
 	.exit
 
 	.procend
+ENDPROC(copy_user_page_asm)
 
 /*
  * NOTE: Code in clear_user_page has a hard coded dependency on the
@@ -446,9 +437,7 @@ copy_user_page_asm:
 	 * lobby for such a change.
 	 */
 
-	.export copy_user_page_asm,code
-
-copy_user_page_asm:
+ENTRY(copy_user_page_asm)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -534,11 +523,10 @@ copy_user_page_asm:
 	.exit
 
 	.procend
+ENDPROC(copy_user_page_asm)
 #endif
 
-	.export __clear_user_page_asm,code
-
-__clear_user_page_asm:
+ENTRY(__clear_user_page_asm)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -618,10 +606,9 @@ __clear_user_page_asm:
 	.exit
 
 	.procend
+ENDPROC(__clear_user_page_asm)
 
-	.export flush_kernel_dcache_page_asm
-
-flush_kernel_dcache_page_asm:
+ENTRY(flush_kernel_dcache_page_asm)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -662,10 +649,9 @@ flush_kernel_dcache_page_asm:
 	.exit
 
 	.procend
+ENDPROC(flush_kernel_dcache_page_asm)
 	
-	.export flush_user_dcache_page
-
-flush_user_dcache_page:
+ENTRY(flush_user_dcache_page)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -706,10 +692,9 @@ flush_user_dcache_page:
 	.exit
 
 	.procend
+ENDPROC(flush_user_dcache_page)
 
-	.export flush_user_icache_page
-
-flush_user_icache_page:
+ENTRY(flush_user_icache_page)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -750,11 +735,10 @@ flush_user_icache_page:
 	.exit
 
 	.procend
+ENDPROC(flush_user_icache_page)
 
 
-	.export purge_kernel_dcache_page
-
-purge_kernel_dcache_page:
+ENTRY(purge_kernel_dcache_page)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -794,15 +778,14 @@ purge_kernel_dcache_page:
 	.exit
 
 	.procend
+ENDPROC(purge_kernel_dcache_page)
 
 #if 0
 	/* Currently not used, but it still is a possible alternate
 	 * solution.
 	 */
 
-	.export flush_alias_page
-
-flush_alias_page:
+ENTRY(flush_alias_page)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -882,10 +865,9 @@ flush_user_dcache_range_asm:
 	.exit
 
 	.procend
+ENDPROC(flush_alias_page)
 
-	.export flush_kernel_dcache_range_asm
-
-flush_kernel_dcache_range_asm:
+ENTRY(flush_kernel_dcache_range_asm)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -905,10 +887,9 @@ flush_kernel_dcache_range_asm:
 	.exit
 
 	.procend
+ENDPROC(flush_kernel_dcache_range_asm)
 
-	.export flush_user_icache_range_asm
-
-flush_user_icache_range_asm:
+ENTRY(flush_user_icache_range_asm)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -927,10 +908,9 @@ flush_user_icache_range_asm:
 	.exit
 
 	.procend
+ENDPROC(flush_user_icache_range_asm)
 
-	.export flush_kernel_icache_page
-
-flush_kernel_icache_page:
+ENTRY(flush_kernel_icache_page)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -971,10 +951,9 @@ flush_kernel_icache_page:
 	.exit
 
 	.procend
+ENDPROC(flush_kernel_icache_page)
 
-	.export flush_kernel_icache_range_asm
-
-flush_kernel_icache_range_asm:
+ENTRY(flush_kernel_icache_range_asm)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -992,14 +971,13 @@ flush_kernel_icache_range_asm:
 	nop
 	.exit
 	.procend
+ENDPROC(flush_kernel_icache_range_asm)
 
 	/* align should cover use of rfi in disable_sr_hashing_asm and
 	 * srdis_done.
 	 */
 	.align	256
-	.export disable_sr_hashing_asm,code
-
-disable_sr_hashing_asm:
+ENTRY(disable_sr_hashing_asm)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -1088,5 +1066,6 @@ srdis_done:
 	.exit
 
 	.procend
+ENDPROC(disable_sr_hashing_asm)
 
 	.end
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index 8f6a0b312f7a..7aca704e96f0 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -7,7 +7,7 @@
  *    Copyright (C) 2001-2003 Grant Grundler <grundler with parisc-linux.org>
  *    Copyright (C) 2002-2003 Matthew Wilcox <willy at parisc-linux.org>
  *    Copyright (C) 2002 Randolph Chung <tausq at parisc-linux.org>
- *    Copyright (C) 2002-2003 Helge Deller <deller with parisc-linux.org>
+ *    Copyright (C) 2002-2007 Helge Deller <deller with parisc-linux.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
@@ -38,7 +38,7 @@ EXPORT_SYMBOL(__cmpxchg_u32);
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(__atomic_hash);
 #endif
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 EXPORT_SYMBOL(__xchg64);
 EXPORT_SYMBOL(__cmpxchg_u64);
 #endif
@@ -58,7 +58,7 @@ EXPORT_SYMBOL(fixup_get_user_skip_2);
 EXPORT_SYMBOL(fixup_put_user_skip_1);
 EXPORT_SYMBOL(fixup_put_user_skip_2);
 
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
 /* Needed so insmod can set dp value */
 extern int $global$;
 EXPORT_SYMBOL($global$);
@@ -135,7 +135,7 @@ EXPORT_SYMBOL(__muldi3);
 asmlinkage void * __canonicalize_funcptr_for_compare(void *);
 EXPORT_SYMBOL(__canonicalize_funcptr_for_compare);
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 extern void __divdi3(void);
 extern void __udivdi3(void);
 extern void __umoddi3(void);
@@ -147,7 +147,7 @@ EXPORT_SYMBOL(__umoddi3);
 EXPORT_SYMBOL(__moddi3);
 #endif
 
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
 extern void $$dyncall(void);
 EXPORT_SYMBOL($$dyncall);
 #endif
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index a6caf1073085..0c3aecb85a5c 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -342,7 +342,7 @@ pcxl_dma_init(void)
 	pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL,
 					    get_order(pcxl_res_size));
 	memset(pcxl_res_map, 0, pcxl_res_size);
-	proc_gsc_root = proc_mkdir("gsc", 0);
+	proc_gsc_root = proc_mkdir("gsc", NULL);
 	if (!proc_gsc_root)
     		printk(KERN_WARNING
 			"pcxl_dma_init: Unable to create gsc /proc dir entry\n");
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index 199887a61c76..563df0072dee 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -200,8 +200,8 @@ static void
 pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
 {
 	if (!r->parent) {
-		printk(KERN_EMERG "PCI: resource not parented! [%lx-%lx]\n",
-				r->start, r->end);
+		printk(KERN_EMERG "PCI: resource not parented! [%p-%p]\n",
+				(void*) r->start, (void*) r->end);
 		r->parent = hba_res;
 
 		/* reverse link is harder *sigh*  */
diff --git a/arch/parisc/kernel/perf_asm.S b/arch/parisc/kernel/perf_asm.S
index 5e7bb90e7e08..43874ca3ed67 100644
--- a/arch/parisc/kernel/perf_asm.S
+++ b/arch/parisc/kernel/perf_asm.S
@@ -20,6 +20,7 @@
  */
 
 #include <asm/assembly.h>
+#include <linux/linkage.h>
 
 #ifdef CONFIG_64BIT
 	.level		2.0w
@@ -41,10 +42,8 @@
 ; starting/stopping the coprocessor with the pmenb/pmdis.
 ;
 	.text
-	.align 32
 
-	.export perf_intrigue_enable_perf_counters,code
-perf_intrigue_enable_perf_counters:
+ENTRY(perf_intrigue_enable_perf_counters)
 	.proc
 	.callinfo  frame=0,NO_CALLS
 	.entry
@@ -69,9 +68,9 @@ perf_intrigue_enable_perf_counters:
 	nop
 	.exit
 	.procend
+ENDPROC(perf_intrigue_enable_perf_counters)
 
-	.export perf_intrigue_disable_perf_counters,code
-perf_intrigue_disable_perf_counters:
+ENTRY(perf_intrigue_disable_perf_counters)
 	.proc
 	.callinfo  frame=0,NO_CALLS
 	.entry
@@ -86,6 +85,7 @@ perf_intrigue_disable_perf_counters:
 	mtctl   %r26,ccr                 ; turn off performance coprocessor
 	.exit
 	.procend
+ENDPROC(perf_intrigue_disable_perf_counters)
 
 ;***********************************************************************
 ;*
@@ -117,8 +117,7 @@ perf_intrigue_disable_perf_counters:
 ;*
 ;***********************************************************************
 
-	.export perf_rdr_shift_in_W,code
-perf_rdr_shift_in_W:
+ENTRY(perf_rdr_shift_in_W)
 	.proc
 	.callinfo frame=0,NO_CALLS
 	.entry
@@ -550,6 +549,7 @@ perf_rdr_shift_in_W_leave:
 	.exit
 	MTDIAG_2	(24)			; restore DR2
 	.procend
+ENDPROC(perf_rdr_shift_in_W)
 
 
 ;***********************************************************************
@@ -575,8 +575,7 @@ perf_rdr_shift_in_W_leave:
 ;*
 ;***********************************************************************
 
-	.export perf_rdr_shift_out_W,code
-perf_rdr_shift_out_W:
+ENTRY(perf_rdr_shift_out_W)
 	.proc
 	.callinfo frame=0,NO_CALLS
 	.entry
@@ -983,6 +982,7 @@ perf_rdr_shift_out_W_leave:
 	.exit
 	MTDIAG_2	(23)			; restore DR2
 	.procend
+ENDPROC(perf_rdr_shift_out_W)
 
 
 ;***********************************************************************
@@ -1012,8 +1012,7 @@ perf_rdr_shift_out_W_leave:
 ;*
 ;***********************************************************************
 
-	.export perf_rdr_shift_in_U,code
-perf_rdr_shift_in_U:
+ENTRY(perf_rdr_shift_in_U)
 	.proc
 	.callinfo frame=0,NO_CALLS
 	.entry
@@ -1343,6 +1342,7 @@ perf_rdr_shift_in_U_leave:
 	.exit
 	MTDIAG_2	(24)			; restore DR2
 	.procend
+ENDPROC(perf_rdr_shift_in_U)
 
 ;***********************************************************************
 ;*
@@ -1369,8 +1369,7 @@ perf_rdr_shift_in_U_leave:
 ;*
 ;***********************************************************************
 
-	.export perf_rdr_shift_out_U,code
-perf_rdr_shift_out_U:
+ENTRY(perf_rdr_shift_out_U)
 	.proc
 	.callinfo frame=0,NO_CALLS
 	.entry
@@ -1687,4 +1686,5 @@ perf_rdr_shift_out_U_leave:
 	.exit
 	MTDIAG_2	(23)			; restore DR2
 	.procend
+ENDPROC(perf_rdr_shift_out_U)
 
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 2f9f9dfa66f7..0dd3847f494c 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -13,7 +13,7 @@
  *    Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
  *    Copyright (C) 2001 Alan Modra <amodra at parisc-linux.org>
  *    Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
- *    Copyright (C) 2001-2002 Helge Deller <deller at parisc-linux.org>
+ *    Copyright (C) 2001-2007 Helge Deller <deller at parisc-linux.org>
  *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
  *
  *
@@ -303,7 +303,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
 		 * Copy function and argument to be called from
 		 * ret_from_kernel_thread.
 		 */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 		cregs->gr[27] = pregs->gr[27];
 #endif
 		cregs->gr[26] = pregs->gr[26];
@@ -355,8 +355,8 @@ asmlinkage int sys_execve(struct pt_regs *regs)
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
 		goto out;
-	error = do_execve(filename, (char __user **) regs->gr[25],
-		(char __user **) regs->gr[24], regs);
+	error = do_execve(filename, (char __user * __user *) regs->gr[25],
+		(char __user * __user *) regs->gr[24], regs);
 	if (error == 0) {
 		task_lock(current);
 		current->ptrace &= ~PT_DTRACE;
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index fb81e5687e7c..7c056dcebf55 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -93,7 +93,7 @@ static int __init processor_probe(struct parisc_device *dev)
 	cpuid = boot_cpu_data.cpu_count;
 	txn_addr = dev->hpa.start;	/* for legacy PDC */
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	if (is_pdc_pat()) {
 		ulong status;
 		unsigned long bytecnt;
@@ -153,8 +153,6 @@ static int __init processor_probe(struct parisc_device *dev)
 	p->cpuid = cpuid;	/* save CPU id */
 	p->txn_addr = txn_addr;	/* save CPU IRQ address */
 #ifdef CONFIG_SMP
-	spin_lock_init(&p->lock);
-
 	/*
 	** FIXME: review if any other initialization is clobbered
 	**	for boot_cpu by the above memset().
@@ -311,11 +309,11 @@ int __init init_per_cpu(int cpunum)
 	} else {
 		printk(KERN_WARNING  "WARNING: No FP CoProcessor?!"
 			" (coproc_cfg.ccr_functional == 0x%lx, expected 0xc0)\n"
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 			"Halting Machine - FP required\n"
 #endif
 			, coproc_cfg.ccr_functional);
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 		mdelay(100);	/* previous chars get pushed to console */
 		panic("FP CoProc not reported");
 #endif
@@ -339,9 +337,6 @@ show_cpuinfo (struct seq_file *m, void *v)
 #ifdef CONFIG_SMP
 		if (0 == cpu_data[n].hpa)
 			continue;
-#ifdef ENTRY_SYS_CPUS
-#error iCOD support wants to show CPU state here
-#endif
 #endif
 		seq_printf(m, "processor\t: %d\n"
 				"cpu family\t: PA-RISC %s\n",
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 3f28de974556..0d0d617b6f21 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -36,7 +36,7 @@
 #define DBG(x...)
 #endif
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 
 /* This function is needed to translate 32 bit pt_regs offsets in to
  * 64 bit pt_regs offsets.  For example, a 32 bit gdb under a 64 bit kernel
@@ -90,7 +90,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 	case PTRACE_PEEKDATA: {
 		int copied;
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 		if (__is_compat_task(child)) {
 			unsigned int tmp;
 
@@ -122,7 +122,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 	case PTRACE_POKETEXT: /* write the word at location addr. */
 	case PTRACE_POKEDATA:
 		ret = 0;
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 		if (__is_compat_task(child)) {
 			unsigned int tmp = (unsigned int)data;
 			DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
@@ -145,7 +145,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 	   processes, the kernel saves all regs on a syscall. */
 	case PTRACE_PEEKUSR: {
 		ret = -EIO;
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 		if (__is_compat_task(child)) {
 			unsigned int tmp;
 
@@ -204,7 +204,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 			ret = 0;
 			goto out_tsk;
 		}
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 		if (__is_compat_task(child)) {
 			if (addr & (sizeof(int)-1))
 				goto out_tsk;
diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S
index 789061f6ceb4..7a92695d95a6 100644
--- a/arch/parisc/kernel/real2.S
+++ b/arch/parisc/kernel/real2.S
@@ -11,6 +11,8 @@
 #include <asm/psw.h>
 #include <asm/assembly.h>
 
+#include <linux/linkage.h>
+
 	.section	.bss
 	.export real_stack
 	.export real32_stack
@@ -39,8 +41,6 @@ save_cr_end:
 
 	.text
 
-	.export real32_call_asm
-
 	/* unsigned long real32_call_asm(unsigned int *sp,
 	 *		unsigned int *arg0p,
 	 *		unsigned int iodc_fn)
@@ -49,7 +49,7 @@ save_cr_end:
 	 *	iodc_fn is the IODC function to call
 	 */
 
-real32_call_asm:
+ENTRY(real32_call_asm)
 	STREG	%rp, -RP_OFFSET(%sp)	/* save RP */
 #ifdef CONFIG_64BIT
 	callee_save
@@ -107,6 +107,7 @@ ric_ret:
 	LDREG	-RP_OFFSET(%sp), %rp	/* restore RP */
 	bv	0(%rp)
 	nop
+ENDPROC(real32_call_asm)
 
 
 #  define PUSH_CR(r, where) mfctl r, %r1 ! STREG,ma %r1, REG_SZ(where)
@@ -218,7 +219,6 @@ rfi_r2v_1:
 /************************ 64-bit real-mode calls ***********************/
 /* This is only usable in wide kernels right now and will probably stay so */
 	.text
-	.export real64_call_asm
 	/* unsigned long real64_call_asm(unsigned long *sp,
 	 *		unsigned long *arg0p,
 	 *		unsigned long fn)
@@ -226,7 +226,7 @@ rfi_r2v_1:
 	 *	arg0p points to where saved arg values may be found
 	 *	iodc_fn is the IODC function to call
 	 */
-real64_call_asm:
+ENTRY(real64_call_asm)
 	std	%rp, -0x10(%sp)		/* save RP */
 	std	%sp, -8(%arg0)		/* save SP on real-mode stack */
 	copy	%arg0, %sp		/* adopt the real-mode SP */
@@ -272,19 +272,21 @@ r64_ret:
 	ldd	-0x10(%sp), %rp		/* restore RP */
 	bv	0(%rp)
 	nop
+ENDPROC(real64_call_asm)
 
 #endif
 
-	.export __canonicalize_funcptr_for_compare
 	.text
 	/* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html
 	**	GCC 3.3 and later has a new function in libgcc.a for
 	**	comparing function pointers.
 	*/
-__canonicalize_funcptr_for_compare:
+ENTRY(__canonicalize_funcptr_for_compare)
 #ifdef CONFIG_64BIT
 	bve (%r2)
 #else
 	bv %r0(%r2)
 #endif
 	copy %r26,%r28
+ENDPROC(__canonicalize_funcptr_for_compare)
+
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index 74b3686dd1e0..bd2116e03f34 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -120,13 +120,13 @@ extern void collect_boot_cpu_data(void);
 
 void __init setup_arch(char **cmdline_p)
 {
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	extern int parisc_narrow_firmware;
 #endif
 
 	init_per_cpu(smp_processor_id());	/* Set Modes & Enable FP */
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	printk(KERN_INFO "The 64-bit Kernel has started...\n");
 #else
 	printk(KERN_INFO "The 32-bit Kernel has started...\n");
@@ -134,7 +134,7 @@ void __init setup_arch(char **cmdline_p)
 
 	pdc_console_init();
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	if(parisc_narrow_firmware) {
 		printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");
 	}
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index ee6653edeb7a..9784e405f849 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -59,58 +59,13 @@
  * this. */
 #define A(__x)	((unsigned long)(__x))
 
-int do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall);
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #include "sys32.h"
 #endif
 
-asmlinkage int
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
-{
-	sigset_t saveset, newset;
-#ifdef __LP64__
-	compat_sigset_t newset32;
-
-	if (is_compat_task()) {
-		/* XXX: Don't preclude handling different sized sigset_t's.  */
-		if (sigsetsize != sizeof(compat_sigset_t))
-			return -EINVAL;
-		if (copy_from_user(&newset32, (compat_sigset_t __user *)unewset, sizeof(newset32)))
-			return -EFAULT;
-		sigset_32to64(&newset,&newset32);
-		
-	} else 
-#endif
-	{
-		/* XXX: Don't preclude handling different sized sigset_t's.  */
-		if (sigsetsize != sizeof(sigset_t))
-			return -EINVAL;
-	
-		if (copy_from_user(&newset, unewset, sizeof(newset)))
-			return -EFAULT;
-	}
-
-	sigdelsetmask(&newset, ~_BLOCKABLE);
-
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	regs->gr[28] = -EINTR;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, regs, 1))
-			return -EINTR;
-	}
-}
-
 /*
  * Do a signal return - restore sigcontext.
  */
@@ -148,7 +103,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 	sigset_t set;
 	unsigned long usp = (regs->gr[30] & ~(0x01UL));
 	unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	compat_sigset_t compat_set;
 	struct compat_rt_sigframe __user * compat_frame;
 	
@@ -162,7 +117,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 		(usp - sigframe_size);
 	DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	compat_frame = (struct compat_rt_sigframe __user *)frame;
 	
 	if (is_compat_task()) {
@@ -184,7 +139,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 	spin_unlock_irq(&current->sighand->siglock);
 
 	/* Good thing we saved the old gr[30], eh? */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	if (is_compat_task()) {
 		DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
 				&compat_frame->uc.uc_mcontext);
@@ -296,7 +251,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	unsigned long rp, usp;
 	unsigned long haddr, sigframe_size;
 	int err = 0;
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	compat_int_t compat_val;
 	struct compat_rt_sigframe __user * compat_frame;
 	compat_sigset_t compat_set;
@@ -310,7 +265,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	DBG(1,"setup_rt_frame: frame %p info %p\n", frame, info);
 
 	
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 
 	compat_frame = (struct compat_rt_sigframe __user *)frame;
 	
@@ -390,7 +345,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
 	haddr = A(ka->sa.sa_handler);
 	/* The sa_handler may be a pointer to a function descriptor */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	if (is_compat_task()) {
 #endif
 		if (haddr & PA_PLABEL_FDESC) {
@@ -405,7 +360,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 			haddr = fdesc.addr;
 			regs->gr[19] = fdesc.gp;
 		}
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	} else {
 		Elf64_Fdesc fdesc;
 		Elf64_Fdesc __user *ufdesc = (Elf64_Fdesc __user *)A(haddr & ~3);
@@ -425,19 +380,19 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	/* The syscall return path will create IAOQ values from r31.
 	 */
 	sigframe_size = PARISC_RT_SIGFRAME_SIZE;
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	if (is_compat_task())
 		sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
 #endif
 	if (in_syscall) {
 		regs->gr[31] = haddr;
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 		if (!test_thread_flag(TIF_32BIT))
 			sigframe_size |= 1;
 #endif
 	} else {
 		unsigned long psw = USER_PSW;
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 		if (!test_thread_flag(TIF_32BIT))
 			psw |= PSW_W;
 #endif
@@ -462,7 +417,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	regs->gr[2]  = rp;                /* userland return pointer */
 	regs->gr[26] = sig;               /* signal number */
 	
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	if (is_compat_task()) {
 		regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
 		regs->gr[24] = A(&compat_frame->uc);   /* ucontext pointer */
@@ -516,6 +471,97 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 	return 1;
 }
 
+static inline void
+syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
+{
+	/* Check the return code */
+	switch (regs->gr[28]) {
+	case -ERESTART_RESTARTBLOCK:
+		current_thread_info()->restart_block.fn =
+			do_no_restart_syscall;
+	case -ERESTARTNOHAND:
+		DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
+		regs->gr[28] = -EINTR;
+		break;
+
+	case -ERESTARTSYS:
+		if (!(ka->sa.sa_flags & SA_RESTART)) {
+			DBG(1,"ERESTARTSYS: putting -EINTR\n");
+			regs->gr[28] = -EINTR;
+			break;
+		}
+		/* fallthrough */
+	case -ERESTARTNOINTR:
+		/* A syscall is just a branch, so all
+		 * we have to do is fiddle the return pointer.
+		 */
+		regs->gr[31] -= 8; /* delayed branching */
+		/* Preserve original r28. */
+		regs->gr[28] = regs->orig_r28;
+		break;
+	}
+}
+
+static inline void
+insert_restart_trampoline(struct pt_regs *regs)
+{
+	switch(regs->gr[28]) {
+	case -ERESTART_RESTARTBLOCK: {
+		/* Restart the system call - no handlers present */
+		unsigned int *usp = (unsigned int *)regs->gr[30];
+
+		/* Setup a trampoline to restart the syscall
+		 * with __NR_restart_syscall
+		 *
+		 *  0: <return address (orig r31)>
+		 *  4: <2nd half for 64-bit>
+		 *  8: ldw 0(%sp), %r31
+		 * 12: be 0x100(%sr2, %r0)
+		 * 16: ldi __NR_restart_syscall, %r20
+		 */
+#ifdef CONFIG_64BIT
+		put_user(regs->gr[31] >> 32, &usp[0]);
+		put_user(regs->gr[31] & 0xffffffff, &usp[1]);
+		put_user(0x0fc010df, &usp[2]);
+#else
+		put_user(regs->gr[31], &usp[0]);
+		put_user(0x0fc0109f, &usp[2]);
+#endif
+		put_user(0xe0008200, &usp[3]);
+		put_user(0x34140000, &usp[4]);
+
+		/* Stack is 64-byte aligned, and we only need
+		 * to flush 1 cache line.
+		 * Flushing one cacheline is cheap.
+		 * "sync" on bigger (> 4 way) boxes is not.
+		 */
+		flush_icache_range(regs->gr[30], regs->gr[30] + 4);
+
+		regs->gr[31] = regs->gr[30] + 8;
+		/* Preserve original r28. */
+		regs->gr[28] = regs->orig_r28;
+
+		return;
+	}
+	case -ERESTARTNOHAND:
+	case -ERESTARTSYS:
+	case -ERESTARTNOINTR: {
+		/* Hooray for delayed branching.  We don't
+		 * have to restore %r20 (the system call
+		 * number) because it gets loaded in the delay
+		 * slot of the branch external instruction.
+		 */
+		regs->gr[31] -= 8;
+		/* Preserve original r28. */
+		regs->gr[28] = regs->orig_r28;
+
+		return;
+	}
+	default:
+		break;
+	}
+}
+
 /*
  * Note that 'init' is a special process: it doesn't get signals it doesn't
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
@@ -527,13 +573,13 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
  * registers).  As noted below, the syscall number gets restored for
  * us due to the magic of delayed branching.
  */
-
-asmlinkage int
-do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall)
+asmlinkage void
+do_signal(struct pt_regs *regs, long in_syscall)
 {
 	siginfo_t info;
 	struct k_sigaction ka;
 	int signr;
+	sigset_t *oldset;
 
 	DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n",
 	       oldset, regs, regs->sr[7], in_syscall);
@@ -543,7 +589,9 @@ do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall)
 	   we would be called in that case, but for some reason we
 	   are. */
 
-	if (!oldset)
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
 		oldset = &current->blocked;
 
 	DBG(1,"do_signal: oldset %08lx / %08lx\n", 
@@ -560,98 +608,41 @@ do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall)
 		  break;
 		
 		/* Restart a system call if necessary. */
-		if (in_syscall) {
-			/* Check the return code */
-			switch (regs->gr[28]) {
-		        case -ERESTART_RESTARTBLOCK:
-				current_thread_info()->restart_block.fn = do_no_restart_syscall;
-			case -ERESTARTNOHAND:
-				DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
-				regs->gr[28] = -EINTR;
-				break;
-
-			case -ERESTARTSYS:
-				if (!(ka.sa.sa_flags & SA_RESTART)) {
-					DBG(1,"ERESTARTSYS: putting -EINTR\n");
-					regs->gr[28] = -EINTR;
-					break;
-				}
-			/* fallthrough */
-			case -ERESTARTNOINTR:
-				/* A syscall is just a branch, so all
-				   we have to do is fiddle the return pointer. */
-				regs->gr[31] -= 8; /* delayed branching */
-				/* Preserve original r28. */
-				regs->gr[28] = regs->orig_r28;
-				break;
-			}
-		}
+		if (in_syscall)
+			syscall_restart(regs, &ka);
+
 		/* Whee!  Actually deliver the signal.  If the
 		   delivery failed, we need to continue to iterate in
 		   this loop so we can deliver the SIGSEGV... */
-		if (handle_signal(signr, &info, &ka, oldset, regs, in_syscall)) {
+		if (handle_signal(signr, &info, &ka, oldset,
+				  regs, in_syscall)) {
 			DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
 				regs->gr[28]);
-			return 1;
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
+			return;
 		}
 	}
 	/* end of while(1) looping forever if we can't force a signal */
 
 	/* Did we come from a system call? */
-	if (in_syscall) {
-		/* Restart the system call - no handlers present */
-		if (regs->gr[28] == -ERESTART_RESTARTBLOCK) {
-			unsigned int *usp = (unsigned int *)regs->gr[30];
-
-			/* Setup a trampoline to restart the syscall
-			 * with __NR_restart_syscall
-			 *
-			 *  0: <return address (orig r31)>
-			 *  4: <2nd half for 64-bit>
-			 *  8: ldw 0(%sp), %r31
-			 * 12: be 0x100(%sr2, %r0)
-			 * 16: ldi __NR_restart_syscall, %r20
-			 */
-#ifndef __LP64__
-			put_user(regs->gr[31], &usp[0]);
-			put_user(0x0fc0109f, &usp[2]);
-#else
-			put_user(regs->gr[31] >> 32, &usp[0]);
-			put_user(regs->gr[31] & 0xffffffff, &usp[1]);
-			put_user(0x0fc010df, &usp[2]);
-#endif
-			put_user(0xe0008200, &usp[3]);
-			put_user(0x34140000, &usp[4]);
-
-			/* Stack is 64-byte aligned, and we only need
-			 * to flush 1 cache line.
-			 * Flushing one cacheline is cheap.
-			 * "sync" on bigger (> 4 way) boxes is not.
-			 */
-			asm("fdc %%r0(%%sr3, %0)\n"
-			    "sync\n"
-			    "fic %%r0(%%sr3, %0)\n"
-			    "sync\n"
-			    : : "r"(regs->gr[30]));
-
-			regs->gr[31] = regs->gr[30] + 8;
-			/* Preserve original r28. */
-			regs->gr[28] = regs->orig_r28;
-		} else if (regs->gr[28] == -ERESTARTNOHAND ||
-		           regs->gr[28] == -ERESTARTSYS ||
-		           regs->gr[28] == -ERESTARTNOINTR) {
-			/* Hooray for delayed branching.  We don't
-                           have to restore %r20 (the system call
-                           number) because it gets loaded in the delay
-                           slot of the branch external instruction. */
-			regs->gr[31] -= 8;
-			/* Preserve original r28. */
-			regs->gr[28] = regs->orig_r28;
-		}
-	}
+	if (in_syscall)
+		insert_restart_trampoline(regs);
 	
 	DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 
 		regs->gr[28]);
 
-	return 0;
+	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
+
+	return;
+}
+
+void do_notify_resume(struct pt_regs *regs, long in_syscall)
+{
+	if (test_thread_flag(TIF_SIGPENDING) ||
+	    test_thread_flag(TIF_RESTORE_SIGMASK))
+		do_signal(regs, in_syscall);
 }
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
index a6b4231cafa1..1c1a37f73053 100644
--- a/arch/parisc/kernel/signal32.c
+++ b/arch/parisc/kernel/signal32.c
@@ -1,6 +1,8 @@
 /*    Signal support for 32-bit kernel builds
  *
  *    Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2006 Kyle McMartin <kyle at parisc-linux.org>
+ *
  *    Code was mostly borrowed from kernel/signal.c.
  *    See kernel/signal.c for additional Copyrights.
  *
@@ -401,7 +403,7 @@ setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __
 int
 copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
 {
-	unsigned long tmp;
+	compat_uptr_t addr;
 	int err;
 
 	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
@@ -424,8 +426,8 @@ copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
 			err |= __get_user(to->si_uid, &from->si_uid);
 			break;
 		      case __SI_FAULT >> 16:
-			err |= __get_user(tmp, &from->si_addr);
-			to->si_addr = (void __user *) tmp;
+			err |= __get_user(addr, &from->si_addr);
+			to->si_addr = compat_ptr(addr);
 			break;
 		      case __SI_POLL >> 16:
 			err |= __get_user(to->si_band, &from->si_band);
@@ -445,7 +447,8 @@ copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
 int
 copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
 {
-	unsigned int addr;
+	compat_uptr_t addr;
+	compat_int_t val;
 	int err;
 
 	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
@@ -474,8 +477,8 @@ copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
 			err |= __put_user(from->si_uid, &to->si_uid);
 			break;
 		case __SI_FAULT >> 16:
-			/* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */
-			err |= __put_user(from->_sifields._pad[0], &to->si_addr);
+			addr = ptr_to_compat(from->si_addr);
+			err |= __put_user(addr, &to->si_addr);
 			break;
 		case __SI_POLL >> 16:
 			err |= __put_user(from->si_band, &to->si_band);
@@ -484,17 +487,36 @@ copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
 		case __SI_TIMER >> 16:
 			err |= __put_user(from->si_tid, &to->si_tid);
 			err |= __put_user(from->si_overrun, &to->si_overrun);
-			addr = (unsigned long) from->si_ptr;
-			err |= __put_user(addr, &to->si_ptr);
+			val = (compat_int_t)from->si_int;
+			err |= __put_user(val, &to->si_int);
 			break;
 		case __SI_RT >> 16:	/* Not generated by the kernel as of now.  */
 		case __SI_MESGQ >> 16:
 			err |= __put_user(from->si_uid, &to->si_uid);
 			err |= __put_user(from->si_pid, &to->si_pid);
-			addr = (unsigned long) from->si_ptr;
-			err |= __put_user(addr, &to->si_ptr);
+			val = (compat_int_t)from->si_int;
+			err |= __put_user(val, &to->si_int);
 			break;
 		}
 	}
 	return err;
 }
+
+asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
+	struct compat_siginfo __user *uinfo)
+{
+	siginfo_t info;
+
+	if (copy_siginfo_from_user32(&info, uinfo))
+		return -EFAULT;
+
+	/* Not even root can pretend to send signals from the kernel.
+	   Nor can they impersonate a kill(), which adds source info.  */
+	if (info.si_code >= 0)
+		return -EPERM;
+	info.si_signo = sig;
+
+	/* POSIX.1b doesn't mention process groups.  */
+	return kill_proc_info(sig, &info, pid);
+}
+
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 12cc019307ad..6ba9257fdb7f 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -16,9 +16,6 @@
 **      the Free Software Foundation; either version 2 of the License, or
 **      (at your option) any later version.
 */
-#undef ENTRY_SYS_CPUS	/* syscall support for iCOD-like functionality */
-
-
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
@@ -51,7 +48,15 @@
 #include <asm/unistd.h>
 #include <asm/cacheflush.h>
 
-#define kDEBUG 0
+#undef DEBUG_SMP
+#ifdef DEBUG_SMP
+static int smp_debug_lvl = 0;
+#define smp_debug(lvl, printargs...)		\
+		if (lvl >= smp_debug_lvl)	\
+			printk(printargs);
+#else
+#define smp_debug(lvl, ...)
+#endif /* DEBUG_SMP */
 
 DEFINE_SPINLOCK(smp_lock);
 
@@ -76,6 +81,7 @@ cpumask_t cpu_possible_map __read_mostly = CPU_MASK_ALL;	/* Bitmap of Present CP
 EXPORT_SYMBOL(cpu_online_map);
 EXPORT_SYMBOL(cpu_possible_map);
 
+DEFINE_PER_CPU(spinlock_t, ipi_lock) = SPIN_LOCK_UNLOCKED;
 
 struct smp_call_struct {
 	void (*func) (void *info);
@@ -107,13 +113,6 @@ enum ipi_message_type {
 static void
 ipi_init(int cpuid)
 {
-
-	/* If CPU is present ... */
-#ifdef ENTRY_SYS_CPUS
-	/* *and* running (not stopped) ... */
-#error iCOD support wants state checked here.
-#endif
-
 #error verify IRQ_OFFSET(IPI_IRQ) is ipi_interrupt() in new IRQ region
 
 	if(cpu_online(cpuid) )
@@ -133,23 +132,12 @@ ipi_init(int cpuid)
 static void
 halt_processor(void) 
 {
-#ifdef ENTRY_SYS_CPUS
-#error halt_processor() needs rework
-/*
-** o migrate I/O interrupts off this CPU.
-** o leave IPI enabled - __cli() will disable IPI.
-** o leave CPU in online map - just change the state
-*/
-	cpu_data[this_cpu].state = STATE_STOPPED;
-	mark_bh(IPI_BH);
-#else
 	/* REVISIT : redirect I/O Interrupts to another CPU? */
 	/* REVISIT : does PM *know* this CPU isn't available? */
 	cpu_clear(smp_processor_id(), cpu_online_map);
 	local_irq_disable();
 	for (;;)
 		;
-#endif
 }
 
 
@@ -167,10 +155,11 @@ ipi_interrupt(int irq, void *dev_id)
 	mb();	/* Order interrupt and bit testing. */
 
 	for (;;) {
-		spin_lock_irqsave(&(p->lock),flags);
+		spinlock_t *lock = &per_cpu(ipi_lock, this_cpu);
+		spin_lock_irqsave(lock, flags);
 		ops = p->pending_ipi;
 		p->pending_ipi = 0;
-		spin_unlock_irqrestore(&(p->lock),flags);
+		spin_unlock_irqrestore(lock, flags);
 
 		mb(); /* Order bit clearing and data access. */
 
@@ -184,15 +173,11 @@ ipi_interrupt(int irq, void *dev_id)
 
 			switch (which) {
 			case IPI_NOP:
-#if (kDEBUG>=100)
-				printk(KERN_DEBUG "CPU%d IPI_NOP\n",this_cpu);
-#endif /* kDEBUG */
+				smp_debug(100, KERN_DEBUG "CPU%d IPI_NOP\n", this_cpu);
 				break;
 				
 			case IPI_RESCHEDULE:
-#if (kDEBUG>=100)
-				printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu);
-#endif /* kDEBUG */
+				smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu);
 				/*
 				 * Reschedule callback.  Everything to be
 				 * done is done by the interrupt return path.
@@ -200,9 +185,7 @@ ipi_interrupt(int irq, void *dev_id)
 				break;
 
 			case IPI_CALL_FUNC:
-#if (kDEBUG>=100)
-				printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu);
-#endif /* kDEBUG */
+				smp_debug(100, KERN_DEBUG "CPU%d IPI_CALL_FUNC\n", this_cpu);
 				{
 					volatile struct smp_call_struct *data;
 					void (*func)(void *info);
@@ -233,28 +216,16 @@ ipi_interrupt(int irq, void *dev_id)
 				break;
 
 			case IPI_CPU_START:
-#if (kDEBUG>=100)
-				printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu);
-#endif /* kDEBUG */
-#ifdef ENTRY_SYS_CPUS
-				p->state = STATE_RUNNING;
-#endif
+				smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_START\n", this_cpu);
 				break;
 
 			case IPI_CPU_STOP:
-#if (kDEBUG>=100)
-				printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu);
-#endif /* kDEBUG */
-#ifdef ENTRY_SYS_CPUS
-#else
+				smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_STOP\n", this_cpu);
 				halt_processor();
-#endif
 				break;
 
 			case IPI_CPU_TEST:
-#if (kDEBUG>=100)
-				printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu);
-#endif /* kDEBUG */
+				smp_debug(100, KERN_DEBUG "CPU%d is alive!\n", this_cpu);
 				break;
 
 			default:
@@ -275,12 +246,13 @@ static inline void
 ipi_send(int cpu, enum ipi_message_type op)
 {
 	struct cpuinfo_parisc *p = &cpu_data[cpu];
+	spinlock_t *lock = &per_cpu(ipi_lock, cpu);
 	unsigned long flags;
 
-	spin_lock_irqsave(&(p->lock),flags);
+	spin_lock_irqsave(lock, flags);
 	p->pending_ipi |= 1 << op;
 	gsc_writel(IPI_IRQ - CPU_IRQ_BASE, cpu_data[cpu].hpa);
-	spin_unlock_irqrestore(&(p->lock),flags);
+	spin_unlock_irqrestore(lock, flags);
 }
 
 
@@ -560,13 +532,8 @@ int __init smp_boot_one_cpu(int cpuid)
 
 alive:
 	/* Remember the Slave data */
-#if (kDEBUG>=100)
-	printk(KERN_DEBUG "SMP: CPU:%d came alive after %ld _us\n",
+	smp_debug(100, KERN_DEBUG "SMP: CPU:%d came alive after %ld _us\n",
 		cpuid, timeout * 100);
-#endif /* kDEBUG */
-#ifdef ENTRY_SYS_CPUS
-	cpu_data[cpuid].state = STATE_RUNNING;
-#endif
 	return 0;
 }
 
@@ -574,10 +541,6 @@ void __devinit smp_prepare_boot_cpu(void)
 {
 	int bootstrap_processor=cpu_data[0].cpuid;	/* CPU ID of BSP */
 
-#ifdef ENTRY_SYS_CPUS
-	cpu_data[0].state = STATE_RUNNING;
-#endif
-
 	/* Setup BSP mappings */
 	printk("SMP: bootstrap CPU ID is %d\n",bootstrap_processor);
 
@@ -616,101 +579,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	return cpu_online(cpu) ? 0 : -ENOSYS;
 }
 
-
-
-#ifdef ENTRY_SYS_CPUS
-/* Code goes along with:
-**    entry.s:        ENTRY_NAME(sys_cpus)   / * 215, for cpu stat * /
-*/
-int sys_cpus(int argc, char **argv)
-{
-	int i,j=0;
-	extern int current_pid(int cpu);
-
-	if( argc > 2 ) {
-		printk("sys_cpus:Only one argument supported\n");
-		return (-1);
-	}
-	if ( argc == 1 ){
-	
-#ifdef DUMP_MORE_STATE
-		for_each_online_cpu(i) {
-			int cpus_per_line = 4;
-
-			if (j++ % cpus_per_line)
-				printk(" %3d",i);
-			else
-				printk("\n %3d",i);
-		}
-		printk("\n"); 
-#else
-	    	printk("\n 0\n"); 
-#endif
-	} else if((argc==2) && !(strcmp(argv[1],"-l"))) {
-		printk("\nCPUSTATE  TASK CPUNUM CPUID HARDCPU(HPA)\n");
-#ifdef DUMP_MORE_STATE
-		for_each_online_cpu(i) {
-			if (cpu_data[i].cpuid != NO_PROC_ID) {
-				switch(cpu_data[i].state) {
-					case STATE_RENDEZVOUS:
-						printk("RENDEZVS ");
-						break;
-					case STATE_RUNNING:
-						printk((current_pid(i)!=0) ? "RUNNING  " : "IDLING   ");
-						break;
-					case STATE_STOPPED:
-						printk("STOPPED  ");
-						break;
-					case STATE_HALTED:
-						printk("HALTED   ");
-						break;
-					default:
-						printk("%08x?", cpu_data[i].state);
-						break;
-				}
-				if(cpu_online(i)) {
-					printk(" %4d",current_pid(i));
-				}	
-				printk(" %6d",cpu_number_map(i));
-				printk(" %5d",i);
-				printk(" 0x%lx\n",cpu_data[i].hpa);
-			}	
-		}
-#else
-		printk("\n%s  %4d      0     0 --------",
-			(current->pid)?"RUNNING ": "IDLING  ",current->pid); 
-#endif
-	} else if ((argc==2) && !(strcmp(argv[1],"-s"))) { 
-#ifdef DUMP_MORE_STATE
-     		printk("\nCPUSTATE   CPUID\n");
-		for_each_online_cpu(i) {
-			if (cpu_data[i].cpuid != NO_PROC_ID) {
-				switch(cpu_data[i].state) {
-					case STATE_RENDEZVOUS:
-						printk("RENDEZVS");break;
-					case STATE_RUNNING:
-						printk((current_pid(i)!=0) ? "RUNNING " : "IDLING");
-						break;
-					case STATE_STOPPED:
-						printk("STOPPED ");break;
-					case STATE_HALTED:
-						printk("HALTED  ");break;
-					default:
-				}
-				printk("  %5d\n",i);
-			}	
-		}
-#else
-		printk("\n%s    CPU0",(current->pid==0)?"RUNNING ":"IDLING  "); 
-#endif
-	} else {
-		printk("sys_cpus:Unknown request\n");
-		return (-1);
-	}
-	return 0;
-}
-#endif /* ENTRY_SYS_CPUS */
-
 #ifdef CONFIG_PROC_FS
 int __init
 setup_profiling_timer(unsigned int multiplier)
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index a05800429304..10859f53e94f 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -12,27 +12,23 @@
 #include <asm/errno.h>
 #include <asm/psw.h>
 #include <asm/thread_info.h>
-
 #include <asm/assembly.h>
 #include <asm/processor.h>
 
+#include <linux/linkage.h>
+
 	/* We fill the empty parts of the gateway page with
  	 * something that will kill the kernel or a
  	 * userspace application.
 	 */
 #define KILL_INSN	break	0,0
 
-#ifdef CONFIG_64BIT
-	.level          2.0w
-#else
-	.level		1.1
-#endif
+	.level          LEVEL
 
 	.text
 
 	.import syscall_exit,code
 	.import syscall_exit_rfi,code
-	.export linux_gateway_page
 
 	/* Linux gateway page is aliased to virtual page 0 in the kernel
 	 * address space. Since it is a gateway page it cannot be
@@ -43,7 +39,7 @@
 	 */
 
 	.align ASM_PAGE_SIZE
-linux_gateway_page:
+ENTRY(linux_gateway_page)
 
         /* ADDRESS 0x00 to 0xb0 = 176 bytes / 4 bytes per insn = 44 insns */
 	.rept 44
@@ -595,73 +591,43 @@ cas_action:
 	   the other for the store. Either return -EFAULT.
 	   Each of the entries must be relocated. */
 	.section __ex_table,"aw"
-#ifdef CONFIG_64BIT
-	/* Pad the address calculation */
-	.word	0,(2b - linux_gateway_page)
-	.word	0,(3b - linux_gateway_page)
-#else
-	.word	(2b - linux_gateway_page)
-	.word	(3b - linux_gateway_page)
-#endif
+	ASM_ULONG_INSN (1b - linux_gateway_page), (3b - linux_gateway_page)
+	ASM_ULONG_INSN (2b - linux_gateway_page), (3b - linux_gateway_page)
 	.previous
 
-	.section __ex_table,"aw"
-#ifdef CONFIG_64BIT
-	/* Pad the address calculation */
-	.word	0,(1b - linux_gateway_page)
-	.word	0,(3b - linux_gateway_page)
-#else
-	.word	(1b - linux_gateway_page)
-	.word	(3b - linux_gateway_page)
-#endif
-	.previous
-
-end_compare_and_swap:
 
 	/* Make sure nothing else is placed on this page */
 	.align ASM_PAGE_SIZE
-	.export end_linux_gateway_page
-end_linux_gateway_page:
+END(linux_gateway_page)
+ENTRY(end_linux_gateway_page)
 
 	/* Relocate symbols assuming linux_gateway_page is mapped
 	   to virtual address 0x0 */
-#ifdef CONFIG_64BIT
-	/* FIXME: The code will always be on the gateay page
-		  and thus it will be on the first 4k, the
-		  assembler seems to think that the final
-		  subtraction result is only a word in
-		  length, so we pad the value.
-	*/
-#define LWS_ENTRY(_name_) .word 0,(lws_##_name_ - linux_gateway_page)
-#else
-#define LWS_ENTRY(_name_) .word  (lws_##_name_ - linux_gateway_page)
-#endif
+
+#define LWS_ENTRY(_name_) ASM_ULONG_INSN (lws_##_name_ - linux_gateway_page)
 
 	.section .rodata,"a"
 
 	.align ASM_PAGE_SIZE
 	/* Light-weight-syscall table */
 	/* Start of lws table. */
-	.export lws_table
-.Llws_table:
-lws_table:
+ENTRY(lws_table)
 	LWS_ENTRY(compare_and_swap32)	/* 0 - ELF32 Atomic compare and swap */
 	LWS_ENTRY(compare_and_swap64)	/* 1 - ELF64 Atomic compare and swap */
+END(lws_table)
 	/* End of lws table */
 
 	.align ASM_PAGE_SIZE
-	.export sys_call_table
-.Lsys_call_table:
-sys_call_table:
+ENTRY(sys_call_table)
 #include "syscall_table.S"
+END(sys_call_table)
 
 #ifdef CONFIG_64BIT
 	.align ASM_PAGE_SIZE
-	.export sys_call_table64
-.Lsys_call_table64:
-sys_call_table64:
+ENTRY(sys_call_table64)
 #define SYSCALL_TABLE_64BIT
 #include "syscall_table.S"
+END(sys_call_table64)
 #endif
 
 #ifdef CONFIG_SMP
@@ -671,9 +637,7 @@ sys_call_table64:
 	*/
 	.section .data
 	.align 4096
-	.export lws_lock_start
-.Llws_lock_start:
-lws_lock_start:
+ENTRY(lws_lock_start)
 	/* lws locks */
 	.align 16
 	.rept 16
@@ -683,6 +647,7 @@ lws_lock_start:
 	.word 0
 	.word 0
 	.endr
+END(lws_lock_start)
 	.previous
 #endif
 /* CONFIG_SMP for lws_lock_start */
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index be8eb9a0d24a..8bf87e5d9c37 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -10,7 +10,7 @@
  *    Copyright (C) 2000 Grant Grundler <grundler at parisc-linux.org>
  *    Copyright (C) 2001 Richard Hirst <rhirst with parisc-linux.org>
  *    Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
- *    Copyright (C) 2001 Helge Deller <deller at parisc-linux.org>
+ *    Copyright (C) 2001-2007 Helge Deller <deller at parisc-linux.org>
  *    Copyright (C) 2000-2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
  *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
  *    Copyright (C) 2005-2006 Kyle McMartin <kyle at parisc-linux.org>
@@ -282,8 +282,8 @@
 	 * to worry about faulting trying to copy in a larger 64-bit
 	 * struct from a 32-bit user-space app.
 	 */
-	ENTRY_SAME(rt_sigqueueinfo)
-	ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */
+	ENTRY_COMP(rt_sigqueueinfo)
+	ENTRY_COMP(rt_sigsuspend)
 	ENTRY_SAME(chown)		/* 180 */
 	/* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */
 	ENTRY_COMP(setsockopt)
@@ -377,9 +377,9 @@
 	ENTRY_SAME(inotify_init)
 	ENTRY_SAME(inotify_add_watch)	/* 270 */
 	ENTRY_SAME(inotify_rm_watch)
-	ENTRY_SAME(ni_syscall)		/* 271 ENTRY_COMP(pselect6) */
-	ENTRY_SAME(ni_syscall)		/* 272 ENTRY_COMP(ppoll) */
 	ENTRY_SAME(migrate_pages)
+	ENTRY_COMP(pselect6)
+	ENTRY_COMP(ppoll)
 	ENTRY_COMP(openat)		/* 275 */
 	ENTRY_SAME(mkdirat)
 	ENTRY_SAME(mknodat)
@@ -399,5 +399,11 @@
 	ENTRY_SAME(splice)
 	ENTRY_OURS(sync_file_range)
 	ENTRY_SAME(tee)
+	ENTRY_COMP(vmsplice)
+	ENTRY_COMP(move_pages)		/* 295 */
+	ENTRY_SAME(getcpu)
+	ENTRY_SAME(epoll_pwait)
+	ENTRY_COMP(statfs64)
+	ENTRY_COMP(fstatfs64)
 	/* Nothing yet */
 
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 5f1b51af06a9..d1db8e518654 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/profile.h>
+#include <linux/clocksource.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -98,7 +99,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
 	 * cycles after the IT fires. But it's arbitrary how much time passes
 	 * before we call it "late". I've picked one second.
 	 */
-	if (ticks_elapsed > HZ) {
+	if (unlikely(ticks_elapsed > HZ)) {
 		/* Scenario 3: very long delay?  bad in any case */
 		printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!"
 			" cycles %lX rem %lX "
@@ -147,10 +148,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
 		write_sequnlock(&xtime_lock);
 	}
 
-	/* check soft power switch status */
-	if (cpu == 0 && !atomic_read(&power_tasklet.count))
-		tasklet_schedule(&power_tasklet);
-
 	return IRQ_HANDLED;
 }
 
@@ -172,121 +169,41 @@ unsigned long profile_pc(struct pt_regs *regs)
 EXPORT_SYMBOL(profile_pc);
 
 
-/*
- * Return the number of micro-seconds that elapsed since the last
- * update to wall time (aka xtime).  The xtime_lock
- * must be at least read-locked when calling this routine.
- */
-static inline unsigned long gettimeoffset (void)
-{
-#ifndef CONFIG_SMP
-	/*
-	 * FIXME: This won't work on smp because jiffies are updated by cpu 0.
-	 *    Once parisc-linux learns the cr16 difference between processors,
-	 *    this could be made to work.
-	 */
-	unsigned long now;
-	unsigned long prev_tick;
-	unsigned long next_tick;
-	unsigned long elapsed_cycles;
-	unsigned long usec;
-	unsigned long cpuid = smp_processor_id();
-	unsigned long cpt = clocktick;
-
-	next_tick = cpu_data[cpuid].it_value;
-	now = mfctl(16);	/* Read the hardware interval timer.  */
+/* clock source code */
 
-	prev_tick = next_tick - cpt;
+static cycle_t read_cr16(void)
+{
+	return get_cycles();
+}
 
-	/* Assume Scenario 1: "now" is later than prev_tick.  */
-	elapsed_cycles = now - prev_tick;
+static int cr16_update_callback(void);
 
-/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */
-#if HZ == 1000
-	if (elapsed_cycles > (cpt << 10) )
-#elif HZ == 250
-	if (elapsed_cycles > (cpt << 8) )
-#elif HZ == 100
-	if (elapsed_cycles > (cpt << 7) )
-#else
-#warn WTF is HZ set to anyway?
-	if (elapsed_cycles > (HZ * cpt) )
-#endif
-	{
-		/* Scenario 3: clock ticks are missing. */
-		printk (KERN_CRIT "gettimeoffset(CPU %ld): missing %ld ticks!"
-			" cycles %lX prev/now/next %lX/%lX/%lX  clock %lX\n",
-			cpuid, elapsed_cycles / cpt,
-			elapsed_cycles, prev_tick, now, next_tick, cpt);
-	}
+static struct clocksource clocksource_cr16 = {
+	.name			= "cr16",
+	.rating			= 300,
+	.read			= read_cr16,
+	.mask			= CLOCKSOURCE_MASK(BITS_PER_LONG),
+	.mult			= 0, /* to be set */
+	.shift			= 22,
+	.update_callback	= cr16_update_callback,
+	.is_continuous		= 1,
+};
 
-	/* FIXME: Can we improve the precision? Not with PAGE0. */
-	usec = (elapsed_cycles * 10000) / PAGE0->mem_10msec;
-	return usec;
-#else
-	return 0;
-#endif
-}
-
-void
-do_gettimeofday (struct timeval *tv)
+static int cr16_update_callback(void)
 {
-	unsigned long flags, seq, usec, sec;
-
-	/* Hold xtime_lock and adjust timeval.  */
-	do {
-		seq = read_seqbegin_irqsave(&xtime_lock, flags);
-		usec = gettimeoffset();
-		sec = xtime.tv_sec;
-		usec += (xtime.tv_nsec / 1000);
-	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-	/* Move adjusted usec's into sec's.  */
-	while (usec >= USEC_PER_SEC) {
-		usec -= USEC_PER_SEC;
-		++sec;
+	int change = 0;
+
+	/* since the cr16 cycle counters are not syncronized across CPUs,
+	   we'll check if we should switch to a safe clocksource: */
+	if (clocksource_cr16.rating != 0 && num_online_cpus() > 1) {
+		clocksource_cr16.rating = 0;
+		clocksource_reselect();
+		change = 1;
 	}
 
-	/* Return adjusted result.  */
-	tv->tv_sec = sec;
-	tv->tv_usec = usec;
+	return change;
 }
 
-EXPORT_SYMBOL(do_gettimeofday);
-
-int
-do_settimeofday (struct timespec *tv)
-{
-	time_t wtm_sec, sec = tv->tv_sec;
-	long wtm_nsec, nsec = tv->tv_nsec;
-
-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-		return -EINVAL;
-
-	write_seqlock_irq(&xtime_lock);
-	{
-		/*
-		 * This is revolting. We need to set "xtime"
-		 * correctly. However, the value in this location is
-		 * the value at the most recent update of wall time.
-		 * Discover what correction gettimeofday would have
-		 * done, and then undo it!
-		 */
-		nsec -= gettimeoffset() * 1000;
-
-		wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-		wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
-		set_normalized_timespec(&xtime, sec, nsec);
-		set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
-		ntp_clear();
-	}
-	write_sequnlock_irq(&xtime_lock);
-	clock_was_set();
-	return 0;
-}
-EXPORT_SYMBOL(do_settimeofday);
 
 void __init start_cpu_itimer(void)
 {
@@ -301,11 +218,18 @@ void __init start_cpu_itimer(void)
 void __init time_init(void)
 {
 	static struct pdc_tod tod_data;
+	unsigned long current_cr16_khz;
 
 	clocktick = (100 * PAGE0->mem_10msec) / HZ;
 
 	start_cpu_itimer();	/* get CPU 0 started */
 
+	/* register at clocksource framework */
+	current_cr16_khz = PAGE0->mem_10msec/10;  /* kHz */
+	clocksource_cr16.mult = clocksource_khz2mult(current_cr16_khz,
+						clocksource_cr16.shift);
+	clocksource_register(&clocksource_cr16);
+
 	if (pdc_tod_read(&tod_data) == 0) {
 		unsigned long flags;
 
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 65cd6ca32fed..55bc1471967d 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/console.h>
 #include <linux/kallsyms.h>
+#include <linux/bug.h>
 
 #include <asm/assembly.h>
 #include <asm/system.h>
@@ -39,6 +40,8 @@
 #include <asm/pdc.h>
 #include <asm/pdc_chassis.h>
 #include <asm/unwind.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
 
 #include "../math-emu/math-emu.h"	/* for handle_fpe() */
 
@@ -49,7 +52,7 @@
 DEFINE_SPINLOCK(pa_dbit_lock);
 #endif
 
-int printbinary(char *buf, unsigned long x, int nbits)
+static int printbinary(char *buf, unsigned long x, int nbits)
 {
 	unsigned long mask = 1UL << (nbits - 1);
 	while (mask != 0) {
@@ -61,7 +64,7 @@ int printbinary(char *buf, unsigned long x, int nbits)
 	return nbits;
 }
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #define RFMT "%016lx"
 #else
 #define RFMT "%08lx"
@@ -160,13 +163,13 @@ static void do_show_stack(struct unwind_frame_info *info)
 {
 	int i = 1;
 
-	printk("Backtrace:\n");
+	printk(KERN_CRIT "Backtrace:\n");
 	while (i <= 16) {
 		if (unwind_once(info) < 0 || info->ip == 0)
 			break;
 
 		if (__kernel_text_address(info->ip)) {
-			printk(" [<" RFMT ">] ", info->ip);
+			printk("%s [<" RFMT ">] ", (i&0x3)==1 ? KERN_CRIT : "", info->ip);
 #ifdef CONFIG_KALLSYMS
 			print_symbol("%s\n", info->ip);
 #else
@@ -185,18 +188,19 @@ void show_stack(struct task_struct *task, unsigned long *s)
 
 	if (!task) {
 		unsigned long sp;
-		struct pt_regs *r;
 
 HERE:
 		asm volatile ("copy %%r30, %0" : "=r"(sp));
-		r = kzalloc(sizeof(struct pt_regs), GFP_KERNEL);
-		if (!r)
-			return;
-		r->iaoq[0] = (unsigned long)&&HERE;
-		r->gr[2] = (unsigned long)__builtin_return_address(0);
-		r->gr[30] = sp;
-		unwind_frame_init(&info, current, r);
-		kfree(r);
+		{
+			struct pt_regs r;
+
+			memset(&r, 0, sizeof(struct pt_regs));
+			r.iaoq[0] = (unsigned long)&&HERE;
+			r.gr[2] = (unsigned long)__builtin_return_address(0);
+			r.gr[30] = sp;
+
+			unwind_frame_init(&info, current, &r);
+		}
 	} else {
 		unwind_frame_init_from_blocked_task(&info, task);
 	}
@@ -204,6 +208,11 @@ HERE:
 	do_show_stack(&info);
 }
 
+int is_valid_bugaddr(unsigned long iaoq)
+{
+	return 1;
+}
+
 void die_if_kernel(char *str, struct pt_regs *regs, long err)
 {
 	if (user_mode(regs)) {
@@ -222,15 +231,15 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
 	oops_in_progress = 1;
 
 	/* Amuse the user in a SPARC fashion */
-	printk(
-"      _______________________________ \n"
-"     < Your System ate a SPARC! Gah! >\n"
-"      ------------------------------- \n"
-"             \\   ^__^\n"
-"              \\  (xx)\\_______\n"
-"                 (__)\\       )\\/\\\n"
-"                  U  ||----w |\n"
-"                     ||     ||\n");
+	if (err) printk(
+KERN_CRIT "      _______________________________ \n"
+KERN_CRIT "     < Your System ate a SPARC! Gah! >\n"
+KERN_CRIT "      ------------------------------- \n"
+KERN_CRIT "             \\   ^__^\n"
+KERN_CRIT "              \\  (xx)\\_______\n"
+KERN_CRIT "                 (__)\\       )\\/\\\n"
+KERN_CRIT "                  U  ||----w |\n"
+KERN_CRIT "                     ||     ||\n");
 	
 	/* unlock the pdc lock if necessary */
 	pdc_emergency_unlock();
@@ -242,9 +251,20 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
 	if (!console_drivers)
 		pdc_console_restart();
 	
-	printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
-		current->comm, current->pid, str, err);
+	if (err)
+		printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
+			current->comm, current->pid, str, err);
+
+	/* Wot's wrong wif bein' racy? */
+	if (current->thread.flags & PARISC_KERNEL_DEATH) {
+		printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__);
+		local_irq_enable();
+		while (1);
+	}
+	current->thread.flags |= PARISC_KERNEL_DEATH;
+
 	show_regs(regs);
+	dump_stack();
 
 	if (in_interrupt())
 		panic("Fatal exception in interrupt");
@@ -255,14 +275,6 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
 		panic("Fatal exception");
 	}
 
-	/* Wot's wrong wif bein' racy? */
-	if (current->thread.flags & PARISC_KERNEL_DEATH) {
-		printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__);
-		local_irq_enable();
-		while (1);
-	}
-
-	current->thread.flags |= PARISC_KERNEL_DEATH;
 	do_exit(SIGSEGV);
 }
 
@@ -273,61 +285,45 @@ int syscall_ipi(int (*syscall) (struct pt_regs *), struct pt_regs *regs)
 
 /* gdb uses break 4,8 */
 #define GDB_BREAK_INSN 0x10004
-void handle_gdb_break(struct pt_regs *regs, int wot)
+static void handle_gdb_break(struct pt_regs *regs, int wot)
 {
 	struct siginfo si;
 
-	si.si_code = wot;
-	si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
 	si.si_signo = SIGTRAP;
 	si.si_errno = 0;
+	si.si_code = wot;
+	si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
 	force_sig_info(SIGTRAP, &si, current);
 }
 
-void handle_break(unsigned iir, struct pt_regs *regs)
+static void handle_break(struct pt_regs *regs)
 {
-	struct siginfo si;
-
-	switch(iir) {
-	case 0x00:
-#ifdef PRINT_USER_FAULTS
-		printk(KERN_DEBUG "break 0,0: pid=%d command='%s'\n",
-		       current->pid, current->comm);
-#endif
-		die_if_kernel("Breakpoint", regs, 0);
-#ifdef PRINT_USER_FAULTS
-		show_regs(regs);
-#endif
-		si.si_code = TRAP_BRKPT;
-		si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
-		si.si_signo = SIGTRAP;
-		force_sig_info(SIGTRAP, &si, current);
-		break;
-
-	case GDB_BREAK_INSN:
-		die_if_kernel("Breakpoint", regs, 0);
-		handle_gdb_break(regs, TRAP_BRKPT);
-		break;
+	unsigned iir = regs->iir;
+
+	if (unlikely(iir == PARISC_BUG_BREAK_INSN && !user_mode(regs))) {
+		/* check if a BUG() or WARN() trapped here.  */
+		enum bug_trap_type tt;
+		tt = report_bug(regs->iaoq[0] & ~3);
+		if (tt == BUG_TRAP_TYPE_WARN) {
+			regs->iaoq[0] += 4;
+			regs->iaoq[1] += 4;
+			return; /* return to next instruction when WARN_ON().  */
+		}
+		die_if_kernel("Unknown kernel breakpoint", regs,
+			(tt == BUG_TRAP_TYPE_NONE) ? 9 : 0);
+	}
 
-	default:
 #ifdef PRINT_USER_FAULTS
-		printk(KERN_DEBUG "break %#08x: pid=%d command='%s'\n",
-		       iir, current->pid, current->comm);
+	if (unlikely(iir != GDB_BREAK_INSN)) {
+		printk(KERN_DEBUG "break %d,%d: pid=%d command='%s'\n",
+			iir & 31, (iir>>13) & ((1<<13)-1),
+			current->pid, current->comm);
 		show_regs(regs);
-#endif
-		si.si_signo = SIGTRAP;
-		si.si_code = TRAP_BRKPT;
-		si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
-		force_sig_info(SIGTRAP, &si, current);
-		return;
 	}
-}
-
+#endif
 
-int handle_toc(void)
-{
-	printk(KERN_CRIT "TOC call.\n");
-	return 0;
+	/* send standard GDB signal */
+	handle_gdb_break(regs, TRAP_BRKPT);
 }
 
 static void default_trap(int code, struct pt_regs *regs)
@@ -336,7 +332,7 @@ static void default_trap(int code, struct pt_regs *regs)
 	show_regs(regs);
 }
 
-void (*cpu_lpmc) (int code, struct pt_regs *regs) = default_trap;
+void (*cpu_lpmc) (int code, struct pt_regs *regs) __read_mostly = default_trap;
 
 
 void transfer_pim_to_trap_frame(struct pt_regs *regs)
@@ -554,7 +550,8 @@ void handle_interruption(int code, struct pt_regs *regs)
 		/* Low-priority machine check */
 		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC);
 		
-		flush_all_caches();
+		flush_cache_all();
+		flush_tlb_all();
 		cpu_lpmc(5, regs);
 		return;
 
@@ -572,7 +569,7 @@ void handle_interruption(int code, struct pt_regs *regs)
 
 	case  9:
 		/* Break instruction trap */
-		handle_break(regs->iir,regs);
+		handle_break(regs);
 		return;
 	
 	case 10:
@@ -840,7 +837,7 @@ int __init check_ivt(void *iva)
 	return 0;
 }
 	
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
 extern const void fault_vector_11;
 #endif
 extern const void fault_vector_20;
@@ -852,7 +849,7 @@ void __init trap_init(void)
 	if (boot_cpu_data.cpu_type >= pcxu)
 		iva = (void *) &fault_vector_20;
 	else
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 		panic("Can't boot 64-bit OS on PA1.1 processor!");
 #else
 		iva = (void *) &fault_vector_11;
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index bd2230d6a2a6..347bb922e6d0 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -20,8 +20,11 @@
  *
  */
 
+#include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
 #include <asm/uaccess.h>
 
 /* #define DEBUG_UNALIGNED 1 */
@@ -32,7 +35,7 @@
 #define DPRINTF(fmt, args...)
 #endif
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #define RFMT "%016lx"
 #else
 #define RFMT "%08lx"
@@ -147,15 +150,8 @@ static int emulate_ldh(struct pt_regs *regs, int toreg)
 "4:	ldi	-2, %1\n"
 	FIXUP_BRANCH(3b)
 "	.previous\n"
-"	.section __ex_table,\"aw\"\n"
-#ifdef __LP64__
-"	.dword	1b,4b\n"
-"	.dword  2b,4b\n"
-#else
-"	.word	1b,4b\n"
-"	.word	2b,4b\n"
-#endif
-"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b, 4b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b, 4b)
 	: "=r" (val), "=r" (ret)
 	: "0" (val), "r" (saddr), "r" (regs->isr)
 	: "r20", FIXUP_BRANCH_CLOBBER );
@@ -192,15 +188,8 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop)
 "4:	ldi	-2, %1\n"
 	FIXUP_BRANCH(3b)
 "	.previous\n"
-"	.section __ex_table,\"aw\"\n"
-#ifdef __LP64__
-"	.dword	1b,4b\n"
-"	.dword  2b,4b\n"
-#else
-"	.word	1b,4b\n"
-"	.word	2b,4b\n"
-#endif
-"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b, 4b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b, 4b)
 	: "=r" (val), "=r" (ret)
 	: "0" (val), "r" (saddr), "r" (regs->isr)
 	: "r19", "r20", FIXUP_BRANCH_CLOBBER );
@@ -224,7 +213,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
 		regs->isr, regs->ior, toreg);
 #ifdef CONFIG_PA20
 
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
 	if (!flop)
 		return -1;
 #endif
@@ -243,15 +232,8 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
 "4:	ldi	-2, %1\n"
 	FIXUP_BRANCH(3b)
 "	.previous\n"
-"	.section __ex_table,\"aw\"\n"
-#ifdef __LP64__
-"	.dword	1b,4b\n"
-"	.dword  2b,4b\n"
-#else
-"	.word	1b,4b\n"
-"	.word	2b,4b\n"
-#endif
-"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,4b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,4b)
 	: "=r" (val), "=r" (ret)
 	: "0" (val), "r" (saddr), "r" (regs->isr)
 	: "r19", "r20", FIXUP_BRANCH_CLOBBER );
@@ -275,17 +257,9 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
 "5:	ldi	-2, %2\n"
 	FIXUP_BRANCH(4b)
 "	.previous\n"
-"	.section __ex_table,\"aw\"\n"
-#ifdef __LP64__
-"	.dword	1b,5b\n"
-"	.dword  2b,5b\n"
-"	.dword	3b,5b\n"
-#else
-"	.word	1b,5b\n"
-"	.word	2b,5b\n"
-"	.word	3b,5b\n"
-#endif
-"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,5b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,5b)
+	ASM_EXCEPTIONTABLE_ENTRY(3b,5b)
 	: "=r" (valh), "=r" (vall), "=r" (ret)
 	: "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr)
 	: "r19", "r20", FIXUP_BRANCH_CLOBBER );
@@ -325,15 +299,8 @@ static int emulate_sth(struct pt_regs *regs, int frreg)
 "4:	ldi	-2, %0\n"
 	FIXUP_BRANCH(3b)
 "	.previous\n"
-"	.section __ex_table,\"aw\"\n"
-#ifdef __LP64__
-"	.dword	1b,4b\n"
-"	.dword  2b,4b\n"
-#else
-"	.word	1b,4b\n"
-"	.word	2b,4b\n"
-#endif
-"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,4b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,4b)
 	: "=r" (ret)
 	: "r" (val), "r" (regs->ior), "r" (regs->isr)
 	: "r19", FIXUP_BRANCH_CLOBBER );
@@ -379,15 +346,8 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop)
 "4:	ldi	-2, %0\n"
 	FIXUP_BRANCH(3b)
 "	.previous\n"
-"	.section __ex_table,\"aw\"\n"
-#ifdef __LP64__
-"	.dword	1b,4b\n"
-"	.dword  2b,4b\n"
-#else
-"	.word	1b,4b\n"
-"	.word	2b,4b\n"
-#endif
-"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,4b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,4b)
 	: "=r" (ret)
 	: "r" (val), "r" (regs->ior), "r" (regs->isr)
 	: "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
@@ -410,7 +370,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
 		val,  regs->isr, regs->ior);
 
 #ifdef CONFIG_PA20
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
 	if (!flop)
 		return -1;
 #endif
@@ -436,19 +396,10 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
 "6:	ldi	-2, %0\n"
 	FIXUP_BRANCH(5b)
 "	.previous\n"
-"	.section __ex_table,\"aw\"\n"
-#ifdef __LP64__
-"	.dword	1b,6b\n"
-"	.dword  2b,6b\n"
-"	.dword	3b,6b\n"
-"	.dword  4b,6b\n"
-#else
-"	.word	1b,6b\n"
-"	.word	2b,6b\n"
-"	.word	3b,6b\n"
-"	.word	4b,6b\n"
-#endif
-"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,6b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,6b)
+	ASM_EXCEPTIONTABLE_ENTRY(3b,6b)
+	ASM_EXCEPTIONTABLE_ENTRY(4b,6b)
 	: "=r" (ret)
 	: "r" (val), "r" (regs->ior), "r" (regs->isr)
 	: "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
@@ -479,21 +430,11 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
 "7:	ldi	-2, %0\n"
 	FIXUP_BRANCH(6b)
 "	.previous\n"
-"	.section __ex_table,\"aw\"\n"
-#ifdef __LP64__
-"	.dword	1b,7b\n"
-"	.dword  2b,7b\n"
-"	.dword	3b,7b\n"
-"	.dword  4b,7b\n"
-"	.dword  5b,7b\n"
-#else
-"	.word	1b,7b\n"
-"	.word	2b,7b\n"
-"	.word	3b,7b\n"
-"	.word	4b,7b\n"
-"	.word  	5b,7b\n"
-#endif
-"	.previous\n"
+	ASM_EXCEPTIONTABLE_ENTRY(1b,7b)
+	ASM_EXCEPTIONTABLE_ENTRY(2b,7b)
+	ASM_EXCEPTIONTABLE_ENTRY(3b,7b)
+	ASM_EXCEPTIONTABLE_ENTRY(4b,7b)
+	ASM_EXCEPTIONTABLE_ENTRY(5b,7b)
 	: "=r" (ret)
 	: "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr)
 	: "r19", "r20", "r21", "r1", FIXUP_BRANCH_CLOBBER );
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index c10ab47d81fa..5f75b3e65986 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -10,6 +10,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/kallsyms.h>
 
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 3b78c2794c36..2a8253358c6c 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -68,6 +68,8 @@ SECTIONS
 
   RODATA
 
+  BUG_TABLE
+
   /* writeable */
   . = ALIGN(ASM_PAGE_SIZE);	/* Make sure this is page aligned so
   				   that we can properly leave these
diff --git a/arch/parisc/lib/bitops.c b/arch/parisc/lib/bitops.c
index f352666b5b2f..e3eb739fab19 100644
--- a/arch/parisc/lib/bitops.c
+++ b/arch/parisc/lib/bitops.c
@@ -17,7 +17,7 @@ raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
 };
 #endif
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 unsigned long __xchg64(unsigned long x, unsigned long *ptr)
 {
 	unsigned long temp, flags;
@@ -56,7 +56,7 @@ unsigned long __xchg8(char x, char *ptr)
 }
 
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 unsigned long __cmpxchg_u64(volatile unsigned long *ptr, unsigned long old, unsigned long new)
 {
 	unsigned long flags;
diff --git a/arch/parisc/lib/fixup.S b/arch/parisc/lib/fixup.S
index ecce3d35401f..d172d4245cdc 100644
--- a/arch/parisc/lib/fixup.S
+++ b/arch/parisc/lib/fixup.S
@@ -22,6 +22,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/assembly.h>
 #include <asm/errno.h>
+#include <linux/linkage.h>
 
 #ifdef CONFIG_SMP
 	.macro  get_fault_ip t1 t2
@@ -30,7 +31,7 @@
 	/* t2 = smp_processor_id() */
 	mfctl 30,\t2
 	ldw TI_CPU(\t2),\t2
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	extrd,u \t2,63,32,\t2
 #endif
 	/* t2 = &__per_cpu_offset[smp_processor_id()]; */
@@ -58,33 +59,34 @@
 	.section .fixup, "ax"
 
 	/* get_user() fixups, store -EFAULT in r8, and 0 in r9 */
-	.export fixup_get_user_skip_1
-fixup_get_user_skip_1:
+ENTRY(fixup_get_user_skip_1)
 	get_fault_ip %r1,%r8
 	ldo 4(%r1), %r1
 	ldi -EFAULT, %r8
 	bv %r0(%r1)
 	copy %r0, %r9
+ENDPROC(fixup_get_user_skip_1)
 
-	.export fixup_get_user_skip_2
-fixup_get_user_skip_2:
+ENTRY(fixup_get_user_skip_2)
 	get_fault_ip %r1,%r8
 	ldo 8(%r1), %r1
 	ldi -EFAULT, %r8
 	bv %r0(%r1)
 	copy %r0, %r9
+ENDPROC(fixup_get_user_skip_2)
 
 	/* put_user() fixups, store -EFAULT in r8 */
-	.export fixup_put_user_skip_1
-fixup_put_user_skip_1:
+ENTRY(fixup_put_user_skip_1)
 	get_fault_ip %r1,%r8
 	ldo 4(%r1), %r1
 	bv %r0(%r1)
 	ldi -EFAULT, %r8
+ENDPROC(fixup_put_user_skip_1)
 
-	.export fixup_put_user_skip_2
-fixup_put_user_skip_2:
+ENTRY(fixup_put_user_skip_2)
 	get_fault_ip %r1,%r8
 	ldo 8(%r1), %r1
 	bv %r0(%r1)
 	ldi -EFAULT, %r8
+ENDPROC(fixup_put_user_skip_2)
+
diff --git a/arch/parisc/lib/lusercopy.S b/arch/parisc/lib/lusercopy.S
index a0509855c9a7..1bd23ccec17b 100644
--- a/arch/parisc/lib/lusercopy.S
+++ b/arch/parisc/lib/lusercopy.S
@@ -37,6 +37,7 @@
 	
 #include <asm/assembly.h>
 #include <asm/errno.h>
+#include <linux/linkage.h>
 
 	/*
 	 * get_sr gets the appropriate space value into
@@ -67,8 +68,7 @@
 	 *         otherwise strlen (i.e. excludes zero byte)
 	 */
 
-	.export lstrncpy_from_user,code
-lstrncpy_from_user:
+ENTRY(lstrncpy_from_user)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -87,6 +87,7 @@ $lsfu_exit:
 	bv          %r0(%r2)
 	nop
 	.exit
+ENDPROC(lstrncpy_from_user)
 
 	.section .fixup,"ax"
 3:      fixup_branch $lsfu_exit
@@ -94,13 +95,8 @@ $lsfu_exit:
 	.previous
 
 	.section __ex_table,"aw"
-#ifdef __LP64__
-	.dword      1b,3b
-	.dword      2b,3b
-#else
-	.word       1b,3b
-	.word       2b,3b
-#endif
+	ASM_ULONG_INSN 1b,3b
+	ASM_ULONG_INSN 2b,3b
 	.previous
 
 	.procend
@@ -112,8 +108,7 @@ $lsfu_exit:
 	 * otherwise, returns number of bytes not transferred.
 	 */
 
-	.export lclear_user,code
-lclear_user:
+ENTRY(lclear_user)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -127,6 +122,7 @@ $lclu_done:
 	bv          %r0(%r2)
 	copy        %r25,%r28
 	.exit
+ENDPROC(lclear_user)
 
 	.section .fixup,"ax"
 2:      fixup_branch $lclu_done
@@ -134,11 +130,7 @@ $lclu_done:
 	.previous
 
 	.section __ex_table,"aw"
-#ifdef __LP64__
-	.dword      1b,2b
-#else
-	.word       1b,2b
-#endif
+	ASM_ULONG_INSN 1b,2b
 	.previous
 
 	.procend
@@ -151,8 +143,7 @@ $lclu_done:
 	 *         else strlen + 1 (i.e. includes zero byte).
 	 */
 
-	.export lstrnlen_user,code
-lstrnlen_user:
+ENTRY(lstrnlen_user)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -172,6 +163,7 @@ $lslen_done:
 $lslen_nzero:
 	b           $lslen_done
 	ldo         1(%r26),%r26 /* special case for N == 0 */
+ENDPROC(lstrnlen_user)
 
 	.section .fixup,"ax"
 3:      fixup_branch $lslen_done
@@ -179,13 +171,8 @@ $lslen_nzero:
 	.previous
 
 	.section __ex_table,"aw"
-#ifdef __LP64__
-	.dword      1b,3b
-	.dword      2b,3b
-#else
-	.word       1b,3b
-	.word       2b,3b
-#endif
+	ASM_ULONG_INSN 1b,3b
+	ASM_ULONG_INSN 2b,3b
 	.previous
 
 	.procend
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index 5575e41f9d60..2c43ebe99a9c 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -96,30 +96,18 @@ DECLARE_PER_CPU(struct exception_data, exception_data);
 #define DPRINTF(fmt, args...)
 #endif
 
-#ifndef __LP64__
-#define EXC_WORD ".word"
-#else
-#define EXC_WORD ".dword"
-#endif
-
 #define def_load_ai_insn(_insn,_sz,_tt,_s,_a,_t,_e)	\
 	__asm__ __volatile__ (				\
-	"1:\t" #_insn ",ma " #_sz "(" _s ",%1), %0\n" 	\
-	"\t.section __ex_table,\"aw\"\n"		\
-	"\t" EXC_WORD "\t1b\n"				\
-	"\t" EXC_WORD "\t" #_e "\n"			\
-	"\t.previous\n"					\
+	"1:\t" #_insn ",ma " #_sz "(" _s ",%1), %0\n\t"	\
+	ASM_EXCEPTIONTABLE_ENTRY(1b,_e)			\
 	: _tt(_t), "+r"(_a)				\
 	: 						\
 	: "r8")
 
 #define def_store_ai_insn(_insn,_sz,_tt,_s,_a,_t,_e) 	\
 	__asm__ __volatile__ (				\
-	"1:\t" #_insn ",ma %1, " #_sz "(" _s ",%0)\n" 	\
-	"\t.section __ex_table,\"aw\"\n"		\
-	"\t" EXC_WORD "\t1b\n"				\
-	"\t" EXC_WORD "\t" #_e "\n"			\
-	"\t.previous\n"					\
+	"1:\t" #_insn ",ma %1, " #_sz "(" _s ",%0)\n\t"	\
+	ASM_EXCEPTIONTABLE_ENTRY(1b,_e)			\
 	: "+r"(_a) 					\
 	: _tt(_t)					\
 	: "r8")
@@ -133,22 +121,16 @@ DECLARE_PER_CPU(struct exception_data, exception_data);
 
 #define def_load_insn(_insn,_tt,_s,_o,_a,_t,_e) 	\
 	__asm__ __volatile__ (				\
-	"1:\t" #_insn " " #_o "(" _s ",%1), %0\n"	\
-	"\t.section __ex_table,\"aw\"\n"		\
-	"\t" EXC_WORD "\t1b\n"				\
-	"\t" EXC_WORD "\t" #_e "\n"			\
-	"\t.previous\n"					\
+	"1:\t" #_insn " " #_o "(" _s ",%1), %0\n\t"	\
+	ASM_EXCEPTIONTABLE_ENTRY(1b,_e)			\
 	: _tt(_t) 					\
 	: "r"(_a)					\
 	: "r8")
 
 #define def_store_insn(_insn,_tt,_s,_t,_o,_a,_e) 	\
 	__asm__ __volatile__ (				\
-	"1:\t" #_insn " %0, " #_o "(" _s ",%1)\n" 	\
-	"\t.section __ex_table,\"aw\"\n"		\
-	"\t" EXC_WORD "\t1b\n"				\
-	"\t" EXC_WORD "\t" #_e "\n"			\
-	"\t.previous\n"					\
+	"1:\t" #_insn " %0, " #_o "(" _s ",%1)\n\t" 	\
+	ASM_EXCEPTIONTABLE_ENTRY(1b,_e)			\
 	: 						\
 	: _tt(_t), "r"(_a)				\
 	: "r8")
@@ -167,8 +149,8 @@ extern inline void prefetch_dst(const void *addr)
 	__asm__("ldd 0(" d_space ",%0), %%r0" : : "r" (addr));
 }
 #else
-#define prefetch_src(addr)
-#define prefetch_dst(addr)
+#define prefetch_src(addr) do { } while(0)
+#define prefetch_dst(addr) do { } while(0)
 #endif
 
 /* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 641f9c920eee..f6f67554c623 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -24,10 +24,6 @@
 			 /*  dumped to the console via printk)          */
 
 
-/* Defines for parisc_acctyp()	*/
-#define READ		0
-#define WRITE		1
-
 /* Various important other fields */
 #define bit22set(x)		(x & 0x00000200)
 #define bits23_25set(x)		(x & 0x000001c0)
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 12117db0043b..75ea9f2a8a41 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -6,7 +6,7 @@
  *    changed by Philipp Rumpf
  *  Copyright 1999 Philipp Rumpf (prumpf@tux.org)
  *  Copyright 2004 Randolph Chung (tausq@debian.org)
- *  Copyright 2006 Helge Deller (deller@gmx.de)
+ *  Copyright 2006-2007 Helge Deller (deller@gmx.de)
  *
  */
 
@@ -24,6 +24,7 @@
 #include <linux/pagemap.h>	/* for release_pages and page_cache_release */
 
 #include <asm/pgalloc.h>
+#include <asm/pgtable.h>
 #include <asm/tlb.h>
 #include <asm/pdc_chassis.h>
 #include <asm/mmzone.h>
@@ -65,11 +66,11 @@ static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly;
 physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly;
 int npmem_ranges __read_mostly;
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #define MAX_MEM         (~0UL)
-#else /* !__LP64__ */
+#else /* !CONFIG_64BIT */
 #define MAX_MEM         (3584U*1024U*1024U)
-#endif /* !__LP64__ */
+#endif /* !CONFIG_64BIT */
 
 static unsigned long mem_limit __read_mostly = MAX_MEM;
 
@@ -452,6 +453,8 @@ unsigned long pcxl_dma_start __read_mostly;
 
 void __init mem_init(void)
 {
+	int codesize, reservedpages, datasize, initsize;
+
 	high_memory = __va((max_pfn << PAGE_SHIFT));
 
 #ifndef CONFIG_DISCONTIGMEM
@@ -466,7 +469,32 @@ void __init mem_init(void)
 	}
 #endif
 
-	printk(KERN_INFO "Memory: %luk available\n", num_physpages << (PAGE_SHIFT-10));
+	codesize = (unsigned long)_etext - (unsigned long)_text;
+	datasize = (unsigned long)_edata - (unsigned long)_etext;
+	initsize = (unsigned long)__init_end - (unsigned long)__init_begin;
+
+	reservedpages = 0;
+{
+	unsigned long pfn;
+#ifdef CONFIG_DISCONTIGMEM
+	int i;
+
+	for (i = 0; i < npmem_ranges; i++) {
+		for (pfn = node_start_pfn(i); pfn < node_end_pfn(i); pfn++) {
+			if (PageReserved(pfn_to_page(pfn)))
+				reservedpages++;
+		}
+	}
+#else /* !CONFIG_DISCONTIGMEM */
+	for (pfn = 0; pfn < max_pfn; pfn++) {
+		/*
+		 * Only count reserved RAM pages
+		 */
+		if (PageReserved(pfn_to_page(pfn)))
+			reservedpages++;
+	}
+#endif
+}
 
 #ifdef CONFIG_PA11
 	if (hppa_dma_ops == &pcxl_dma_ops) {
@@ -480,6 +508,38 @@ void __init mem_init(void)
 	vmalloc_start = SET_MAP_OFFSET(MAP_START);
 #endif
 
+	printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
+		(unsigned long)nr_free_pages() << (PAGE_SHIFT-10),
+		num_physpages << (PAGE_SHIFT-10),
+		codesize >> 10,
+		reservedpages << (PAGE_SHIFT-10),
+		datasize >> 10,
+		initsize >> 10
+	);
+
+#ifdef CONFIG_DEBUG_KERNEL /* double-sanity-check paranoia */
+	printk("virtual kernel memory layout:\n"
+	       "    vmalloc : 0x%p - 0x%p   (%4ld MB)\n"
+	       "    memory  : 0x%p - 0x%p   (%4ld MB)\n"
+	       "      .init : 0x%p - 0x%p   (%4ld kB)\n"
+	       "      .data : 0x%p - 0x%p   (%4ld kB)\n"
+	       "      .text : 0x%p - 0x%p   (%4ld kB)\n",
+
+	       (void*)VMALLOC_START, (void*)VMALLOC_END,
+	       (VMALLOC_END - VMALLOC_START) >> 20,
+
+	       __va(0), high_memory,
+	       ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
+
+	       __init_begin, __init_end,
+	       ((unsigned long)__init_end - (unsigned long)__init_begin) >> 10,
+
+	       _etext, _edata,
+	       ((unsigned long)_edata - (unsigned long)_etext) >> 10,
+
+	       _text, _etext,
+	       ((unsigned long)_etext - (unsigned long)_text) >> 10);
+#endif
 }
 
 unsigned long *empty_zero_page __read_mostly;
@@ -547,7 +607,7 @@ void show_mem(void)
 
 				printk("Zone list for zone %d on node %d: ", j, i);
 				for (k = 0; zl->zones[k] != NULL; k++) 
-					printk("[%d/%s] ", zone_to_nid(zl->zones[k]), zl->zones[k]->name);
+					printk("[%ld/%s] ", zone_to_nid(zl->zones[k]), zl->zones[k]->name);
 				printk("\n");
 			}
 		}
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index 44b42c7f639d..92d496ad07c9 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -26,7 +26,7 @@
  */
 void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
 {
-	void *addr;
+	void __iomem *addr;
 	struct vm_struct *area;
 	unsigned long offset, last_addr;
 	pgprot_t pgprot;
@@ -80,14 +80,14 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
 	if (!area)
 		return NULL;
 
-	addr = area->addr;
+	addr = (void __iomem *) area->addr;
 	if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
 			       phys_addr, pgprot)) {
 		vfree(addr);
 		return NULL;
 	}
 
-	return (void __iomem *) (offset + (char *)addr);
+	return (void __iomem *) (offset + (char __iomem *)addr);
 }
 EXPORT_SYMBOL(__ioremap);
 
diff --git a/arch/parisc/mm/kmap.c b/arch/parisc/mm/kmap.c
deleted file mode 100644
index 1b1acd5e2f6e..000000000000
--- a/arch/parisc/mm/kmap.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/* 
- *    kmap/page table map and unmap support routines
- *
- *    Copyright 1999,2000 Hewlett-Packard Company
- *    Copyright 2000 John Marvin <jsm at hp.com>
- *    Copyright 2000 Grant Grundler <grundler at parisc-linux.org>
- *    Copyright 2000 Philipp Rumpf <prumpf@tux.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.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-/*
-** Stolen mostly from arch/parisc/kernel/pci-dma.c
-*/
-
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-
-#include <asm/io.h>
-#include <asm/page.h>		/* get_order */
-
-#undef flush_cache_all
-#define flush_cache_all flush_all_caches
-
-typedef void (*pte_iterator_t) (pte_t * pte, unsigned long arg);
-
-#if 0
-/* XXX This routine could be used with iterate_page() to replace
- * unmap_uncached_page() and save a little code space but I didn't
- * do that since I'm not certain whether this is the right path. -PB
- */
-static void unmap_cached_pte(pte_t * pte, unsigned long addr, unsigned long arg)
-{
-	pte_t page = *pte;
-	pte_clear(&init_mm, addr, pte);
-	if (!pte_none(page)) {
-		if (pte_present(page)) {
-			unsigned long map_nr = pte_pagenr(page);
-			if (map_nr < max_mapnr)
-				__free_page(mem_map + map_nr);
-		} else {
-			printk(KERN_CRIT
-			       "Whee.. Swapped out page in kernel page table\n");
-		}
-	}
-}
-#endif
-
-/* These two routines should probably check a few things... */
-static void set_uncached(pte_t * pte, unsigned long arg)
-{
-	pte_val(*pte) |= _PAGE_NO_CACHE;
-}
-
-static void set_cached(pte_t * pte, unsigned long arg)
-{
-	pte_val(*pte) &= ~_PAGE_NO_CACHE;
-}
-
-static inline void iterate_pte(pmd_t * pmd, unsigned long address,
-			       unsigned long size, pte_iterator_t op,
-			       unsigned long arg)
-{
-	pte_t *pte;
-	unsigned long end;
-
-	if (pmd_none(*pmd))
-		return;
-	if (pmd_bad(*pmd)) {
-		pmd_ERROR(*pmd);
-		pmd_clear(pmd);
-		return;
-	}
-	pte = pte_offset(pmd, address);
-	address &= ~PMD_MASK;
-	end = address + size;
-	if (end > PMD_SIZE)
-		end = PMD_SIZE;
-	do {
-		op(pte, arg);
-		address += PAGE_SIZE;
-		pte++;
-	} while (address < end);
-}
-
-static inline void iterate_pmd(pgd_t * dir, unsigned long address,
-			       unsigned long size, pte_iterator_t op,
-			       unsigned long arg)
-{
-	pmd_t *pmd;
-	unsigned long end;
-
-	if (pgd_none(*dir))
-		return;
-	if (pgd_bad(*dir)) {
-		pgd_ERROR(*dir);
-		pgd_clear(dir);
-		return;
-	}
-	pmd = pmd_offset(dir, address);
-	address &= ~PGDIR_MASK;
-	end = address + size;
-	if (end > PGDIR_SIZE)
-		end = PGDIR_SIZE;
-	do {
-		iterate_pte(pmd, address, end - address, op, arg);
-		address = (address + PMD_SIZE) & PMD_MASK;
-		pmd++;
-	} while (address < end);
-}
-
-static void iterate_pages(unsigned long address, unsigned long size,
-			  pte_iterator_t op, unsigned long arg)
-{
-	pgd_t *dir;
-	unsigned long end = address + size;
-
-	dir = pgd_offset_k(address);
-	flush_cache_all();
-	do {
-		iterate_pmd(dir, address, end - address, op, arg);
-		address = (address + PGDIR_SIZE) & PGDIR_MASK;
-		dir++;
-	} while (address && (address < end));
-	flush_tlb_all();
-}
-
-void
-kernel_set_cachemode(unsigned long vaddr, unsigned long size, int what)
-{
-	switch (what) {
-	case IOMAP_FULL_CACHING:
-		iterate_pages(vaddr, size, set_cached, 0);
-		flush_tlb_range(NULL, vaddr, size);
-		break;
-	case IOMAP_NOCACHE_SER:
-		iterate_pages(vaddr, size, set_uncached, 0);
-		flush_tlb_range(NULL, vaddr, size);
-		break;
-	default:
-		printk(KERN_CRIT
-		       "kernel_set_cachemode mode %d not understood\n",
-		       what);
-		break;
-	}
-}
diff --git a/arch/parisc/oprofile/init.c b/arch/parisc/oprofile/init.c
index a5b898c4d0b0..113f5139f551 100644
--- a/arch/parisc/oprofile/init.c
+++ b/arch/parisc/oprofile/init.c
@@ -18,6 +18,6 @@ int __init oprofile_arch_init(struct oprofile_operations * ops)
 }
 
 
-void oprofile_arch_exit()
+void oprofile_arch_exit(void)
 {
 }