diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/dra7.dtsi linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/dra7.dtsi
--- linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/dra7.dtsi	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/dra7.dtsi	2015-08-16 19:34:13.000000000 -0400
@@ -116,7 +116,7 @@
 				ranges = <0 0x2000 0x2000>;
 
 				scm_conf: scm_conf@0 {
-					compatible = "syscon";
+					compatible = "syscon", "simple-bus";
 					reg = <0x0 0x1400>;
 					#address-cells = <1>;
 					#size-cells = <1>;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/imx6qdl.dtsi linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/imx6qdl.dtsi
--- linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/imx6qdl.dtsi	2015-08-15 08:11:56.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/imx6qdl.dtsi	2015-08-16 20:31:07.000000000 -0400
@@ -181,10 +181,10 @@
 			interrupt-names = "msi";
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 0x7>;
-			interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-			                <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
-			                <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
-			                <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-map = <0 0 0 1 &gpc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 2 &gpc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 3 &gpc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 4 &gpc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&clks IMX6QDL_CLK_PCIE_AXI>,
 				 <&clks IMX6QDL_CLK_LVDS1_GATE>,
 				 <&clks IMX6QDL_CLK_PCIE_REF_125M>;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/k2e.dtsi linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/k2e.dtsi
--- linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/k2e.dtsi	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/k2e.dtsi	2015-08-16 19:34:13.000000000 -0400
@@ -131,10 +131,17 @@
 					<GIC_SPI 376 IRQ_TYPE_EDGE_RISING>;
 			};
 		};
+
+		mdio: mdio@24200f00 {
+			compatible	= "ti,keystone_mdio", "ti,davinci_mdio";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x24200f00 0x100>;
+			status = "disabled";
+			clocks = <&clkcpgmac>;
+			clock-names = "fck";
+			bus_freq	= <2500000>;
+		};
 		/include/ "k2e-netcp.dtsi"
 	};
 };
-
-&mdio {
-	reg = <0x24200f00 0x100>;
-};
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/k2hk.dtsi linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/k2hk.dtsi
--- linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/k2hk.dtsi	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/k2hk.dtsi	2015-08-16 19:34:13.000000000 -0400
@@ -98,6 +98,17 @@
 			#gpio-cells = <2>;
 			gpio,syscon-dev = <&devctrl 0x25c>;
 		};
+
+		mdio: mdio@02090300 {
+			compatible	= "ti,keystone_mdio", "ti,davinci_mdio";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x02090300 0x100>;
+			status = "disabled";
+			clocks = <&clkcpgmac>;
+			clock-names = "fck";
+			bus_freq	= <2500000>;
+		};
 		/include/ "k2hk-netcp.dtsi"
 	};
 };
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/k2l.dtsi linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/k2l.dtsi
--- linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/k2l.dtsi	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/k2l.dtsi	2015-08-16 19:34:13.000000000 -0400
@@ -29,7 +29,6 @@
 	};
 
 	soc {
-
 		/include/ "k2l-clocks.dtsi"
 
 		uart2: serial@02348400 {
@@ -79,6 +78,17 @@
 			#gpio-cells = <2>;
 			gpio,syscon-dev = <&devctrl 0x24c>;
 		};
+
+		mdio: mdio@26200f00 {
+			compatible	= "ti,keystone_mdio", "ti,davinci_mdio";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x26200f00 0x100>;
+			status = "disabled";
+			clocks = <&clkcpgmac>;
+			clock-names = "fck";
+			bus_freq	= <2500000>;
+		};
 		/include/ "k2l-netcp.dtsi"
 	};
 };
@@ -96,7 +106,3 @@
        /* Pin muxed. Enabled and configured by Bootloader */
        status = "disabled";
 };
-
-&mdio {
-	reg = <0x26200f00 0x100>;
-};
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/keystone.dtsi linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/keystone.dtsi
--- linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/keystone.dtsi	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/keystone.dtsi	2015-08-16 19:34:13.000000000 -0400
@@ -267,17 +267,6 @@
 				  1 0 0x21000A00 0x00000100>;
 		};
 
-		mdio: mdio@02090300 {
-			compatible	= "ti,keystone_mdio", "ti,davinci_mdio";
-			#address-cells = <1>;
-			#size-cells = <0>;
-			reg		= <0x02090300 0x100>;
-			status = "disabled";
-			clocks = <&clkpa>;
-			clock-names = "fck";
-			bus_freq	= <2500000>;
-		};
-
 		kirq0: keystone_irq@26202a0 {
 			compatible = "ti,keystone-irq";
 			interrupts = <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/omap2430.dtsi linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/omap2430.dtsi
--- linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/omap2430.dtsi	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/omap2430.dtsi	2015-08-16 19:34:13.000000000 -0400
@@ -51,7 +51,8 @@
 				};
 
 				scm_conf: scm_conf@270 {
-					compatible = "syscon";
+					compatible = "syscon",
+						     "simple-bus";
 					reg = <0x270 0x240>;
 					#address-cells = <1>;
 					#size-cells = <1>;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/omap4.dtsi linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/omap4.dtsi
--- linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/omap4.dtsi	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/omap4.dtsi	2015-08-16 19:34:13.000000000 -0400
@@ -191,7 +191,8 @@
 				};
 
 				omap4_padconf_global: omap4_padconf_global@5a0 {
-					compatible = "syscon";
+					compatible = "syscon",
+						     "simple-bus";
 					reg = <0x5a0 0x170>;
 					#address-cells = <1>;
 					#size-cells = <1>;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/omap5.dtsi linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/omap5.dtsi
--- linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/omap5.dtsi	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/omap5.dtsi	2015-08-16 19:34:13.000000000 -0400
@@ -180,7 +180,8 @@
 				};
 
 				omap5_padconf_global: omap5_padconf_global@5a0 {
-					compatible = "syscon";
+					compatible = "syscon",
+						     "simple-bus";
 					reg = <0x5a0 0xec>;
 					#address-cells = <1>;
 					#size-cells = <1>;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/ste-dbx5x0.dtsi linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/ste-dbx5x0.dtsi
--- linux-libre-4.2-rc6-gnu/arch/arm/boot/dts/ste-dbx5x0.dtsi	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/boot/dts/ste-dbx5x0.dtsi	2015-08-16 19:34:13.000000000 -0400
@@ -15,6 +15,33 @@
 #include "skeleton.dtsi"
 
 / {
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "ste,dbx500-smp";
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+			};
+		};
+		CPU0: cpu@300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x300>;
+		};
+		CPU1: cpu@301 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x301>;
+		};
+	};
+
 	soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -22,32 +49,6 @@
 		interrupt-parent = <&intc>;
 		ranges;
 
