diff -druN linux-libre-3.0-gnu/arch/alpha/include/asm/futex.h linux-libre-3.0.40-gnu/arch/alpha/include/asm/futex.h
--- linux-libre-3.0-gnu/arch/alpha/include/asm/futex.h	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/alpha/include/asm/futex.h	2012-08-09 11:28:18.000000000 -0400
@@ -108,7 +108,7 @@
 	"	lda	$31,3b-2b(%0)\n"
 	"	.previous\n"
 	:	"+r"(ret), "=&r"(prev), "=&r"(cmp)
-	:	"r"(uaddr), "r"((long)oldval), "r"(newval)
+	:	"r"(uaddr), "r"((long)(int)oldval), "r"(newval)
 	:	"memory");
 
 	*uval = prev;
diff -druN linux-libre-3.0-gnu/arch/alpha/kernel/time.c linux-libre-3.0.40-gnu/arch/alpha/kernel/time.c
--- linux-libre-3.0-gnu/arch/alpha/kernel/time.c	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/alpha/kernel/time.c	2012-08-09 11:28:18.000000000 -0400
@@ -91,7 +91,7 @@
 #define test_irq_work_pending()      __get_cpu_var(irq_work_pending)
 #define clear_irq_work_pending()     __get_cpu_var(irq_work_pending) = 0
 
-void set_irq_work_pending(void)
+void arch_irq_work_raise(void)
 {
 	set_irq_work_pending_flag();
 }
diff -druN linux-libre-3.0-gnu/arch/arm/configs/ezx_defconfig linux-libre-3.0.40-gnu/arch/arm/configs/ezx_defconfig
--- linux-libre-3.0-gnu/arch/arm/configs/ezx_defconfig	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/configs/ezx_defconfig	2012-08-09 11:28:18.000000000 -0400
@@ -287,7 +287,7 @@
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 # CONFIG_USB_ETH_RNDIS is not set
 CONFIG_MMC=y
diff -druN linux-libre-3.0-gnu/arch/arm/configs/imote2_defconfig linux-libre-3.0.40-gnu/arch/arm/configs/imote2_defconfig
--- linux-libre-3.0-gnu/arch/arm/configs/imote2_defconfig	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/configs/imote2_defconfig	2012-08-09 11:28:18.000000000 -0400
@@ -263,7 +263,7 @@
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 # CONFIG_USB_ETH_RNDIS is not set
 CONFIG_MMC=y
diff -druN linux-libre-3.0-gnu/arch/arm/configs/magician_defconfig linux-libre-3.0.40-gnu/arch/arm/configs/magician_defconfig
--- linux-libre-3.0-gnu/arch/arm/configs/magician_defconfig	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/configs/magician_defconfig	2012-08-09 11:28:18.000000000 -0400
@@ -132,7 +132,7 @@
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_VBUS_DRAW=500
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 # CONFIG_USB_ETH_RNDIS is not set
 CONFIG_USB_GADGETFS=m
diff -druN linux-libre-3.0-gnu/arch/arm/configs/zeus_defconfig linux-libre-3.0.40-gnu/arch/arm/configs/zeus_defconfig
--- linux-libre-3.0-gnu/arch/arm/configs/zeus_defconfig	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/configs/zeus_defconfig	2012-08-09 11:28:18.000000000 -0400
@@ -140,7 +140,7 @@
 CONFIG_USB_SERIAL_GENERIC=y
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_GADGET=m
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
diff -druN linux-libre-3.0-gnu/arch/arm/include/asm/assembler.h linux-libre-3.0.40-gnu/arch/arm/include/asm/assembler.h
--- linux-libre-3.0-gnu/arch/arm/include/asm/assembler.h	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/include/asm/assembler.h	2012-08-09 11:28:18.000000000 -0400
@@ -137,6 +137,11 @@
 	disable_irq
 	.endm
 
+	.macro	save_and_disable_irqs_notrace, oldcpsr
+	mrs	\oldcpsr, cpsr
+	disable_irq_notrace
+	.endm
+
 /*
  * Restore interrupt state previously stored in a register.  We don't
  * guarantee that this will preserve the flags.
diff -druN linux-libre-3.0-gnu/arch/arm/include/asm/cacheflush.h linux-libre-3.0.40-gnu/arch/arm/include/asm/cacheflush.h
--- linux-libre-3.0-gnu/arch/arm/include/asm/cacheflush.h	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/include/asm/cacheflush.h	2012-08-09 11:28:18.000000000 -0400
@@ -249,7 +249,7 @@
  * Harvard caches are synchronised for the user space address range.
  * This is used for the ARM private sys_cacheflush system call.
  */
