diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index e06e3c3434a4a3206a4ddcba4727214593877299..6db8aea5667fae5cda6c2dae62e7f6b0e4b123dd 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -363,7 +363,6 @@ menu "Power management options"
 
 config ARCH_SUSPEND_POSSIBLE
 	def_bool y
-	depends on !SMP
 
 source kernel/power/Kconfig
 endmenu
diff --git a/arch/frv/include/asm/system.h b/arch/frv/include/asm/system.h
index 0a6d8d9ca45bdbb6398b2ff2882203743963ea8b..6c10fd2c626ddde848763573e7caf769f479e42f 100644
--- a/arch/frv/include/asm/system.h
+++ b/arch/frv/include/asm/system.h
@@ -45,21 +45,12 @@ do {									\
 #define wmb()			asm volatile ("membar" : : :"memory")
 #define read_barrier_depends()	do { } while (0)
 
-#ifdef CONFIG_SMP
-#define smp_mb()			mb()
-#define smp_rmb()			rmb()
-#define smp_wmb()			wmb()
-#define smp_read_barrier_depends()	read_barrier_depends()
-#define set_mb(var, value) \
-	do { xchg(&var, (value)); } while (0)
-#else
 #define smp_mb()			barrier()
 #define smp_rmb()			barrier()
 #define smp_wmb()			barrier()
 #define smp_read_barrier_depends()	do {} while(0)
 #define set_mb(var, value) \
 	do { var = (value); barrier(); } while (0)
-#endif
 
 extern void die_if_kernel(const char *, ...) __attribute__((format(printf, 1, 2)));
 extern void free_initmem(void);
diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h
index 8582e9c7531c8f3433f0749fec1861cf92847919..cefbe73dc119c5b265e59c83d3da7d230278560e 100644
--- a/arch/frv/include/asm/thread_info.h
+++ b/arch/frv/include/asm/thread_info.h
@@ -21,6 +21,8 @@
 
 #define THREAD_SIZE		8192
 
+#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
+
 /*
  * low level task data that entry.S needs immediate access to
  * - this struct should fit entirely inside of one cache line
@@ -87,7 +89,7 @@ register struct thread_info *__current_thread_info asm("gr15");
 #define alloc_thread_info_node(tsk, node)			\
 		kzalloc_node(THREAD_SIZE, GFP_KERNEL, node)
 #else
-#define alloc_thread_info_node(tsk)				\
+#define alloc_thread_info_node(tsk, node)			\
 		kmalloc_node(THREAD_SIZE, GFP_KERNEL, node)
 #endif
 
diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c
index 372fe60b1c2e1bd40cbd444db00226127f76c850..9afc2ea400dc4b79931c624d7013251706ae1a0e 100644
--- a/arch/frv/kernel/irq-mb93091.c
+++ b/arch/frv/kernel/irq-mb93091.c
@@ -47,7 +47,7 @@ static void frv_fpga_mask(struct irq_data *d)
 
 static void frv_fpga_ack(struct irq_data *d)
 {
-	__clr_IFR(1 << (irq - IRQ_BASE_FPGA));
+	__clr_IFR(1 << (d->irq - IRQ_BASE_FPGA));
 }
 
 static void frv_fpga_mask_ack(struct irq_data *d)
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 4ed6fcd6b7263c3e38953e536f4cd07a290c61e7..9332e52ea8c270aadacb79b61446336202e1fea6 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -95,10 +95,27 @@ extern struct vm_struct *remove_vm_area(const void *addr);
 
 extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
 			struct page ***pages);
+#ifdef CONFIG_MMU
 extern int map_kernel_range_noflush(unsigned long start, unsigned long size,
 				    pgprot_t prot, struct page **pages);
 extern void unmap_kernel_range_noflush(unsigned long addr, unsigned long size);
 extern void unmap_kernel_range(unsigned long addr, unsigned long size);
+#else
+static inline int
+map_kernel_range_noflush(unsigned long start, unsigned long size,
+			pgprot_t prot, struct page **pages)
+{
+	return size >> PAGE_SHIFT;
+}
+static inline void
+unmap_kernel_range_noflush(unsigned long addr, unsigned long size)
+{
+}
+static inline void
+unmap_kernel_range(unsigned long addr, unsigned long size)
+{
+}
+#endif
 
 /* Allocate/destroy a 'vmalloc' VM area. */
 extern struct vm_struct *alloc_vm_area(size_t size);
@@ -116,11 +133,26 @@ extern struct vm_struct *vmlist;
 extern __init void vm_area_register_early(struct vm_struct *vm, size_t align);
 
 #ifdef CONFIG_SMP
+# ifdef CONFIG_MMU
 struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
 				     const size_t *sizes, int nr_vms,
 				     size_t align);
 
 void pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms);
+# else
+static inline struct vm_struct **
+pcpu_get_vm_areas(const unsigned long *offsets,
+		const size_t *sizes, int nr_vms,
+		size_t align)
+{
+	return NULL;
+}
+
+static inline void
+pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms)
+{
+}
+# endif
 #endif
 
 #endif /* _LINUX_VMALLOC_H */
diff --git a/mm/nommu.c b/mm/nommu.c
index cb86e7d5e7f5591c8508fba1f98a150e1e968e50..c4c542c736a962774f0770eef0d50c419b19a2cb 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1971,21 +1971,10 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 }
 EXPORT_SYMBOL(filemap_fault);
 
-/*
- * Access another process' address space.
- * - source/target buffer must be kernel space
- */
-int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+		unsigned long addr, void *buf, int len, int write)
 {
 	struct vm_area_struct *vma;
-	struct mm_struct *mm;
-
-	if (addr + len < addr)
-		return 0;
-
-	mm = get_task_mm(tsk);
-	if (!mm)
-		return 0;
 
 	down_read(&mm->mmap_sem);
 
@@ -2010,6 +1999,43 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
 	}
 
 	up_read(&mm->mmap_sem);
+
+	return len;
+}
+
+/**
+ * @access_remote_vm - access another process' address space
+ * @mm:		the mm_struct of the target address space
+ * @addr:	start address to access
+ * @buf:	source or destination buffer
+ * @len:	number of bytes to transfer
+ * @write:	whether the access is a write
+ *
+ * The caller must hold a reference on @mm.
+ */
+int access_remote_vm(struct mm_struct *mm, unsigned long addr,
+		void *buf, int len, int write)
+{
+	return __access_remote_vm(NULL, mm, addr, buf, len, write);
+}
+
+/*
+ * Access another process' address space.
+ * - source/target buffer must be kernel space
+ */
+int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+{
+	struct mm_struct *mm;
+
+	if (addr + len < addr)
+		return 0;
+
+	mm = get_task_mm(tsk);
+	if (!mm)
+		return 0;
+
+	len = __access_remote_vm(tsk, mm, addr, buf, len, write);
+
 	mmput(mm);
 	return len;
 }
diff --git a/mm/percpu.c b/mm/percpu.c
index 3f930018aa60dc075bc49f7283c57b2b3b6f0035..55d4d113fbd37fe4edb7531dc61102fc8f7c1bcc 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -1008,8 +1008,7 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr)
 	}
 
 	if (in_first_chunk) {
-		if ((unsigned long)addr < VMALLOC_START ||
-		    (unsigned long)addr >= VMALLOC_END)
+		if (!is_vmalloc_addr(addr))
 			return __pa(addr);
 		else
 			return page_to_phys(vmalloc_to_page(addr));