-		cpus {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			cpu-map {
-				cluster0 {
-					core0 {
-						cpu = <&CPU0>;
-					};
-					core1 {
-						cpu = <&CPU1>;
-					};
-				};
-			};
-			CPU0: cpu@0 {
-				device_type = "cpu";
-				compatible = "arm,cortex-a9";
-				reg = <0>;
-			};
-			CPU1: cpu@1 {
-				device_type = "cpu";
-				compatible = "arm,cortex-a9";
-				reg = <1>;
-			};
-		};
-
 		ptm@801ae000 {
 			compatible = "arm,coresight-etm3x", "arm,primecell";
 			reg = <0x801ae000 0x1000>;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/kernel/entry-common.S linux-libre-4.2-rc7-gnu/arch/arm/kernel/entry-common.S
--- linux-libre-4.2-rc6-gnu/arch/arm/kernel/entry-common.S	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/kernel/entry-common.S	2015-08-16 19:34:13.000000000 -0400
@@ -61,6 +61,7 @@ work_pending:
 	movlt	scno, #(__NR_restart_syscall - __NR_SYSCALL_BASE)
 	ldmia	sp, {r0 - r6}			@ have to reload r0 - r6
 	b	local_restart			@ ... and off we go
+ENDPROC(ret_fast_syscall)
 
 /*
  * "slow" syscall return path.  "why" tells us if this was a real syscall.
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/kernel/head.S linux-libre-4.2-rc7-gnu/arch/arm/kernel/head.S
--- linux-libre-4.2-rc6-gnu/arch/arm/kernel/head.S	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/kernel/head.S	2015-08-16 19:34:13.000000000 -0400
@@ -399,6 +399,9 @@ ENTRY(secondary_startup)
 	sub	lr, r4, r5			@ mmu has been enabled
 	add	r3, r7, lr
 	ldrd	r4, [r3, #0]			@ get secondary_data.pgdir
+ARM_BE8(eor	r4, r4, r5)			@ Swap r5 and r4 in BE:
+ARM_BE8(eor	r5, r4, r5)			@ it can be done in 3 steps
+ARM_BE8(eor	r4, r4, r5)			@ without using a temp reg.
 	ldr	r8, [r3, #8]			@ get secondary_data.swapper_pg_dir
 	badr	lr, __enable_mmu		@ return address
 	mov	r13, r12			@ __secondary_switched address
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/kernel/vdso.c linux-libre-4.2-rc7-gnu/arch/arm/kernel/vdso.c
--- linux-libre-4.2-rc6-gnu/arch/arm/kernel/vdso.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/kernel/vdso.c	2015-08-16 19:34:13.000000000 -0400
@@ -296,7 +296,6 @@ static bool tk_is_cntvct(const struct ti
  */
 void update_vsyscall(struct timekeeper *tk)
 {
-	struct timespec xtime_coarse;
 	struct timespec64 *wtm = &tk->wall_to_monotonic;
 
 	if (!cntvct_ok) {
@@ -308,10 +307,10 @@ void update_vsyscall(struct timekeeper *
 
 	vdso_write_begin(vdso_data);
 
-	xtime_coarse = __current_kernel_time();
 	vdso_data->tk_is_cntvct			= tk_is_cntvct(tk);
-	vdso_data->xtime_coarse_sec		= xtime_coarse.tv_sec;
-	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
+	vdso_data->xtime_coarse_sec		= tk->xtime_sec;
+	vdso_data->xtime_coarse_nsec		= (u32)(tk->tkr_mono.xtime_nsec >>
+							tk->tkr_mono.shift);
 	vdso_data->wtm_clock_sec		= wtm->tv_sec;
 	vdso_data->wtm_clock_nsec		= wtm->tv_nsec;
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/mach-exynos/pm_domains.c linux-libre-4.2-rc7-gnu/arch/arm/mach-exynos/pm_domains.c
--- linux-libre-4.2-rc6-gnu/arch/arm/mach-exynos/pm_domains.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/mach-exynos/pm_domains.c	2015-08-16 19:34:13.000000000 -0400
@@ -146,9 +146,8 @@ static __init int exynos4_pm_init_power_
 		pd->base = of_iomap(np, 0);
 		if (!pd->base) {
 			pr_warn("%s: failed to map memory\n", __func__);
-			kfree(pd->pd.name);
+			kfree_const(pd->pd.name);
 			kfree(pd);
-			of_node_put(np);
 			continue;
 		}
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm/vdso/Makefile linux-libre-4.2-rc7-gnu/arch/arm/vdso/Makefile
--- linux-libre-4.2-rc6-gnu/arch/arm/vdso/Makefile	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm/vdso/Makefile	2015-08-16 19:34:13.000000000 -0400
@@ -14,7 +14,7 @@ VDSO_LDFLAGS += -Wl,-z,max-page-size=409
 VDSO_LDFLAGS += -nostdlib -shared
 VDSO_LDFLAGS += $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
 VDSO_LDFLAGS += $(call cc-ldoption, -Wl$(comma)--build-id)
-VDSO_LDFLAGS += $(call cc-option, -fuse-ld=bfd)
+VDSO_LDFLAGS += $(call cc-ldoption, -fuse-ld=bfd)
 
 obj-$(CONFIG_VDSO) += vdso.o
 extra-$(CONFIG_VDSO) += vdso.lds
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/arm64/kernel/vdso.c linux-libre-4.2-rc7-gnu/arch/arm64/kernel/vdso.c
--- linux-libre-4.2-rc6-gnu/arch/arm64/kernel/vdso.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/arm64/kernel/vdso.c	2015-08-16 19:34:13.000000000 -0400
@@ -199,16 +199,15 @@ up_fail:
  */
 void update_vsyscall(struct timekeeper *tk)
 {
-	struct timespec xtime_coarse;
 	u32 use_syscall = strcmp(tk->tkr_mono.clock->name, "arch_sys_counter");
 
 	++vdso_data->tb_seq_count;
 	smp_wmb();
 
-	xtime_coarse = __current_kernel_time();
 	vdso_data->use_syscall			= use_syscall;
-	vdso_data->xtime_coarse_sec		= xtime_coarse.tv_sec;
-	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
+	vdso_data->xtime_coarse_sec		= tk->xtime_sec;
+	vdso_data->xtime_coarse_nsec		= tk->tkr_mono.xtime_nsec >>
+							tk->tkr_mono.shift;
 	vdso_data->wtm_clock_sec		= tk->wall_to_monotonic.tv_sec;
 	vdso_data->wtm_clock_nsec		= tk->wall_to_monotonic.tv_nsec;
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/mips/kernel/scall64-64.S linux-libre-4.2-rc7-gnu/arch/mips/kernel/scall64-64.S
--- linux-libre-4.2-rc6-gnu/arch/mips/kernel/scall64-64.S	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/mips/kernel/scall64-64.S	2015-08-16 19:34:13.000000000 -0400
@@ -80,7 +80,7 @@ syscall_trace_entry:
 	SAVE_STATIC
 	move	s0, t2
 	move	a0, sp
-	daddiu	a1, v0, __NR_64_Linux
+	move	a1, v0
 	jal	syscall_trace_enter
 
 	bltz	v0, 2f			# seccomp failed? Skip syscall
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/mips/kernel/scall64-n32.S linux-libre-4.2-rc7-gnu/arch/mips/kernel/scall64-n32.S
--- linux-libre-4.2-rc6-gnu/arch/mips/kernel/scall64-n32.S	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/mips/kernel/scall64-n32.S	2015-08-16 19:34:13.000000000 -0400
@@ -72,7 +72,7 @@ n32_syscall_trace_entry:
 	SAVE_STATIC
 	move	s0, t2
 	move	a0, sp
-	daddiu	a1, v0, __NR_N32_Linux
+	move	a1, v0
 	jal	syscall_trace_enter
 
 	bltz	v0, 2f			# seccomp failed? Skip syscall
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/entry/entry_64_compat.S linux-libre-4.2-rc7-gnu/arch/x86/entry/entry_64_compat.S
--- linux-libre-4.2-rc6-gnu/arch/x86/entry/entry_64_compat.S	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/entry/entry_64_compat.S	2015-08-16 19:34:13.000000000 -0400
@@ -140,6 +140,7 @@ sysexit_from_sys_call:
 	 */
 	andl	$~TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
 	movl	RIP(%rsp), %ecx		/* User %eip */
+	movq    RAX(%rsp), %rax
 	RESTORE_RSI_RDI
 	xorl	%edx, %edx		/* Do not leak kernel information */
 	xorq	%r8, %r8
@@ -219,7 +220,6 @@ sysexit_from_sys_call:
 1:	setbe	%al			/* 1 if error, 0 if not */
 	movzbl	%al, %edi		/* zero-extend that into %edi */
 	call	__audit_syscall_exit
-	movq	RAX(%rsp), %rax		/* reload syscall return value */
 	movl	$(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %edi
 	DISABLE_INTERRUPTS(CLBR_NONE)
 	TRACE_IRQS_OFF
@@ -368,6 +368,7 @@ sysretl_from_sys_call:
 	RESTORE_RSI_RDI_RDX
 	movl	RIP(%rsp), %ecx
 	movl	EFLAGS(%rsp), %r11d
+	movq    RAX(%rsp), %rax
 	xorq	%r10, %r10
 	xorq	%r9, %r9
 	xorq	%r8, %r8
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/include/asm/sigcontext.h linux-libre-4.2-rc7-gnu/arch/x86/include/asm/sigcontext.h
--- linux-libre-4.2-rc6-gnu/arch/x86/include/asm/sigcontext.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/include/asm/sigcontext.h	2015-08-16 19:34:13.000000000 -0400
@@ -57,9 +57,9 @@ struct sigcontext {
 	unsigned long ip;
 	unsigned long flags;
 	unsigned short cs;
-	unsigned short __pad2;	/* Was called gs, but was always zero. */
-	unsigned short __pad1;	/* Was called fs, but was always zero. */
-	unsigned short ss;
+	unsigned short gs;
+	unsigned short fs;
+	unsigned short __pad0;
 	unsigned long err;
 	unsigned long trapno;
 	unsigned long oldmask;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/include/uapi/asm/sigcontext.h linux-libre-4.2-rc7-gnu/arch/x86/include/uapi/asm/sigcontext.h
--- linux-libre-4.2-rc6-gnu/arch/x86/include/uapi/asm/sigcontext.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/include/uapi/asm/sigcontext.h	2015-08-16 19:34:13.000000000 -0400
@@ -177,24 +177,9 @@ struct sigcontext {
 	__u64 rip;
 	__u64 eflags;		/* RFLAGS */
 	__u16 cs;
-
-	/*
-	 * Prior to 2.5.64 ("[PATCH] x86-64 updates for 2.5.64-bk3"),
-	 * Linux saved and restored fs and gs in these slots.  This
-	 * was counterproductive, as fsbase and gsbase were never
-	 * saved, so arch_prctl was presumably unreliable.
-	 *
-	 * If these slots are ever needed for any other purpose, there
-	 * is some risk that very old 64-bit binaries could get
-	 * confused.  I doubt that many such binaries still work,
-	 * though, since the same patch in 2.5.64 also removed the
-	 * 64-bit set_thread_area syscall, so it appears that there is
-	 * no TLS API that works in both pre- and post-2.5.64 kernels.
-	 */
-	__u16 __pad2;		/* Was gs. */
-	__u16 __pad1;		/* Was fs. */
-
-	__u16 ss;
+	__u16 gs;
+	__u16 fs;
+	__u16 __pad0;
 	__u64 err;
 	__u64 trapno;
 	__u64 oldmask;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/kernel/cpu/perf_event_intel.c linux-libre-4.2-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel.c
--- linux-libre-4.2-rc6-gnu/arch/x86/kernel/cpu/perf_event_intel.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel.c	2015-08-16 19:34:13.000000000 -0400
@@ -2534,7 +2534,7 @@ static int intel_pmu_cpu_prepare(int cpu
 	if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) {
 		cpuc->shared_regs = allocate_shared_regs(cpu);
 		if (!cpuc->shared_regs)
-			return NOTIFY_BAD;
+			goto err;
 	}
 
 	if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
@@ -2542,18 +2542,27 @@ static int intel_pmu_cpu_prepare(int cpu
 
 		cpuc->constraint_list = kzalloc(sz, GFP_KERNEL);
 		if (!cpuc->constraint_list)
-			return NOTIFY_BAD;
+			goto err_shared_regs;
 
 		cpuc->excl_cntrs = allocate_excl_cntrs(cpu);
-		if (!cpuc->excl_cntrs) {
-			kfree(cpuc->constraint_list);
-			kfree(cpuc->shared_regs);
-			return NOTIFY_BAD;
-		}
+		if (!cpuc->excl_cntrs)
+			goto err_constraint_list;
+
 		cpuc->excl_thread_id = 0;
 	}
 
 	return NOTIFY_OK;
+
+err_constraint_list:
+	kfree(cpuc->constraint_list);
+	cpuc->constraint_list = NULL;
+
+err_shared_regs:
+	kfree(cpuc->shared_regs);
+	cpuc->shared_regs = NULL;
+
+err:
+	return NOTIFY_BAD;
 }
 
 static void intel_pmu_cpu_starting(int cpu)
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/kernel/cpu/perf_event_intel_cqm.c linux-libre-4.2-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel_cqm.c
--- linux-libre-4.2-rc6-gnu/arch/x86/kernel/cpu/perf_event_intel_cqm.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel_cqm.c	2015-08-16 19:34:13.000000000 -0400
@@ -1255,7 +1255,7 @@ static inline void cqm_pick_event_reader
 	cpumask_set_cpu(cpu, &cqm_cpumask);
 }
 
-static void intel_cqm_cpu_prepare(unsigned int cpu)
+static void intel_cqm_cpu_starting(unsigned int cpu)
 {
 	struct intel_pqr_state *state = &per_cpu(pqr_state, cpu);
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
@@ -1296,13 +1296,11 @@ static int intel_cqm_cpu_notifier(struct
 	unsigned int cpu  = (unsigned long)hcpu;
 
 	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_UP_PREPARE:
-		intel_cqm_cpu_prepare(cpu);
-		break;
 	case CPU_DOWN_PREPARE:
 		intel_cqm_cpu_exit(cpu);
 		break;
 	case CPU_STARTING:
+		intel_cqm_cpu_starting(cpu);
 		cqm_pick_event_reader(cpu);
 		break;
 	}
@@ -1373,7 +1371,7 @@ static int __init intel_cqm_init(void)
 		goto out;
 
 	for_each_online_cpu(i) {
-		intel_cqm_cpu_prepare(i);
+		intel_cqm_cpu_starting(i);
 		cqm_pick_event_reader(i);
 	}
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/kernel/signal.c linux-libre-4.2-rc7-gnu/arch/x86/kernel/signal.c
--- linux-libre-4.2-rc6-gnu/arch/x86/kernel/signal.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/kernel/signal.c	2015-08-16 19:34:13.000000000 -0400
@@ -93,8 +93,15 @@ int restore_sigcontext(struct pt_regs *r
 		COPY(r15);
 #endif /* CONFIG_X86_64 */
 
+#ifdef CONFIG_X86_32
 		COPY_SEG_CPL3(cs);
 		COPY_SEG_CPL3(ss);
+#else /* !CONFIG_X86_32 */
+		/* Kernel saves and restores only the CS segment register on signals,
+		 * which is the bare minimum needed to allow mixed 32/64-bit code.
+		 * App's signal handler can save/restore other segments if needed. */
+		COPY_SEG_CPL3(cs);
+#endif /* CONFIG_X86_32 */
 
 		get_user_ex(tmpflags, &sc->flags);
 		regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
@@ -154,9 +161,8 @@ int setup_sigcontext(struct sigcontext _
 #else /* !CONFIG_X86_32 */
 		put_user_ex(regs->flags, &sc->flags);
 		put_user_ex(regs->cs, &sc->cs);
-		put_user_ex(0, &sc->__pad2);
-		put_user_ex(0, &sc->__pad1);
-		put_user_ex(regs->ss, &sc->ss);
+		put_user_ex(0, &sc->gs);
+		put_user_ex(0, &sc->fs);
 #endif /* CONFIG_X86_32 */
 
 		put_user_ex(fpstate, &sc->fpstate);
@@ -451,19 +457,9 @@ static int __setup_rt_frame(int sig, str
 
 	regs->sp = (unsigned long)frame;
 
-	/*
-	 * Set up the CS and SS registers to run signal handlers in
-	 * 64-bit mode, even if the handler happens to be interrupting
-	 * 32-bit or 16-bit code.
-	 *
-	 * SS is subtle.  In 64-bit mode, we don't need any particular
-	 * SS descriptor, but we do need SS to be valid.  It's possible
-	 * that the old SS is entirely bogus -- this can happen if the
-	 * signal we're trying to deliver is #GP or #SS caused by a bad
-	 * SS value.
-	 */
+	/* Set up the CS register to run signal handlers in 64-bit mode,
+	   even if the handler happens to be interrupting 32-bit code. */
 	regs->cs = __USER_CS;
-	regs->ss = __USER_DS;
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/kernel/step.c linux-libre-4.2-rc7-gnu/arch/x86/kernel/step.c
--- linux-libre-4.2-rc6-gnu/arch/x86/kernel/step.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/kernel/step.c	2015-08-16 19:34:13.000000000 -0400
@@ -28,11 +28,11 @@ unsigned long convert_ip_to_linear(struc
 		struct desc_struct *desc;
 		unsigned long base;
 
-		seg &= ~7UL;
+		seg >>= 3;
 
 		mutex_lock(&child->mm->context.lock);
 		if (unlikely(!child->mm->context.ldt ||
-			     (seg >> 3) >= child->mm->context.ldt->size))
+			     seg >= child->mm->context.ldt->size))
 			addr = -1L; /* bogus selector, access would fault */
 		else {
 			desc = &child->mm->context.ldt->entries[seg];
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/kvm/x86.c linux-libre-4.2-rc7-gnu/arch/x86/kvm/x86.c
--- linux-libre-4.2-rc6-gnu/arch/x86/kvm/x86.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/kvm/x86.c	2015-08-16 19:34:13.000000000 -0400
@@ -2105,7 +2105,7 @@ int kvm_set_msr_common(struct kvm_vcpu *
 		if (guest_cpuid_has_tsc_adjust(vcpu)) {
 			if (!msr_info->host_initiated) {
 				s64 adj = data - vcpu->arch.ia32_tsc_adjust_msr;
-				kvm_x86_ops->adjust_tsc_offset(vcpu, adj, true);
+				adjust_tsc_offset_guest(vcpu, adj);
 			}
 			vcpu->arch.ia32_tsc_adjust_msr = data;
 		}
@@ -6327,6 +6327,7 @@ static void process_smi_save_state_64(st
 static void process_smi(struct kvm_vcpu *vcpu)
 {
 	struct kvm_segment cs, ds;
+	struct desc_ptr dt;
 	char buf[512];
 	u32 cr0;
 
@@ -6359,6 +6360,10 @@ static void process_smi(struct kvm_vcpu
 
 	kvm_x86_ops->set_cr4(vcpu, 0);
 
+	/* Undocumented: IDT limit is set to zero on entry to SMM.  */
+	dt.address = dt.size = 0;
+	kvm_x86_ops->set_idt(vcpu, &dt);
+
 	__kvm_set_dr(vcpu, 7, DR7_FIXED_1);
 
 	cs.selector = (vcpu->arch.smbase >> 4) & 0xffff;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/math-emu/fpu_entry.c linux-libre-4.2-rc7-gnu/arch/x86/math-emu/fpu_entry.c
--- linux-libre-4.2-rc6-gnu/arch/x86/math-emu/fpu_entry.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/math-emu/fpu_entry.c	2015-08-16 19:34:13.000000000 -0400
@@ -29,7 +29,6 @@
 
 #include <asm/uaccess.h>
 #include <asm/traps.h>
-#include <asm/desc.h>
 #include <asm/user.h>
 #include <asm/fpu/internal.h>
 
@@ -181,7 +180,7 @@ void math_emulate(struct math_emu_info *
 			math_abort(FPU_info, SIGILL);
 		}
 
-		code_descriptor = LDT_DESCRIPTOR(FPU_CS);
+		code_descriptor = FPU_get_ldt_descriptor(FPU_CS);
 		if (SEG_D_SIZE(code_descriptor)) {
 			/* The above test may be wrong, the book is not clear */
 			/* Segmented 32 bit protected mode */
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/math-emu/fpu_system.h linux-libre-4.2-rc7-gnu/arch/x86/math-emu/fpu_system.h
--- linux-libre-4.2-rc6-gnu/arch/x86/math-emu/fpu_system.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/math-emu/fpu_system.h	2015-08-16 19:34:13.000000000 -0400
@@ -16,9 +16,24 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 
-/* s is always from a cpu register, and the cpu does bounds checking
- * during register load --> no further bounds checks needed */
-#define LDT_DESCRIPTOR(s)	(((struct desc_struct *)current->mm->context.ldt)[(s) >> 3])
+#include <asm/desc.h>
+#include <asm/mmu_context.h>
+
+static inline struct desc_struct FPU_get_ldt_descriptor(unsigned seg)
+{
+	static struct desc_struct zero_desc;
+	struct desc_struct ret = zero_desc;
+
+#ifdef CONFIG_MODIFY_LDT_SYSCALL
+	seg >>= 3;
+	mutex_lock(&current->mm->context.lock);
+	if (current->mm->context.ldt && seg < current->mm->context.ldt->size)
+		ret = current->mm->context.ldt->entries[seg];
+	mutex_unlock(&current->mm->context.lock);
+#endif
+	return ret;
+}
+
 #define SEG_D_SIZE(x)		((x).b & (3 << 21))
 #define SEG_G_BIT(x)		((x).b & (1 << 23))
 #define SEG_GRANULARITY(x)	(((x).b & (1 << 23)) ? 4096 : 1)
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/math-emu/get_address.c linux-libre-4.2-rc7-gnu/arch/x86/math-emu/get_address.c
--- linux-libre-4.2-rc6-gnu/arch/x86/math-emu/get_address.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/math-emu/get_address.c	2015-08-16 19:34:13.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/stddef.h>
 
 #include <asm/uaccess.h>
-#include <asm/desc.h>
 
 #include "fpu_system.h"
 #include "exception.h"
@@ -158,7 +157,7 @@ static long pm_address(u_char FPU_modrm,
 		addr->selector = PM_REG_(segment);
 	}
 
-	descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
+	descriptor = FPU_get_ldt_descriptor(addr->selector);
 	base_address = SEG_BASE_ADDR(descriptor);
 	address = base_address + offset;
 	limit = base_address
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/xen/Makefile linux-libre-4.2-rc7-gnu/arch/x86/xen/Makefile
--- linux-libre-4.2-rc6-gnu/arch/x86/xen/Makefile	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/xen/Makefile	2015-08-16 19:34:13.000000000 -0400
@@ -13,13 +13,13 @@ CFLAGS_mmu.o			:= $(nostackp)
 obj-y		:= enlighten.o setup.o multicalls.o mmu.o irq.o \
 			time.o xen-asm.o xen-asm_$(BITS).o \
 			grant-table.o suspend.o platform-pci-unplug.o \
-			p2m.o
+			p2m.o apic.o
 
 obj-$(CONFIG_EVENT_TRACING) += trace.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
 obj-$(CONFIG_XEN_DEBUG_FS)	+= debugfs.o
-obj-$(CONFIG_XEN_DOM0)		+= apic.o vga.o
+obj-$(CONFIG_XEN_DOM0)		+= vga.o
 obj-$(CONFIG_SWIOTLB_XEN)	+= pci-swiotlb-xen.o
 obj-$(CONFIG_XEN_EFI)		+= efi.o
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/arch/x86/xen/xen-ops.h linux-libre-4.2-rc7-gnu/arch/x86/xen/xen-ops.h
--- linux-libre-4.2-rc6-gnu/arch/x86/xen/xen-ops.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/arch/x86/xen/xen-ops.h	2015-08-16 19:34:13.000000000 -0400
@@ -101,17 +101,15 @@ struct dom0_vga_console_info;
 
 #ifdef CONFIG_XEN_DOM0
 void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size);
-void __init xen_init_apic(void);
 #else
 static inline void __init xen_init_vga(const struct dom0_vga_console_info *info,
 				       size_t size)
 {
 }
-static inline void __init xen_init_apic(void)
-{
-}
 #endif
 
+void __init xen_init_apic(void);
+
 #ifdef CONFIG_XEN_EFI
 extern void xen_efi_init(void);
 #else
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/block/blk-settings.c linux-libre-4.2-rc7-gnu/block/blk-settings.c
--- linux-libre-4.2-rc6-gnu/block/blk-settings.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/block/blk-settings.c	2015-08-16 19:34:13.000000000 -0400
@@ -241,8 +241,8 @@ EXPORT_SYMBOL(blk_queue_bounce_limit);
  * Description:
  *    Enables a low level driver to set a hard upper limit,
  *    max_hw_sectors, on the size of requests.  max_hw_sectors is set by
- *    the device driver based upon the combined capabilities of I/O
- *    controller and storage device.
+ *    the device driver based upon the capabilities of the I/O
+ *    controller.
  *
  *    max_sectors is a soft limit imposed by the block layer for
  *    filesystem type requests.  This value can be overridden on a
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/Documentation/devicetree/bindings/arm/cpus.txt linux-libre-4.2-rc7-gnu/Documentation/devicetree/bindings/arm/cpus.txt
--- linux-libre-4.2-rc6-gnu/Documentation/devicetree/bindings/arm/cpus.txt	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/Documentation/devicetree/bindings/arm/cpus.txt	2015-08-16 19:34:13.000000000 -0400
@@ -199,6 +199,7 @@ nodes to be present and contain the prop
 			    "qcom,kpss-acc-v1"
 			    "qcom,kpss-acc-v2"
 			    "rockchip,rk3066-smp"
+			    "ste,dbx500-smp"
 
 	- cpu-release-addr
 		Usage: required for systems that have an "enable-method"
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/base/regmap/regcache-rbtree.c linux-libre-4.2-rc7-gnu/drivers/base/regmap/regcache-rbtree.c
--- linux-libre-4.2-rc6-gnu/drivers/base/regmap/regcache-rbtree.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/base/regmap/regcache-rbtree.c	2015-08-16 19:34:13.000000000 -0400
@@ -296,11 +296,20 @@ static int regcache_rbtree_insert_to_blo
 	if (!blk)
 		return -ENOMEM;
 
-	present = krealloc(rbnode->cache_present,
-		    BITS_TO_LONGS(blklen) * sizeof(*present), GFP_KERNEL);
-	if (!present) {
-		kfree(blk);
-		return -ENOMEM;
+	if (BITS_TO_LONGS(blklen) > BITS_TO_LONGS(rbnode->blklen)) {
+		present = krealloc(rbnode->cache_present,
+				   BITS_TO_LONGS(blklen) * sizeof(*present),
+				   GFP_KERNEL);
+		if (!present) {
+			kfree(blk);
+			return -ENOMEM;
+		}
+
+		memset(present + BITS_TO_LONGS(rbnode->blklen), 0,
+		       (BITS_TO_LONGS(blklen) - BITS_TO_LONGS(rbnode->blklen))
+		       * sizeof(*present));
+	} else {
+		present = rbnode->cache_present;
 	}
 
 	/* insert the register value in the correct place in the rbnode block */
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/block/xen-blkback/blkback.c linux-libre-4.2-rc7-gnu/drivers/block/xen-blkback/blkback.c
--- linux-libre-4.2-rc6-gnu/drivers/block/xen-blkback/blkback.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/block/xen-blkback/blkback.c	2015-08-16 19:34:13.000000000 -0400
@@ -369,8 +369,8 @@ static void purge_persistent_gnt(struct
 		return;
 	}
 
-	if (work_pending(&blkif->persistent_purge_work)) {
-		pr_alert_ratelimited("Scheduled work from previous purge is still pending, cannot purge list\n");
+	if (work_busy(&blkif->persistent_purge_work)) {
+		pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n");
 		return;
 	}
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/block/xen-blkfront.c linux-libre-4.2-rc7-gnu/drivers/block/xen-blkfront.c
--- linux-libre-4.2-rc6-gnu/drivers/block/xen-blkfront.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/block/xen-blkfront.c	2015-08-16 19:34:13.000000000 -0400
@@ -179,6 +179,7 @@ static DEFINE_SPINLOCK(minor_lock);
 	((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME)
 
 static int blkfront_setup_indirect(struct blkfront_info *info);
+static int blkfront_gather_backend_features(struct blkfront_info *info);
 
 static int get_id_from_freelist(struct blkfront_info *info)
 {
@@ -1128,8 +1129,10 @@ static void blkif_completion(struct blk_
 				 * Add the used indirect page back to the list of
 				 * available pages for indirect grefs.
 				 */
-				indirect_page = pfn_to_page(s->indirect_grants[i]->pfn);
-				list_add(&indirect_page->lru, &info->indirect_pages);
+				if (!info->feature_persistent) {
+					indirect_page = pfn_to_page(s->indirect_grants[i]->pfn);
+					list_add(&indirect_page->lru, &info->indirect_pages);
+				}
 				s->indirect_grants[i]->gref = GRANT_INVALID_REF;
 				list_add_tail(&s->indirect_grants[i]->node, &info->grants);
 			}
@@ -1519,7 +1522,7 @@ static int blkif_recover(struct blkfront
 	info->shadow_free = info->ring.req_prod_pvt;
 	info->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff;
 
-	rc = blkfront_setup_indirect(info);
+	rc = blkfront_gather_backend_features(info);
 	if (rc) {
 		kfree(copy);
 		return rc;
@@ -1720,20 +1723,13 @@ static void blkfront_setup_discard(struc
 
 static int blkfront_setup_indirect(struct blkfront_info *info)
 {
-	unsigned int indirect_segments, segs;
+	unsigned int segs;
 	int err, i;
 
-	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
-			    "feature-max-indirect-segments", "%u", &indirect_segments,
-			    NULL);
-	if (err) {
-		info->max_indirect_segments = 0;
+	if (info->max_indirect_segments == 0)
 		segs = BLKIF_MAX_SEGMENTS_PER_REQUEST;
-	} else {
-		info->max_indirect_segments = min(indirect_segments,
-						  xen_blkif_max_segments);
+	else
 		segs = info->max_indirect_segments;
-	}
 
 	err = fill_grant_buffer(info, (segs + INDIRECT_GREFS(segs)) * BLK_RING_SIZE(info));
 	if (err)
@@ -1797,6 +1793,68 @@ out_of_memory:
 }
 
 /*
+ * Gather all backend feature-*
+ */
+static int blkfront_gather_backend_features(struct blkfront_info *info)
+{
+	int err;
+	int barrier, flush, discard, persistent;
+	unsigned int indirect_segments;
+
+	info->feature_flush = 0;
+
+	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+			"feature-barrier", "%d", &barrier,
+			NULL);
+
+	/*
+	 * If there's no "feature-barrier" defined, then it means
+	 * we're dealing with a very old backend which writes
+	 * synchronously; nothing to do.
+	 *
+	 * If there are barriers, then we use flush.
+	 */
+	if (!err && barrier)
+		info->feature_flush = REQ_FLUSH | REQ_FUA;
+	/*
+	 * And if there is "feature-flush-cache" use that above
+	 * barriers.
+	 */
+	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+			"feature-flush-cache", "%d", &flush,
+			NULL);
+
+	if (!err && flush)
+		info->feature_flush = REQ_FLUSH;
+
+	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+			"feature-discard", "%d", &discard,
+			NULL);
+
+	if (!err && discard)
+		blkfront_setup_discard(info);
+
+	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+			"feature-persistent", "%u", &persistent,
+			NULL);
+	if (err)
+		info->feature_persistent = 0;
+	else
+		info->feature_persistent = persistent;
+
+	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+			    "feature-max-indirect-segments", "%u", &indirect_segments,
+			    NULL);
+	if (err)
+		info->max_indirect_segments = 0;
+	else
+		info->max_indirect_segments = min(indirect_segments,
+						  xen_blkif_max_segments);
+
+	return blkfront_setup_indirect(info);
+}
+
+/*
  * Invoked when the backend is finally 'ready' (and has told produced
  * the details about the physical device - #sectors, size, etc).
  */
@@ -1807,7 +1865,6 @@ static void blkfront_connect(struct blkf
 	unsigned int physical_sector_size;
 	unsigned int binfo;
 	int err;
-	int barrier, flush, discard, persistent;
 
 	switch (info->connected) {
 	case BLKIF_STATE_CONNECTED:
@@ -1864,48 +1921,7 @@ static void blkfront_connect(struct blkf
 	if (err != 1)
 		physical_sector_size = sector_size;
 
-	info->feature_flush = 0;
-
-	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
-			    "feature-barrier", "%d", &barrier,
-			    NULL);
-
-	/*
-	 * If there's no "feature-barrier" defined, then it means
-	 * we're dealing with a very old backend which writes
-	 * synchronously; nothing to do.
-	 *
-	 * If there are barriers, then we use flush.
-	 */
-	if (!err && barrier)
-		info->feature_flush = REQ_FLUSH | REQ_FUA;
-	/*
-	 * And if there is "feature-flush-cache" use that above
-	 * barriers.
-	 */
-	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
-			    "feature-flush-cache", "%d", &flush,
-			    NULL);
-
-	if (!err && flush)
-		info->feature_flush = REQ_FLUSH;
-
-	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
-			    "feature-discard", "%d", &discard,
-			    NULL);
-
-	if (!err && discard)
-		blkfront_setup_discard(info);
-
-	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
-			    "feature-persistent", "%u", &persistent,
-			    NULL);
-	if (err)
-		info->feature_persistent = 0;
-	else
-		info->feature_persistent = persistent;
-
-	err = blkfront_setup_indirect(info);
+	err = blkfront_gather_backend_features(info);
 	if (err) {
 		xenbus_dev_fatal(info->xbdev, err, "setup_indirect at %s",
 				 info->xbdev->otherend);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/block/zram/zram_drv.c linux-libre-4.2-rc7-gnu/drivers/block/zram/zram_drv.c
--- linux-libre-4.2-rc6-gnu/drivers/block/zram/zram_drv.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/block/zram/zram_drv.c	2015-08-16 19:34:13.000000000 -0400
@@ -496,10 +496,9 @@ static void zram_meta_free(struct zram_m
 	kfree(meta);
 }
 
-static struct zram_meta *zram_meta_alloc(int device_id, u64 disksize)
+static struct zram_meta *zram_meta_alloc(char *pool_name, u64 disksize)
 {
 	size_t num_pages;
-	char pool_name[8];
 	struct zram_meta *meta = kmalloc(sizeof(*meta), GFP_KERNEL);
 
 	if (!meta)
@@ -512,7 +511,6 @@ static struct zram_meta *zram_meta_alloc
 		goto out_error;
 	}
 
-	snprintf(pool_name, sizeof(pool_name), "zram%d", device_id);
 	meta->mem_pool = zs_create_pool(pool_name, GFP_NOIO | __GFP_HIGHMEM);
 	if (!meta->mem_pool) {
 		pr_err("Error creating memory pool\n");
@@ -1031,7 +1029,7 @@ static ssize_t disksize_store(struct dev
 		return -EINVAL;
 
 	disksize = PAGE_ALIGN(disksize);
-	meta = zram_meta_alloc(zram->disk->first_minor, disksize);
+	meta = zram_meta_alloc(zram->disk->disk_name, disksize);
 	if (!meta)
 		return -ENOMEM;
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/clk/pxa/clk-pxa3xx.c linux-libre-4.2-rc7-gnu/drivers/clk/pxa/clk-pxa3xx.c
--- linux-libre-4.2-rc6-gnu/drivers/clk/pxa/clk-pxa3xx.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/clk/pxa/clk-pxa3xx.c	2015-08-16 19:34:13.000000000 -0400
@@ -126,7 +126,7 @@ PARENTS(pxa3xx_ac97_bus) = { "ring_osc_6
 PARENTS(pxa3xx_sbus) = { "ring_osc_60mhz", "system_bus" };
 PARENTS(pxa3xx_smemcbus) = { "ring_osc_60mhz", "smemc" };
 
-#define CKEN_AB(bit) ((CKEN_ ## bit > 31) ? &CKENA : &CKENB)
+#define CKEN_AB(bit) ((CKEN_ ## bit > 31) ? &CKENB : &CKENA)
 #define PXA3XX_CKEN(dev_id, con_id, parents, mult_lp, div_lp, mult_hp,	\
 		    div_hp, bit, is_lp, flags)				\
 	PXA_CKEN(dev_id, con_id, bit, parents, mult_lp, div_lp,		\
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/clocksource/sh_cmt.c linux-libre-4.2-rc7-gnu/drivers/clocksource/sh_cmt.c
--- linux-libre-4.2-rc6-gnu/drivers/clocksource/sh_cmt.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/clocksource/sh_cmt.c	2015-08-16 19:34:13.000000000 -0400
@@ -661,6 +661,9 @@ static void sh_cmt_clocksource_suspend(s
 {
 	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
+	if (!ch->cs_enabled)
+		return;
+
 	sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
 	pm_genpd_syscore_poweroff(&ch->cmt->pdev->dev);
 }
@@ -669,6 +672,9 @@ static void sh_cmt_clocksource_resume(st
 {
 	struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
 
+	if (!ch->cs_enabled)
+		return;
+
 	pm_genpd_syscore_poweron(&ch->cmt->pdev->dev);
 	sh_cmt_start(ch, FLAG_CLOCKSOURCE);
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/edac/ppc4xx_edac.c linux-libre-4.2-rc7-gnu/drivers/edac/ppc4xx_edac.c
--- linux-libre-4.2-rc6-gnu/drivers/edac/ppc4xx_edac.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/edac/ppc4xx_edac.c	2015-08-16 19:34:13.000000000 -0400
@@ -920,7 +920,7 @@ static int ppc4xx_edac_init_csrows(struc
 	 */
 
 	for (row = 0; row < mci->nr_csrows; row++) {
-		struct csrow_info *csi = &mci->csrows[row];
+		struct csrow_info *csi = mci->csrows[row];
 
 		/*
 		 * Get the configuration settings for this
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c linux-libre-4.2-rc7-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
--- linux-libre-4.2-rc6-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c	2015-08-15 08:09:18.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c	2015-08-16 20:28:14.000000000 -0400
@@ -369,7 +369,7 @@ static int amdgpu_uvd_cs_msg_decode(uint
 	unsigned height_in_mb = ALIGN(height / 16, 2);
 	unsigned fs_in_mb = width_in_mb * height_in_mb;
 
-	unsigned image_size, tmp, min_dpb_size, num_dpb_buffer;
+	unsigned image_size, tmp, min_dpb_size, num_dpb_buffer, min_ctx_size;
 
 	image_size = width * height;
 	image_size += image_size / 2;
@@ -461,6 +461,8 @@ static int amdgpu_uvd_cs_msg_decode(uint
 
 		num_dpb_buffer = (le32_to_cpu(msg[59]) & 0xff) + 2;
 		min_dpb_size = image_size * num_dpb_buffer;
+		min_ctx_size = ((width + 255) / 16) * ((height + 255) / 16)
+					   * 16 * num_dpb_buffer + 52 * 1024;
 		break;
 
 	default:
@@ -481,6 +483,7 @@ static int amdgpu_uvd_cs_msg_decode(uint
 
 	buf_sizes[0x1] = dpb_size;
 	buf_sizes[0x2] = image_size;
+	buf_sizes[0x4] = min_ctx_size;
 	return 0;
 }
 
@@ -623,6 +626,13 @@ static int amdgpu_uvd_cs_pass2(struct am
 			return -EINVAL;
 		}
 
+	} else if (cmd == 0x206) {
+		if ((end - start) < ctx->buf_sizes[4]) {
+			DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd,
+					  (unsigned)(end - start),
+					  ctx->buf_sizes[4]);
+			return -EINVAL;
+		}
 	} else if ((cmd != 0x100) && (cmd != 0x204)) {
 		DRM_ERROR("invalid UVD command %X!\n", cmd);
 		return -EINVAL;
@@ -750,9 +760,10 @@ int amdgpu_uvd_ring_parse_cs(struct amdg
 	struct amdgpu_uvd_cs_ctx ctx = {};
 	unsigned buf_sizes[] = {
 		[0x00000000]	=	2048,
-		[0x00000001]	=	32 * 1024 * 1024,
-		[0x00000002]	=	2048 * 1152 * 3,
+		[0x00000001]	=	0xFFFFFFFF,
+		[0x00000002]	=	0xFFFFFFFF,
 		[0x00000003]	=	2048,
+		[0x00000004]	=	0xFFFFFFFF,
 	};
 	struct amdgpu_ib *ib = &parser->ibs[ib_idx];
 	int r;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c linux-libre-4.2-rc7-gnu/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
--- linux-libre-4.2-rc6-gnu/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c	2015-08-15 08:09:25.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c	2015-08-16 20:28:24.000000000 -0400
@@ -3116,7 +3116,7 @@ static int gfx_v8_0_cp_compute_resume(st
 				WREG32(mmCP_MEC_DOORBELL_RANGE_LOWER,
 				       AMDGPU_DOORBELL_KIQ << 2);
 				WREG32(mmCP_MEC_DOORBELL_RANGE_UPPER,
-						0x7FFFF << 2);
+				       AMDGPU_DOORBELL_MEC_RING7 << 2);
 			}
 			tmp = RREG32(mmCP_HQD_PQ_DOORBELL_CONTROL);
 			tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c linux-libre-4.2-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c
--- linux-libre-4.2-rc6-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c	2015-08-16 19:34:13.000000000 -0400
@@ -1745,7 +1745,6 @@ static int fimc_probe(struct platform_de
 	spin_lock_init(&ctx->lock);
 	platform_set_drvdata(pdev, ctx);
 
-	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
 
 	ret = exynos_drm_ippdrv_register(ippdrv);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c linux-libre-4.2-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c
--- linux-libre-4.2-rc6-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c	2015-08-16 19:34:13.000000000 -0400
@@ -593,8 +593,7 @@ static int gsc_src_set_transf(struct dev
 
 	gsc_write(cfg, GSC_IN_CON);
 
-	ctx->rotation = cfg &
-		(GSC_IN_ROT_90 | GSC_IN_ROT_270) ? 1 : 0;
+	ctx->rotation = (cfg & GSC_IN_ROT_90) ? 1 : 0;
 	*swap = ctx->rotation;
 
 	return 0;
@@ -857,8 +856,7 @@ static int gsc_dst_set_transf(struct dev
 
 	gsc_write(cfg, GSC_IN_CON);
 
-	ctx->rotation = cfg &
-		(GSC_IN_ROT_90 | GSC_IN_ROT_270) ? 1 : 0;
+	ctx->rotation = (cfg & GSC_IN_ROT_90) ? 1 : 0;
 	*swap = ctx->rotation;
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/gpu/drm/exynos/exynos_hdmi.c linux-libre-4.2-rc7-gnu/drivers/gpu/drm/exynos/exynos_hdmi.c
--- linux-libre-4.2-rc6-gnu/drivers/gpu/drm/exynos/exynos_hdmi.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/gpu/drm/exynos/exynos_hdmi.c	2015-08-16 19:34:13.000000000 -0400
@@ -1064,6 +1064,7 @@ static int hdmi_get_modes(struct drm_con
 {
 	struct hdmi_context *hdata = ctx_from_connector(connector);
 	struct edid *edid;
+	int ret;
 
 	if (!hdata->ddc_adpt)
 		return -ENODEV;
@@ -1079,7 +1080,11 @@ static int hdmi_get_modes(struct drm_con
 
 	drm_mode_connector_update_edid_property(connector, edid);
 
-	return drm_add_edid_modes(connector, edid);
+	ret = drm_add_edid_modes(connector, edid);
+
+	kfree(edid);
+
+	return ret;
 }
 
 static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/gpu/drm/exynos/exynos_mixer.c linux-libre-4.2-rc7-gnu/drivers/gpu/drm/exynos/exynos_mixer.c
--- linux-libre-4.2-rc6-gnu/drivers/gpu/drm/exynos/exynos_mixer.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/gpu/drm/exynos/exynos_mixer.c	2015-08-16 19:34:13.000000000 -0400
@@ -718,6 +718,10 @@ static irqreturn_t mixer_irq_handler(int
 
 	/* handling VSYNC */
 	if (val & MXR_INT_STATUS_VSYNC) {
+		/* vsync interrupt use different bit for read and clear */
+		val |= MXR_INT_CLEAR_VSYNC;
+		val &= ~MXR_INT_STATUS_VSYNC;
+
 		/* interlace scan need to check shadow register */
 		if (ctx->interlace) {
 			base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
@@ -743,11 +747,6 @@ static irqreturn_t mixer_irq_handler(int
 
 out:
 	/* clear interrupts */
-	if (~val & MXR_INT_EN_VSYNC) {
-		/* vsync interrupt use different bit for read and clear */
-		val &= ~MXR_INT_EN_VSYNC;
-		val |= MXR_INT_CLEAR_VSYNC;
-	}
 	mixer_reg_write(res, MXR_INT_STATUS, val);
 
 	spin_unlock(&res->reg_slock);
@@ -907,8 +906,8 @@ static int mixer_enable_vblank(struct ex
 	}
 
 	/* enable vsync interrupt */
-	mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC,
-			MXR_INT_EN_VSYNC);
+	mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
+	mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
 
 	return 0;
 }
@@ -918,7 +917,13 @@ static void mixer_disable_vblank(struct
 	struct mixer_context *mixer_ctx = crtc->ctx;
 	struct mixer_resources *res = &mixer_ctx->mixer_res;
 
+	if (!mixer_ctx->powered) {
+		mixer_ctx->int_en &= MXR_INT_EN_VSYNC;
+		return;
+	}
+
 	/* disable vsync interrupt */
+	mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
 	mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
 }
 
@@ -1047,6 +1052,8 @@ static void mixer_enable(struct exynos_d
 
 	mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
 
+	if (ctx->int_en & MXR_INT_EN_VSYNC)
+		mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
 	mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
 	mixer_win_reset(ctx);
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c linux-libre-4.2-rc7-gnu/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
--- linux-libre-4.2-rc6-gnu/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c	2015-08-16 19:34:13.000000000 -0400
@@ -166,30 +166,14 @@ gk104_fifo_context_attach(struct nvkm_ob
 }
 
 static int
-gk104_fifo_chan_kick(struct gk104_fifo_chan *chan)
-{
-	struct nvkm_object *obj = (void *)chan;
-	struct gk104_fifo_priv *priv = (void *)obj->engine;
-
-	nv_wr32(priv, 0x002634, chan->base.chid);
-	if (!nv_wait(priv, 0x002634, 0x100000, 0x000000)) {
-		nv_error(priv, "channel %d [%s] kick timeout\n",
-			 chan->base.chid, nvkm_client_name(chan));
-		return -EBUSY;
-	}
-
-	return 0;
-}
-
-static int
 gk104_fifo_context_detach(struct nvkm_object *parent, bool suspend,
 			  struct nvkm_object *object)
 {
 	struct nvkm_bar *bar = nvkm_bar(parent);
+	struct gk104_fifo_priv *priv = (void *)parent->engine;
 	struct gk104_fifo_base *base = (void *)parent->parent;
 	struct gk104_fifo_chan *chan = (void *)parent;
 	u32 addr;
-	int ret;
 
 	switch (nv_engidx(object->engine)) {
 	case NVDEV_ENGINE_SW    : return 0;
@@ -204,9 +188,13 @@ gk104_fifo_context_detach(struct nvkm_ob
 		return -EINVAL;
 	}
 
-	ret = gk104_fifo_chan_kick(chan);
-	if (ret && suspend)
-		return ret;
+	nv_wr32(priv, 0x002634, chan->base.chid);
+	if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) {
+		nv_error(priv, "channel %d [%s] kick timeout\n",
+			 chan->base.chid, nvkm_client_name(chan));
+		if (suspend)
+			return -EBUSY;
+	}
 
 	if (addr) {
 		nv_wo32(base, addr + 0x00, 0x00000000);
@@ -331,7 +319,6 @@ gk104_fifo_chan_fini(struct nvkm_object
 		gk104_fifo_runlist_update(priv, chan->engine);
 	}
 
-	gk104_fifo_chan_kick(chan);
 	nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000);
 	return nvkm_fifo_channel_fini(&chan->base, suspend);
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c linux-libre-4.2-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
--- linux-libre-4.2-rc6-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c	2015-08-16 19:34:13.000000000 -0400
@@ -2492,7 +2492,7 @@ int vmw_execbuf_process(struct drm_file
 	ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes,
 				     true, NULL);
 	if (unlikely(ret != 0))
-		goto out_err;
+		goto out_err_nores;
 
 	ret = vmw_validate_buffers(dev_priv, sw_context);
 	if (unlikely(ret != 0))
@@ -2536,6 +2536,7 @@ int vmw_execbuf_process(struct drm_file
 	vmw_resource_relocations_free(&sw_context->res_relocations);
 
 	vmw_fifo_commit(dev_priv, command_size);
+	mutex_unlock(&dev_priv->binding_mutex);
 
 	vmw_query_bo_switch_commit(dev_priv, sw_context);
 	ret = vmw_execbuf_fence_commands(file_priv, dev_priv,
@@ -2551,7 +2552,6 @@ int vmw_execbuf_process(struct drm_file
 		DRM_ERROR("Fence submission error. Syncing.\n");
 
 	vmw_resource_list_unreserve(&sw_context->resource_list, false);
-	mutex_unlock(&dev_priv->binding_mutex);
 
 	ttm_eu_fence_buffer_objects(&ticket, &sw_context->validate_nodes,
 				    (void *) fence);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/hid/hid-input.c linux-libre-4.2-rc7-gnu/drivers/hid/hid-input.c
--- linux-libre-4.2-rc6-gnu/drivers/hid/hid-input.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/hid/hid-input.c	2015-08-16 19:34:13.000000000 -0400
@@ -462,12 +462,15 @@ out:
 
 static void hidinput_cleanup_battery(struct hid_device *dev)
 {
+	const struct power_supply_desc *psy_desc;
+
 	if (!dev->battery)
 		return;
 
+	psy_desc = dev->battery->desc;
 	power_supply_unregister(dev->battery);
-	kfree(dev->battery->desc->name);
-	kfree(dev->battery->desc);
+	kfree(psy_desc->name);
+	kfree(psy_desc);
 	dev->battery = NULL;
 }
 #else  /* !CONFIG_HID_BATTERY_STRENGTH */
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/hid/hid-uclogic.c linux-libre-4.2-rc7-gnu/drivers/hid/hid-uclogic.c
--- linux-libre-4.2-rc6-gnu/drivers/hid/hid-uclogic.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/hid/hid-uclogic.c	2015-08-16 19:34:13.000000000 -0400
@@ -858,7 +858,7 @@ static int uclogic_tablet_enable(struct
 	for (p = drvdata->rdesc;
 	     p <= drvdata->rdesc + drvdata->rsize - 4;) {
 		if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D &&
-		    p[3] < sizeof(params)) {
+		    p[3] < ARRAY_SIZE(params)) {
 			v = params[p[3]];
 			put_unaligned(cpu_to_le32(v), (s32 *)p);
 			p += 4;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/hid/wacom_sys.c linux-libre-4.2-rc7-gnu/drivers/hid/wacom_sys.c
--- linux-libre-4.2-rc6-gnu/drivers/hid/wacom_sys.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/hid/wacom_sys.c	2015-08-16 19:34:13.000000000 -0400
@@ -1284,6 +1284,39 @@ fail_register_pen_input:
 	return error;
 }
 
+/*
+ * Not all devices report physical dimensions from HID.
+ * Compute the default from hardcoded logical dimension
+ * and resolution before driver overwrites them.
+ */
+static void wacom_set_default_phy(struct wacom_features *features)
+{
+	if (features->x_resolution) {
+		features->x_phy = (features->x_max * 100) /
+					features->x_resolution;
+		features->y_phy = (features->y_max * 100) /
+					features->y_resolution;
+	}
+}
+
+static void wacom_calculate_res(struct wacom_features *features)
+{
+	/* set unit to "100th of a mm" for devices not reported by HID */
+	if (!features->unit) {
+		features->unit = 0x11;
+		features->unitExpo = -3;
+	}
+
+	features->x_resolution = wacom_calc_hid_res(features->x_max,
+						    features->x_phy,
+						    features->unit,
+						    features->unitExpo);
+	features->y_resolution = wacom_calc_hid_res(features->y_max,
+						    features->y_phy,
+						    features->unit,
+						    features->unitExpo);
+}
+
 static void wacom_wireless_work(struct work_struct *work)
 {
 	struct wacom *wacom = container_of(work, struct wacom, work);
@@ -1341,6 +1374,8 @@ static void wacom_wireless_work(struct w
 		if (wacom_wac1->features.type != INTUOSHT &&
 		    wacom_wac1->features.type != BAMBOO_PT)
 			wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PAD;
+		wacom_set_default_phy(&wacom_wac1->features);
+		wacom_calculate_res(&wacom_wac1->features);
 		snprintf(wacom_wac1->pen_name, WACOM_NAME_MAX, "%s (WL) Pen",
 			 wacom_wac1->features.name);
 		snprintf(wacom_wac1->pad_name, WACOM_NAME_MAX, "%s (WL) Pad",
@@ -1359,7 +1394,9 @@ static void wacom_wireless_work(struct w
 			wacom_wac2->features =
 				*((struct wacom_features *)id->driver_data);
 			wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
+			wacom_set_default_phy(&wacom_wac2->features);
 			wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096;
+			wacom_calculate_res(&wacom_wac2->features);
 			snprintf(wacom_wac2->touch_name, WACOM_NAME_MAX,
 				 "%s (WL) Finger",wacom_wac2->features.name);
 			snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX,
@@ -1407,39 +1444,6 @@ void wacom_battery_work(struct work_stru
 	}
 }
 
-/*
- * Not all devices report physical dimensions from HID.
- * Compute the default from hardcoded logical dimension
- * and resolution before driver overwrites them.
- */
-static void wacom_set_default_phy(struct wacom_features *features)
-{
-	if (features->x_resolution) {
-		features->x_phy = (features->x_max * 100) /
-					features->x_resolution;
-		features->y_phy = (features->y_max * 100) /
-					features->y_resolution;
-	}
-}
-
-static void wacom_calculate_res(struct wacom_features *features)
-{
-	/* set unit to "100th of a mm" for devices not reported by HID */
-	if (!features->unit) {
-		features->unit = 0x11;
-		features->unitExpo = -3;
-	}
-
-	features->x_resolution = wacom_calc_hid_res(features->x_max,
-						    features->x_phy,
-						    features->unit,
-						    features->unitExpo);
-	features->y_resolution = wacom_calc_hid_res(features->y_max,
-						    features->y_phy,
-						    features->unit,
-						    features->unitExpo);
-}
-
 static size_t wacom_compute_pktlen(struct hid_device *hdev)
 {
 	struct hid_report_enum *report_enum;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/md/dm-cache-policy-mq.c linux-libre-4.2-rc7-gnu/drivers/md/dm-cache-policy-mq.c
--- linux-libre-4.2-rc6-gnu/drivers/md/dm-cache-policy-mq.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/md/dm-cache-policy-mq.c	2015-08-16 19:34:13.000000000 -0400
@@ -1471,5 +1471,3 @@ module_exit(mq_exit);
 MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("mq cache policy");
-
-MODULE_ALIAS("dm-cache-default");
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/md/dm-cache-policy-smq.c linux-libre-4.2-rc7-gnu/drivers/md/dm-cache-policy-smq.c
--- linux-libre-4.2-rc6-gnu/drivers/md/dm-cache-policy-smq.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/md/dm-cache-policy-smq.c	2015-08-16 19:34:13.000000000 -0400
@@ -1789,3 +1789,5 @@ module_exit(smq_exit);
 MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("smq cache policy");
+
+MODULE_ALIAS("dm-cache-default");
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/md/dm-thin-metadata.c linux-libre-4.2-rc7-gnu/drivers/md/dm-thin-metadata.c
--- linux-libre-4.2-rc6-gnu/drivers/md/dm-thin-metadata.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/md/dm-thin-metadata.c	2015-08-16 19:34:13.000000000 -0400
@@ -1293,8 +1293,8 @@ static int __release_metadata_snap(struc
 		return r;
 
 	disk_super = dm_block_data(copy);
-	dm_sm_dec_block(pmd->metadata_sm, le64_to_cpu(disk_super->data_mapping_root));
-	dm_sm_dec_block(pmd->metadata_sm, le64_to_cpu(disk_super->device_details_root));
+	dm_btree_del(&pmd->info, le64_to_cpu(disk_super->data_mapping_root));
+	dm_btree_del(&pmd->details_info, le64_to_cpu(disk_super->device_details_root));
 	dm_sm_dec_block(pmd->metadata_sm, held_root);
 
 	return dm_tm_unlock(pmd->tm, copy);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/md/persistent-data/dm-btree.c linux-libre-4.2-rc7-gnu/drivers/md/persistent-data/dm-btree.c
--- linux-libre-4.2-rc6-gnu/drivers/md/persistent-data/dm-btree.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/md/persistent-data/dm-btree.c	2015-08-16 19:34:13.000000000 -0400
@@ -667,12 +667,7 @@ static int insert(struct dm_btree_info *
 	struct btree_node *n;
 	struct dm_btree_value_type le64_type;
 
-	le64_type.context = NULL;
-	le64_type.size = sizeof(__le64);
-	le64_type.inc = NULL;
-	le64_type.dec = NULL;
-	le64_type.equal = NULL;
-
+	init_le64_type(info->tm, &le64_type);
 	init_shadow_spine(&spine, info);
 
 	for (level = 0; level < (info->levels - 1); level++) {
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/md/persistent-data/dm-btree-internal.h linux-libre-4.2-rc7-gnu/drivers/md/persistent-data/dm-btree-internal.h
--- linux-libre-4.2-rc6-gnu/drivers/md/persistent-data/dm-btree-internal.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/md/persistent-data/dm-btree-internal.h	2015-08-16 19:34:13.000000000 -0400
@@ -138,4 +138,10 @@ int lower_bound(struct btree_node *n, ui
 
 extern struct dm_block_validator btree_node_validator;
 
+/*
+ * Value type for upper levels of multi-level btrees.
+ */
+extern void init_le64_type(struct dm_transaction_manager *tm,
+			   struct dm_btree_value_type *vt);
+
 #endif	/* DM_BTREE_INTERNAL_H */
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/md/persistent-data/dm-btree-remove.c linux-libre-4.2-rc7-gnu/drivers/md/persistent-data/dm-btree-remove.c
--- linux-libre-4.2-rc6-gnu/drivers/md/persistent-data/dm-btree-remove.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/md/persistent-data/dm-btree-remove.c	2015-08-16 19:34:13.000000000 -0400
@@ -544,14 +544,6 @@ static int remove_raw(struct shadow_spin
 	return r;
 }
 
-static struct dm_btree_value_type le64_type = {
-	.context = NULL,
-	.size = sizeof(__le64),
-	.inc = NULL,
-	.dec = NULL,
-	.equal = NULL
-};
-
 int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
 		    uint64_t *keys, dm_block_t *new_root)
 {
@@ -559,12 +551,14 @@ int dm_btree_remove(struct dm_btree_info
 	int index = 0, r = 0;
 	struct shadow_spine spine;
 	struct btree_node *n;
+	struct dm_btree_value_type le64_vt;
 
+	init_le64_type(info->tm, &le64_vt);
 	init_shadow_spine(&spine, info);
 	for (level = 0; level < info->levels; level++) {
 		r = remove_raw(&spine, info,
 			       (level == last_level ?
-				&info->value_type : &le64_type),
+				&info->value_type : &le64_vt),
 			       root, keys[level], (unsigned *)&index);
 		if (r < 0)
 			break;
@@ -654,11 +648,13 @@ static int remove_one(struct dm_btree_in
 	int index = 0, r = 0;
 	struct shadow_spine spine;
 	struct btree_node *n;
+	struct dm_btree_value_type le64_vt;
 	uint64_t k;
 
+	init_le64_type(info->tm, &le64_vt);
 	init_shadow_spine(&spine, info);
 	for (level = 0; level < last_level; level++) {
-		r = remove_raw(&spine, info, &le64_type,
+		r = remove_raw(&spine, info, &le64_vt,
 			       root, keys[level], (unsigned *) &index);
 		if (r < 0)
 			goto out;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/md/persistent-data/dm-btree-spine.c linux-libre-4.2-rc7-gnu/drivers/md/persistent-data/dm-btree-spine.c
--- linux-libre-4.2-rc6-gnu/drivers/md/persistent-data/dm-btree-spine.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/md/persistent-data/dm-btree-spine.c	2015-08-16 19:34:13.000000000 -0400
@@ -249,3 +249,40 @@ int shadow_root(struct shadow_spine *s)
 {
 	return s->root;
 }
+
+static void le64_inc(void *context, const void *value_le)
+{
+	struct dm_transaction_manager *tm = context;
+	__le64 v_le;
+
+	memcpy(&v_le, value_le, sizeof(v_le));
+	dm_tm_inc(tm, le64_to_cpu(v_le));
+}
+
+static void le64_dec(void *context, const void *value_le)
+{
+	struct dm_transaction_manager *tm = context;
+	__le64 v_le;
+
+	memcpy(&v_le, value_le, sizeof(v_le));
+	dm_tm_dec(tm, le64_to_cpu(v_le));
+}
+
+static int le64_equal(void *context, const void *value1_le, const void *value2_le)
+{
+	__le64 v1_le, v2_le;
+
+	memcpy(&v1_le, value1_le, sizeof(v1_le));
+	memcpy(&v2_le, value2_le, sizeof(v2_le));
+	return v1_le == v2_le;
+}
+
+void init_le64_type(struct dm_transaction_manager *tm,
+		    struct dm_btree_value_type *vt)
+{
+	vt->context = tm;
+	vt->size = sizeof(__le64);
+	vt->inc = le64_inc;
+	vt->dec = le64_dec;
+	vt->equal = le64_equal;
+}
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/memory/omap-gpmc.c linux-libre-4.2-rc7-gnu/drivers/memory/omap-gpmc.c
--- linux-libre-4.2-rc6-gnu/drivers/memory/omap-gpmc.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/memory/omap-gpmc.c	2015-08-16 19:34:13.000000000 -0400
@@ -2245,6 +2245,9 @@ void omap3_gpmc_save_context(void)
 {
 	int i;
 
+	if (!gpmc_base)
+		return;
+
 	gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG);
 	gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE);
 	gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL);
@@ -2277,6 +2280,9 @@ void omap3_gpmc_restore_context(void)
 {
 	int i;
 
+	if (!gpmc_base)
+		return;
+
 	gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig);
 	gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable);
 	gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/mfd/arizona-core.c linux-libre-4.2-rc7-gnu/drivers/mfd/arizona-core.c
--- linux-libre-4.2-rc6-gnu/drivers/mfd/arizona-core.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/mfd/arizona-core.c	2015-08-16 19:34:13.000000000 -0400
@@ -651,7 +651,7 @@ static int arizona_runtime_suspend(struc
 
 		arizona->has_fully_powered_off = true;
 
-		disable_irq(arizona->irq);
+		disable_irq_nosync(arizona->irq);
 		arizona_enable_reset(arizona);
 		regulator_bulk_disable(arizona->num_core_supplies,
 				       arizona->core_supplies);
@@ -1141,10 +1141,6 @@ int arizona_dev_init(struct arizona *ari
 			     arizona->pdata.gpio_defaults[i]);
 	}
 
-	pm_runtime_set_autosuspend_delay(arizona->dev, 100);
-	pm_runtime_use_autosuspend(arizona->dev);
-	pm_runtime_enable(arizona->dev);
-
 	/* Chip default */
 	if (!arizona->pdata.clk32k_src)
 		arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2;
@@ -1245,11 +1241,17 @@ int arizona_dev_init(struct arizona *ari
 					   arizona->pdata.spk_fmt[i]);
 	}
 
+	pm_runtime_set_active(arizona->dev);
+	pm_runtime_enable(arizona->dev);
+
 	/* Set up for interrupts */
 	ret = arizona_irq_init(arizona);
 	if (ret != 0)
 		goto err_reset;
 
+	pm_runtime_set_autosuspend_delay(arizona->dev, 100);
+	pm_runtime_use_autosuspend(arizona->dev);
+
 	arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error",
 			    arizona_clkgen_err, arizona);
 	arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked",
@@ -1278,10 +1280,6 @@ int arizona_dev_init(struct arizona *ari
 		goto err_irq;
 	}
 
-#ifdef CONFIG_PM
-	regulator_disable(arizona->dcvdd);
-#endif
-
 	return 0;
 
 err_irq:
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/mfd/Kconfig linux-libre-4.2-rc7-gnu/drivers/mfd/Kconfig
--- linux-libre-4.2-rc6-gnu/drivers/mfd/Kconfig	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/mfd/Kconfig	2015-08-16 19:34:13.000000000 -0400
@@ -115,7 +115,7 @@ config MFD_CROS_EC_I2C
 
 config MFD_CROS_EC_SPI
 	tristate "ChromeOS Embedded Controller (SPI)"
-	depends on MFD_CROS_EC && CROS_EC_PROTO && SPI && OF
+	depends on MFD_CROS_EC && CROS_EC_PROTO && SPI
 
 	---help---
 	  If you say Y here, you get support for talking to the ChromeOS EC
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/bonding/bond_main.c linux-libre-4.2-rc7-gnu/drivers/net/bonding/bond_main.c
--- linux-libre-4.2-rc6-gnu/drivers/net/bonding/bond_main.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/bonding/bond_main.c	2015-08-16 19:34:13.000000000 -0400
@@ -786,6 +786,7 @@ static bool bond_should_notify_peers(str
 		   slave ? slave->dev->name : "NULL");
 
 	if (!slave || !bond->send_peer_notif ||
+	    !netif_carrier_ok(bond->dev) ||
 	    test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
 		return false;
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/3com/3c59x.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/3com/3c59x.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/3com/3c59x.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/3com/3c59x.c	2015-08-16 19:34:13.000000000 -0400
@@ -1763,16 +1763,9 @@ vortex_open(struct net_device *dev)
 			vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 		}
 		if (i != RX_RING_SIZE) {
-			int j;
 			pr_emerg("%s: no memory for rx ring\n", dev->name);
-			for (j = 0; j < i; j++) {
-				if (vp->rx_skbuff[j]) {
-					dev_kfree_skb(vp->rx_skbuff[j]);
-					vp->rx_skbuff[j] = NULL;
-				}
-			}
 			retval = -ENOMEM;
-			goto err_free_irq;
+			goto err_free_skb;
 		}
 		/* Wrap the ring. */
 		vp->rx_ring[i-1].next = cpu_to_le32(vp->rx_ring_dma);
@@ -1782,7 +1775,13 @@ vortex_open(struct net_device *dev)
 	if (!retval)
 		goto out;
 
-err_free_irq:
+err_free_skb:
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		if (vp->rx_skbuff[i]) {
+			dev_kfree_skb(vp->rx_skbuff[i]);
+			vp->rx_skbuff[i] = NULL;
+		}
+	}
 	free_irq(dev->irq, dev);
 err:
 	if (vortex_debug > 1)
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2015-08-15 08:19:00.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2015-08-16 20:38:56.000000000 -0400
@@ -262,9 +262,9 @@ static u16 bnx2x_free_tx_pkt(struct bnx2
 	if (likely(skb)) {
 		(*pkts_compl)++;
 		(*bytes_compl) += skb->len;
+		dev_kfree_skb_any(skb);
 	}
 
-	dev_kfree_skb_any(skb);
 	tx_buf->first_bd = 0;
 	tx_buf->skb = NULL;
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c	2015-08-16 19:34:13.000000000 -0400
@@ -1718,6 +1718,22 @@ static int bnx2x_nvram_write(struct bnx2
 		offset += sizeof(u32);
 		data_buf += sizeof(u32);
 		written_so_far += sizeof(u32);
+
+		/* At end of each 4Kb page, release nvram lock to allow MFW
+		 * chance to take it for its own use.
+		 */
+		if ((cmd_flags & MCPR_NVM_COMMAND_LAST) &&
+		    (written_so_far < buf_size)) {
+			DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+			   "Releasing NVM lock after offset 0x%x\n",
+			   (u32)(offset - sizeof(u32)));
+			bnx2x_release_nvram_lock(bp);
+			usleep_range(1000, 2000);
+			rc = bnx2x_acquire_nvram_lock(bp);
+			if (rc)
+				return rc;
+		}
+
 		cmd_flags = 0;
 	}
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/brocade/bna/bnad.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/brocade/bna/bnad.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/brocade/bna/bnad.c	2015-08-15 08:18:27.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/brocade/bna/bnad.c	2015-08-16 20:38:30.000000000 -0400
@@ -676,6 +676,7 @@ bnad_cq_process(struct bnad *bnad, struc
 			if (!next_cmpl->valid)
 				break;
 		}
+		packets++;
 
 		/* TODO: BNA_CQ_EF_LOCAL ? */
 		if (unlikely(flags & (BNA_CQ_EF_MAC_ERROR |
@@ -692,7 +693,6 @@ bnad_cq_process(struct bnad *bnad, struc
 		else
 			bnad_cq_setup_skb_frags(rcb, skb, sop_ci, nvecs, len);
 
-		packets++;
 		rcb->rxq->rx_packets++;
 		rcb->rxq->rx_bytes += totlen;
 		ccb->bytes_per_intr += totlen;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/cavium/Kconfig linux-libre-4.2-rc7-gnu/drivers/net/ethernet/cavium/Kconfig
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/cavium/Kconfig	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/cavium/Kconfig	2015-08-16 19:34:13.000000000 -0400
@@ -16,7 +16,6 @@ if NET_VENDOR_CAVIUM
 config THUNDER_NIC_PF
 	tristate "Thunder Physical function driver"
 	depends on 64BIT
-	default ARCH_THUNDER
 	select THUNDER_NIC_BGX
 	---help---
 	  This driver supports Thunder's NIC physical function.
@@ -29,14 +28,12 @@ config THUNDER_NIC_PF
 config THUNDER_NIC_VF
 	tristate "Thunder Virtual function driver"
 	depends on 64BIT
-	default ARCH_THUNDER
 	---help---
 	  This driver supports Thunder's NIC virtual function
 
 config	THUNDER_NIC_BGX
 	tristate "Thunder MAC interface driver (BGX)"
 	depends on 64BIT
-	default ARCH_THUNDER
 	---help---
 	  This driver supports programming and controlling of MAC
 	  interface from NIC physical function driver.
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c	2015-08-16 19:34:13.000000000 -0400
@@ -2332,10 +2332,11 @@ int t4_setup_debugfs(struct adapter *ada
 					EXT_MEM1_SIZE_G(size));
 		}
 	} else {
-		if (i & EXT_MEM_ENABLE_F)
+		if (i & EXT_MEM_ENABLE_F) {
 			size = t4_read_reg(adap, MA_EXT_MEMORY_BAR_A);
 			add_debugfs_mem(adap, "mc", MEM_MC,
 					EXT_MEM_SIZE_G(size));
+		}
 	}
 
 	de = debugfs_create_file_size("flash", S_IRUSR, adap->debugfs_root, adap,
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/emulex/benet/be_cmds.h linux-libre-4.2-rc7-gnu/drivers/net/ethernet/emulex/benet/be_cmds.h
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/emulex/benet/be_cmds.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/emulex/benet/be_cmds.h	2015-08-16 19:34:13.000000000 -0400
@@ -620,6 +620,11 @@ enum be_if_flags {
 					 BE_IF_FLAGS_VLAN_PROMISCUOUS |\
 					 BE_IF_FLAGS_MCAST_PROMISCUOUS)
 
+#define BE_IF_EN_FLAGS	(BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_PASS_L3L4_ERRORS |\
+			BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_UNTAGGED)
+
+#define BE_IF_ALL_FILT_FLAGS	(BE_IF_EN_FLAGS | BE_IF_FLAGS_ALL_PROMISCUOUS)
+
 /* An RX interface is an object with one or more MAC addresses and
  * filtering capabilities. */
 struct be_cmd_req_if_create {
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/emulex/benet/be_main.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/emulex/benet/be_main.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/emulex/benet/be_main.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/emulex/benet/be_main.c	2015-08-16 19:34:13.000000000 -0400
@@ -273,6 +273,10 @@ static int be_mac_addr_set(struct net_de
 	if (ether_addr_equal(addr->sa_data, netdev->dev_addr))
 		return 0;
 
+	/* if device is not running, copy MAC to netdev->dev_addr */
+	if (!netif_running(netdev))
+		goto done;
+
 	/* The PMAC_ADD cmd may fail if the VF doesn't have FILTMGMT
 	 * privilege or if PF did not provision the new MAC address.
 	 * On BE3, this cmd will always fail if the VF doesn't have the
@@ -307,9 +311,9 @@ static int be_mac_addr_set(struct net_de
 		status = -EPERM;
 		goto err;
 	}
-
-	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-	dev_info(dev, "MAC address changed to %pM\n", mac);
+done:
+	ether_addr_copy(netdev->dev_addr, addr->sa_data);
+	dev_info(dev, "MAC address changed to %pM\n", addr->sa_data);
 	return 0;
 err:
 	dev_warn(dev, "MAC address change to %pM failed\n", addr->sa_data);
@@ -2447,10 +2451,24 @@ static void be_eq_clean(struct be_eq_obj
 	be_eq_notify(eqo->adapter, eqo->q.id, false, true, num, 0);
 }
 
-static void be_rx_cq_clean(struct be_rx_obj *rxo)
+/* Free posted rx buffers that were not used */
+static void be_rxq_clean(struct be_rx_obj *rxo)
 {
-	struct be_rx_page_info *page_info;
 	struct be_queue_info *rxq = &rxo->q;
+	struct be_rx_page_info *page_info;
+
+	while (atomic_read(&rxq->used) > 0) {
+		page_info = get_rx_page_info(rxo);
+		put_page(page_info->page);
+		memset(page_info, 0, sizeof(*page_info));
+	}
+	BUG_ON(atomic_read(&rxq->used));
+	rxq->tail = 0;
+	rxq->head = 0;
+}
+
+static void be_rx_cq_clean(struct be_rx_obj *rxo)
+{
 	struct be_queue_info *rx_cq = &rxo->cq;
 	struct be_rx_compl_info *rxcp;
 	struct be_adapter *adapter = rxo->adapter;
@@ -2487,16 +2505,6 @@ static void be_rx_cq_clean(struct be_rx_
 
 	/* After cleanup, leave the CQ in unarmed state */
 	be_cq_notify(adapter, rx_cq->id, false, 0);
-
-	/* Then free posted rx buffers that were not used */
-	while (atomic_read(&rxq->used) > 0) {
-		page_info = get_rx_page_info(rxo);
-		put_page(page_info->page);
-		memset(page_info, 0, sizeof(*page_info));
-	}
-	BUG_ON(atomic_read(&rxq->used));
-	rxq->tail = 0;
-	rxq->head = 0;
 }
 
 static void be_tx_compl_clean(struct be_adapter *adapter)
@@ -2576,8 +2584,8 @@ static void be_evt_queues_destroy(struct
 			be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ);
 			napi_hash_del(&eqo->napi);
 			netif_napi_del(&eqo->napi);
+			free_cpumask_var(eqo->affinity_mask);
 		}
-		free_cpumask_var(eqo->affinity_mask);
 		be_queue_free(adapter, &eqo->q);
 	}
 }
@@ -2594,13 +2602,7 @@ static int be_evt_queues_create(struct b
 
 	for_all_evt_queues(adapter, eqo, i) {
 		int numa_node = dev_to_node(&adapter->pdev->dev);
-		if (!zalloc_cpumask_var(&eqo->affinity_mask, GFP_KERNEL))
-			return -ENOMEM;
-		cpumask_set_cpu(cpumask_local_spread(i, numa_node),
-				eqo->affinity_mask);
-		netif_napi_add(adapter->netdev, &eqo->napi, be_poll,
-			       BE_NAPI_WEIGHT);
-		napi_hash_add(&eqo->napi);
+
 		aic = &adapter->aic_obj[i];
 		eqo->adapter = adapter;
 		eqo->idx = i;
@@ -2616,6 +2618,14 @@ static int be_evt_queues_create(struct b
 		rc = be_cmd_eq_create(adapter, eqo);
 		if (rc)
 			return rc;
+
+		if (!zalloc_cpumask_var(&eqo->affinity_mask, GFP_KERNEL))
+			return -ENOMEM;
+		cpumask_set_cpu(cpumask_local_spread(i, numa_node),
+				eqo->affinity_mask);
+		netif_napi_add(adapter->netdev, &eqo->napi, be_poll,
+			       BE_NAPI_WEIGHT);
+		napi_hash_add(&eqo->napi);
 	}
 	return 0;
 }
@@ -3354,13 +3364,54 @@ static void be_rx_qs_destroy(struct be_a
 	for_all_rx_queues(adapter, rxo, i) {
 		q = &rxo->q;
 		if (q->created) {
+			/* If RXQs are destroyed while in an "out of buffer"
+			 * state, there is a possibility of an HW stall on
+			 * Lancer. So, post 64 buffers to each queue to relieve
+			 * the "out of buffer" condition.
+			 * Make sure there's space in the RXQ before posting.
+			 */
+			if (lancer_chip(adapter)) {
+				be_rx_cq_clean(rxo);
+				if (atomic_read(&q->used) == 0)
+					be_post_rx_frags(rxo, GFP_KERNEL,
+							 MAX_RX_POST);
+			}
+
 			be_cmd_rxq_destroy(adapter, q);
 			be_rx_cq_clean(rxo);
+			be_rxq_clean(rxo);
 		}
 		be_queue_free(adapter, q);
 	}
 }
 
+static void be_disable_if_filters(struct be_adapter *adapter)
+{
+	be_cmd_pmac_del(adapter, adapter->if_handle,
+			adapter->pmac_id[0], 0);
+
+	be_clear_uc_list(adapter);
+
+	/* The IFACE flags are enabled in the open path and cleared
+	 * in the close path. When a VF gets detached from the host and
+	 * assigned to a VM the following happens:
+	 *	- VF's IFACE flags get cleared in the detach path
+	 *	- IFACE create is issued by the VF in the attach path
+	 * Due to a bug in the BE3/Skyhawk-R FW
+	 * (Lancer FW doesn't have the bug), the IFACE capability flags
+	 * specified along with the IFACE create cmd issued by a VF are not
+	 * honoured by FW.  As a consequence, if a *new* driver
+	 * (that enables/disables IFACE flags in open/close)
+	 * is loaded in the host and an *old* driver is * used by a VM/VF,
+	 * the IFACE gets created *without* the needed flags.
+	 * To avoid this, disable RX-filter flags only for Lancer.
+	 */
+	if (lancer_chip(adapter)) {
+		be_cmd_rx_filter(adapter, BE_IF_ALL_FILT_FLAGS, OFF);
+		adapter->if_flags &= ~BE_IF_ALL_FILT_FLAGS;
+	}
+}
+
 static int be_close(struct net_device *netdev)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
@@ -3373,6 +3424,8 @@ static int be_close(struct net_device *n
 	if (!(adapter->flags & BE_FLAGS_SETUP_DONE))
 		return 0;
 
+	be_disable_if_filters(adapter);
+
 	be_roce_dev_close(adapter);
 
 	if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
@@ -3392,7 +3445,6 @@ static int be_close(struct net_device *n
 	be_tx_compl_clean(adapter);
 
 	be_rx_qs_destroy(adapter);
-	be_clear_uc_list(adapter);
 
 	for_all_evt_queues(adapter, eqo, i) {
 		if (msix_enabled(adapter))
@@ -3477,6 +3529,31 @@ static int be_rx_qs_create(struct be_ada
 	return 0;
 }
 
+static int be_enable_if_filters(struct be_adapter *adapter)
+{
+	int status;
+
+	status = be_cmd_rx_filter(adapter, BE_IF_EN_FLAGS, ON);
+	if (status)
+		return status;
+
+	/* For BE3 VFs, the PF programs the initial MAC address */
+	if (!(BEx_chip(adapter) && be_virtfn(adapter))) {
+		status = be_cmd_pmac_add(adapter, adapter->netdev->dev_addr,
+					 adapter->if_handle,
+					 &adapter->pmac_id[0], 0);
+		if (status)
+			return status;
+	}
+
+	if (adapter->vlans_added)
+		be_vid_config(adapter);
+
+	be_set_rx_mode(adapter->netdev);
+
+	return 0;
+}
+
 static int be_open(struct net_device *netdev)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
@@ -3490,6 +3567,10 @@ static int be_open(struct net_device *ne
 	if (status)
 		goto err;
 
+	status = be_enable_if_filters(adapter);
+	if (status)
+		goto err;
+
 	status = be_irq_register(adapter);
 	if (status)
 		goto err;
@@ -3686,16 +3767,6 @@ static void be_cancel_err_detection(stru
 	}
 }
 
-static void be_mac_clear(struct be_adapter *adapter)
-{
-	if (adapter->pmac_id) {
-		be_cmd_pmac_del(adapter, adapter->if_handle,
-				adapter->pmac_id[0], 0);
-		kfree(adapter->pmac_id);
-		adapter->pmac_id = NULL;
-	}
-}
-
 #ifdef CONFIG_BE2NET_VXLAN
 static void be_disable_vxlan_offloads(struct be_adapter *adapter)
 {
@@ -3770,8 +3841,8 @@ static int be_clear(struct be_adapter *a
 #ifdef CONFIG_BE2NET_VXLAN
 	be_disable_vxlan_offloads(adapter);
 #endif
-	/* delete the primary mac along with the uc-mac list */
-	be_mac_clear(adapter);
+	kfree(adapter->pmac_id);
+	adapter->pmac_id = NULL;
 
 	be_cmd_if_destroy(adapter, adapter->if_handle,  0);
 
@@ -3782,25 +3853,11 @@ static int be_clear(struct be_adapter *a
 	return 0;
 }
 
-static int be_if_create(struct be_adapter *adapter, u32 *if_handle,
-			u32 cap_flags, u32 vf)
-{
-	u32 en_flags;
-
-	en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
-		   BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS |
-		   BE_IF_FLAGS_RSS | BE_IF_FLAGS_DEFQ_RSS;
-
-	en_flags &= cap_flags;
-
-	return be_cmd_if_create(adapter, cap_flags, en_flags, if_handle, vf);
-}
-
 static int be_vfs_if_create(struct be_adapter *adapter)
 {
 	struct be_resources res = {0};
+	u32 cap_flags, en_flags, vf;
 	struct be_vf_cfg *vf_cfg;
-	u32 cap_flags, vf;
 	int status;
 
 	/* If a FW profile exists, then cap_flags are updated */
@@ -3821,8 +3878,12 @@ static int be_vfs_if_create(struct be_ad
 			}
 		}
 
-		status = be_if_create(adapter, &vf_cfg->if_handle,
-				      cap_flags, vf + 1);
+		en_flags = cap_flags & (BE_IF_FLAGS_UNTAGGED |
+					BE_IF_FLAGS_BROADCAST |
+					BE_IF_FLAGS_MULTICAST |
+					BE_IF_FLAGS_PASS_L3L4_ERRORS);
+		status = be_cmd_if_create(adapter, cap_flags, en_flags,
+					  &vf_cfg->if_handle, vf + 1);
 		if (status)
 			return status;
 	}
@@ -4194,15 +4255,8 @@ static int be_mac_setup(struct be_adapte
 
 		memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
 		memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
-	} else {
-		/* Maybe the HW was reset; dev_addr must be re-programmed */
-		memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN);
 	}
 
-	/* For BE3-R VFs, the PF programs the initial MAC address */
-	if (!(BEx_chip(adapter) && be_virtfn(adapter)))
-		be_cmd_pmac_add(adapter, mac, adapter->if_handle,
-				&adapter->pmac_id[0], 0);
 	return 0;
 }
 
@@ -4342,6 +4396,7 @@ static int be_func_init(struct be_adapte
 static int be_setup(struct be_adapter *adapter)
 {
 	struct device *dev = &adapter->pdev->dev;
+	u32 en_flags;
 	int status;
 
 	status = be_func_init(adapter);
@@ -4364,8 +4419,11 @@ static int be_setup(struct be_adapter *a
 	if (status)
 		goto err;
 
-	status = be_if_create(adapter, &adapter->if_handle,
-			      be_if_cap_flags(adapter), 0);
+	/* will enable all the needed filter flags in be_open() */
+	en_flags = BE_IF_FLAGS_RSS | BE_IF_FLAGS_DEFQ_RSS;
+	en_flags = en_flags & be_if_cap_flags(adapter);
+	status = be_cmd_if_create(adapter, be_if_cap_flags(adapter), en_flags,
+				  &adapter->if_handle, 0);
 	if (status)
 		goto err;
 
@@ -4391,11 +4449,6 @@ static int be_setup(struct be_adapter *a
 		dev_err(dev, "Please upgrade firmware to version >= 4.0\n");
 	}
 
-	if (adapter->vlans_added)
-		be_vid_config(adapter);
-
-	be_set_rx_mode(adapter->netdev);
-
 	status = be_cmd_set_flow_control(adapter, adapter->tx_fc,
 					 adapter->rx_fc);
 	if (status)
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/freescale/fec_main.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/freescale/fec_main.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/freescale/fec_main.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/freescale/fec_main.c	2015-08-16 19:34:13.000000000 -0400
@@ -3433,6 +3433,7 @@ fec_probe(struct platform_device *pdev)
 
 	pm_runtime_set_autosuspend_delay(&pdev->dev, FEC_MDIO_PM_TIMEOUT);
 	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_get_noresume(&pdev->dev);
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c	2015-08-16 19:34:13.000000000 -0400
@@ -586,7 +586,8 @@ static int fs_enet_start_xmit(struct sk_
 	frag = skb_shinfo(skb)->frags;
 	while (nr_frags) {
 		CBDC_SC(bdp,
-			BD_ENET_TX_STATS | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+			BD_ENET_TX_STATS | BD_ENET_TX_INTR | BD_ENET_TX_LAST |
+			BD_ENET_TX_TC);
 		CBDS_SC(bdp, BD_ENET_TX_READY);
 
 		if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0)
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/freescale/fs_enet/mac-fec.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/freescale/fs_enet/mac-fec.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/mac-fec.c	2015-08-16 19:34:13.000000000 -0400
@@ -110,7 +110,7 @@ static int do_pd_setup(struct fs_enet_pr
 }
 
 #define FEC_NAPI_RX_EVENT_MSK	(FEC_ENET_RXF | FEC_ENET_RXB)
-#define FEC_NAPI_TX_EVENT_MSK	(FEC_ENET_TXF | FEC_ENET_TXB)
+#define FEC_NAPI_TX_EVENT_MSK	(FEC_ENET_TXF)
 #define FEC_RX_EVENT		(FEC_ENET_RXF)
 #define FEC_TX_EVENT		(FEC_ENET_TXF)
 #define FEC_ERR_EVENT_MSK	(FEC_ENET_HBERR | FEC_ENET_BABR | \
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/freescale/gianfar_ethtool.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/freescale/gianfar_ethtool.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/freescale/gianfar_ethtool.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/freescale/gianfar_ethtool.c	2015-08-16 19:34:13.000000000 -0400
@@ -900,27 +900,6 @@ static int gfar_check_filer_hardware(str
 	return 0;
 }
 
-static int gfar_comp_asc(const void *a, const void *b)
-{
-	return memcmp(a, b, 4);
-}
-
-static int gfar_comp_desc(const void *a, const void *b)
-{
-	return -memcmp(a, b, 4);
-}
-
-static void gfar_swap(void *a, void *b, int size)
-{
-	u32 *_a = a;
-	u32 *_b = b;
-
-	swap(_a[0], _b[0]);
-	swap(_a[1], _b[1]);
-	swap(_a[2], _b[2]);
-	swap(_a[3], _b[3]);
-}
-
 /* Write a mask to filer cache */
 static void gfar_set_mask(u32 mask, struct filer_table *tab)
 {
@@ -1270,310 +1249,6 @@ static int gfar_convert_to_filer(struct
 	return 0;
 }
 
-/* Copy size filer entries */
-static void gfar_copy_filer_entries(struct gfar_filer_entry dst[0],
-				    struct gfar_filer_entry src[0], s32 size)
-{
-	while (size > 0) {
-		size--;
-		dst[size].ctrl = src[size].ctrl;
-		dst[size].prop = src[size].prop;
-	}
-}
-
-/* Delete the contents of the filer-table between start and end
- * and collapse them
- */
-static int gfar_trim_filer_entries(u32 begin, u32 end, struct filer_table *tab)
-{
-	int length;
-
-	if (end > MAX_FILER_CACHE_IDX || end < begin)
-		return -EINVAL;
-
-	end++;
-	length = end - begin;
-
-	/* Copy */
-	while (end < tab->index) {
-		tab->fe[begin].ctrl = tab->fe[end].ctrl;
-		tab->fe[begin++].prop = tab->fe[end++].prop;
-
-	}
-	/* Fill up with don't cares */
-	while (begin < tab->index) {
-		tab->fe[begin].ctrl = 0x60;
-		tab->fe[begin].prop = 0xFFFFFFFF;
-		begin++;
-	}
-
-	tab->index -= length;
-	return 0;
-}
-
-/* Make space on the wanted location */
-static int gfar_expand_filer_entries(u32 begin, u32 length,
-				     struct filer_table *tab)
-{
-	if (length == 0 || length + tab->index > MAX_FILER_CACHE_IDX ||
-	    begin > MAX_FILER_CACHE_IDX)
-		return -EINVAL;
-
-	gfar_copy_filer_entries(&(tab->fe[begin + length]), &(tab->fe[begin]),
-				tab->index - length + 1);
-
-	tab->index += length;
-	return 0;
-}
-
-static int gfar_get_next_cluster_start(int start, struct filer_table *tab)
-{
-	for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1);
-	     start++) {
-		if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) ==
-		    (RQFCR_AND | RQFCR_CLE))
-			return start;
-	}
-	return -1;
-}
-
-static int gfar_get_next_cluster_end(int start, struct filer_table *tab)
-{
-	for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1);
-	     start++) {
-		if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) ==
-		    (RQFCR_CLE))
-			return start;
-	}
-	return -1;
-}
-
-/* Uses hardwares clustering option to reduce
- * the number of filer table entries
- */
-static void gfar_cluster_filer(struct filer_table *tab)
-{
-	s32 i = -1, j, iend, jend;
-
-	while ((i = gfar_get_next_cluster_start(++i, tab)) != -1) {
-		j = i;
-		while ((j = gfar_get_next_cluster_start(++j, tab)) != -1) {
-			/* The cluster entries self and the previous one
-			 * (a mask) must be identical!
-			 */
-			if (tab->fe[i].ctrl != tab->fe[j].ctrl)
-				break;
-			if (tab->fe[i].prop != tab->fe[j].prop)
-				break;
-			if (tab->fe[i - 1].ctrl != tab->fe[j - 1].ctrl)
-				break;
-			if (tab->fe[i - 1].prop != tab->fe[j - 1].prop)
-				break;
-			iend = gfar_get_next_cluster_end(i, tab);
-			jend = gfar_get_next_cluster_end(j, tab);
-			if (jend == -1 || iend == -1)
-				break;
-
-			/* First we make some free space, where our cluster
-			 * element should be. Then we copy it there and finally
-			 * delete in from its old location.
-			 */
-			if (gfar_expand_filer_entries(iend, (jend - j), tab) ==
-			    -EINVAL)
-				break;
-
-			gfar_copy_filer_entries(&(tab->fe[iend + 1]),
-						&(tab->fe[jend + 1]), jend - j);
-
-			if (gfar_trim_filer_entries(jend - 1,
-						    jend + (jend - j),
-						    tab) == -EINVAL)
-				return;
-
-			/* Mask out cluster bit */
-			tab->fe[iend].ctrl &= ~(RQFCR_CLE);
-		}
-	}
-}
-
-/* Swaps the masked bits of a1<>a2 and b1<>b2 */
-static void gfar_swap_bits(struct gfar_filer_entry *a1,
-			   struct gfar_filer_entry *a2,
-			   struct gfar_filer_entry *b1,
-			   struct gfar_filer_entry *b2, u32 mask)
-{
-	u32 temp[4];
-	temp[0] = a1->ctrl & mask;
-	temp[1] = a2->ctrl & mask;
-	temp[2] = b1->ctrl & mask;
-	temp[3] = b2->ctrl & mask;
-
-	a1->ctrl &= ~mask;
-	a2->ctrl &= ~mask;
-	b1->ctrl &= ~mask;
-	b2->ctrl &= ~mask;
-
-	a1->ctrl |= temp[1];
-	a2->ctrl |= temp[0];
-	b1->ctrl |= temp[3];
-	b2->ctrl |= temp[2];
-}
-
-/* Generate a list consisting of masks values with their start and
- * end of validity and block as indicator for parts belonging
- * together (glued by ANDs) in mask_table
- */
-static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table,
-				    struct filer_table *tab)
-{
-	u32 i, and_index = 0, block_index = 1;
-
-	for (i = 0; i < tab->index; i++) {
-
-		/* LSByte of control = 0 sets a mask */
-		if (!(tab->fe[i].ctrl & 0xF)) {
-			mask_table[and_index].mask = tab->fe[i].prop;
-			mask_table[and_index].start = i;
-			mask_table[and_index].block = block_index;
-			if (and_index >= 1)
-				mask_table[and_index - 1].end = i - 1;
-			and_index++;
-		}
-		/* cluster starts and ends will be separated because they should
-		 * hold their position
-		 */
-		if (tab->fe[i].ctrl & RQFCR_CLE)
-			block_index++;
-		/* A not set AND indicates the end of a depended block */
-		if (!(tab->fe[i].ctrl & RQFCR_AND))
-			block_index++;
-	}
-
-	mask_table[and_index - 1].end = i - 1;
-
-	return and_index;
-}
-
-/* Sorts the entries of mask_table by the values of the masks.
- * Important: The 0xFF80 flags of the first and last entry of a
- * block must hold their position (which queue, CLusterEnable, ReJEct,
- * AND)
- */
-static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table,
-				 struct filer_table *temp_table, u32 and_index)
-{
-	/* Pointer to compare function (_asc or _desc) */
-	int (*gfar_comp)(const void *, const void *);
-
-	u32 i, size = 0, start = 0, prev = 1;
-	u32 old_first, old_last, new_first, new_last;
-
-	gfar_comp = &gfar_comp_desc;
-
-	for (i = 0; i < and_index; i++) {
-		if (prev != mask_table[i].block) {
-			old_first = mask_table[start].start + 1;
-			old_last = mask_table[i - 1].end;
-			sort(mask_table + start, size,
-			     sizeof(struct gfar_mask_entry),
-			     gfar_comp, &gfar_swap);
-
-			/* Toggle order for every block. This makes the
-			 * thing more efficient!
-			 */
-			if (gfar_comp == gfar_comp_desc)
-				gfar_comp = &gfar_comp_asc;
-			else
-				gfar_comp = &gfar_comp_desc;
-
-			new_first = mask_table[start].start + 1;
-			new_last = mask_table[i - 1].end;
-
-			gfar_swap_bits(&temp_table->fe[new_first],
-				       &temp_table->fe[old_first],
-				       &temp_table->fe[new_last],
-				       &temp_table->fe[old_last],
-				       RQFCR_QUEUE | RQFCR_CLE |
-				       RQFCR_RJE | RQFCR_AND);
-
-			start = i;
-			size = 0;
-		}
-		size++;
-		prev = mask_table[i].block;
-	}
-}
-
-/* Reduces the number of masks needed in the filer table to save entries
- * This is done by sorting the masks of a depended block. A depended block is
- * identified by gluing ANDs or CLE. The sorting order toggles after every
- * block. Of course entries in scope of a mask must change their location with
- * it.
- */
-static int gfar_optimize_filer_masks(struct filer_table *tab)
-{
-	struct filer_table *temp_table;
-	struct gfar_mask_entry *mask_table;
-
-	u32 and_index = 0, previous_mask = 0, i = 0, j = 0, size = 0;
-	s32 ret = 0;
-
-	/* We need a copy of the filer table because
-	 * we want to change its order
-	 */
-	temp_table = kmemdup(tab, sizeof(*temp_table), GFP_KERNEL);
-	if (temp_table == NULL)
-		return -ENOMEM;
-
-	mask_table = kcalloc(MAX_FILER_CACHE_IDX / 2 + 1,
-			     sizeof(struct gfar_mask_entry), GFP_KERNEL);
-
-	if (mask_table == NULL) {
-		ret = -ENOMEM;
-		goto end;
-	}
-
-	and_index = gfar_generate_mask_table(mask_table, tab);
-
-	gfar_sort_mask_table(mask_table, temp_table, and_index);
-
-	/* Now we can copy the data from our duplicated filer table to
-	 * the real one in the order the mask table says
-	 */
-	for (i = 0; i < and_index; i++) {
-		size = mask_table[i].end - mask_table[i].start + 1;
-		gfar_copy_filer_entries(&(tab->fe[j]),
-				&(temp_table->fe[mask_table[i].start]), size);
-		j += size;
-	}
-
-	/* And finally we just have to check for duplicated masks and drop the
-	 * second ones
-	 */
-	for (i = 0; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) {
-		if (tab->fe[i].ctrl == 0x80) {
-			previous_mask = i++;
-			break;
-		}
-	}
-	for (; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) {
-		if (tab->fe[i].ctrl == 0x80) {
-			if (tab->fe[i].prop == tab->fe[previous_mask].prop) {
-				/* Two identical ones found!
-				 * So drop the second one!
-				 */
-				gfar_trim_filer_entries(i, i, tab);
-			} else
-				/* Not identical! */
-				previous_mask = i;
-		}
-	}
-
-	kfree(mask_table);
-end:	kfree(temp_table);
-	return ret;
-}
-
 /* Write the bit-pattern from software's buffer to hardware registers */
 static int gfar_write_filer_table(struct gfar_private *priv,
 				  struct filer_table *tab)
@@ -1583,11 +1258,10 @@ static int gfar_write_filer_table(struct
 		return -EBUSY;
 
 	/* Fill regular entries */
-	for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].prop);
-	     i++)
+	for (; i < MAX_FILER_IDX && (tab->fe[i].ctrl | tab->fe[i].prop); i++)
 		gfar_write_filer(priv, i, tab->fe[i].ctrl, tab->fe[i].prop);
 	/* Fill the rest with fall-troughs */
-	for (; i < MAX_FILER_IDX - 1; i++)
+	for (; i < MAX_FILER_IDX; i++)
 		gfar_write_filer(priv, i, 0x60, 0xFFFFFFFF);
 	/* Last entry must be default accept
 	 * because that's what people expect
@@ -1621,7 +1295,6 @@ static int gfar_process_filer_changes(st
 {
 	struct ethtool_flow_spec_container *j;
 	struct filer_table *tab;
-	s32 i = 0;
 	s32 ret = 0;
 
 	/* So index is set to zero, too! */
@@ -1646,17 +1319,6 @@ static int gfar_process_filer_changes(st
 		}
 	}
 
-	i = tab->index;
-
-	/* Optimizations to save entries */
-	gfar_cluster_filer(tab);
-	gfar_optimize_filer_masks(tab);
-
-	pr_debug("\tSummary:\n"
-		 "\tData on hardware: %d\n"
-		 "\tCompression rate: %d%%\n",
-		 tab->index, 100 - (100 * tab->index) / i);
-
 	/* Write everything to hardware */
 	ret = gfar_write_filer_table(priv, tab);
 	if (ret == -EBUSY) {
@@ -1722,13 +1384,14 @@ static int gfar_add_cls(struct gfar_priv
 	}
 
 process:
+	priv->rx_list.count++;
 	ret = gfar_process_filer_changes(priv);
 	if (ret)
 		goto clean_list;
-	priv->rx_list.count++;
 	return ret;
 
 clean_list:
+	priv->rx_list.count--;
 	list_del(&temp->list);
 clean_mem:
 	kfree(temp);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/marvell/mvpp2.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/marvell/mvpp2.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/marvell/mvpp2.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/marvell/mvpp2.c	2015-08-16 19:34:13.000000000 -0400
@@ -27,6 +27,8 @@
 #include <linux/of_address.h>
 #include <linux/phy.h>
 #include <linux/clk.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
 #include <uapi/linux/ppp_defs.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
@@ -299,6 +301,7 @@
 
 /* Coalescing */
 #define MVPP2_TXDONE_COAL_PKTS_THRESH	15
+#define MVPP2_TXDONE_HRTIMER_PERIOD_NS	1000000UL
 #define MVPP2_RX_COAL_PKTS		32
 #define MVPP2_RX_COAL_USEC		100
 
@@ -660,6 +663,14 @@ struct mvpp2_pcpu_stats {
 	u64	tx_bytes;
 };
 
+/* Per-CPU port control */
+struct mvpp2_port_pcpu {
+	struct hrtimer tx_done_timer;
+	bool timer_scheduled;
+	/* Tasklet for egress finalization */
+	struct tasklet_struct tx_done_tasklet;
+};
+
 struct mvpp2_port {
 	u8 id;
 
@@ -679,6 +690,9 @@ struct mvpp2_port {
 	u32 pending_cause_rx;
 	struct napi_struct napi;
 
+	/* Per-CPU port control */
+	struct mvpp2_port_pcpu __percpu *pcpu;
+
 	/* Flags */
 	unsigned long flags;
 
@@ -776,6 +790,9 @@ struct mvpp2_txq_pcpu {
 	/* Array of transmitted skb */
 	struct sk_buff **tx_skb;
 
+	/* Array of transmitted buffers' physical addresses */
+	dma_addr_t *tx_buffs;
+
 	/* Index of last TX DMA descriptor that was inserted */
 	int txq_put_index;
 
@@ -913,8 +930,6 @@ struct mvpp2_bm_pool {
 	/* Occupied buffers indicator */
 	atomic_t in_use;
 	int in_use_thresh;
-
-	spinlock_t lock;
 };
 
 struct mvpp2_buff_hdr {
@@ -963,9 +978,13 @@ static void mvpp2_txq_inc_get(struct mvp
 }
 
 static void mvpp2_txq_inc_put(struct mvpp2_txq_pcpu *txq_pcpu,
-			      struct sk_buff *skb)
+			      struct sk_buff *skb,
+			      struct mvpp2_tx_desc *tx_desc)
 {
 	txq_pcpu->tx_skb[txq_pcpu->txq_put_index] = skb;
+	if (skb)
+		txq_pcpu->tx_buffs[txq_pcpu->txq_put_index] =
+							 tx_desc->buf_phys_addr;
 	txq_pcpu->txq_put_index++;
 	if (txq_pcpu->txq_put_index == txq_pcpu->size)
 		txq_pcpu->txq_put_index = 0;
@@ -3376,7 +3395,6 @@ static int mvpp2_bm_pool_create(struct p
 	bm_pool->pkt_size = 0;
 	bm_pool->buf_num = 0;
 	atomic_set(&bm_pool->in_use, 0);
-	spin_lock_init(&bm_pool->lock);
 
 	return 0;
 }
@@ -3647,7 +3665,6 @@ static struct mvpp2_bm_pool *
 mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type,
 		  int pkt_size)
 {
-	unsigned long flags = 0;
 	struct mvpp2_bm_pool *new_pool = &port->priv->bm_pools[pool];
 	int num;
 
@@ -3656,8 +3673,6 @@ mvpp2_bm_pool_use(struct mvpp2_port *por
 		return NULL;
 	}
 
-	spin_lock_irqsave(&new_pool->lock, flags);
-
 	if (new_pool->type == MVPP2_BM_FREE)
 		new_pool->type = type;
 
@@ -3686,8 +3701,6 @@ mvpp2_bm_pool_use(struct mvpp2_port *por
 		if (num != pkts_num) {
 			WARN(1, "pool %d: %d of %d allocated\n",
 			     new_pool->id, num, pkts_num);
-			/* We need to undo the bufs_add() allocations */
-			spin_unlock_irqrestore(&new_pool->lock, flags);
 			return NULL;
 		}
 	}
@@ -3695,15 +3708,12 @@ mvpp2_bm_pool_use(struct mvpp2_port *por
 	mvpp2_bm_pool_bufsize_set(port->priv, new_pool,
 				  MVPP2_RX_BUF_SIZE(new_pool->pkt_size));
 
-	spin_unlock_irqrestore(&new_pool->lock, flags);
-
 	return new_pool;
 }
 
 /* Initialize pools for swf */
 static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
 {
-	unsigned long flags = 0;
 	int rxq;
 
 	if (!port->pool_long) {
@@ -3714,9 +3724,7 @@ static int mvpp2_swf_bm_pool_init(struct
 		if (!port->pool_long)
 			return -ENOMEM;
 
-		spin_lock_irqsave(&port->pool_long->lock, flags);
 		port->pool_long->port_map |= (1 << port->id);
-		spin_unlock_irqrestore(&port->pool_long->lock, flags);
 
 		for (rxq = 0; rxq < rxq_number; rxq++)
 			mvpp2_rxq_long_pool_set(port, rxq, port->pool_long->id);
@@ -3730,9 +3738,7 @@ static int mvpp2_swf_bm_pool_init(struct
 		if (!port->pool_short)
 			return -ENOMEM;
 
-		spin_lock_irqsave(&port->pool_short->lock, flags);
 		port->pool_short->port_map |= (1 << port->id);
-		spin_unlock_irqrestore(&port->pool_short->lock, flags);
 
 		for (rxq = 0; rxq < rxq_number; rxq++)
 			mvpp2_rxq_short_pool_set(port, rxq,
@@ -3806,7 +3812,6 @@ static void mvpp2_interrupts_unmask(void
 
 	mvpp2_write(port->priv, MVPP2_ISR_RX_TX_MASK_REG(port->id),
 		    (MVPP2_CAUSE_MISC_SUM_MASK |
-		     MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK |
 		     MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK));
 }
 
@@ -4382,23 +4387,6 @@ static void mvpp2_rx_time_coal_set(struc
 	rxq->time_coal = usec;
 }
 
-/* Set threshold for TX_DONE pkts coalescing */
-static void mvpp2_tx_done_pkts_coal_set(void *arg)
-{
-	struct mvpp2_port *port = arg;
-	int queue;
-	u32 val;
-
-	for (queue = 0; queue < txq_number; queue++) {
-		struct mvpp2_tx_queue *txq = port->txqs[queue];
-
-		val = (txq->done_pkts_coal << MVPP2_TRANSMITTED_THRESH_OFFSET) &
-		       MVPP2_TRANSMITTED_THRESH_MASK;
-		mvpp2_write(port->priv, MVPP2_TXQ_NUM_REG, txq->id);
-		mvpp2_write(port->priv, MVPP2_TXQ_THRESH_REG, val);
-	}
-}
-
 /* Free Tx queue skbuffs */
 static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
 				struct mvpp2_tx_queue *txq,
@@ -4407,8 +4395,8 @@ static void mvpp2_txq_bufs_free(struct m
 	int i;
 
 	for (i = 0; i < num; i++) {
-		struct mvpp2_tx_desc *tx_desc = txq->descs +
-							txq_pcpu->txq_get_index;
+		dma_addr_t buf_phys_addr =
+				    txq_pcpu->tx_buffs[txq_pcpu->txq_get_index];
 		struct sk_buff *skb = txq_pcpu->tx_skb[txq_pcpu->txq_get_index];
 
 		mvpp2_txq_inc_get(txq_pcpu);
@@ -4416,8 +4404,8 @@ static void mvpp2_txq_bufs_free(struct m
 		if (!skb)
 			continue;
 
-		dma_unmap_single(port->dev->dev.parent, tx_desc->buf_phys_addr,
-				 tx_desc->data_size, DMA_TO_DEVICE);
+		dma_unmap_single(port->dev->dev.parent, buf_phys_addr,
+				 skb_headlen(skb), DMA_TO_DEVICE);
 		dev_kfree_skb_any(skb);
 	}
 }
@@ -4433,7 +4421,7 @@ static inline struct mvpp2_rx_queue *mvp
 static inline struct mvpp2_tx_queue *mvpp2_get_tx_queue(struct mvpp2_port *port,
 							u32 cause)
 {
-	int queue = fls(cause >> 16) - 1;
+	int queue = fls(cause) - 1;
 
 	return port->txqs[queue];
 }
@@ -4460,6 +4448,29 @@ static void mvpp2_txq_done(struct mvpp2_
 			netif_tx_wake_queue(nq);
 }
 
+static unsigned int mvpp2_tx_done(struct mvpp2_port *port, u32 cause)
+{
+	struct mvpp2_tx_queue *txq;
+	struct mvpp2_txq_pcpu *txq_pcpu;
+	unsigned int tx_todo = 0;
+
+	while (cause) {
+		txq = mvpp2_get_tx_queue(port, cause);
+		if (!txq)
+			break;
+
+		txq_pcpu = this_cpu_ptr(txq->pcpu);
+
+		if (txq_pcpu->count) {
+			mvpp2_txq_done(port, txq, txq_pcpu);
+			tx_todo += txq_pcpu->count;
+		}
+
+		cause &= ~(1 << txq->log_id);
+	}
+	return tx_todo;
+}
+
 /* Rx/Tx queue initialization/cleanup methods */
 
 /* Allocate and initialize descriptors for aggr TXQ */
@@ -4649,12 +4660,13 @@ static int mvpp2_txq_init(struct mvpp2_p
 		txq_pcpu->tx_skb = kmalloc(txq_pcpu->size *
 					   sizeof(*txq_pcpu->tx_skb),
 					   GFP_KERNEL);
-		if (!txq_pcpu->tx_skb) {
-			dma_free_coherent(port->dev->dev.parent,
-					  txq->size * MVPP2_DESC_ALIGNED_SIZE,
-					  txq->descs, txq->descs_phys);
-			return -ENOMEM;
-		}
+		if (!txq_pcpu->tx_skb)
+			goto error;
+
+		txq_pcpu->tx_buffs = kmalloc(txq_pcpu->size *
+					     sizeof(dma_addr_t), GFP_KERNEL);
+		if (!txq_pcpu->tx_buffs)
+			goto error;
 
 		txq_pcpu->count = 0;
 		txq_pcpu->reserved_num = 0;
@@ -4663,6 +4675,19 @@ static int mvpp2_txq_init(struct mvpp2_p
 	}
 
 	return 0;
+
+error:
+	for_each_present_cpu(cpu) {
+		txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
+		kfree(txq_pcpu->tx_skb);
+		kfree(txq_pcpu->tx_buffs);
+	}
+
+	dma_free_coherent(port->dev->dev.parent,
+			  txq->size * MVPP2_DESC_ALIGNED_SIZE,
+			  txq->descs, txq->descs_phys);
+
+	return -ENOMEM;
 }
 
 /* Free allocated TXQ resources */
@@ -4675,6 +4700,7 @@ static void mvpp2_txq_deinit(struct mvpp
 	for_each_present_cpu(cpu) {
 		txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
 		kfree(txq_pcpu->tx_skb);
+		kfree(txq_pcpu->tx_buffs);
 	}
 
 	if (txq->descs)
@@ -4805,7 +4831,6 @@ static int mvpp2_setup_txqs(struct mvpp2
 			goto err_cleanup;
 	}
 
-	on_each_cpu(mvpp2_tx_done_pkts_coal_set, port, 1);
 	on_each_cpu(mvpp2_txq_sent_counter_clear, port, 1);
 	return 0;
 
@@ -4887,6 +4912,49 @@ static void mvpp2_link_event(struct net_
 	}
 }
 
+static void mvpp2_timer_set(struct mvpp2_port_pcpu *port_pcpu)
+{
+	ktime_t interval;
+
+	if (!port_pcpu->timer_scheduled) {
+		port_pcpu->timer_scheduled = true;
+		interval = ktime_set(0, MVPP2_TXDONE_HRTIMER_PERIOD_NS);
+		hrtimer_start(&port_pcpu->tx_done_timer, interval,
+			      HRTIMER_MODE_REL_PINNED);
+	}
+}
+
+static void mvpp2_tx_proc_cb(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct mvpp2_port *port = netdev_priv(dev);
+	struct mvpp2_port_pcpu *port_pcpu = this_cpu_ptr(port->pcpu);
+	unsigned int tx_todo, cause;
+
+	if (!netif_running(dev))
+		return;
+	port_pcpu->timer_scheduled = false;
+
+	/* Process all the Tx queues */
+	cause = (1 << txq_number) - 1;
+	tx_todo = mvpp2_tx_done(port, cause);
+
+	/* Set the timer in case not all the packets were processed */
+	if (tx_todo)
+		mvpp2_timer_set(port_pcpu);
+}
+
+static enum hrtimer_restart mvpp2_hr_timer_cb(struct hrtimer *timer)
+{
+	struct mvpp2_port_pcpu *port_pcpu = container_of(timer,
+							 struct mvpp2_port_pcpu,
+							 tx_done_timer);
+
+	tasklet_schedule(&port_pcpu->tx_done_tasklet);
+
+	return HRTIMER_NORESTART;
+}
+
 /* Main RX/TX processing routines */
 
 /* Display more error info */
@@ -5144,11 +5212,11 @@ static int mvpp2_tx_frag_process(struct
 		if (i == (skb_shinfo(skb)->nr_frags - 1)) {
 			/* Last descriptor */
 			tx_desc->command = MVPP2_TXD_L_DESC;
-			mvpp2_txq_inc_put(txq_pcpu, skb);
+			mvpp2_txq_inc_put(txq_pcpu, skb, tx_desc);
 		} else {
 			/* Descriptor in the middle: Not First, Not Last */
 			tx_desc->command = 0;
-			mvpp2_txq_inc_put(txq_pcpu, NULL);
+			mvpp2_txq_inc_put(txq_pcpu, NULL, tx_desc);
 		}
 	}
 
@@ -5214,12 +5282,12 @@ static int mvpp2_tx(struct sk_buff *skb,
 		/* First and Last descriptor */
 		tx_cmd |= MVPP2_TXD_F_DESC | MVPP2_TXD_L_DESC;
 		tx_desc->command = tx_cmd;
-		mvpp2_txq_inc_put(txq_pcpu, skb);
+		mvpp2_txq_inc_put(txq_pcpu, skb, tx_desc);
 	} else {
 		/* First but not Last */
 		tx_cmd |= MVPP2_TXD_F_DESC | MVPP2_TXD_PADDING_DISABLE;
 		tx_desc->command = tx_cmd;
-		mvpp2_txq_inc_put(txq_pcpu, NULL);
+		mvpp2_txq_inc_put(txq_pcpu, NULL, tx_desc);
 
 		/* Continue with other skb fragments */
 		if (mvpp2_tx_frag_process(port, skb, aggr_txq, txq)) {
@@ -5255,6 +5323,17 @@ out:
 		dev_kfree_skb_any(skb);
 	}
 
+	/* Finalize TX processing */
+	if (txq_pcpu->count >= txq->done_pkts_coal)
+		mvpp2_txq_done(port, txq, txq_pcpu);
+
+	/* Set the timer in case not all frags were processed */
+	if (txq_pcpu->count <= frags && txq_pcpu->count > 0) {
+		struct mvpp2_port_pcpu *port_pcpu = this_cpu_ptr(port->pcpu);
+
+		mvpp2_timer_set(port_pcpu);
+	}
+
 	return NETDEV_TX_OK;
 }
 
@@ -5268,10 +5347,11 @@ static inline void mvpp2_cause_error(str
 		netdev_err(dev, "tx fifo underrun error\n");
 }
 
-static void mvpp2_txq_done_percpu(void *arg)
+static int mvpp2_poll(struct napi_struct *napi, int budget)
 {
-	struct mvpp2_port *port = arg;
-	u32 cause_rx_tx, cause_tx, cause_misc;
+	u32 cause_rx_tx, cause_rx, cause_misc;
+	int rx_done = 0;
+	struct mvpp2_port *port = netdev_priv(napi->dev);
 
 	/* Rx/Tx cause register
 	 *
@@ -5285,7 +5365,7 @@ static void mvpp2_txq_done_percpu(void *
 	 */
 	cause_rx_tx = mvpp2_read(port->priv,
 				 MVPP2_ISR_RX_TX_CAUSE_REG(port->id));
-	cause_tx = cause_rx_tx & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
+	cause_rx_tx &= ~MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
 	cause_misc = cause_rx_tx & MVPP2_CAUSE_MISC_SUM_MASK;
 
 	if (cause_misc) {
@@ -5297,26 +5377,6 @@ static void mvpp2_txq_done_percpu(void *
 			    cause_rx_tx & ~MVPP2_CAUSE_MISC_SUM_MASK);
 	}
 
-	/* Release TX descriptors */
-	if (cause_tx) {
-		struct mvpp2_tx_queue *txq = mvpp2_get_tx_queue(port, cause_tx);
-		struct mvpp2_txq_pcpu *txq_pcpu = this_cpu_ptr(txq->pcpu);
-
-		if (txq_pcpu->count)
-			mvpp2_txq_done(port, txq, txq_pcpu);
-	}
-}
-
-static int mvpp2_poll(struct napi_struct *napi, int budget)
-{
-	u32 cause_rx_tx, cause_rx;
-	int rx_done = 0;
-	struct mvpp2_port *port = netdev_priv(napi->dev);
-
-	on_each_cpu(mvpp2_txq_done_percpu, port, 1);
-
-	cause_rx_tx = mvpp2_read(port->priv,
-				 MVPP2_ISR_RX_TX_CAUSE_REG(port->id));
 	cause_rx = cause_rx_tx & MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK;
 
 	/* Process RX packets */
@@ -5561,6 +5621,8 @@ err_cleanup_rxqs:
 static int mvpp2_stop(struct net_device *dev)
 {
 	struct mvpp2_port *port = netdev_priv(dev);
+	struct mvpp2_port_pcpu *port_pcpu;
+	int cpu;
 
 	mvpp2_stop_dev(port);
 	mvpp2_phy_disconnect(port);
@@ -5569,6 +5631,13 @@ static int mvpp2_stop(struct net_device
 	on_each_cpu(mvpp2_interrupts_mask, port, 1);
 
 	free_irq(port->irq, port);
+	for_each_present_cpu(cpu) {
+		port_pcpu = per_cpu_ptr(port->pcpu, cpu);
+
+		hrtimer_cancel(&port_pcpu->tx_done_timer);
+		port_pcpu->timer_scheduled = false;
+		tasklet_kill(&port_pcpu->tx_done_tasklet);
+	}
 	mvpp2_cleanup_rxqs(port);
 	mvpp2_cleanup_txqs(port);
 
@@ -5784,7 +5853,6 @@ static int mvpp2_ethtool_set_coalesce(st
 		txq->done_pkts_coal = c->tx_max_coalesced_frames;
 	}
 
-	on_each_cpu(mvpp2_tx_done_pkts_coal_set, port, 1);
 	return 0;
 }
 
@@ -6035,6 +6103,7 @@ static int mvpp2_port_probe(struct platf
 {
 	struct device_node *phy_node;
 	struct mvpp2_port *port;
+	struct mvpp2_port_pcpu *port_pcpu;
 	struct net_device *dev;
 	struct resource *res;
 	const char *dt_mac_addr;
@@ -6044,7 +6113,7 @@ static int mvpp2_port_probe(struct platf
 	int features;
 	int phy_mode;
 	int priv_common_regs_num = 2;
-	int err, i;
+	int err, i, cpu;
 
 	dev = alloc_etherdev_mqs(sizeof(struct mvpp2_port), txq_number,
 				 rxq_number);
@@ -6135,6 +6204,24 @@ static int mvpp2_port_probe(struct platf
 	}
 	mvpp2_port_power_up(port);
 
+	port->pcpu = alloc_percpu(struct mvpp2_port_pcpu);
+	if (!port->pcpu) {
+		err = -ENOMEM;
+		goto err_free_txq_pcpu;
+	}
+
+	for_each_present_cpu(cpu) {
+		port_pcpu = per_cpu_ptr(port->pcpu, cpu);
+
+		hrtimer_init(&port_pcpu->tx_done_timer, CLOCK_MONOTONIC,
+			     HRTIMER_MODE_REL_PINNED);
+		port_pcpu->tx_done_timer.function = mvpp2_hr_timer_cb;
+		port_pcpu->timer_scheduled = false;
+
+		tasklet_init(&port_pcpu->tx_done_tasklet, mvpp2_tx_proc_cb,
+			     (unsigned long)dev);
+	}
+
 	netif_napi_add(dev, &port->napi, mvpp2_poll, NAPI_POLL_WEIGHT);
 	features = NETIF_F_SG | NETIF_F_IP_CSUM;
 	dev->features = features | NETIF_F_RXCSUM;
@@ -6144,7 +6231,7 @@ static int mvpp2_port_probe(struct platf
 	err = register_netdev(dev);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to register netdev\n");
-		goto err_free_txq_pcpu;
+		goto err_free_port_pcpu;
 	}
 	netdev_info(dev, "Using %s mac address %pM\n", mac_from, dev->dev_addr);
 
@@ -6153,6 +6240,8 @@ static int mvpp2_port_probe(struct platf
 	priv->port_list[id] = port;
 	return 0;
 
+err_free_port_pcpu:
+	free_percpu(port->pcpu);
 err_free_txq_pcpu:
 	for (i = 0; i < txq_number; i++)
 		free_percpu(port->txqs[i]->pcpu);
@@ -6171,6 +6260,7 @@ static void mvpp2_port_remove(struct mvp
 	int i;
 
 	unregister_netdev(port->dev);
+	free_percpu(port->pcpu);
 	free_percpu(port->stats);
 	for (i = 0; i < txq_number; i++)
 		free_percpu(port->txqs[i]->pcpu);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c	2015-08-16 19:34:13.000000000 -0400
@@ -391,6 +391,8 @@ static int handle_hca_cap(struct mlx5_co
 	/* disable cmdif checksum */
 	MLX5_SET(cmd_hca_cap, set_hca_cap, cmdif_checksum, 0);
 
+	MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12);
+
 	err = set_caps(dev, set_ctx, set_sz);
 
 query_ex:
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/realtek/r8169.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/realtek/r8169.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/realtek/r8169.c	2015-08-15 08:20:29.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/realtek/r8169.c	2015-08-16 20:40:12.000000000 -0400
@@ -4857,10 +4857,12 @@ static void rtl_init_rxcfg(struct rtl816
 	case RTL_GIGA_MAC_VER_46:
 	case RTL_GIGA_MAC_VER_47:
 	case RTL_GIGA_MAC_VER_48:
+		RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF);
+		break;
 	case RTL_GIGA_MAC_VER_49:
 	case RTL_GIGA_MAC_VER_50:
 	case RTL_GIGA_MAC_VER_51:
-		RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF);
+		RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
 		break;
 	default:
 		RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/rocker/rocker.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/rocker/rocker.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/rocker/rocker.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/rocker/rocker.c	2015-08-16 19:34:13.000000000 -0400
@@ -4821,6 +4821,7 @@ static void rocker_remove_ports(const st
 		rocker_port_ig_tbl(rocker_port, SWITCHDEV_TRANS_NONE,
 				   ROCKER_OP_FLAG_REMOVE);
 		unregister_netdev(rocker_port->dev);
+		free_netdev(rocker_port->dev);
 	}
 	kfree(rocker->ports);
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c	2015-08-16 19:34:13.000000000 -0400
@@ -42,7 +42,7 @@
 #define NSS_COMMON_CLK_DIV_MASK			0x7f
 
 #define NSS_COMMON_CLK_SRC_CTRL			0x14
-#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x)	(1 << x)
+#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x)	(x)
 /* Mode is coded on 1 bit but is different depending on the MAC ID:
  * MAC0: QSGMII=0 RGMII=1
  * MAC1: QSGMII=0 SGMII=0 RGMII=1
@@ -291,7 +291,7 @@ static void *ipq806x_gmac_setup(struct p
 
 	/* Configure the clock src according to the mode */
 	regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
-	val &= ~NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
+	val &= ~(1 << NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id));
 	switch (gmac->phy_mode) {
 	case PHY_INTERFACE_MODE_RGMII:
 		val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/ti/netcp_core.c linux-libre-4.2-rc7-gnu/drivers/net/ethernet/ti/netcp_core.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/ti/netcp_core.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/ti/netcp_core.c	2015-08-16 19:34:13.000000000 -0400
@@ -34,6 +34,7 @@
 #define NETCP_SOP_OFFSET	(NET_IP_ALIGN + NET_SKB_PAD)
 #define NETCP_NAPI_WEIGHT	64
 #define NETCP_TX_TIMEOUT	(5 * HZ)
+#define NETCP_PACKET_SIZE	(ETH_FRAME_LEN + ETH_FCS_LEN)
 #define NETCP_MIN_PACKET_SIZE	ETH_ZLEN
 #define NETCP_MAX_MCAST_ADDR	16
 
@@ -804,30 +805,28 @@ static void netcp_allocate_rx_buf(struct
 	if (likely(fdq == 0)) {
 		unsigned int primary_buf_len;
 		/* Allocate a primary receive queue entry */
-		buf_len = netcp->rx_buffer_sizes[0] + NETCP_SOP_OFFSET;
+		buf_len = NETCP_PACKET_SIZE + NETCP_SOP_OFFSET;
 		primary_buf_len = SKB_DATA_ALIGN(buf_len) +
 				SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
-		if (primary_buf_len <= PAGE_SIZE) {
-			bufptr = netdev_alloc_frag(primary_buf_len);
-			pad[1] = primary_buf_len;
-		} else {
-			bufptr = kmalloc(primary_buf_len, GFP_ATOMIC |
-					 GFP_DMA32 | __GFP_COLD);
-			pad[1] = 0;
-		}
+		bufptr = netdev_alloc_frag(primary_buf_len);
+		pad[1] = primary_buf_len;
 
 		if (unlikely(!bufptr)) {
-			dev_warn_ratelimited(netcp->ndev_dev, "Primary RX buffer alloc failed\n");
+			dev_warn_ratelimited(netcp->ndev_dev,
+					     "Primary RX buffer alloc failed\n");
 			goto fail;
 		}
 		dma = dma_map_single(netcp->dev, bufptr, buf_len,
 				     DMA_TO_DEVICE);
+		if (unlikely(dma_mapping_error(netcp->dev, dma)))
+			goto fail;
+
 		pad[0] = (u32)bufptr;
 
 	} else {
 		/* Allocate a secondary receive queue entry */
-		page = alloc_page(GFP_ATOMIC | GFP_DMA32 | __GFP_COLD);
+		page = alloc_page(GFP_ATOMIC | GFP_DMA | __GFP_COLD);
 		if (unlikely(!page)) {
 			dev_warn_ratelimited(netcp->ndev_dev, "Secondary page alloc failed\n");
 			goto fail;
@@ -1010,7 +1009,7 @@ netcp_tx_map_skb(struct sk_buff *skb, st
 
 	/* Map the linear buffer */
 	dma_addr = dma_map_single(dev, skb->data, pkt_len, DMA_TO_DEVICE);
-	if (unlikely(!dma_addr)) {
+	if (unlikely(dma_mapping_error(dev, dma_addr))) {
 		dev_err(netcp->ndev_dev, "Failed to map skb buffer\n");
 		return NULL;
 	}
@@ -1546,8 +1545,8 @@ static int netcp_setup_navigator_resourc
 	knav_queue_disable_notify(netcp->rx_queue);
 
 	/* open Rx FDQs */
-	for (i = 0; i < KNAV_DMA_FDQ_PER_CHAN &&
-	     netcp->rx_queue_depths[i] && netcp->rx_buffer_sizes[i]; ++i) {
+	for (i = 0; i < KNAV_DMA_FDQ_PER_CHAN && netcp->rx_queue_depths[i];
+	     ++i) {
 		snprintf(name, sizeof(name), "rx-fdq-%s-%d", ndev->name, i);
 		netcp->rx_fdq[i] = knav_queue_open(name, KNAV_QUEUE_GP, 0);
 		if (IS_ERR_OR_NULL(netcp->rx_fdq[i])) {
@@ -1941,14 +1940,6 @@ static int netcp_create_interface(struct
 		netcp->rx_queue_depths[0] = 128;
 	}
 
-	ret = of_property_read_u32_array(node_interface, "rx-buffer-size",
-					 netcp->rx_buffer_sizes,
-					 KNAV_DMA_FDQ_PER_CHAN);
-	if (ret) {
-		dev_err(dev, "missing \"rx-buffer-size\" parameter\n");
-		netcp->rx_buffer_sizes[0] = 1536;
-	}
-
 	ret = of_property_read_u32_array(node_interface, "rx-pool", temp, 2);
 	if (ret < 0) {
 		dev_err(dev, "missing \"rx-pool\" parameter\n");
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ethernet/ti/netcp.h linux-libre-4.2-rc7-gnu/drivers/net/ethernet/ti/netcp.h
--- linux-libre-4.2-rc6-gnu/drivers/net/ethernet/ti/netcp.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ethernet/ti/netcp.h	2015-08-16 19:34:13.000000000 -0400
@@ -85,7 +85,6 @@ struct netcp_intf {
 	struct list_head	rxhook_list_head;
 	unsigned int		rx_queue_id;
 	void			*rx_fdq[KNAV_DMA_FDQ_PER_CHAN];
-	u32			rx_buffer_sizes[KNAV_DMA_FDQ_PER_CHAN];
 	struct napi_struct	rx_napi;
 	struct napi_struct	tx_napi;
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/hamradio/mkiss.c linux-libre-4.2-rc7-gnu/drivers/net/hamradio/mkiss.c
--- linux-libre-4.2-rc6-gnu/drivers/net/hamradio/mkiss.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/hamradio/mkiss.c	2015-08-16 19:34:13.000000000 -0400
@@ -728,11 +728,12 @@ static int mkiss_open(struct tty_struct
 	dev->type = ARPHRD_AX25;
 
 	/* Perform the low-level AX25 initialization. */
-	if ((err = ax_open(ax->dev))) {
+	err = ax_open(ax->dev);
+	if (err)
 		goto out_free_netdev;
-	}
 
-	if (register_netdev(dev))
+	err = register_netdev(dev);
+	if (err)
 		goto out_free_buffers;
 
 	/* after register_netdev() - because else printk smashes the kernel */
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/ntb_netdev.c linux-libre-4.2-rc7-gnu/drivers/net/ntb_netdev.c
--- linux-libre-4.2-rc6-gnu/drivers/net/ntb_netdev.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/ntb_netdev.c	2015-08-16 19:34:13.000000000 -0400
@@ -102,6 +102,12 @@ static void ntb_netdev_rx_handler(struct
 
 	netdev_dbg(ndev, "%s: %d byte payload received\n", __func__, len);
 
+	if (len < 0) {
+		ndev->stats.rx_errors++;
+		ndev->stats.rx_length_errors++;
+		goto enqueue_again;
+	}
+
 	skb_put(skb, len);
 	skb->protocol = eth_type_trans(skb, ndev);
 	skb->ip_summed = CHECKSUM_NONE;
@@ -121,6 +127,7 @@ static void ntb_netdev_rx_handler(struct
 		return;
 	}
 
+enqueue_again:
 	rc = ntb_transport_rx_enqueue(qp, skb, skb->data, ndev->mtu + ETH_HLEN);
 	if (rc) {
 		dev_kfree_skb(skb);
@@ -184,7 +191,7 @@ static int ntb_netdev_open(struct net_de
 
 		rc = ntb_transport_rx_enqueue(dev->qp, skb, skb->data,
 					      ndev->mtu + ETH_HLEN);
-		if (rc == -EINVAL) {
+		if (rc) {
 			dev_kfree_skb(skb);
 			goto err;
 		}
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/virtio_net.c linux-libre-4.2-rc7-gnu/drivers/net/virtio_net.c
--- linux-libre-4.2-rc6-gnu/drivers/net/virtio_net.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/virtio_net.c	2015-08-16 19:34:13.000000000 -0400
@@ -1756,9 +1756,9 @@ static int virtnet_probe(struct virtio_d
 	/* Do we support "hardware" checksums? */
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) {
 		/* This opens up the world of extra features. */
-		dev->hw_features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+		dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_SG;
 		if (csum)
-			dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+			dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
 
 		if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
 			dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/wan/cosa.c linux-libre-4.2-rc7-gnu/drivers/net/wan/cosa.c
--- linux-libre-4.2-rc6-gnu/drivers/net/wan/cosa.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/wan/cosa.c	2015-08-16 19:34:13.000000000 -0400
@@ -589,7 +589,8 @@ static int cosa_probe(int base, int irq,
 		chan->netdev->base_addr = chan->cosa->datareg;
 		chan->netdev->irq = chan->cosa->irq;
 		chan->netdev->dma = chan->cosa->dma;
-		if (register_hdlc_device(chan->netdev)) {
+		err = register_hdlc_device(chan->netdev);
+		if (err) {
 			netdev_warn(chan->netdev,
 				    "register_hdlc_device() failed\n");
 			free_netdev(chan->netdev);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/wireless/b43/tables_nphy.c linux-libre-4.2-rc7-gnu/drivers/net/wireless/b43/tables_nphy.c
--- linux-libre-4.2-rc6-gnu/drivers/net/wireless/b43/tables_nphy.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/wireless/b43/tables_nphy.c	2015-08-16 19:34:13.000000000 -0400
@@ -3728,7 +3728,7 @@ const u32 *b43_nphy_get_tx_gain_table(st
 		switch (phy->rev) {
 		case 6:
 		case 5:
-			if (sprom->fem.ghz5.extpa_gain == 3)
+			if (sprom->fem.ghz2.extpa_gain == 3)
 				return b43_ntab_tx_gain_epa_rev3_hi_pwr_2g;
 			/* fall through */
 		case 4:
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/wireless/iwlwifi/mvm/scan.c linux-libre-4.2-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/scan.c
--- linux-libre-4.2-rc6-gnu/drivers/net/wireless/iwlwifi/mvm/scan.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/scan.c	2015-08-16 19:34:13.000000000 -0400
@@ -1023,7 +1023,7 @@ static void iwl_mvm_scan_umac_dwell(stru
 	cmd->scan_priority =
 		iwl_mvm_scan_priority(mvm, IWL_SCAN_PRIORITY_EXT_6);
 
-	if (iwl_mvm_scan_total_iterations(params) == 0)
+	if (iwl_mvm_scan_total_iterations(params) == 1)
 		cmd->ooc_priority =
 			iwl_mvm_scan_priority(mvm, IWL_SCAN_PRIORITY_EXT_6);
 	else
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c linux-libre-4.2-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c
--- linux-libre-4.2-rc6-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c	2015-08-16 19:34:13.000000000 -0400
@@ -478,10 +478,16 @@ static void iwl_pcie_apm_stop(struct iwl
 		if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000)
 			iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG,
 					  APMG_PCIDEV_STT_VAL_WAKE_ME);
-		else if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
+		else if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) {
+			iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
+				    CSR_RESET_LINK_PWR_MGMT_DISABLED);
 			iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
 				    CSR_HW_IF_CONFIG_REG_PREPARE |
 				    CSR_HW_IF_CONFIG_REG_ENABLE_PME);
+			mdelay(1);
+			iwl_clear_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
+				      CSR_RESET_LINK_PWR_MGMT_DISABLED);
+		}
 		mdelay(5);
 	}
 
@@ -575,6 +581,10 @@ static int iwl_pcie_prepare_card_hw(stru
 	if (ret >= 0)
 		return 0;
 
+	iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
+		    CSR_RESET_LINK_PWR_MGMT_DISABLED);
+	msleep(1);
+
 	for (iter = 0; iter < 10; iter++) {
 		/* If HW is not ready, prepare the conditions to check again */
 		iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
@@ -582,8 +592,10 @@ static int iwl_pcie_prepare_card_hw(stru
 
 		do {
 			ret = iwl_pcie_set_hw_ready(trans);
-			if (ret >= 0)
-				return 0;
+			if (ret >= 0) {
+				ret = 0;
+				goto out;
+			}
 
 			usleep_range(200, 1000);
 			t += 200;
@@ -593,6 +605,10 @@ static int iwl_pcie_prepare_card_hw(stru
 
 	IWL_ERR(trans, "Couldn't prepare the card\n");
 
+out:
+	iwl_clear_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
+		      CSR_RESET_LINK_PWR_MGMT_DISABLED);
+
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/wireless/iwlwifi/pcie/tx.c linux-libre-4.2-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/tx.c
--- linux-libre-4.2-rc6-gnu/drivers/net/wireless/iwlwifi/pcie/tx.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/tx.c	2015-08-16 19:34:13.000000000 -0400
@@ -1875,8 +1875,19 @@ int iwl_trans_pcie_tx(struct iwl_trans *
 
 	/* start timer if queue currently empty */
 	if (q->read_ptr == q->write_ptr) {
-		if (txq->wd_timeout)
-			mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
+		if (txq->wd_timeout) {
+			/*
+			 * If the TXQ is active, then set the timer, if not,
+			 * set the timer in remainder so that the timer will
+			 * be armed with the right value when the station will
+			 * wake up.
+			 */
+			if (!txq->frozen)
+				mod_timer(&txq->stuck_timer,
+					  jiffies + txq->wd_timeout);
+			else
+				txq->frozen_expiry_remainder = txq->wd_timeout;
+		}
 		IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", q->id);
 		iwl_trans_pcie_ref(trans);
 	}
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c linux-libre-4.2-rc7-gnu/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
--- linux-libre-4.2-rc6-gnu/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c	2015-08-15 08:25:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c	2015-08-16 20:45:38.000000000 -0400
@@ -172,6 +172,7 @@ static int rsi_load_ta_instructions(stru
 		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
 	u32 len;
 	u32 num_blocks;
+	const u8 *fw;
 	const struct firmware *fw_entry = NULL;
 	u32 block_size = dev->tx_blk_size;
 	int status = 0;
@@ -200,6 +201,10 @@ static int rsi_load_ta_instructions(stru
 		return status;
 	}
 
+	/* Copy firmware into DMA-accessible memory */
+	fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
+	if (!fw)
+		return -ENOMEM;
 	len = fw_entry->size;
 
 	if (len % 4)
@@ -210,7 +215,8 @@ static int rsi_load_ta_instructions(stru
 	rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len);
 	rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks);
 
-	status = rsi_copy_to_card(common, fw_entry->data, len, num_blocks);
+	status = rsi_copy_to_card(common, fw, len, num_blocks);
+	kfree(fw);
 	release_firmware(fw_entry);
 	return status;
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/wireless/rsi/rsi_91x_usb_ops.c linux-libre-4.2-rc7-gnu/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
--- linux-libre-4.2-rc6-gnu/drivers/net/wireless/rsi/rsi_91x_usb_ops.c	2015-08-15 08:25:33.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/wireless/rsi/rsi_91x_usb_ops.c	2015-08-16 20:45:42.000000000 -0400
@@ -146,7 +146,10 @@ static int rsi_load_ta_instructions(stru
 		return status;
 	}
 
+	/* Copy firmware into DMA-accessible memory */
 	fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
+	if (!fw)
+		return -ENOMEM;
 	len = fw_entry->size;
 
 	if (len % 4)
@@ -158,6 +161,7 @@ static int rsi_load_ta_instructions(stru
 	rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks);
 
 	status = rsi_copy_to_card(common, fw, len, num_blocks);
+	kfree(fw);
 	release_firmware(fw_entry);
 	return status;
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/wireless/rtlwifi/core.c linux-libre-4.2-rc7-gnu/drivers/net/wireless/rtlwifi/core.c
--- linux-libre-4.2-rc6-gnu/drivers/net/wireless/rtlwifi/core.c	2015-08-15 08:26:00.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/wireless/rtlwifi/core.c	2015-08-16 20:46:13.000000000 -0400
@@ -1015,9 +1015,12 @@ static void send_beacon_frame(struct iee
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
+	struct rtl_tcb_desc tcb_desc;
 
-	if (skb)
-		rtlpriv->intf_ops->adapter_tx(hw, NULL, skb, NULL);
+	if (skb) {
+		memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+		rtlpriv->intf_ops->adapter_tx(hw, NULL, skb, &tcb_desc);
+	}
 }
 
 static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/wireless/rtlwifi/rtl8723be/sw.c linux-libre-4.2-rc7-gnu/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
--- linux-libre-4.2-rc6-gnu/drivers/net/wireless/rtlwifi/rtl8723be/sw.c	2015-08-15 08:27:01.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/wireless/rtlwifi/rtl8723be/sw.c	2015-08-16 20:47:00.000000000 -0400
@@ -385,6 +385,7 @@ module_param_named(debug, rtl8723be_mod_
 module_param_named(ips, rtl8723be_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl8723be_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444);
+module_param_named(msi, rtl8723be_mod_params.msi_support, bool, 0444);
 module_param_named(disable_watchdog, rtl8723be_mod_params.disable_watchdog,
 		   bool, 0444);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/xen-netback/interface.c linux-libre-4.2-rc7-gnu/drivers/net/xen-netback/interface.c
--- linux-libre-4.2-rc6-gnu/drivers/net/xen-netback/interface.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/xen-netback/interface.c	2015-08-16 19:34:13.000000000 -0400
@@ -61,6 +61,12 @@ void xenvif_skb_zerocopy_prepare(struct
 void xenvif_skb_zerocopy_complete(struct xenvif_queue *queue)
 {
 	atomic_dec(&queue->inflight_packets);
+
+	/* Wake the dealloc thread _after_ decrementing inflight_packets so
+	 * that if kthread_stop() has already been called, the dealloc thread
+	 * does not wait forever with nothing to wake it.
+	 */
+	wake_up(&queue->dealloc_wq);
 }
 
 int xenvif_schedulable(struct xenvif *vif)
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/net/xen-netback/netback.c linux-libre-4.2-rc7-gnu/drivers/net/xen-netback/netback.c
--- linux-libre-4.2-rc6-gnu/drivers/net/xen-netback/netback.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/net/xen-netback/netback.c	2015-08-16 19:34:13.000000000 -0400
@@ -810,23 +810,17 @@ static inline struct sk_buff *xenvif_all
 static struct gnttab_map_grant_ref *xenvif_get_requests(struct xenvif_queue *queue,
 							struct sk_buff *skb,
 							struct xen_netif_tx_request *txp,
-							struct gnttab_map_grant_ref *gop)
+							struct gnttab_map_grant_ref *gop,
+							unsigned int frag_overflow,
+							struct sk_buff *nskb)
 {
 	struct skb_shared_info *shinfo = skb_shinfo(skb);
 	skb_frag_t *frags = shinfo->frags;
 	u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
 	int start;
 	pending_ring_idx_t index;
-	unsigned int nr_slots, frag_overflow = 0;
+	unsigned int nr_slots;
 
-	/* At this point shinfo->nr_frags is in fact the number of
-	 * slots, which can be as large as XEN_NETBK_LEGACY_SLOTS_MAX.
-	 */
-	if (shinfo->nr_frags > MAX_SKB_FRAGS) {
-		frag_overflow = shinfo->nr_frags - MAX_SKB_FRAGS;
-		BUG_ON(frag_overflow > MAX_SKB_FRAGS);
-		shinfo->nr_frags = MAX_SKB_FRAGS;
-	}
 	nr_slots = shinfo->nr_frags;
 
 	/* Skip first skb fragment if it is on same page as header fragment. */
@@ -841,13 +835,6 @@ static struct gnttab_map_grant_ref *xenv
 	}
 
 	if (frag_overflow) {
-		struct sk_buff *nskb = xenvif_alloc_skb(0);
-		if (unlikely(nskb == NULL)) {
-			if (net_ratelimit())
-				netdev_err(queue->vif->dev,
-					   "Can't allocate the frag_list skb.\n");
-			return NULL;
-		}
 
 		shinfo = skb_shinfo(nskb);
 		frags = shinfo->frags;
@@ -1175,9 +1162,10 @@ static void xenvif_tx_build_gops(struct
 				     unsigned *copy_ops,
 				     unsigned *map_ops)
 {
-	struct gnttab_map_grant_ref *gop = queue->tx_map_ops, *request_gop;
-	struct sk_buff *skb;
+	struct gnttab_map_grant_ref *gop = queue->tx_map_ops;
+	struct sk_buff *skb, *nskb;
 	int ret;
+	unsigned int frag_overflow;
 
 	while (skb_queue_len(&queue->tx_queue) < budget) {
 		struct xen_netif_tx_request txreq;
@@ -1265,6 +1253,29 @@ static void xenvif_tx_build_gops(struct
 			break;
 		}
 
+		skb_shinfo(skb)->nr_frags = ret;
+		if (data_len < txreq.size)
+			skb_shinfo(skb)->nr_frags++;
+		/* At this point shinfo->nr_frags is in fact the number of
+		 * slots, which can be as large as XEN_NETBK_LEGACY_SLOTS_MAX.
+		 */
+		frag_overflow = 0;
+		nskb = NULL;
+		if (skb_shinfo(skb)->nr_frags > MAX_SKB_FRAGS) {
+			frag_overflow = skb_shinfo(skb)->nr_frags - MAX_SKB_FRAGS;
+			BUG_ON(frag_overflow > MAX_SKB_FRAGS);
+			skb_shinfo(skb)->nr_frags = MAX_SKB_FRAGS;
+			nskb = xenvif_alloc_skb(0);
+			if (unlikely(nskb == NULL)) {
+				kfree_skb(skb);
+				xenvif_tx_err(queue, &txreq, idx);
+				if (net_ratelimit())
+					netdev_err(queue->vif->dev,
+						   "Can't allocate the frag_list skb.\n");
+				break;
+			}
+		}
+
 		if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) {
 			struct xen_netif_extra_info *gso;
 			gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
@@ -1272,6 +1283,7 @@ static void xenvif_tx_build_gops(struct
 			if (xenvif_set_skb_gso(queue->vif, skb, gso)) {
 				/* Failure in xenvif_set_skb_gso is fatal. */
 				kfree_skb(skb);
+				kfree_skb(nskb);
 				break;
 			}
 		}
@@ -1294,9 +1306,7 @@ static void xenvif_tx_build_gops(struct
 
 		(*copy_ops)++;
 
-		skb_shinfo(skb)->nr_frags = ret;
 		if (data_len < txreq.size) {
-			skb_shinfo(skb)->nr_frags++;
 			frag_set_pending_idx(&skb_shinfo(skb)->frags[0],
 					     pending_idx);
 			xenvif_tx_create_map_op(queue, pending_idx, &txreq, gop);
@@ -1310,13 +1320,8 @@ static void xenvif_tx_build_gops(struct
 
 		queue->pending_cons++;
 
-		request_gop = xenvif_get_requests(queue, skb, txfrags, gop);
-		if (request_gop == NULL) {
-			kfree_skb(skb);
-			xenvif_tx_err(queue, &txreq, idx);
-			break;
-		}
-		gop = request_gop;
+		gop = xenvif_get_requests(queue, skb, txfrags, gop,
+				          frag_overflow, nskb);
 
 		__skb_queue_tail(&queue->tx_queue, skb);
 
@@ -1536,7 +1541,6 @@ void xenvif_zerocopy_callback(struct ubu
 		smp_wmb();
 		queue->dealloc_prod++;
 	} while (ubuf);
-	wake_up(&queue->dealloc_wq);
 	spin_unlock_irqrestore(&queue->callback_lock, flags);
 
 	if (likely(zerocopy_success))
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/ntb/ntb.c linux-libre-4.2-rc7-gnu/drivers/ntb/ntb.c
--- linux-libre-4.2-rc6-gnu/drivers/ntb/ntb.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/ntb/ntb.c	2015-08-16 19:34:13.000000000 -0400
@@ -114,7 +114,7 @@ int ntb_register_device(struct ntb_dev *
 	ntb->dev.bus = &ntb_bus;
 	ntb->dev.parent = &ntb->pdev->dev;
 	ntb->dev.release = ntb_dev_release;
-	dev_set_name(&ntb->dev, pci_name(ntb->pdev));
+	dev_set_name(&ntb->dev, "%s", pci_name(ntb->pdev));
 
 	ntb->ctx = NULL;
 	ntb->ctx_ops = NULL;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/ntb/ntb_transport.c linux-libre-4.2-rc7-gnu/drivers/ntb/ntb_transport.c
--- linux-libre-4.2-rc6-gnu/drivers/ntb/ntb_transport.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/ntb/ntb_transport.c	2015-08-16 19:34:13.000000000 -0400
@@ -142,10 +142,11 @@ struct ntb_transport_qp {
 
 	void (*rx_handler)(struct ntb_transport_qp *qp, void *qp_data,
 			   void *data, int len);
+	struct list_head rx_post_q;
 	struct list_head rx_pend_q;
 	struct list_head rx_free_q;
-	spinlock_t ntb_rx_pend_q_lock;
-	spinlock_t ntb_rx_free_q_lock;
+	/* ntb_rx_q_lock: synchronize access to rx_XXXX_q */
+	spinlock_t ntb_rx_q_lock;
 	void *rx_buff;
 	unsigned int rx_index;
 	unsigned int rx_max_entry;
@@ -211,6 +212,8 @@ struct ntb_transport_ctx {
 	bool link_is_up;
 	struct delayed_work link_work;
 	struct work_struct link_cleanup;
+
+	struct dentry *debugfs_node_dir;
 };
 
 enum {
@@ -436,13 +439,17 @@ static ssize_t debugfs_read(struct file
 	char *buf;
 	ssize_t ret, out_offset, out_count;
 
+	qp = filp->private_data;
+
+	if (!qp || !qp->link_is_up)
+		return 0;
+
 	out_count = 1000;
 
 	buf = kmalloc(out_count, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
-	qp = filp->private_data;
 	out_offset = 0;
 	out_offset += snprintf(buf + out_offset, out_count - out_offset,
 			       "NTB QP stats\n");
@@ -534,6 +541,27 @@ out:
 	return entry;
 }
 
+static struct ntb_queue_entry *ntb_list_mv(spinlock_t *lock,
+					   struct list_head *list,
+					   struct list_head *to_list)
+{
+	struct ntb_queue_entry *entry;
+	unsigned long flags;
+
+	spin_lock_irqsave(lock, flags);
+
+	if (list_empty(list)) {
+		entry = NULL;
+	} else {
+		entry = list_first_entry(list, struct ntb_queue_entry, entry);
+		list_move_tail(&entry->entry, to_list);
+	}
+
+	spin_unlock_irqrestore(lock, flags);
+
+	return entry;
+}
+
 static int ntb_transport_setup_qp_mw(struct ntb_transport_ctx *nt,
 				     unsigned int qp_num)
 {
@@ -601,13 +629,16 @@ static void ntb_free_mw(struct ntb_trans
 }
 
 static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw,
-		      unsigned int size)
+		      resource_size_t size)
 {
 	struct ntb_transport_mw *mw = &nt->mw_vec[num_mw];
 	struct pci_dev *pdev = nt->ndev->pdev;
-	unsigned int xlat_size, buff_size;
+	size_t xlat_size, buff_size;
 	int rc;
 
+	if (!size)
+		return -EINVAL;
+
 	xlat_size = round_up(size, mw->xlat_align_size);
 	buff_size = round_up(size, mw->xlat_align);
 
@@ -627,7 +658,7 @@ static int ntb_set_mw(struct ntb_transpo
 	if (!mw->virt_addr) {
 		mw->xlat_size = 0;
 		mw->buff_size = 0;
-		dev_err(&pdev->dev, "Unable to alloc MW buff of size %d\n",
+		dev_err(&pdev->dev, "Unable to alloc MW buff of size %zu\n",
 			buff_size);
 		return -ENOMEM;
 	}
@@ -867,6 +898,8 @@ static void ntb_qp_link_work(struct work
 
 		if (qp->event_handler)
 			qp->event_handler(qp->cb_data, qp->link_is_up);
+
+		tasklet_schedule(&qp->rxc_db_work);
 	} else if (nt->link_is_up)
 		schedule_delayed_work(&qp->link_work,
 				      msecs_to_jiffies(NTB_LINK_DOWN_TIMEOUT));
@@ -923,12 +956,12 @@ static int ntb_transport_init_queue(stru
 	qp->tx_max_frame = min(transport_mtu, tx_size / 2);
 	qp->tx_max_entry = tx_size / qp->tx_max_frame;
 
-	if (nt_debugfs_dir) {
+	if (nt->debugfs_node_dir) {
 		char debugfs_name[4];
 
 		snprintf(debugfs_name, 4, "qp%d", qp_num);
 		qp->debugfs_dir = debugfs_create_dir(debugfs_name,
-						     nt_debugfs_dir);
+						     nt->debugfs_node_dir);
 
 		qp->debugfs_stats = debugfs_create_file("stats", S_IRUSR,
 							qp->debugfs_dir, qp,
@@ -941,10 +974,10 @@ static int ntb_transport_init_queue(stru
 	INIT_DELAYED_WORK(&qp->link_work, ntb_qp_link_work);
 	INIT_WORK(&qp->link_cleanup, ntb_qp_link_cleanup_work);
 
-	spin_lock_init(&qp->ntb_rx_pend_q_lock);
-	spin_lock_init(&qp->ntb_rx_free_q_lock);
+	spin_lock_init(&qp->ntb_rx_q_lock);
 	spin_lock_init(&qp->ntb_tx_free_q_lock);
 
+	INIT_LIST_HEAD(&qp->rx_post_q);
 	INIT_LIST_HEAD(&qp->rx_pend_q);
 	INIT_LIST_HEAD(&qp->rx_free_q);
 	INIT_LIST_HEAD(&qp->tx_free_q);
@@ -1031,6 +1064,12 @@ static int ntb_transport_probe(struct nt
 		goto err2;
 	}
 
+	if (nt_debugfs_dir) {
+		nt->debugfs_node_dir =
+			debugfs_create_dir(pci_name(ndev->pdev),
+					   nt_debugfs_dir);
+	}
+
 	for (i = 0; i < qp_count; i++) {
 		rc = ntb_transport_init_queue(nt, i);
 		if (rc)
@@ -1107,22 +1146,47 @@ static void ntb_transport_free(struct nt
 	kfree(nt);
 }
 
-static void ntb_rx_copy_callback(void *data)
+static void ntb_complete_rxc(struct ntb_transport_qp *qp)
 {
-	struct ntb_queue_entry *entry = data;
-	struct ntb_transport_qp *qp = entry->qp;
-	void *cb_data = entry->cb_data;
-	unsigned int len = entry->len;
-	struct ntb_payload_header *hdr = entry->rx_hdr;
+	struct ntb_queue_entry *entry;
+	void *cb_data;
+	unsigned int len;
+	unsigned long irqflags;
 
-	hdr->flags = 0;
+	spin_lock_irqsave(&qp->ntb_rx_q_lock, irqflags);
 
-	iowrite32(entry->index, &qp->rx_info->entry);
+	while (!list_empty(&qp->rx_post_q)) {
+		entry = list_first_entry(&qp->rx_post_q,
+					 struct ntb_queue_entry, entry);
+		if (!(entry->flags & DESC_DONE_FLAG))
+			break;
 
-	ntb_list_add(&qp->ntb_rx_free_q_lock, &entry->entry, &qp->rx_free_q);
+		entry->rx_hdr->flags = 0;
+		iowrite32(entry->index, &qp->rx_info->entry);
 
-	if (qp->rx_handler && qp->client_ready)
-		qp->rx_handler(qp, qp->cb_data, cb_data, len);
+		cb_data = entry->cb_data;
+		len = entry->len;
+
+		list_move_tail(&entry->entry, &qp->rx_free_q);
+
+		spin_unlock_irqrestore(&qp->ntb_rx_q_lock, irqflags);
+
+		if (qp->rx_handler && qp->client_ready)
+			qp->rx_handler(qp, qp->cb_data, cb_data, len);
+
+		spin_lock_irqsave(&qp->ntb_rx_q_lock, irqflags);
+	}
+
+	spin_unlock_irqrestore(&qp->ntb_rx_q_lock, irqflags);
+}
+
+static void ntb_rx_copy_callback(void *data)
+{
+	struct ntb_queue_entry *entry = data;
+
+	entry->flags |= DESC_DONE_FLAG;
+
+	ntb_complete_rxc(entry->qp);
 }
 
 static void ntb_memcpy_rx(struct ntb_queue_entry *entry, void *offset)
@@ -1138,19 +1202,18 @@ static void ntb_memcpy_rx(struct ntb_que
 	ntb_rx_copy_callback(entry);
 }
 
-static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset,
-			 size_t len)
+static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset)
 {
 	struct dma_async_tx_descriptor *txd;
 	struct ntb_transport_qp *qp = entry->qp;
 	struct dma_chan *chan = qp->dma_chan;
 	struct dma_device *device;
-	size_t pay_off, buff_off;
+	size_t pay_off, buff_off, len;
 	struct dmaengine_unmap_data *unmap;
 	dma_cookie_t cookie;
 	void *buf = entry->buf;
 
-	entry->len = len;
+	len = entry->len;
 
 	if (!chan)
 		goto err;
@@ -1226,7 +1289,6 @@ static int ntb_process_rxc(struct ntb_tr
 	struct ntb_payload_header *hdr;
 	struct ntb_queue_entry *entry;
 	void *offset;
-	int rc;
 
 	offset = qp->rx_buff + qp->rx_max_frame * qp->rx_index;
 	hdr = offset + qp->rx_max_frame - sizeof(struct ntb_payload_header);
@@ -1255,65 +1317,43 @@ static int ntb_process_rxc(struct ntb_tr
 		return -EIO;
 	}
 
-	entry = ntb_list_rm(&qp->ntb_rx_pend_q_lock, &qp->rx_pend_q);
+	entry = ntb_list_mv(&qp->ntb_rx_q_lock, &qp->rx_pend_q, &qp->rx_post_q);
 	if (!entry) {
 		dev_dbg(&qp->ndev->pdev->dev, "no receive buffer\n");
 		qp->rx_err_no_buf++;
-
-		rc = -ENOMEM;
-		goto err;
+		return -EAGAIN;
 	}
 
+	entry->rx_hdr = hdr;
+	entry->index = qp->rx_index;
+
 	if (hdr->len > entry->len) {
 		dev_dbg(&qp->ndev->pdev->dev,
 			"receive buffer overflow! Wanted %d got %d\n",
 			hdr->len, entry->len);
 		qp->rx_err_oflow++;
 
-		rc = -EIO;
-		goto err;
-	}
+		entry->len = -EIO;
+		entry->flags |= DESC_DONE_FLAG;
 
-	dev_dbg(&qp->ndev->pdev->dev,
-		"RX OK index %u ver %u size %d into buf size %d\n",
-		qp->rx_index, hdr->ver, hdr->len, entry->len);
+		ntb_complete_rxc(qp);
+	} else {
+		dev_dbg(&qp->ndev->pdev->dev,
+			"RX OK index %u ver %u size %d into buf size %d\n",
+			qp->rx_index, hdr->ver, hdr->len, entry->len);
 
-	qp->rx_bytes += hdr->len;
-	qp->rx_pkts++;
+		qp->rx_bytes += hdr->len;
+		qp->rx_pkts++;
 
-	entry->index = qp->rx_index;
-	entry->rx_hdr = hdr;
+		entry->len = hdr->len;
 
-	ntb_async_rx(entry, offset, hdr->len);
+		ntb_async_rx(entry, offset);
+	}
 
 	qp->rx_index++;
 	qp->rx_index %= qp->rx_max_entry;
 
 	return 0;
-
-err:
-	/* FIXME: if this syncrhonous update of the rx_index gets ahead of
-	 * asyncrhonous ntb_rx_copy_callback of previous entry, there are three
-	 * scenarios:
-	 *
-	 * 1) The peer might miss this update, but observe the update
-	 * from the memcpy completion callback.  In this case, the buffer will
-	 * not be freed on the peer to be reused for a different packet.  The
-	 * successful rx of a later packet would clear the condition, but the
-	 * condition could persist if several rx fail in a row.
-	 *
-	 * 2) The peer may observe this update before the asyncrhonous copy of
-	 * prior packets is completed.  The peer may overwrite the buffers of
-	 * the prior packets before they are copied.
-	 *
-	 * 3) Both: the peer may observe the update, and then observe the index
-	 * decrement by the asynchronous completion callback.  Who knows what
-	 * badness that will cause.
-	 */
-	hdr->flags = 0;
-	iowrite32(qp->rx_index, &qp->rx_info->entry);
-
-	return rc;
 }
 
 static void ntb_transport_rxc_db(unsigned long data)
@@ -1333,7 +1373,7 @@ static void ntb_transport_rxc_db(unsigne
 			break;
 	}
 
-	if (qp->dma_chan)
+	if (i && qp->dma_chan)
 		dma_async_issue_pending(qp->dma_chan);
 
 	if (i == qp->rx_max_entry) {
@@ -1609,7 +1649,7 @@ ntb_transport_create_queue(void *data, s
 			goto err1;
 
 		entry->qp = qp;
-		ntb_list_add(&qp->ntb_rx_free_q_lock, &entry->entry,
+		ntb_list_add(&qp->ntb_rx_q_lock, &entry->entry,
 			     &qp->rx_free_q);
 	}
 
@@ -1634,7 +1674,7 @@ err2:
 	while ((entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q)))
 		kfree(entry);
 err1:
-	while ((entry = ntb_list_rm(&qp->ntb_rx_free_q_lock, &qp->rx_free_q)))
+	while ((entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_free_q)))
 		kfree(entry);
 	if (qp->dma_chan)
 		dma_release_channel(qp->dma_chan);
@@ -1652,7 +1692,6 @@ EXPORT_SYMBOL_GPL(ntb_transport_create_q
  */
 void ntb_transport_free_queue(struct ntb_transport_qp *qp)
 {
-	struct ntb_transport_ctx *nt = qp->transport;
 	struct pci_dev *pdev;
 	struct ntb_queue_entry *entry;
 	u64 qp_bit;
@@ -1689,18 +1728,23 @@ void ntb_transport_free_queue(struct ntb
 	qp->tx_handler = NULL;
 	qp->event_handler = NULL;
 
-	while ((entry = ntb_list_rm(&qp->ntb_rx_free_q_lock, &qp->rx_free_q)))
+	while ((entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_free_q)))
 		kfree(entry);
 
-	while ((entry = ntb_list_rm(&qp->ntb_rx_pend_q_lock, &qp->rx_pend_q))) {
-		dev_warn(&pdev->dev, "Freeing item from a non-empty queue\n");
+	while ((entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_pend_q))) {
+		dev_warn(&pdev->dev, "Freeing item from non-empty rx_pend_q\n");
+		kfree(entry);
+	}
+
+	while ((entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_post_q))) {
+		dev_warn(&pdev->dev, "Freeing item from non-empty rx_post_q\n");
 		kfree(entry);
 	}
 
 	while ((entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q)))
 		kfree(entry);
 
-	nt->qp_bitmap_free |= qp_bit;
+	qp->transport->qp_bitmap_free |= qp_bit;
 
 	dev_info(&pdev->dev, "NTB Transport QP %d freed\n", qp->qp_num);
 }
@@ -1724,14 +1768,14 @@ void *ntb_transport_rx_remove(struct ntb
 	if (!qp || qp->client_ready)
 		return NULL;
 
-	entry = ntb_list_rm(&qp->ntb_rx_pend_q_lock, &qp->rx_pend_q);
+	entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_pend_q);
 	if (!entry)
 		return NULL;
 
 	buf = entry->cb_data;
 	*len = entry->len;
 
-	ntb_list_add(&qp->ntb_rx_free_q_lock, &entry->entry, &qp->rx_free_q);
+	ntb_list_add(&qp->ntb_rx_q_lock, &entry->entry, &qp->rx_free_q);
 
 	return buf;
 }
@@ -1757,15 +1801,18 @@ int ntb_transport_rx_enqueue(struct ntb_
 	if (!qp)
 		return -EINVAL;
 
-	entry = ntb_list_rm(&qp->ntb_rx_free_q_lock, &qp->rx_free_q);
+	entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_free_q);
 	if (!entry)
 		return -ENOMEM;
 
 	entry->cb_data = cb;
 	entry->buf = data;
 	entry->len = len;
+	entry->flags = 0;
 
-	ntb_list_add(&qp->ntb_rx_pend_q_lock, &entry->entry, &qp->rx_pend_q);
+	ntb_list_add(&qp->ntb_rx_q_lock, &entry->entry, &qp->rx_pend_q);
+
+	tasklet_schedule(&qp->rxc_db_work);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/platform/chrome/Kconfig linux-libre-4.2-rc7-gnu/drivers/platform/chrome/Kconfig
--- linux-libre-4.2-rc6-gnu/drivers/platform/chrome/Kconfig	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/platform/chrome/Kconfig	2015-08-16 19:34:13.000000000 -0400
@@ -4,7 +4,6 @@
 
 menuconfig CHROME_PLATFORMS
 	bool "Platform support for Chrome hardware"
-	depends on X86 || ARM
 	---help---
 	  Say Y here to get to see options for platform support for
 	  various Chromebooks and Chromeboxes. This option alone does
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/scsi/libfc/fc_exch.c linux-libre-4.2-rc7-gnu/drivers/scsi/libfc/fc_exch.c
--- linux-libre-4.2-rc6-gnu/drivers/scsi/libfc/fc_exch.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/scsi/libfc/fc_exch.c	2015-08-16 19:34:13.000000000 -0400
@@ -733,8 +733,6 @@ static bool fc_invoke_resp(struct fc_exc
 	if (resp) {
 		resp(sp, fp, arg);
 		res = true;
-	} else if (!IS_ERR(fp)) {
-		fc_frame_free(fp);
 	}
 
 	spin_lock_bh(&ep->ex_lock);
@@ -1596,7 +1594,8 @@ static void fc_exch_recv_seq_resp(struct
 	 * If new exch resp handler is valid then call that
 	 * first.
 	 */
-	fc_invoke_resp(ep, sp, fp);
+	if (!fc_invoke_resp(ep, sp, fp))
+		fc_frame_free(fp);
 
 	fc_exch_release(ep);
 	return;
@@ -1695,7 +1694,8 @@ static void fc_exch_abts_resp(struct fc_
 	fc_exch_hold(ep);
 	if (!rc)
 		fc_exch_delete(ep);
-	fc_invoke_resp(ep, sp, fp);
+	if (!fc_invoke_resp(ep, sp, fp))
+		fc_frame_free(fp);
 	if (has_rec)
 		fc_exch_timer_set(ep, ep->r_a_tov);
 	fc_exch_release(ep);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/scsi/libfc/fc_fcp.c linux-libre-4.2-rc7-gnu/drivers/scsi/libfc/fc_fcp.c
--- linux-libre-4.2-rc6-gnu/drivers/scsi/libfc/fc_fcp.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/scsi/libfc/fc_fcp.c	2015-08-16 19:34:13.000000000 -0400
@@ -1039,11 +1039,26 @@ restart:
 		fc_fcp_pkt_hold(fsp);
 		spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
 
-		if (!fc_fcp_lock_pkt(fsp)) {
+		spin_lock_bh(&fsp->scsi_pkt_lock);
+		if (!(fsp->state & FC_SRB_COMPL)) {
+			fsp->state |= FC_SRB_COMPL;
+			/*
+			 * TODO: dropping scsi_pkt_lock and then reacquiring
+			 * again around fc_fcp_cleanup_cmd() is required,
+			 * since fc_fcp_cleanup_cmd() calls into
+			 * fc_seq_set_resp() and that func preempts cpu using
+			 * schedule. May be schedule and related code should be
+			 * removed instead of unlocking here to avoid scheduling
+			 * while atomic bug.
+			 */
+			spin_unlock_bh(&fsp->scsi_pkt_lock);
+
 			fc_fcp_cleanup_cmd(fsp, error);
+
+			spin_lock_bh(&fsp->scsi_pkt_lock);
 			fc_io_compl(fsp);
-			fc_fcp_unlock_pkt(fsp);
 		}
+		spin_unlock_bh(&fsp->scsi_pkt_lock);
 
 		fc_fcp_pkt_release(fsp);
 		spin_lock_irqsave(&si->scsi_queue_lock, flags);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/scsi/libiscsi.c linux-libre-4.2-rc7-gnu/drivers/scsi/libiscsi.c
--- linux-libre-4.2-rc6-gnu/drivers/scsi/libiscsi.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/scsi/libiscsi.c	2015-08-16 19:34:13.000000000 -0400
@@ -2941,10 +2941,10 @@ void iscsi_conn_teardown(struct iscsi_cl
 {
 	struct iscsi_conn *conn = cls_conn->dd_data;
 	struct iscsi_session *session = conn->session;
-	unsigned long flags;
 
 	del_timer_sync(&conn->transport_timer);
 
+	mutex_lock(&session->eh_mutex);
 	spin_lock_bh(&session->frwd_lock);
 	conn->c_stage = ISCSI_CONN_CLEANUP_WAIT;
 	if (session->leadconn == conn) {
@@ -2956,28 +2956,6 @@ void iscsi_conn_teardown(struct iscsi_cl
 	}
 	spin_unlock_bh(&session->frwd_lock);
 
-	/*
-	 * Block until all in-progress commands for this connection
-	 * time out or fail.
-	 */
-	for (;;) {
-		spin_lock_irqsave(session->host->host_lock, flags);
-		if (!atomic_read(&session->host->host_busy)) { /* OK for ERL == 0 */
-			spin_unlock_irqrestore(session->host->host_lock, flags);
-			break;
-		}
-		spin_unlock_irqrestore(session->host->host_lock, flags);
-		msleep_interruptible(500);
-		iscsi_conn_printk(KERN_INFO, conn, "iscsi conn_destroy(): "
-				  "host_busy %d host_failed %d\n",
-				  atomic_read(&session->host->host_busy),
-				  session->host->host_failed);
-		/*
-		 * force eh_abort() to unblock
-		 */
-		wake_up(&conn->ehwait);
-	}
-
 	/* flush queued up work because we free the connection below */
 	iscsi_suspend_tx(conn);
 
@@ -2994,6 +2972,7 @@ void iscsi_conn_teardown(struct iscsi_cl
 	if (session->leadconn == conn)
 		session->leadconn = NULL;
 	spin_unlock_bh(&session->frwd_lock);
+	mutex_unlock(&session->eh_mutex);
 
 	iscsi_destroy_conn(cls_conn);
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/scsi/sd.c linux-libre-4.2-rc7-gnu/drivers/scsi/sd.c
--- linux-libre-4.2-rc6-gnu/drivers/scsi/sd.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/scsi/sd.c	2015-08-16 19:34:13.000000000 -0400
@@ -2770,9 +2770,9 @@ static int sd_revalidate_disk(struct gen
 	max_xfer = sdkp->max_xfer_blocks;
 	max_xfer <<= ilog2(sdp->sector_size) - 9;
 
-	max_xfer = min_not_zero(queue_max_hw_sectors(sdkp->disk->queue),
-				max_xfer);
-	blk_queue_max_hw_sectors(sdkp->disk->queue, max_xfer);
+	sdkp->disk->queue->limits.max_sectors =
+		min_not_zero(queue_max_hw_sectors(sdkp->disk->queue), max_xfer);
+
 	set_capacity(disk, sdkp->capacity);
 	sd_config_write_same(sdkp);
 	kfree(buffer);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/video/console/fbcon.c linux-libre-4.2-rc7-gnu/drivers/video/console/fbcon.c
--- linux-libre-4.2-rc6-gnu/drivers/video/console/fbcon.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/video/console/fbcon.c	2015-08-16 19:34:13.000000000 -0400
@@ -1306,10 +1306,11 @@ static void fbcon_cursor(struct vc_data
 	int y;
  	int c = scr_readw((u16 *) vc->vc_pos);
 
+	ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
+
 	if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)
 		return;
 
-	ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
 	if (vc->vc_cursor_type & 0x10)
 		fbcon_del_cursor_timer(info);
 	else
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/video/fbdev/Kconfig linux-libre-4.2-rc7-gnu/drivers/video/fbdev/Kconfig
--- linux-libre-4.2-rc6-gnu/drivers/video/fbdev/Kconfig	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/video/fbdev/Kconfig	2015-08-16 19:34:13.000000000 -0400
@@ -298,7 +298,7 @@ config FB_ARMCLCD
 
 # Helper logic selected only by the ARM Versatile platform family.
 config PLAT_VERSATILE_CLCD
-	def_bool ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS
+	def_bool ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS || ARCH_INTEGRATOR
 	depends on ARM
 	depends on FB_ARMCLCD && FB=y
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/video/fbdev/omap2/dss/dss-of.c linux-libre-4.2-rc7-gnu/drivers/video/fbdev/omap2/dss/dss-of.c
--- linux-libre-4.2-rc6-gnu/drivers/video/fbdev/omap2/dss/dss-of.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/video/fbdev/omap2/dss/dss-of.c	2015-08-16 19:34:13.000000000 -0400
@@ -60,6 +60,8 @@ omapdss_of_get_next_port(const struct de
 			}
 			prev = port;
 		} while (of_node_cmp(port->name, "port") != 0);
+
+		of_node_put(ports);
 	}
 
 	return port;
@@ -94,7 +96,7 @@ struct device_node *dss_of_port_get_pare
 	if (!port)
 		return NULL;
 
-	np = of_get_next_parent(port);
+	np = of_get_parent(port);
 
 	for (i = 0; i < 2 && np; ++i) {
 		struct property *prop;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/video/fbdev/pxa3xx-gcu.c linux-libre-4.2-rc7-gnu/drivers/video/fbdev/pxa3xx-gcu.c
--- linux-libre-4.2-rc6-gnu/drivers/video/fbdev/pxa3xx-gcu.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/video/fbdev/pxa3xx-gcu.c	2015-08-16 19:34:13.000000000 -0400
@@ -653,7 +653,7 @@ static int pxa3xx_gcu_probe(struct platf
 		goto err_free_dma;
 	}
 
-	ret = clk_enable(priv->clk);
+	ret = clk_prepare_enable(priv->clk);
 	if (ret < 0) {
 		dev_err(dev, "failed to enable clock\n");
 		goto err_misc_deregister;
@@ -685,7 +685,7 @@ err_misc_deregister:
 	misc_deregister(&priv->misc_dev);
 
 err_disable_clk:
-	clk_disable(priv->clk);
+	clk_disable_unprepare(priv->clk);
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/video/of_videomode.c linux-libre-4.2-rc7-gnu/drivers/video/of_videomode.c
--- linux-libre-4.2-rc6-gnu/drivers/video/of_videomode.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/video/of_videomode.c	2015-08-16 19:34:13.000000000 -0400
@@ -44,11 +44,9 @@ int of_get_videomode(struct device_node
 		index = disp->native_mode;
 
 	ret = videomode_from_timings(disp, vm, index);
-	if (ret)
-		return ret;
 
 	display_timings_release(disp);
 
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(of_get_videomode);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/xen/events/events_base.c linux-libre-4.2-rc7-gnu/drivers/xen/events/events_base.c
--- linux-libre-4.2-rc6-gnu/drivers/xen/events/events_base.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/xen/events/events_base.c	2015-08-16 19:34:13.000000000 -0400
@@ -452,12 +452,10 @@ static void xen_free_irq(unsigned irq)
 	irq_free_desc(irq);
 }
 
-static void xen_evtchn_close(unsigned int port, unsigned int cpu)
+static void xen_evtchn_close(unsigned int port)
 {
 	struct evtchn_close close;
 
-	xen_evtchn_op_close(port, cpu);
-
 	close.port = port;
 	if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
 		BUG();
@@ -546,7 +544,7 @@ out:
 
 err:
 	pr_err("irq%d: Failed to set port to irq mapping (%d)\n", irq, rc);
-	xen_evtchn_close(evtchn, NR_CPUS);
+	xen_evtchn_close(evtchn);
 	return 0;
 }
 
@@ -567,7 +565,7 @@ static void shutdown_pirq(struct irq_dat
 		return;
 
 	mask_evtchn(evtchn);
-	xen_evtchn_close(evtchn, cpu_from_evtchn(evtchn));
+	xen_evtchn_close(evtchn);
 	xen_irq_info_cleanup(info);
 }
 
@@ -611,7 +609,7 @@ static void __unbind_from_irq(unsigned i
 	if (VALID_EVTCHN(evtchn)) {
 		unsigned int cpu = cpu_from_irq(irq);
 
-		xen_evtchn_close(evtchn, cpu);
+		xen_evtchn_close(evtchn);
 
 		switch (type_from_irq(irq)) {
 		case IRQT_VIRQ:
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/xen/events/events_fifo.c linux-libre-4.2-rc7-gnu/drivers/xen/events/events_fifo.c
--- linux-libre-4.2-rc6-gnu/drivers/xen/events/events_fifo.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/xen/events/events_fifo.c	2015-08-16 19:34:13.000000000 -0400
@@ -255,12 +255,6 @@ static void evtchn_fifo_unmask(unsigned
 	}
 }
 
-static bool evtchn_fifo_is_linked(unsigned port)
-{
-	event_word_t *word = event_word_from_port(port);
-	return sync_test_bit(EVTCHN_FIFO_BIT(LINKED, word), BM(word));
-}
-
 static uint32_t clear_linked(volatile event_word_t *word)
 {
 	event_word_t new, old, w;
@@ -287,8 +281,7 @@ static void handle_irq_for_port(unsigned
 
 static void consume_one_event(unsigned cpu,
 			      struct evtchn_fifo_control_block *control_block,
-			      unsigned priority, unsigned long *ready,
-			      bool drop)
+			      unsigned priority, unsigned long *ready)
 {
 	struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu);
 	uint32_t head;
@@ -320,15 +313,13 @@ static void consume_one_event(unsigned c
 	if (head == 0)
 		clear_bit(priority, ready);
 
-	if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port)) {
-		if (likely(!drop))
-			handle_irq_for_port(port);
-	}
+	if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port))
+		handle_irq_for_port(port);
 
 	q->head[priority] = head;
 }
 
-static void __evtchn_fifo_handle_events(unsigned cpu, bool drop)
+static void evtchn_fifo_handle_events(unsigned cpu)
 {
 	struct evtchn_fifo_control_block *control_block;
 	unsigned long ready;
@@ -340,16 +331,11 @@ static void __evtchn_fifo_handle_events(
 
 	while (ready) {
 		q = find_first_bit(&ready, EVTCHN_FIFO_MAX_QUEUES);
-		consume_one_event(cpu, control_block, q, &ready, drop);
+		consume_one_event(cpu, control_block, q, &ready);
 		ready |= xchg(&control_block->ready, 0);
 	}
 }
 
-static void evtchn_fifo_handle_events(unsigned cpu)
-{
-	__evtchn_fifo_handle_events(cpu, false);
-}
-
 static void evtchn_fifo_resume(void)
 {
 	unsigned cpu;
@@ -385,26 +371,6 @@ static void evtchn_fifo_resume(void)
 	event_array_pages = 0;
 }
 
-static void evtchn_fifo_close(unsigned port, unsigned int cpu)
-{
-	if (cpu == NR_CPUS)
-		return;
-
-	get_online_cpus();
-	if (cpu_online(cpu)) {
-		if (WARN_ON(irqs_disabled()))
-			goto out;
-
-		while (evtchn_fifo_is_linked(port))
-			cpu_relax();
-	} else {
-		__evtchn_fifo_handle_events(cpu, true);
-	}
-
-out:
-	put_online_cpus();
-}
-
 static const struct evtchn_ops evtchn_ops_fifo = {
 	.max_channels      = evtchn_fifo_max_channels,
 	.nr_channels       = evtchn_fifo_nr_channels,
@@ -418,7 +384,6 @@ static const struct evtchn_ops evtchn_op
 	.unmask            = evtchn_fifo_unmask,
 	.handle_events     = evtchn_fifo_handle_events,
 	.resume            = evtchn_fifo_resume,
-	.close             = evtchn_fifo_close,
 };
 
 static int evtchn_fifo_alloc_control_block(unsigned cpu)
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/xen/events/events_internal.h linux-libre-4.2-rc7-gnu/drivers/xen/events/events_internal.h
--- linux-libre-4.2-rc6-gnu/drivers/xen/events/events_internal.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/xen/events/events_internal.h	2015-08-16 19:34:13.000000000 -0400
@@ -68,7 +68,6 @@ struct evtchn_ops {
 	bool (*test_and_set_mask)(unsigned port);
 	void (*mask)(unsigned port);
 	void (*unmask)(unsigned port);
-	void (*close)(unsigned port, unsigned cpu);
 
 	void (*handle_events)(unsigned cpu);
 	void (*resume)(void);
@@ -146,12 +145,6 @@ static inline void xen_evtchn_resume(voi
 		evtchn_ops->resume();
 }
 
-static inline void xen_evtchn_op_close(unsigned port, unsigned cpu)
-{
-	if (evtchn_ops->close)
-		return evtchn_ops->close(port, cpu);
-}
-
 void xen_evtchn_2l_init(void);
 int xen_evtchn_fifo_init(void);
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/drivers/xen/xenbus/xenbus_client.c linux-libre-4.2-rc7-gnu/drivers/xen/xenbus/xenbus_client.c
--- linux-libre-4.2-rc6-gnu/drivers/xen/xenbus/xenbus_client.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/drivers/xen/xenbus/xenbus_client.c	2015-08-16 19:34:13.000000000 -0400
@@ -814,8 +814,10 @@ static int xenbus_unmap_ring_vfree_hvm(s
 
 	rv = xenbus_unmap_ring(dev, node->handles, node->nr_handles,
 			       addrs);
-	if (!rv)
+	if (!rv) {
 		vunmap(vaddr);
+		free_xenballooned_pages(node->nr_handles, node->hvm.pages);
+	}
 	else
 		WARN(1, "Leaking %p, size %u page(s)\n", vaddr,
 		     node->nr_handles);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/fs/fuse/dev.c linux-libre-4.2-rc7-gnu/fs/fuse/dev.c
--- linux-libre-4.2-rc6-gnu/fs/fuse/dev.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/fs/fuse/dev.c	2015-08-16 19:34:13.000000000 -0400
@@ -2246,7 +2246,15 @@ static long fuse_dev_ioctl(struct file *
 
 			err = -EINVAL;
 			if (old) {
-				struct fuse_dev *fud = fuse_get_dev(old);
+				struct fuse_dev *fud = NULL;
+
+				/*
+				 * Check against file->f_op because CUSE
+				 * uses the same ioctl handler.
+				 */
+				if (old->f_op == file->f_op &&
+				    old->f_cred->user_ns == file->f_cred->user_ns)
+					fud = fuse_get_dev(old);
 
 				if (fud) {
 					mutex_lock(&fuse_mutex);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/fs/namei.c linux-libre-4.2-rc7-gnu/fs/namei.c
--- linux-libre-4.2-rc6-gnu/fs/namei.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/fs/namei.c	2015-08-16 19:34:13.000000000 -0400
@@ -879,7 +879,7 @@ static inline int may_follow_link(struct
 		return 0;
 
 	/* Allowed if parent directory not sticky and world-writable. */
-	parent = nd->path.dentry->d_inode;
+	parent = nd->inode;
 	if ((parent->i_mode & (S_ISVTX|S_IWOTH)) != (S_ISVTX|S_IWOTH))
 		return 0;
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/include/drm/drm_pciids.h linux-libre-4.2-rc7-gnu/include/drm/drm_pciids.h
--- linux-libre-4.2-rc6-gnu/include/drm/drm_pciids.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/include/drm/drm_pciids.h	2015-08-16 19:34:13.000000000 -0400
@@ -172,6 +172,7 @@
 	{0x1002, 0x6610, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6611, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6613, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_NEW_MEMMAP}, \
+	{0x1002, 0x6617, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6620, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6623, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/include/linux/skbuff.h linux-libre-4.2-rc7-gnu/include/linux/skbuff.h
--- linux-libre-4.2-rc6-gnu/include/linux/skbuff.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/include/linux/skbuff.h	2015-08-16 19:34:13.000000000 -0400
@@ -2884,11 +2884,11 @@ static inline bool skb_defer_rx_timestam
  *
  * PHY drivers may accept clones of transmitted packets for
  * timestamping via their phy_driver.txtstamp method. These drivers
- * must call this function to return the skb back to the stack, with
- * or without a timestamp.
+ * must call this function to return the skb back to the stack with a
+ * timestamp.
  *
  * @skb: clone of the the original outgoing packet
- * @hwtstamps: hardware time stamps, may be NULL if not available
+ * @hwtstamps: hardware time stamps
  *
  */
 void skb_complete_tx_timestamp(struct sk_buff *skb,
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/ipc/sem.c linux-libre-4.2-rc7-gnu/ipc/sem.c
--- linux-libre-4.2-rc6-gnu/ipc/sem.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/ipc/sem.c	2015-08-16 19:34:13.000000000 -0400
@@ -253,6 +253,16 @@ static void sem_rcu_free(struct rcu_head
 }
 
 /*
+ * spin_unlock_wait() and !spin_is_locked() are not memory barriers, they
+ * are only control barriers.
+ * The code must pair with spin_unlock(&sem->lock) or
+ * spin_unlock(&sem_perm.lock), thus just the control barrier is insufficient.
+ *
+ * smp_rmb() is sufficient, as writes cannot pass the control barrier.
+ */
+#define ipc_smp_acquire__after_spin_is_unlocked()	smp_rmb()
+
+/*
  * Wait until all currently ongoing simple ops have completed.
  * Caller must own sem_perm.lock.
  * New simple ops cannot start, because simple ops first check
@@ -275,6 +285,7 @@ static void sem_wait_array(struct sem_ar
 		sem = sma->sem_base + i;
 		spin_unlock_wait(&sem->lock);
 	}
+	ipc_smp_acquire__after_spin_is_unlocked();
 }
 
 /*
@@ -327,13 +338,12 @@ static inline int sem_lock(struct sem_ar
 		/* Then check that the global lock is free */
 		if (!spin_is_locked(&sma->sem_perm.lock)) {
 			/*
-			 * The ipc object lock check must be visible on all
-			 * cores before rechecking the complex count.  Otherwise
-			 * we can race with  another thread that does:
+			 * We need a memory barrier with acquire semantics,
+			 * otherwise we can race with another thread that does:
 			 *	complex_count++;
 			 *	spin_unlock(sem_perm.lock);
 			 */
-			smp_rmb();
+			ipc_smp_acquire__after_spin_is_unlocked();
 
 			/*
 			 * Now repeat the test of complex_count:
@@ -2074,17 +2084,28 @@ void exit_sem(struct task_struct *tsk)
 		rcu_read_lock();
 		un = list_entry_rcu(ulp->list_proc.next,
 				    struct sem_undo, list_proc);
-		if (&un->list_proc == &ulp->list_proc)
-			semid = -1;
-		 else
-			semid = un->semid;
+		if (&un->list_proc == &ulp->list_proc) {
+			/*
+			 * We must wait for freeary() before freeing this ulp,
+			 * in case we raced with last sem_undo. There is a small
+			 * possibility where we exit while freeary() didn't
+			 * finish unlocking sem_undo_list.
+			 */
+			spin_unlock_wait(&ulp->lock);
+			rcu_read_unlock();
+			break;
+		}
+		spin_lock(&ulp->lock);
+		semid = un->semid;
+		spin_unlock(&ulp->lock);
 
+		/* exit_sem raced with IPC_RMID, nothing to do */
 		if (semid == -1) {
 			rcu_read_unlock();
-			break;
+			continue;
 		}
 
-		sma = sem_obtain_object_check(tsk->nsproxy->ipc_ns, un->semid);
+		sma = sem_obtain_object_check(tsk->nsproxy->ipc_ns, semid);
 		/* exit_sem raced with IPC_RMID, nothing to do */
 		if (IS_ERR(sma)) {
 			rcu_read_unlock();
@@ -2112,9 +2133,11 @@ void exit_sem(struct task_struct *tsk)
 		ipc_assert_locked_object(&sma->sem_perm);
 		list_del(&un->list_id);
 
-		spin_lock(&ulp->lock);
+		/* we are the last process using this ulp, acquiring ulp->lock
+		 * isn't required. Besides that, we are also protected against
+		 * IPC_RMID as we hold sma->sem_perm lock now
+		 */
 		list_del_rcu(&un->list_proc);
-		spin_unlock(&ulp->lock);
 
 		/* perform adjustments registered in un */
 		for (i = 0; i < sma->sem_nsems; i++) {
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/kernel/events/core.c linux-libre-4.2-rc7-gnu/kernel/events/core.c
--- linux-libre-4.2-rc6-gnu/kernel/events/core.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/kernel/events/core.c	2015-08-16 19:34:13.000000000 -0400
@@ -1868,8 +1868,6 @@ event_sched_in(struct perf_event *event,
 
 	perf_pmu_disable(event->pmu);
 
-	event->tstamp_running += tstamp - event->tstamp_stopped;
-
 	perf_set_shadow_time(event, ctx, tstamp);
 
 	perf_log_itrace_start(event);
@@ -1881,6 +1879,8 @@ event_sched_in(struct perf_event *event,
 		goto out;
 	}
 
+	event->tstamp_running += tstamp - event->tstamp_stopped;
+
 	if (!is_software_event(event))
 		cpuctx->active_oncpu++;
 	if (!ctx->nr_active++)
@@ -3958,28 +3958,21 @@ static void perf_event_for_each(struct p
 		perf_event_for_each_child(sibling, func);
 }
 
-static int perf_event_period(struct perf_event *event, u64 __user *arg)
-{
-	struct perf_event_context *ctx = event->ctx;
-	int ret = 0, active;
+struct period_event {
+	struct perf_event *event;
 	u64 value;
+};
 
-	if (!is_sampling_event(event))
-		return -EINVAL;
-
-	if (copy_from_user(&value, arg, sizeof(value)))
-		return -EFAULT;
-
-	if (!value)
-		return -EINVAL;
+static int __perf_event_period(void *info)
+{
+	struct period_event *pe = info;
+	struct perf_event *event = pe->event;
+	struct perf_event_context *ctx = event->ctx;
+	u64 value = pe->value;
+	bool active;
 
-	raw_spin_lock_irq(&ctx->lock);
+	raw_spin_lock(&ctx->lock);
 	if (event->attr.freq) {
-		if (value > sysctl_perf_event_sample_rate) {
-			ret = -EINVAL;
-			goto unlock;
-		}
-
 		event->attr.sample_freq = value;
 	} else {
 		event->attr.sample_period = value;
@@ -3998,11 +3991,53 @@ static int perf_event_period(struct perf
 		event->pmu->start(event, PERF_EF_RELOAD);
 		perf_pmu_enable(ctx->pmu);
 	}
+	raw_spin_unlock(&ctx->lock);
 
-unlock:
+	return 0;
+}
+
+static int perf_event_period(struct perf_event *event, u64 __user *arg)
+{
+	struct period_event pe = { .event = event, };
+	struct perf_event_context *ctx = event->ctx;
+	struct task_struct *task;
+	u64 value;
+
+	if (!is_sampling_event(event))
+		return -EINVAL;
+
+	if (copy_from_user(&value, arg, sizeof(value)))
+		return -EFAULT;
+
+	if (!value)
+		return -EINVAL;
+
+	if (event->attr.freq && value > sysctl_perf_event_sample_rate)
+		return -EINVAL;
+
+	task = ctx->task;
+	pe.value = value;
+
+	if (!task) {
+		cpu_function_call(event->cpu, __perf_event_period, &pe);
+		return 0;
+	}
+
+retry:
+	if (!task_function_call(task, __perf_event_period, &pe))
+		return 0;
+
+	raw_spin_lock_irq(&ctx->lock);
+	if (ctx->is_active) {
+		raw_spin_unlock_irq(&ctx->lock);
+		task = ctx->task;
+		goto retry;
+	}
+
+	__perf_event_period(&pe);
 	raw_spin_unlock_irq(&ctx->lock);
 
-	return ret;
+	return 0;
 }
 
 static const struct file_operations perf_fops;
@@ -4740,12 +4775,20 @@ static const struct file_operations perf
  * to user-space before waking everybody up.
  */
 
+static inline struct fasync_struct **perf_event_fasync(struct perf_event *event)
+{
+	/* only the parent has fasync state */
+	if (event->parent)
+		event = event->parent;
+	return &event->fasync;
+}
+
 void perf_event_wakeup(struct perf_event *event)
 {
 	ring_buffer_wakeup(event);
 
 	if (event->pending_kill) {
-		kill_fasync(&event->fasync, SIGIO, event->pending_kill);
+		kill_fasync(perf_event_fasync(event), SIGIO, event->pending_kill);
 		event->pending_kill = 0;
 	}
 }
@@ -6124,7 +6167,7 @@ static int __perf_event_overflow(struct
 	else
 		perf_event_output(event, data, regs);
 
-	if (event->fasync && event->pending_kill) {
+	if (*perf_event_fasync(event) && event->pending_kill) {
 		event->pending_wakeup = 1;
 		irq_work_queue(&event->pending);
 	}
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/kernel/events/ring_buffer.c linux-libre-4.2-rc7-gnu/kernel/events/ring_buffer.c
--- linux-libre-4.2-rc6-gnu/kernel/events/ring_buffer.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/kernel/events/ring_buffer.c	2015-08-16 19:34:13.000000000 -0400
@@ -559,11 +559,13 @@ static void __rb_free_aux(struct ring_bu
 		rb->aux_priv = NULL;
 	}
 
-	for (pg = 0; pg < rb->aux_nr_pages; pg++)
-		rb_free_aux_page(rb, pg);
+	if (rb->aux_nr_pages) {
+		for (pg = 0; pg < rb->aux_nr_pages; pg++)
+			rb_free_aux_page(rb, pg);
 
-	kfree(rb->aux_pages);
-	rb->aux_nr_pages = 0;
+		kfree(rb->aux_pages);
+		rb->aux_nr_pages = 0;
+	}
 }
 
 void rb_free_aux(struct ring_buffer *rb)
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/kernel/locking/qspinlock_paravirt.h linux-libre-4.2-rc7-gnu/kernel/locking/qspinlock_paravirt.h
--- linux-libre-4.2-rc6-gnu/kernel/locking/qspinlock_paravirt.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/kernel/locking/qspinlock_paravirt.h	2015-08-16 19:34:13.000000000 -0400
@@ -4,6 +4,7 @@
 
 #include <linux/hash.h>
 #include <linux/bootmem.h>
+#include <linux/debug_locks.h>
 
 /*
  * Implement paravirt qspinlocks; the general idea is to halt the vcpus instead
@@ -286,15 +287,23 @@ __visible void __pv_queued_spin_unlock(s
 {
 	struct __qspinlock *l = (void *)lock;
 	struct pv_node *node;
+	u8 lockval = cmpxchg(&l->locked, _Q_LOCKED_VAL, 0);
 
 	/*
 	 * We must not unlock if SLOW, because in that case we must first
 	 * unhash. Otherwise it would be possible to have multiple @lock
 	 * entries, which would be BAD.
 	 */
-	if (likely(cmpxchg(&l->locked, _Q_LOCKED_VAL, 0) == _Q_LOCKED_VAL))
+	if (likely(lockval == _Q_LOCKED_VAL))
 		return;
 
+	if (unlikely(lockval != _Q_SLOW_VAL)) {
+		if (debug_locks_silent)
+			return;
+		WARN(1, "pvqspinlock: lock %p has corrupted value 0x%x!\n", lock, atomic_read(&lock->val));
+		return;
+	}
+
 	/*
 	 * Since the above failed to release, this must be the SLOW path.
 	 * Therefore start by looking up the blocked node and unhashing it.
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/.mailmap linux-libre-4.2-rc7-gnu/.mailmap
--- linux-libre-4.2-rc6-gnu/.mailmap	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/.mailmap	2015-08-16 19:34:13.000000000 -0400
@@ -17,6 +17,7 @@ Aleksey Gorelov <aleksey_gorelov@phoenix
 Al Viro <viro@ftp.linux.org.uk>
 Al Viro <viro@zenIV.linux.org.uk>
 Andreas Herrmann <aherrman@de.ibm.com>
+Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com>
 Andrew Morton <akpm@linux-foundation.org>
 Andrew Vasquez <andrew.vasquez@qlogic.com>
 Andy Adamson <andros@citi.umich.edu>
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/MAINTAINERS linux-libre-4.2-rc7-gnu/MAINTAINERS
--- linux-libre-4.2-rc6-gnu/MAINTAINERS	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/MAINTAINERS	2015-08-16 19:34:13.000000000 -0400
@@ -3587,6 +3587,15 @@ S:	Maintained
 F:	drivers/gpu/drm/rockchip/
 F:	Documentation/devicetree/bindings/video/rockchip*
 
+DRM DRIVERS FOR STI
+M:	Benjamin Gaignard <benjamin.gaignard@linaro.org>
+M:	Vincent Abriou <vincent.abriou@st.com>
+L:	dri-devel@lists.freedesktop.org
+T:	git http://git.linaro.org/people/benjamin.gaignard/kernel.git
+S:	Maintained
+F:	drivers/gpu/drm/sti
+F:	Documentation/devicetree/bindings/gpu/st,stih4xx.txt
+
 DSBR100 USB FM RADIO DRIVER
 M:	Alexey Klimov <klimov.linux@gmail.com>
 L:	linux-media@vger.kernel.org
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/Makefile linux-libre-4.2-rc7-gnu/Makefile
--- linux-libre-4.2-rc6-gnu/Makefile	2015-08-15 08:07:25.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/Makefile	2015-08-16 20:25:30.000000000 -0400
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 2
 SUBLEVEL = 0
-EXTRAVERSION = -rc6-gnu
+EXTRAVERSION = -rc7-gnu
 NAME = Hurr durr I'ma sheep
 
 # *DOCUMENTATION*
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/mm/cma.h linux-libre-4.2-rc7-gnu/mm/cma.h
--- linux-libre-4.2-rc6-gnu/mm/cma.h	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/mm/cma.h	2015-08-16 19:34:13.000000000 -0400
@@ -16,7 +16,7 @@ struct cma {
 extern struct cma cma_areas[MAX_CMA_AREAS];
 extern unsigned cma_area_count;
 
-static unsigned long cma_bitmap_maxno(struct cma *cma)
+static inline unsigned long cma_bitmap_maxno(struct cma *cma)
 {
 	return cma->count >> cma->order_per_bit;
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/mm/kasan/kasan.c linux-libre-4.2-rc7-gnu/mm/kasan/kasan.c
--- linux-libre-4.2-rc6-gnu/mm/kasan/kasan.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/mm/kasan/kasan.c	2015-08-16 19:34:13.000000000 -0400
@@ -2,7 +2,7 @@
  * This file contains shadow memory manipulation code.
  *
  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- * Author: Andrey Ryabinin <a.ryabinin@samsung.com>
+ * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
  *
  * Some of code borrowed from https://github.com/xairy/linux by
  *        Andrey Konovalov <adech.fo@gmail.com>
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/mm/kasan/report.c linux-libre-4.2-rc7-gnu/mm/kasan/report.c
--- linux-libre-4.2-rc6-gnu/mm/kasan/report.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/mm/kasan/report.c	2015-08-16 19:34:13.000000000 -0400
@@ -2,7 +2,7 @@
  * This file contains error reporting code.
  *
  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- * Author: Andrey Ryabinin <a.ryabinin@samsung.com>
+ * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
  *
  * Some of code borrowed from https://github.com/xairy/linux by
  *        Andrey Konovalov <adech.fo@gmail.com>
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/mm/memory-failure.c linux-libre-4.2-rc7-gnu/mm/memory-failure.c
--- linux-libre-4.2-rc6-gnu/mm/memory-failure.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/mm/memory-failure.c	2015-08-16 19:34:13.000000000 -0400
@@ -1146,8 +1146,11 @@ int memory_failure(unsigned long pfn, in
 	}
 
 	if (!PageHuge(p) && PageTransHuge(hpage)) {
-		if (unlikely(split_huge_page(hpage))) {
-			pr_err("MCE: %#lx: thp split failed\n", pfn);
+		if (!PageAnon(hpage) || unlikely(split_huge_page(hpage))) {
+			if (!PageAnon(hpage))
+				pr_err("MCE: %#lx: non anonymous thp\n", pfn);
+			else
+				pr_err("MCE: %#lx: thp split failed\n", pfn);
 			if (TestClearPageHWPoison(p))
 				atomic_long_sub(nr_pages, &num_poisoned_pages);
 			put_page(p);
@@ -1538,6 +1541,8 @@ static int get_any_page(struct page *pag
 		 */
 		ret = __get_any_page(page, pfn, 0);
 		if (!PageLRU(page)) {
+			/* Drop page reference which is from __get_any_page() */
+			put_page(page);
 			pr_info("soft_offline: %#lx: unknown non LRU page type %lx\n",
 				pfn, page->flags);
 			return -EIO;
@@ -1567,13 +1572,12 @@ static int soft_offline_huge_page(struct
 	unlock_page(hpage);
 
 	ret = isolate_huge_page(hpage, &pagelist);
-	if (ret) {
-		/*
-		 * get_any_page() and isolate_huge_page() takes a refcount each,
-		 * so need to drop one here.
-		 */
-		put_page(hpage);
-	} else {
+	/*
+	 * get_any_page() and isolate_huge_page() takes a refcount each,
+	 * so need to drop one here.
+	 */
+	put_page(hpage);
+	if (!ret) {
 		pr_info("soft offline: %#lx hugepage failed to isolate\n", pfn);
 		return -EBUSY;
 	}
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/mm/memory_hotplug.c linux-libre-4.2-rc7-gnu/mm/memory_hotplug.c
--- linux-libre-4.2-rc6-gnu/mm/memory_hotplug.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/mm/memory_hotplug.c	2015-08-16 19:34:13.000000000 -0400
@@ -1277,6 +1277,7 @@ int __ref add_memory(int nid, u64 start,
 
 	/* create new memmap entry */
 	firmware_map_add_hotplug(start, start + size, "System RAM");
+	memblock_add_node(start, size, nid);
 
 	goto out;
 
@@ -2013,6 +2014,8 @@ void __ref remove_memory(int nid, u64 st
 
 	/* remove memmap entry */
 	firmware_map_remove(start, start + size, "System RAM");
+	memblock_free(start, size);
+	memblock_remove(start, size);
 
 	arch_remove_memory(start, size);
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/mm/page_alloc.c linux-libre-4.2-rc7-gnu/mm/page_alloc.c
--- linux-libre-4.2-rc6-gnu/mm/page_alloc.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/mm/page_alloc.c	2015-08-16 19:34:13.000000000 -0400
@@ -5060,6 +5060,10 @@ static unsigned long __meminit zone_span
 {
 	unsigned long zone_start_pfn, zone_end_pfn;
 
+	/* When hotadd a new node, the node should be empty */
+	if (!node_start_pfn && !node_end_pfn)
+		return 0;
+
 	/* Get the start and end of the zone */
 	zone_start_pfn = arch_zone_lowest_possible_pfn[zone_type];
 	zone_end_pfn = arch_zone_highest_possible_pfn[zone_type];
@@ -5123,6 +5127,10 @@ static unsigned long __meminit zone_abse
 	unsigned long zone_high = arch_zone_highest_possible_pfn[zone_type];
 	unsigned long zone_start_pfn, zone_end_pfn;
 
+	/* When hotadd a new node, the node should be empty */
+	if (!node_start_pfn && !node_end_pfn)
+		return 0;
+
 	zone_start_pfn = clamp(node_start_pfn, zone_low, zone_high);
 	zone_end_pfn = clamp(node_end_pfn, zone_low, zone_high);
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/batman-adv/distributed-arp-table.c linux-libre-4.2-rc7-gnu/net/batman-adv/distributed-arp-table.c
--- linux-libre-4.2-rc6-gnu/net/batman-adv/distributed-arp-table.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/batman-adv/distributed-arp-table.c	2015-08-16 19:34:13.000000000 -0400
@@ -1138,6 +1138,9 @@ void batadv_dat_snoop_outgoing_arp_reply
  * @bat_priv: the bat priv with all the soft interface information
  * @skb: packet to check
  * @hdr_size: size of the encapsulation header
+ *
+ * Returns true if the packet was snooped and consumed by DAT. False if the
+ * packet has to be delivered to the interface
  */
 bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
 					 struct sk_buff *skb, int hdr_size)
@@ -1145,7 +1148,7 @@ bool batadv_dat_snoop_incoming_arp_reply
 	uint16_t type;
 	__be32 ip_src, ip_dst;
 	uint8_t *hw_src, *hw_dst;
-	bool ret = false;
+	bool dropped = false;
 	unsigned short vid;
 
 	if (!atomic_read(&bat_priv->distributed_arp_table))
@@ -1174,12 +1177,17 @@ bool batadv_dat_snoop_incoming_arp_reply
 	/* if this REPLY is directed to a client of mine, let's deliver the
 	 * packet to the interface
 	 */
-	ret = !batadv_is_my_client(bat_priv, hw_dst, vid);
+	dropped = !batadv_is_my_client(bat_priv, hw_dst, vid);
+
+	/* if this REPLY is sent on behalf of a client of mine, let's drop the
+	 * packet because the client will reply by itself
+	 */
+	dropped |= batadv_is_my_client(bat_priv, hw_src, vid);
 out:
-	if (ret)
+	if (dropped)
 		kfree_skb(skb);
-	/* if ret == false -> packet has to be delivered to the interface */
-	return ret;
+	/* if dropped == false -> deliver to the interface */
+	return dropped;
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/batman-adv/gateway_client.c linux-libre-4.2-rc7-gnu/net/batman-adv/gateway_client.c
--- linux-libre-4.2-rc6-gnu/net/batman-adv/gateway_client.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/batman-adv/gateway_client.c	2015-08-16 19:34:13.000000000 -0400
@@ -439,6 +439,8 @@ static void batadv_gw_node_add(struct ba
 
 	INIT_HLIST_NODE(&gw_node->list);
 	gw_node->orig_node = orig_node;
+	gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
+	gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
 	atomic_set(&gw_node->refcount, 1);
 
 	spin_lock_bh(&bat_priv->gw.list_lock);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/batman-adv/soft-interface.c linux-libre-4.2-rc7-gnu/net/batman-adv/soft-interface.c
--- linux-libre-4.2-rc6-gnu/net/batman-adv/soft-interface.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/batman-adv/soft-interface.c	2015-08-16 19:34:13.000000000 -0400
@@ -479,6 +479,9 @@ out:
  */
 void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *vlan)
 {
+	if (!vlan)
+		return;
+
 	if (atomic_dec_and_test(&vlan->refcount)) {
 		spin_lock_bh(&vlan->bat_priv->softif_vlan_list_lock);
 		hlist_del_rcu(&vlan->list);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/batman-adv/translation-table.c linux-libre-4.2-rc7-gnu/net/batman-adv/translation-table.c
--- linux-libre-4.2-rc6-gnu/net/batman-adv/translation-table.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/batman-adv/translation-table.c	2015-08-16 19:34:13.000000000 -0400
@@ -594,6 +594,9 @@ bool batadv_tt_local_add(struct net_devi
 
 	/* increase the refcounter of the related vlan */
 	vlan = batadv_softif_vlan_get(bat_priv, vid);
+	if (WARN(!vlan, "adding TT local entry %pM to non-existent VLAN %d",
+		 addr, BATADV_PRINT_VID(vid)))
+		goto out;
 
 	batadv_dbg(BATADV_DBG_TT, bat_priv,
 		   "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n",
@@ -1034,6 +1037,7 @@ uint16_t batadv_tt_local_remove(struct b
 	struct batadv_tt_local_entry *tt_local_entry;
 	uint16_t flags, curr_flags = BATADV_NO_FLAGS;
 	struct batadv_softif_vlan *vlan;
+	void *tt_entry_exists;
 
 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
 	if (!tt_local_entry)
@@ -1061,11 +1065,22 @@ uint16_t batadv_tt_local_remove(struct b
 	 * immediately purge it
 	 */
 	batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL);
-	hlist_del_rcu(&tt_local_entry->common.hash_entry);
+
+	tt_entry_exists = batadv_hash_remove(bat_priv->tt.local_hash,
+					     batadv_compare_tt,
+					     batadv_choose_tt,
+					     &tt_local_entry->common);
+	if (!tt_entry_exists)
+		goto out;
+
+	/* extra call to free the local tt entry */
 	batadv_tt_local_entry_free_ref(tt_local_entry);
 
 	/* decrease the reference held for this vlan */
 	vlan = batadv_softif_vlan_get(bat_priv, vid);
+	if (!vlan)
+		goto out;
+
 	batadv_softif_vlan_free_ref(vlan);
 	batadv_softif_vlan_free_ref(vlan);
 
@@ -1166,8 +1181,10 @@ static void batadv_tt_local_table_free(s
 			/* decrease the reference held for this vlan */
 			vlan = batadv_softif_vlan_get(bat_priv,
 						      tt_common_entry->vid);
-			batadv_softif_vlan_free_ref(vlan);
-			batadv_softif_vlan_free_ref(vlan);
+			if (vlan) {
+				batadv_softif_vlan_free_ref(vlan);
+				batadv_softif_vlan_free_ref(vlan);
+			}
 
 			batadv_tt_local_entry_free_ref(tt_local);
 		}
@@ -3207,8 +3224,10 @@ static void batadv_tt_local_purge_pendin
 
 			/* decrease the reference held for this vlan */
 			vlan = batadv_softif_vlan_get(bat_priv, tt_common->vid);
-			batadv_softif_vlan_free_ref(vlan);
-			batadv_softif_vlan_free_ref(vlan);
+			if (vlan) {
+				batadv_softif_vlan_free_ref(vlan);
+				batadv_softif_vlan_free_ref(vlan);
+			}
 
 			batadv_tt_local_entry_free_ref(tt_local);
 		}
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/bluetooth/mgmt.c linux-libre-4.2-rc7-gnu/net/bluetooth/mgmt.c
--- linux-libre-4.2-rc6-gnu/net/bluetooth/mgmt.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/bluetooth/mgmt.c	2015-08-16 19:34:13.000000000 -0400
@@ -7820,7 +7820,7 @@ void mgmt_new_ltk(struct hci_dev *hdev,
 	/* Make sure we copy only the significant bytes based on the
 	 * encryption key size, and set the rest of the value to zeroes.
 	 */
-	memcpy(ev.key.val, key->val, sizeof(key->enc_size));
+	memcpy(ev.key.val, key->val, key->enc_size);
 	memset(ev.key.val + key->enc_size, 0,
 	       sizeof(ev.key.val) - key->enc_size);
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/bridge/br_netlink.c linux-libre-4.2-rc7-gnu/net/bridge/br_netlink.c
--- linux-libre-4.2-rc6-gnu/net/bridge/br_netlink.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/bridge/br_netlink.c	2015-08-16 19:34:13.000000000 -0400
@@ -112,6 +112,8 @@ static inline size_t br_port_info_size(v
 		+ nla_total_size(1)	/* IFLA_BRPORT_FAST_LEAVE */
 		+ nla_total_size(1)	/* IFLA_BRPORT_LEARNING */
 		+ nla_total_size(1)	/* IFLA_BRPORT_UNICAST_FLOOD */
+		+ nla_total_size(1)	/* IFLA_BRPORT_PROXYARP */
+		+ nla_total_size(1)	/* IFLA_BRPORT_PROXYARP_WIFI */
 		+ 0;
 }
 
@@ -506,6 +508,8 @@ static const struct nla_policy br_port_p
 	[IFLA_BRPORT_FAST_LEAVE]= { .type = NLA_U8 },
 	[IFLA_BRPORT_LEARNING]	= { .type = NLA_U8 },
 	[IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
+	[IFLA_BRPORT_PROXYARP]	= { .type = NLA_U8 },
+	[IFLA_BRPORT_PROXYARP_WIFI] = { .type = NLA_U8 },
 };
 
 /* Change the state of the port and notify spanning tree */
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/core/datagram.c linux-libre-4.2-rc7-gnu/net/core/datagram.c
--- linux-libre-4.2-rc6-gnu/net/core/datagram.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/core/datagram.c	2015-08-16 19:34:13.000000000 -0400
@@ -131,12 +131,12 @@ out_noerr:
 	goto out;
 }
 
-static int skb_set_peeked(struct sk_buff *skb)
+static struct sk_buff *skb_set_peeked(struct sk_buff *skb)
 {
 	struct sk_buff *nskb;
 
 	if (skb->peeked)
-		return 0;
+		return skb;
 
 	/* We have to unshare an skb before modifying it. */
 	if (!skb_shared(skb))
@@ -144,7 +144,7 @@ static int skb_set_peeked(struct sk_buff
 
 	nskb = skb_clone(skb, GFP_ATOMIC);
 	if (!nskb)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	skb->prev->next = nskb;
 	skb->next->prev = nskb;
@@ -157,7 +157,7 @@ static int skb_set_peeked(struct sk_buff
 done:
 	skb->peeked = 1;
 
-	return 0;
+	return skb;
 }
 
 /**
@@ -229,8 +229,9 @@ struct sk_buff *__skb_recv_datagram(stru
 					continue;
 				}
 
-				error = skb_set_peeked(skb);
-				if (error)
+				skb = skb_set_peeked(skb);
+				error = PTR_ERR(skb);
+				if (IS_ERR(skb))
 					goto unlock_err;
 
 				atomic_inc(&skb->users);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/core/pktgen.c linux-libre-4.2-rc7-gnu/net/core/pktgen.c
--- linux-libre-4.2-rc6-gnu/net/core/pktgen.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/core/pktgen.c	2015-08-16 19:34:13.000000000 -0400
@@ -3514,8 +3514,6 @@ static int pktgen_thread_worker(void *ar
 
 	set_freezable();
 
-	__set_current_state(TASK_RUNNING);
-
 	while (!kthread_should_stop()) {
 		pkt_dev = next_to_run(t);
 
@@ -3560,7 +3558,6 @@ static int pktgen_thread_worker(void *ar
 
 		try_to_freeze();
 	}
-	set_current_state(TASK_INTERRUPTIBLE);
 
 	pr_debug("%s stopping all device\n", t->tsk->comm);
 	pktgen_stop(t);
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/core/request_sock.c linux-libre-4.2-rc7-gnu/net/core/request_sock.c
--- linux-libre-4.2-rc6-gnu/net/core/request_sock.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/core/request_sock.c	2015-08-16 19:34:13.000000000 -0400
@@ -103,10 +103,16 @@ void reqsk_queue_destroy(struct request_
 			spin_lock_bh(&queue->syn_wait_lock);
 			while ((req = lopt->syn_table[i]) != NULL) {
 				lopt->syn_table[i] = req->dl_next;
+				/* Because of following del_timer_sync(),
+				 * we must release the spinlock here
+				 * or risk a dead lock.
+				 */
+				spin_unlock_bh(&queue->syn_wait_lock);
 				atomic_inc(&lopt->qlen_dec);
-				if (del_timer(&req->rsk_timer))
+				if (del_timer_sync(&req->rsk_timer))
 					reqsk_put(req);
 				reqsk_put(req);
+				spin_lock_bh(&queue->syn_wait_lock);
 			}
 			spin_unlock_bh(&queue->syn_wait_lock);
 		}
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/dsa/slave.c linux-libre-4.2-rc7-gnu/net/dsa/slave.c
--- linux-libre-4.2-rc6-gnu/net/dsa/slave.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/dsa/slave.c	2015-08-16 19:34:13.000000000 -0400
@@ -756,7 +756,8 @@ static int dsa_slave_phy_connect(struct
 		return -ENODEV;
 
 	/* Use already configured phy mode */
-	p->phy_interface = p->phy->interface;
+	if (p->phy_interface == PHY_INTERFACE_MODE_NA)
+		p->phy_interface = p->phy->interface;
 	phy_connect_direct(slave_dev, p->phy, dsa_slave_adjust_link,
 			   p->phy_interface);
 
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/ipv4/inet_connection_sock.c linux-libre-4.2-rc7-gnu/net/ipv4/inet_connection_sock.c
--- linux-libre-4.2-rc6-gnu/net/ipv4/inet_connection_sock.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/ipv4/inet_connection_sock.c	2015-08-16 19:34:13.000000000 -0400
@@ -593,7 +593,7 @@ static bool reqsk_queue_unlink(struct re
 	}
 
 	spin_unlock(&queue->syn_wait_lock);
-	if (del_timer(&req->rsk_timer))
+	if (del_timer_sync(&req->rsk_timer))
 		reqsk_put(req);
 	return found;
 }
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/ipv4/netfilter/ipt_SYNPROXY.c linux-libre-4.2-rc7-gnu/net/ipv4/netfilter/ipt_SYNPROXY.c
--- linux-libre-4.2-rc6-gnu/net/ipv4/netfilter/ipt_SYNPROXY.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/ipv4/netfilter/ipt_SYNPROXY.c	2015-08-16 19:34:13.000000000 -0400
@@ -226,7 +226,8 @@ synproxy_send_client_ack(const struct sy
 
 	synproxy_build_options(nth, opts);
 
-	synproxy_send_tcp(skb, nskb, NULL, 0, niph, nth, tcp_hdr_size);
+	synproxy_send_tcp(skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
+	                  niph, nth, tcp_hdr_size);
 }
 
 static bool
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/ipv4/tcp_ipv4.c linux-libre-4.2-rc7-gnu/net/ipv4/tcp_ipv4.c
--- linux-libre-4.2-rc6-gnu/net/ipv4/tcp_ipv4.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/ipv4/tcp_ipv4.c	2015-08-16 19:34:13.000000000 -0400
@@ -1348,7 +1348,7 @@ static struct sock *tcp_v4_hnd_req(struc
 	req = inet_csk_search_req(sk, th->source, iph->saddr, iph->daddr);
 	if (req) {
 		nsk = tcp_check_req(sk, skb, req, false);
-		if (!nsk)
+		if (!nsk || nsk == sk)
 			reqsk_put(req);
 		return nsk;
 	}
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/ipv4/udp.c linux-libre-4.2-rc7-gnu/net/ipv4/udp.c
--- linux-libre-4.2-rc6-gnu/net/ipv4/udp.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/ipv4/udp.c	2015-08-16 19:34:13.000000000 -0400
@@ -1995,12 +1995,19 @@ void udp_v4_early_demux(struct sk_buff *
 
 	skb->sk = sk;
 	skb->destructor = sock_efree;
-	dst = sk->sk_rx_dst;
+	dst = READ_ONCE(sk->sk_rx_dst);
 
 	if (dst)
 		dst = dst_check(dst, 0);
-	if (dst)
-		skb_dst_set_noref(skb, dst);
+	if (dst) {
+		/* DST_NOCACHE can not be used without taking a reference */
+		if (dst->flags & DST_NOCACHE) {
+			if (likely(atomic_inc_not_zero(&dst->__refcnt)))
+				skb_dst_set(skb, dst);
+		} else {
+			skb_dst_set_noref(skb, dst);
+		}
+	}
 }
 
 int udp_rcv(struct sk_buff *skb)
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/ipv6/netfilter/ip6t_SYNPROXY.c linux-libre-4.2-rc7-gnu/net/ipv6/netfilter/ip6t_SYNPROXY.c
--- linux-libre-4.2-rc6-gnu/net/ipv6/netfilter/ip6t_SYNPROXY.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/ipv6/netfilter/ip6t_SYNPROXY.c	2015-08-16 19:34:13.000000000 -0400
@@ -37,12 +37,13 @@ synproxy_build_ip(struct sk_buff *skb, c
 }
 
 static void
-synproxy_send_tcp(const struct sk_buff *skb, struct sk_buff *nskb,
+synproxy_send_tcp(const struct synproxy_net *snet,
+		  const struct sk_buff *skb, struct sk_buff *nskb,
 		  struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo,
 		  struct ipv6hdr *niph, struct tcphdr *nth,
 		  unsigned int tcp_hdr_size)
 {
-	struct net *net = nf_ct_net((struct nf_conn *)nfct);
+	struct net *net = nf_ct_net(snet->tmpl);
 	struct dst_entry *dst;
 	struct flowi6 fl6;
 
@@ -83,7 +84,8 @@ free_nskb:
 }
 
 static void
-synproxy_send_client_synack(const struct sk_buff *skb, const struct tcphdr *th,
+synproxy_send_client_synack(const struct synproxy_net *snet,
+			    const struct sk_buff *skb, const struct tcphdr *th,
 			    const struct synproxy_options *opts)
 {
 	struct sk_buff *nskb;
@@ -119,7 +121,7 @@ synproxy_send_client_synack(const struct
 
 	synproxy_build_options(nth, opts);
 
-	synproxy_send_tcp(skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
+	synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
 			  niph, nth, tcp_hdr_size);
 }
 
@@ -163,7 +165,7 @@ synproxy_send_server_syn(const struct sy
 
 	synproxy_build_options(nth, opts);
 
-	synproxy_send_tcp(skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW,
+	synproxy_send_tcp(snet, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW,
 			  niph, nth, tcp_hdr_size);
 }
 
@@ -203,7 +205,7 @@ synproxy_send_server_ack(const struct sy
 
 	synproxy_build_options(nth, opts);
 
-	synproxy_send_tcp(skb, nskb, NULL, 0, niph, nth, tcp_hdr_size);
+	synproxy_send_tcp(snet, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size);
 }
 
 static void
@@ -241,7 +243,8 @@ synproxy_send_client_ack(const struct sy
 
 	synproxy_build_options(nth, opts);
 
-	synproxy_send_tcp(skb, nskb, NULL, 0, niph, nth, tcp_hdr_size);
+	synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
+	                  niph, nth, tcp_hdr_size);
 }
 
 static bool
@@ -301,7 +304,7 @@ synproxy_tg6(struct sk_buff *skb, const
 					  XT_SYNPROXY_OPT_SACK_PERM |
 					  XT_SYNPROXY_OPT_ECN);
 
-		synproxy_send_client_synack(skb, th, &opts);
+		synproxy_send_client_synack(snet, skb, th, &opts);
 		return NF_DROP;
 
 	} else if (th->ack && !(th->fin || th->rst || th->syn)) {
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/ipv6/route.c linux-libre-4.2-rc7-gnu/net/ipv6/route.c
--- linux-libre-4.2-rc6-gnu/net/ipv6/route.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/ipv6/route.c	2015-08-16 19:34:13.000000000 -0400
@@ -1831,6 +1831,7 @@ int ip6_route_add(struct fib6_config *cf
 		int gwa_type;
 
 		gw_addr = &cfg->fc_gateway;
+		gwa_type = ipv6_addr_type(gw_addr);
 
 		/* if gw_addr is local we will fail to detect this in case
 		 * address is still TENTATIVE (DAD in progress). rt6_lookup()
@@ -1838,11 +1839,12 @@ int ip6_route_add(struct fib6_config *cf
 		 * prefix route was assigned to, which might be non-loopback.
 		 */
 		err = -EINVAL;
-		if (ipv6_chk_addr_and_flags(net, gw_addr, NULL, 0, 0))
+		if (ipv6_chk_addr_and_flags(net, gw_addr,
+					    gwa_type & IPV6_ADDR_LINKLOCAL ?
+					    dev : NULL, 0, 0))
 			goto out;
 
 		rt->rt6i_gateway = *gw_addr;
-		gwa_type = ipv6_addr_type(gw_addr);
 
 		if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) {
 			struct rt6_info *grt;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/ipv6/tcp_ipv6.c linux-libre-4.2-rc7-gnu/net/ipv6/tcp_ipv6.c
--- linux-libre-4.2-rc6-gnu/net/ipv6/tcp_ipv6.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/ipv6/tcp_ipv6.c	2015-08-16 19:34:13.000000000 -0400
@@ -943,7 +943,7 @@ static struct sock *tcp_v6_hnd_req(struc
 				   &ipv6_hdr(skb)->daddr, tcp_v6_iif(skb));
 	if (req) {
 		nsk = tcp_check_req(sk, skb, req, false);
-		if (!nsk)
+		if (!nsk || nsk == sk)
 			reqsk_put(req);
 		return nsk;
 	}
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/netfilter/nf_conntrack_core.c linux-libre-4.2-rc7-gnu/net/netfilter/nf_conntrack_core.c
--- linux-libre-4.2-rc6-gnu/net/netfilter/nf_conntrack_core.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/netfilter/nf_conntrack_core.c	2015-08-16 19:34:13.000000000 -0400
@@ -292,7 +292,7 @@ struct nf_conn *nf_ct_tmpl_alloc(struct
 {
 	struct nf_conn *tmpl;
 
-	tmpl = kzalloc(sizeof(struct nf_conn), GFP_KERNEL);
+	tmpl = kzalloc(sizeof(*tmpl), flags);
 	if (tmpl == NULL)
 		return NULL;
 
@@ -303,7 +303,7 @@ struct nf_conn *nf_ct_tmpl_alloc(struct
 	if (zone) {
 		struct nf_conntrack_zone *nf_ct_zone;
 
-		nf_ct_zone = nf_ct_ext_add(tmpl, NF_CT_EXT_ZONE, GFP_ATOMIC);
+		nf_ct_zone = nf_ct_ext_add(tmpl, NF_CT_EXT_ZONE, flags);
 		if (!nf_ct_zone)
 			goto out_free;
 		nf_ct_zone->id = zone;
@@ -1544,10 +1544,8 @@ void *nf_ct_alloc_hashtable(unsigned int
 	sz = nr_slots * sizeof(struct hlist_nulls_head);
 	hash = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
 					get_order(sz));
-	if (!hash) {
-		printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
+	if (!hash)
 		hash = vzalloc(sz);
-	}
 
 	if (hash && nulls)
 		for (i = 0; i < nr_slots; i++)
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/netfilter/nf_synproxy_core.c linux-libre-4.2-rc7-gnu/net/netfilter/nf_synproxy_core.c
--- linux-libre-4.2-rc6-gnu/net/netfilter/nf_synproxy_core.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/netfilter/nf_synproxy_core.c	2015-08-16 19:34:13.000000000 -0400
@@ -353,10 +353,8 @@ static int __net_init synproxy_net_init(
 	int err = -ENOMEM;
 
 	ct = nf_ct_tmpl_alloc(net, 0, GFP_KERNEL);
-	if (IS_ERR(ct)) {
-		err = PTR_ERR(ct);
+	if (!ct)
 		goto err1;
-	}
 
 	if (!nfct_seqadj_ext_add(ct))
 		goto err2;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/netfilter/xt_CT.c linux-libre-4.2-rc7-gnu/net/netfilter/xt_CT.c
--- linux-libre-4.2-rc6-gnu/net/netfilter/xt_CT.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/netfilter/xt_CT.c	2015-08-16 19:34:13.000000000 -0400
@@ -202,9 +202,10 @@ static int xt_ct_tg_check(const struct x
 		goto err1;
 
 	ct = nf_ct_tmpl_alloc(par->net, info->zone, GFP_KERNEL);
-	ret = PTR_ERR(ct);
-	if (IS_ERR(ct))
+	if (!ct) {
+		ret = -ENOMEM;
 		goto err2;
+	}
 
 	ret = 0;
 	if ((info->ct_events || info->exp_events) &&
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/netlink/af_netlink.c linux-libre-4.2-rc7-gnu/net/netlink/af_netlink.c
--- linux-libre-4.2-rc6-gnu/net/netlink/af_netlink.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/netlink/af_netlink.c	2015-08-16 19:34:13.000000000 -0400
@@ -1096,6 +1096,11 @@ static int netlink_insert(struct sock *s
 
 	err = __netlink_insert(table, sk);
 	if (err) {
+		/* In case the hashtable backend returns with -EBUSY
+		 * from here, it must not escape to the caller.
+		 */
+		if (unlikely(err == -EBUSY))
+			err = -EOVERFLOW;
 		if (err == -EEXIST)
 			err = -EADDRINUSE;
 		nlk_sk(sk)->portid = 0;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/openvswitch/actions.c linux-libre-4.2-rc7-gnu/net/openvswitch/actions.c
--- linux-libre-4.2-rc6-gnu/net/openvswitch/actions.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/openvswitch/actions.c	2015-08-16 19:34:13.000000000 -0400
@@ -273,28 +273,36 @@ static int set_eth_addr(struct sk_buff *
 	return 0;
 }
 
-static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh,
-			__be32 *addr, __be32 new_addr)
+static void update_ip_l4_checksum(struct sk_buff *skb, struct iphdr *nh,
+				  __be32 addr, __be32 new_addr)
 {
 	int transport_len = skb->len - skb_transport_offset(skb);
 
+	if (nh->frag_off & htons(IP_OFFSET))
+		return;
+
 	if (nh->protocol == IPPROTO_TCP) {
 		if (likely(transport_len >= sizeof(struct tcphdr)))
 			inet_proto_csum_replace4(&tcp_hdr(skb)->check, skb,
-						 *addr, new_addr, 1);
+						 addr, new_addr, 1);
 	} else if (nh->protocol == IPPROTO_UDP) {
 		if (likely(transport_len >= sizeof(struct udphdr))) {
 			struct udphdr *uh = udp_hdr(skb);
 
 			if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) {
 				inet_proto_csum_replace4(&uh->check, skb,
-							 *addr, new_addr, 1);
+							 addr, new_addr, 1);
 				if (!uh->check)
 					uh->check = CSUM_MANGLED_0;
 			}
 		}
 	}
+}
 
+static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh,
+			__be32 *addr, __be32 new_addr)
+{
+	update_ip_l4_checksum(skb, nh, *addr, new_addr);
 	csum_replace4(&nh->check, *addr, new_addr);
 	skb_clear_hash(skb);
 	*addr = new_addr;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/rds/info.c linux-libre-4.2-rc7-gnu/net/rds/info.c
--- linux-libre-4.2-rc6-gnu/net/rds/info.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/rds/info.c	2015-08-16 19:34:13.000000000 -0400
@@ -176,7 +176,7 @@ int rds_info_getsockopt(struct socket *s
 
 	/* check for all kinds of wrapping and the like */
 	start = (unsigned long)optval;
-	if (len < 0 || len + PAGE_SIZE - 1 < len || start + len < start) {
+	if (len < 0 || len > INT_MAX - PAGE_SIZE + 1 || start + len < start) {
 		ret = -EINVAL;
 		goto out;
 	}
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/sched/act_mirred.c linux-libre-4.2-rc7-gnu/net/sched/act_mirred.c
--- linux-libre-4.2-rc6-gnu/net/sched/act_mirred.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/sched/act_mirred.c	2015-08-16 19:34:13.000000000 -0400
@@ -98,6 +98,8 @@ static int tcf_mirred_init(struct net *n
 			return ret;
 		ret = ACT_P_CREATED;
 	} else {
+		if (bind)
+			return 0;
 		if (!ovr) {
 			tcf_hash_release(a, bind);
 			return -EEXIST;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/net/sched/sch_fq_codel.c linux-libre-4.2-rc7-gnu/net/sched/sch_fq_codel.c
--- linux-libre-4.2-rc6-gnu/net/sched/sch_fq_codel.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/net/sched/sch_fq_codel.c	2015-08-16 19:34:13.000000000 -0400
@@ -288,10 +288,26 @@ begin:
 
 static void fq_codel_reset(struct Qdisc *sch)
 {
-	struct sk_buff *skb;
+	struct fq_codel_sched_data *q = qdisc_priv(sch);
+	int i;
 
-	while ((skb = fq_codel_dequeue(sch)) != NULL)
-		kfree_skb(skb);
+	INIT_LIST_HEAD(&q->new_flows);
+	INIT_LIST_HEAD(&q->old_flows);
+	for (i = 0; i < q->flows_cnt; i++) {
+		struct fq_codel_flow *flow = q->flows + i;
+
+		while (flow->head) {
+			struct sk_buff *skb = dequeue_head(flow);
+
+			qdisc_qstats_backlog_dec(sch, skb);
+			kfree_skb(skb);
+		}
+
+		INIT_LIST_HEAD(&flow->flowchain);
+		codel_vars_init(&flow->cvars);
+	}
+	memset(q->backlogs, 0, q->flows_cnt * sizeof(u32));
+	sch->q.qlen = 0;
 }
 
 static const struct nla_policy fq_codel_policy[TCA_FQ_CODEL_MAX + 1] = {
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/scripts/kconfig/streamline_config.pl linux-libre-4.2-rc7-gnu/scripts/kconfig/streamline_config.pl
--- linux-libre-4.2-rc6-gnu/scripts/kconfig/streamline_config.pl	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/scripts/kconfig/streamline_config.pl	2015-08-16 19:34:13.000000000 -0400
@@ -137,7 +137,7 @@ my $ksource = ($ARGV[0] ? $ARGV[0] : '.'
 my $kconfig = $ARGV[1];
 my $lsmod_file = $ENV{'LSMOD'};
 
-my @makefiles = `find $ksource -name Makefile 2>/dev/null`;
+my @makefiles = `find $ksource -name Makefile -or -name Kbuild 2>/dev/null`;
 chomp @makefiles;
 
 my %depends;
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/tools/perf/config/Makefile linux-libre-4.2-rc7-gnu/tools/perf/config/Makefile
--- linux-libre-4.2-rc6-gnu/tools/perf/config/Makefile	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/tools/perf/config/Makefile	2015-08-16 19:34:13.000000000 -0400
@@ -638,7 +638,7 @@ ifndef DESTDIR
 prefix ?= $(HOME)
 endif
 bindir_relative = bin
-bindir = $(prefix)/$(bindir_relative)
+bindir = $(abspath $(prefix)/$(bindir_relative))
 mandir = share/man
 infodir = share/info
 perfexecdir = libexec/perf-core
diff -druNp --no-dereference linux-libre-4.2-rc6-gnu/tools/perf/util/stat-shadow.c linux-libre-4.2-rc7-gnu/tools/perf/util/stat-shadow.c
--- linux-libre-4.2-rc6-gnu/tools/perf/util/stat-shadow.c	2015-08-09 15:54:30.000000000 -0400
+++ linux-libre-4.2-rc7-gnu/tools/perf/util/stat-shadow.c	2015-08-16 19:34:13.000000000 -0400
@@ -85,7 +85,7 @@ void perf_stat__update_shadow_stats(stru
 	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
 		update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
 	else if (perf_stat_evsel__is(counter, CYCLES_IN_TX))
-		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
+		update_stats(&runtime_cycles_in_tx_stats[ctx][cpu], count[0]);
 	else if (perf_stat_evsel__is(counter, TRANSACTION_START))
 		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
 	else if (perf_stat_evsel__is(counter, ELISION_START))
@@ -398,20 +398,18 @@ void perf_stat__print_shadow_stats(FILE
 				" #   %5.2f%% aborted cycles         ",
 				100.0 * ((total2-avg) / total));
 	} else if (perf_stat_evsel__is(evsel, TRANSACTION_START) &&
-		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
 
-		if (total)
+		if (avg)
 			ratio = total / avg;
 
 		fprintf(out, " # %8.0f cycles / transaction   ", ratio);
 	} else if (perf_stat_evsel__is(evsel, ELISION_START) &&
-		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
 
-		if (total)
+		if (avg)
 			ratio = total / avg;
 
 		fprintf(out, " # %8.0f cycles / elision       ", ratio);