-#define flush_cache_user_range(vma,start,end) \
+#define flush_cache_user_range(start,end) \
 	__cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end))
 
 /*
diff -druN linux-libre-3.0-gnu/arch/arm/include/asm/futex.h linux-libre-3.0.40-gnu/arch/arm/include/asm/futex.h
--- linux-libre-3.0-gnu/arch/arm/include/asm/futex.h	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/include/asm/futex.h	2012-08-09 11:28:18.000000000 -0400
@@ -25,17 +25,17 @@
 
 #ifdef CONFIG_SMP
 
-#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
+#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg)	\
 	smp_mb();						\
 	__asm__ __volatile__(					\
-	"1:	ldrex	%1, [%2]\n"				\
+	"1:	ldrex	%1, [%3]\n"				\
 	"	" insn "\n"					\
-	"2:	strex	%1, %0, [%2]\n"				\
-	"	teq	%1, #0\n"				\
+	"2:	strex	%2, %0, [%3]\n"				\
+	"	teq	%2, #0\n"				\
 	"	bne	1b\n"					\
 	"	mov	%0, #0\n"				\
-	__futex_atomic_ex_table("%4")				\
-	: "=&r" (ret), "=&r" (oldval)				\
+	__futex_atomic_ex_table("%5")				\
+	: "=&r" (ret), "=&r" (oldval), "=&r" (tmp)		\
 	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
 	: "cc", "memory")
 
@@ -73,14 +73,14 @@
 #include <linux/preempt.h>
 #include <asm/domain.h>
 
-#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
+#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg)	\
 	__asm__ __volatile__(					\
-	"1:	" T(ldr) "	%1, [%2]\n"			\
+	"1:	" T(ldr) "	%1, [%3]\n"			\
 	"	" insn "\n"					\
-	"2:	" T(str) "	%0, [%2]\n"			\
+	"2:	" T(str) "	%0, [%3]\n"			\
 	"	mov	%0, #0\n"				\
-	__futex_atomic_ex_table("%4")				\
-	: "=&r" (ret), "=&r" (oldval)				\
+	__futex_atomic_ex_table("%5")				\
+	: "=&r" (ret), "=&r" (oldval), "=&r" (tmp)		\
 	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
 	: "cc", "memory")
 
@@ -117,7 +117,7 @@
 	int cmp = (encoded_op >> 24) & 15;
 	int oparg = (encoded_op << 8) >> 20;
 	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
+	int oldval = 0, ret, tmp;
 
 	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
 		oparg = 1 << oparg;
@@ -129,19 +129,19 @@
 
 	switch (op) {
 	case FUTEX_OP_SET:
-		__futex_atomic_op("mov	%0, %3", ret, oldval, uaddr, oparg);
+		__futex_atomic_op("mov	%0, %4", ret, oldval, tmp, uaddr, oparg);
 		break;
 	case FUTEX_OP_ADD:
-		__futex_atomic_op("add	%0, %1, %3", ret, oldval, uaddr, oparg);
+		__futex_atomic_op("add	%0, %1, %4", ret, oldval, tmp, uaddr, oparg);
 		break;
 	case FUTEX_OP_OR:
-		__futex_atomic_op("orr	%0, %1, %3", ret, oldval, uaddr, oparg);
+		__futex_atomic_op("orr	%0, %1, %4", ret, oldval, tmp, uaddr, oparg);
 		break;
 	case FUTEX_OP_ANDN:
-		__futex_atomic_op("and	%0, %1, %3", ret, oldval, uaddr, ~oparg);
+		__futex_atomic_op("and	%0, %1, %4", ret, oldval, tmp, uaddr, ~oparg);
 		break;
 	case FUTEX_OP_XOR:
-		__futex_atomic_op("eor	%0, %1, %3", ret, oldval, uaddr, oparg);
+		__futex_atomic_op("eor	%0, %1, %4", ret, oldval, tmp, uaddr, oparg);
 		break;
 	default:
 		ret = -ENOSYS;
diff -druN linux-libre-3.0-gnu/arch/arm/include/asm/hardware/cache-l2x0.h linux-libre-3.0.40-gnu/arch/arm/include/asm/hardware/cache-l2x0.h
--- linux-libre-3.0-gnu/arch/arm/include/asm/hardware/cache-l2x0.h	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/include/asm/hardware/cache-l2x0.h	2012-08-09 11:28:18.000000000 -0400
@@ -64,7 +64,7 @@
 #define L2X0_AUX_CTRL_MASK			0xc0000fff
 #define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT	16
 #define L2X0_AUX_CTRL_WAY_SIZE_SHIFT		17
-#define L2X0_AUX_CTRL_WAY_SIZE_MASK		(0x3 << 17)
+#define L2X0_AUX_CTRL_WAY_SIZE_MASK		(0x7 << 17)
 #define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT	22
 #define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT		26
 #define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT		27
diff -druN linux-libre-3.0-gnu/arch/arm/include/asm/tls.h linux-libre-3.0.40-gnu/arch/arm/include/asm/tls.h
--- linux-libre-3.0-gnu/arch/arm/include/asm/tls.h	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/include/asm/tls.h	2012-08-09 11:28:18.000000000 -0400
@@ -7,6 +7,8 @@
 
 	.macro set_tls_v6k, tp, tmp1, tmp2
 	mcr	p15, 0, \tp, c13, c0, 3		@ set TLS register
+	mov	\tmp1, #0
+	mcr	p15, 0, \tmp1, c13, c0, 2	@ clear user r/w TLS register
 	.endm
 
 	.macro set_tls_v6, tp, tmp1, tmp2
@@ -15,6 +17,8 @@
 	mov	\tmp2, #0xffff0fff
 	tst	\tmp1, #HWCAP_TLS		@ hardware TLS available?
 	mcrne	p15, 0, \tp, c13, c0, 3		@ yes, set TLS register
+	movne	\tmp1, #0
+	mcrne	p15, 0, \tmp1, c13, c0, 2	@ clear user r/w TLS register
 	streq	\tp, [\tmp2, #-15]		@ set TLS value at 0xffff0ff0
 	.endm
 
diff -druN linux-libre-3.0-gnu/arch/arm/Kconfig linux-libre-3.0.40-gnu/arch/arm/Kconfig
--- linux-libre-3.0-gnu/arch/arm/Kconfig	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/Kconfig	2012-08-09 11:28:18.000000000 -0400
@@ -1179,7 +1179,7 @@
 	depends on CPU_V7
 	help
 	  This option enables the workaround for the 743622 Cortex-A9
-	  (r2p0..r2p2) erratum. Under very rare conditions, a faulty
+	  (r2p*) erratum. Under very rare conditions, a faulty
 	  optimisation in the Cortex-A9 Store Buffer may lead to data
 	  corruption. This workaround sets a specific bit in the diagnostic
 	  register of the Cortex-A9 which disables the Store Buffer
@@ -1298,6 +1298,32 @@
 
 source "drivers/pcmcia/Kconfig"
 
+config ARM_ERRATA_764369
+	bool "ARM errata: Data cache line maintenance operation by MVA may not succeed"
+	depends on CPU_V7 && SMP
+	help
+	  This option enables the workaround for erratum 764369
+	  affecting Cortex-A9 MPCore with two or more processors (all
+	  current revisions). Under certain timing circumstances, a data
+	  cache line maintenance operation by MVA targeting an Inner
+	  Shareable memory region may fail to proceed up to either the
+	  Point of Coherency or to the Point of Unification of the
+	  system. This workaround adds a DSB instruction before the
+	  relevant cache maintenance functions and sets a specific bit
+	  in the diagnostic control register of the SCU.
+
+config PL310_ERRATA_769419
+	bool "PL310 errata: no automatic Store Buffer drain"
+	depends on CACHE_L2X0
+	help
+	  On revisions of the PL310 prior to r3p2, the Store Buffer does
+	  not automatically drain. This can cause normal, non-cacheable
+	  writes to be retained when the memory system is idle, leading
+	  to suboptimal I/O performance for drivers using coherent DMA.
+	  This option adds a write barrier to the cpu_idle loop so that,
+	  on systems with an outer cache, the store buffer is drained
+	  explicitly.
+
 endmenu
 
 menu "Kernel Features"
diff -druN linux-libre-3.0-gnu/arch/arm/kernel/head.S linux-libre-3.0.40-gnu/arch/arm/kernel/head.S
--- linux-libre-3.0-gnu/arch/arm/kernel/head.S	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/kernel/head.S	2012-08-09 11:28:18.000000000 -0400
@@ -348,7 +348,7 @@
  *  r13 = *virtual* address to jump to upon completion
  */
 __enable_mmu:
-#ifdef CONFIG_ALIGNMENT_TRAP
+#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
 	orr	r0, r0, #CR_A
 #else
 	bic	r0, r0, #CR_A
diff -druN linux-libre-3.0-gnu/arch/arm/kernel/perf_event_v7.c linux-libre-3.0.40-gnu/arch/arm/kernel/perf_event_v7.c
--- linux-libre-3.0-gnu/arch/arm/kernel/perf_event_v7.c	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/kernel/perf_event_v7.c	2012-08-09 11:28:18.000000000 -0400
@@ -264,8 +264,8 @@
 	[PERF_COUNT_HW_CPU_CYCLES]	    = ARMV7_PERFCTR_CPU_CYCLES,
 	[PERF_COUNT_HW_INSTRUCTIONS]	    =
 					ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
-	[PERF_COUNT_HW_CACHE_REFERENCES]    = ARMV7_PERFCTR_COHERENT_LINE_HIT,
-	[PERF_COUNT_HW_CACHE_MISSES]	    = ARMV7_PERFCTR_COHERENT_LINE_MISS,
+	[PERF_COUNT_HW_CACHE_REFERENCES]    = ARMV7_PERFCTR_DCACHE_ACCESS,
+	[PERF_COUNT_HW_CACHE_MISSES]	    = ARMV7_PERFCTR_DCACHE_REFILL,
 	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
 	[PERF_COUNT_HW_BRANCH_MISSES]	    = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
 	[PERF_COUNT_HW_BUS_CYCLES]	    = ARMV7_PERFCTR_CLOCK_CYCLES,
diff -druN linux-libre-3.0-gnu/arch/arm/kernel/process.c linux-libre-3.0.40-gnu/arch/arm/kernel/process.c
--- linux-libre-3.0-gnu/arch/arm/kernel/process.c	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/kernel/process.c	2012-08-09 11:28:18.000000000 -0400
@@ -191,6 +191,9 @@
 #endif
 
 			local_irq_disable();
+#ifdef CONFIG_PL310_ERRATA_769419
+			wmb();
+#endif
 			if (hlt_counter) {
 				local_irq_enable();
 				cpu_relax();
diff -druN linux-libre-3.0-gnu/arch/arm/kernel/ptrace.c linux-libre-3.0.40-gnu/arch/arm/kernel/ptrace.c
--- linux-libre-3.0-gnu/arch/arm/kernel/ptrace.c	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/kernel/ptrace.c	2012-08-09 11:28:18.000000000 -0400
@@ -719,10 +719,13 @@
 {
 	int ret;
 	struct thread_info *thread = task_thread_info(target);
-	struct vfp_hard_struct new_vfp = thread->vfpstate.hard;
+	struct vfp_hard_struct new_vfp;
 	const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
 	const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
 
+	vfp_sync_hwstate(thread);
+	new_vfp = thread->vfpstate.hard;
+
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
 				  &new_vfp.fpregs,
 				  user_fpregs_offset,
@@ -743,9 +746,8 @@
 	if (ret)
 		return ret;
 
-	vfp_sync_hwstate(thread);
-	thread->vfpstate.hard = new_vfp;
 	vfp_flush_hwstate(thread);
+	thread->vfpstate.hard = new_vfp;
 
 	return 0;
 }
diff -druN linux-libre-3.0-gnu/arch/arm/kernel/signal.c linux-libre-3.0.40-gnu/arch/arm/kernel/signal.c
--- linux-libre-3.0-gnu/arch/arm/kernel/signal.c	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/kernel/signal.c	2012-08-09 11:28:18.000000000 -0400
@@ -227,6 +227,8 @@
 	if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
 		return -EINVAL;
 
+	vfp_flush_hwstate(thread);
+
 	/*
 	 * Copy the floating point registers. There can be unused
 	 * registers see asm/hwcap.h for details.
@@ -251,9 +253,6 @@
 	__get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
 	__get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
 
-	if (!err)
-		vfp_flush_hwstate(thread);
-
 	return err ? -EFAULT : 0;
 }
 
diff -druN linux-libre-3.0-gnu/arch/arm/kernel/smp.c linux-libre-3.0.40-gnu/arch/arm/kernel/smp.c
--- linux-libre-3.0-gnu/arch/arm/kernel/smp.c	2011-07-21 22:17:23.000000000 -0400
+++ linux-libre-3.0.40-gnu/arch/arm/kernel/smp.c	20