diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/arm/boot/dts/ste-snowball.dts linux-libre-4.8.7-gnu/arch/arm/boot/dts/ste-snowball.dts
--- linux-libre-4.8.6-gnu/arch/arm/boot/dts/ste-snowball.dts	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/arm/boot/dts/ste-snowball.dts	2016-11-10 10:39:23.000000000 -0500
@@ -239,14 +239,25 @@
 			arm,primecell-periphid = <0x10480180>;
 			max-frequency = <100000000>;
 			bus-width = <4>;
+			cap-sd-highspeed;
 			cap-mmc-highspeed;
+			sd-uhs-sdr12;
+			sd-uhs-sdr25;
+			/* All direction control is used */
+			st,sig-dir-cmd;
+			st,sig-dir-dat0;
+			st,sig-dir-dat2;
+			st,sig-dir-dat31;
+			st,sig-pin-fbclk;
+			full-pwr-cycle;
 			vmmc-supply = <&ab8500_ldo_aux3_reg>;
 			vqmmc-supply = <&vmmci>;
 			pinctrl-names = "default", "sleep";
 			pinctrl-0 = <&sdi0_default_mode>;
 			pinctrl-1 = <&sdi0_sleep_mode>;
 
-			cd-gpios  = <&gpio6 26 GPIO_ACTIVE_LOW>; // 218
+			/* GPIO218 MMC_CD */
+			cd-gpios  = <&gpio6 26 GPIO_ACTIVE_LOW>;
 
 			status = "okay";
 		};
@@ -549,7 +560,7 @@
 					/* VMMCI level-shifter enable */
 					snowball_cfg3 {
 						pins = "GPIO217_AH12";
-						ste,config = <&gpio_out_lo>;
+						ste,config = <&gpio_out_hi>;
 					};
 					/* VMMCI level-shifter voltage select */
 					snowball_cfg4 {
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/arm/mach-mvebu/Kconfig linux-libre-4.8.7-gnu/arch/arm/mach-mvebu/Kconfig
--- linux-libre-4.8.6-gnu/arch/arm/mach-mvebu/Kconfig	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/arm/mach-mvebu/Kconfig	2016-11-10 10:39:23.000000000 -0500
@@ -23,6 +23,7 @@ config MACH_MVEBU_V7
 	select CACHE_L2X0
 	select ARM_CPU_SUSPEND
 	select MACH_MVEBU_ANY
+	select MVEBU_CLK_COREDIV
 
 config MACH_ARMADA_370
 	bool "Marvell Armada 370 boards"
@@ -32,7 +33,6 @@ config MACH_ARMADA_370
 	select CPU_PJ4B
 	select MACH_MVEBU_V7
 	select PINCTRL_ARMADA_370
-	select MVEBU_CLK_COREDIV
 	help
 	  Say 'Y' here if you want your kernel to support boards based
 	  on the Marvell Armada 370 SoC with device tree.
@@ -50,7 +50,6 @@ config MACH_ARMADA_375
 	select HAVE_SMP
 	select MACH_MVEBU_V7
 	select PINCTRL_ARMADA_375
-	select MVEBU_CLK_COREDIV
 	help
 	  Say 'Y' here if you want your kernel to support boards based
 	  on the Marvell Armada 375 SoC with device tree.
@@ -68,7 +67,6 @@ config MACH_ARMADA_38X
 	select HAVE_SMP
 	select MACH_MVEBU_V7
 	select PINCTRL_ARMADA_38X
-	select MVEBU_CLK_COREDIV
 	help
 	  Say 'Y' here if you want your kernel to support boards based
 	  on the Marvell Armada 380/385 SoC with device tree.
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/arm/mm/abort-lv4t.S linux-libre-4.8.7-gnu/arch/arm/mm/abort-lv4t.S
--- linux-libre-4.8.6-gnu/arch/arm/mm/abort-lv4t.S	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/arm/mm/abort-lv4t.S	2016-11-10 10:39:23.000000000 -0500
@@ -7,7 +7,7 @@
  *	   : r4 = aborted context pc
  *	   : r5 = aborted context psr
  *
- * Returns : r4-r5, r10-r11, r13 preserved
+ * Returns : r4-r5, r9-r11, r13 preserved
  *
  * Purpose : obtain information about current aborted instruction.
  * Note: we read user space.  This means we might cause a data
@@ -48,7 +48,10 @@ ENTRY(v4t_late_abort)
 /* c */	b	do_DataAbort			@ ldc	rd, [rn], #m	@ Same as ldr	rd, [rn], #m
 /* d */	b	do_DataAbort			@ ldc	rd, [rn, #m]
 /* e */	b	.data_unknown
-/* f */
+/* f */	b	.data_unknown
+
+.data_unknown_r9:
+	ldr	r9, [sp], #4
 .data_unknown:	@ Part of jumptable
 	mov	r0, r4
 	mov	r1, r8
@@ -57,6 +60,7 @@ ENTRY(v4t_late_abort)
 .data_arm_ldmstm:
 	tst	r8, #1 << 21			@ check writeback bit
 	beq	do_DataAbort			@ no writeback -> no fixup
+	str	r9, [sp, #-4]!
 	mov	r7, #0x11
 	orr	r7, r7, #0x1100
 	and	r6, r8, r7
@@ -75,12 +79,14 @@ ENTRY(v4t_late_abort)
 	subne	r7, r7, r6, lsl #2		@ Undo increment
 	addeq	r7, r7, r6, lsl #2		@ Undo decrement
 	str	r7, [r2, r9, lsr #14]		@ Put register 'Rn'
+	ldr	r9, [sp], #4
 	b	do_DataAbort
 
 .data_arm_lateldrhpre:
 	tst	r8, #1 << 21			@ Check writeback bit
 	beq	do_DataAbort			@ No writeback -> no fixup
 .data_arm_lateldrhpost:
+	str	r9, [sp, #-4]!
 	and	r9, r8, #0x00f			@ get Rm / low nibble of immediate value
 	tst	r8, #1 << 22			@ if (immediate offset)
 	andne	r6, r8, #0xf00			@ { immediate high nibble
@@ -93,6 +99,7 @@ ENTRY(v4t_late_abort)
 	subne	r7, r7, r6			@ Undo incrmenet
 	addeq	r7, r7, r6			@ Undo decrement
 	str	r7, [r2, r9, lsr #14]		@ Put register 'Rn'
+	ldr	r9, [sp], #4
 	b	do_DataAbort
 
 .data_arm_lateldrpreconst:
@@ -101,12 +108,14 @@ ENTRY(v4t_late_abort)
 .data_arm_lateldrpostconst:
 	movs	r6, r8, lsl #20			@ Get offset
 	beq	do_DataAbort			@ zero -> no fixup
+	str	r9, [sp, #-4]!
 	and	r9, r8, #15 << 16		@ Extract 'n' from instruction
 	ldr	r7, [r2, r9, lsr #14]		@ Get register 'Rn'
 	tst	r8, #1 << 23			@ Check U bit
 	subne	r7, r7, r6, lsr #20		@ Undo increment
 	addeq	r7, r7, r6, lsr #20		@ Undo decrement
 	str	r7, [r2, r9, lsr #14]		@ Put register 'Rn'
+	ldr	r9, [sp], #4
 	b	do_DataAbort
 
 .data_arm_lateldrprereg:
@@ -115,6 +124,7 @@ ENTRY(v4t_late_abort)
 .data_arm_lateldrpostreg:
 	and	r7, r8, #15			@ Extract 'm' from instruction
 	ldr	r6, [r2, r7, lsl #2]		@ Get register 'Rm'
+	str	r9, [sp, #-4]!
 	mov	r9, r8, lsr #7			@ get shift count
 	ands	r9, r9, #31
 	and	r7, r8, #0x70			@ get shift type
@@ -126,33 +136,33 @@ ENTRY(v4t_late_abort)
 	b	.data_arm_apply_r6_and_rn
 	b	.data_arm_apply_r6_and_rn	@ 1: LSL #0
 	nop
-	b	.data_unknown			@ 2: MUL?
+	b	.data_unknown_r9		@ 2: MUL?
 	nop
-	b	.data_unknown			@ 3: MUL?
+	b	.data_unknown_r9		@ 3: MUL?
 	nop
 	mov	r6, r6, lsr r9			@ 4: LSR #!0
 	b	.data_arm_apply_r6_and_rn
 	mov	r6, r6, lsr #32			@ 5: LSR #32
 	b	.data_arm_apply_r6_and_rn
-	b	.data_unknown			@ 6: MUL?
+	b	.data_unknown_r9		@ 6: MUL?
 	nop
-	b	.data_unknown			@ 7: MUL?
+	b	.data_unknown_r9		@ 7: MUL?
 	nop
 	mov	r6, r6, asr r9			@ 8: ASR #!0
 	b	.data_arm_apply_r6_and_rn
 	mov	r6, r6, asr #32			@ 9: ASR #32
 	b	.data_arm_apply_r6_and_rn
-	b	.data_unknown			@ A: MUL?
+	b	.data_unknown_r9		@ A: MUL?
 	nop
-	b	.data_unknown			@ B: MUL?
+	b	.data_unknown_r9		@ B: MUL?
 	nop
 	mov	r6, r6, ror r9			@ C: ROR #!0
 	b	.data_arm_apply_r6_and_rn
 	mov	r6, r6, rrx			@ D: RRX
 	b	.data_arm_apply_r6_and_rn
-	b	.data_unknown			@ E: MUL?
+	b	.data_unknown_r9		@ E: MUL?
 	nop
-	b	.data_unknown			@ F: MUL?
+	b	.data_unknown_r9		@ F: MUL?
 
 .data_thumb_abort:
 	ldrh	r8, [r4]			@ read instruction
@@ -190,6 +200,7 @@ ENTRY(v4t_late_abort)
 .data_thumb_pushpop:
 	tst	r8, #1 << 10
 	beq	.data_unknown
+	str	r9, [sp, #-4]!
 	and	r6, r8, #0x55			@ hweight8(r8) + R bit
 	and	r9, r8, #0xaa
 	add	r6, r6, r9, lsr #1
@@ -204,9 +215,11 @@ ENTRY(v4t_late_abort)
 	addeq	r7, r7, r6, lsl #2		@ increment SP if PUSH
 	subne	r7, r7, r6, lsl #2		@ decrement SP if POP
 	str	r7, [r2, #13 << 2]
+	ldr	r9, [sp], #4
 	b	do_DataAbort
 
 .data_thumb_ldmstm:
+	str	r9, [sp, #-4]!
 	and	r6, r8, #0x55			@ hweight8(r8)
 	and	r9, r8, #0xaa
 	add	r6, r6, r9, lsr #1
@@ -219,4 +232,5 @@ ENTRY(v4t_late_abort)
 	and	r6, r6, #15			@ number of regs to transfer
 	sub	r7, r7, r6, lsl #2		@ always decrement
 	str	r7, [r2, r9, lsr #6]
+	ldr	r9, [sp], #4
 	b	do_DataAbort
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi linux-libre-4.8.7-gnu/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
--- linux-libre-4.8.6-gnu/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi	2016-11-10 10:39:23.000000000 -0500
@@ -131,7 +131,7 @@
 				#address-cells = <0x1>;
 				#size-cells = <0x0>;
 				cell-index = <1>;
-				clocks = <&cpm_syscon0 0 3>;
+				clocks = <&cpm_syscon0 1 21>;
 				status = "disabled";
 			};
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/h8300/include/asm/thread_info.h linux-libre-4.8.7-gnu/arch/h8300/include/asm/thread_info.h
--- linux-libre-4.8.6-gnu/arch/h8300/include/asm/thread_info.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/h8300/include/asm/thread_info.h	2016-11-10 10:39:23.000000000 -0500
@@ -31,7 +31,6 @@ struct thread_info {
 	int		   cpu;			/* cpu we're on */
 	int		   preempt_count;	/* 0 => preemptable, <0 => BUG */
 	mm_segment_t		addr_limit;
-	struct restart_block restart_block;
 };
 
 /*
@@ -44,9 +43,6 @@ struct thread_info {
 	.cpu =		0,			\
 	.preempt_count = INIT_PREEMPT_COUNT,	\
 	.addr_limit	= KERNEL_DS,		\
-	.restart_block	= {			\
-		.fn = do_no_restart_syscall,	\
-	},					\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/h8300/kernel/signal.c linux-libre-4.8.7-gnu/arch/h8300/kernel/signal.c
--- linux-libre-4.8.6-gnu/arch/h8300/kernel/signal.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/h8300/kernel/signal.c	2016-11-10 10:39:23.000000000 -0500
@@ -79,7 +79,7 @@ restore_sigcontext(struct sigcontext *us
 	unsigned int er0;
 
 	/* Always make any pending restarted system calls return -EINTR */
-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+	current->restart_block.fn = do_no_restart_syscall;
 
 	/* restore passed registers */
 #define COPY(r)  do { err |= get_user(regs->r, &usc->sc_##r); } while (0)
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/mips/include/asm/kvm_host.h linux-libre-4.8.7-gnu/arch/mips/include/asm/kvm_host.h
--- linux-libre-4.8.6-gnu/arch/mips/include/asm/kvm_host.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/mips/include/asm/kvm_host.h	2016-11-10 10:39:23.000000000 -0500
@@ -279,7 +279,10 @@ struct kvm_vcpu_arch {
 	/* Host KSEG0 address of the EI/DI offset */
 	void *kseg0_commpage;
 
-	u32 io_gpr;		/* GPR used as IO source/target */
+	/* Resume PC after MMIO completion */
+	unsigned long io_pc;
+	/* GPR used as IO source/target */
+	u32 io_gpr;
 
 	struct hrtimer comparecount_timer;
 	/* Count timer control KVM register */
@@ -301,8 +304,6 @@ struct kvm_vcpu_arch {
 	/* Bitmask of pending exceptions to be cleared */
 	unsigned long pending_exceptions_clr;
 
-	u32 pending_load_cause;
-
 	/* Save/Restore the entryhi register when are are preempted/scheduled back in */
 	unsigned long preempt_entryhi;
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/mips/kernel/relocate.c linux-libre-4.8.7-gnu/arch/mips/kernel/relocate.c
--- linux-libre-4.8.6-gnu/arch/mips/kernel/relocate.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/mips/kernel/relocate.c	2016-11-10 10:39:23.000000000 -0500
@@ -200,7 +200,7 @@ static inline __init unsigned long get_r
 
 #if defined(CONFIG_USE_OF)
 	/* Get any additional entropy passed in device tree */
-	{
+	if (initial_boot_params) {
 		int node, len;
 		u64 *prop;
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/mips/kvm/emulate.c linux-libre-4.8.7-gnu/arch/mips/kvm/emulate.c
--- linux-libre-4.8.6-gnu/arch/mips/kvm/emulate.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/mips/kvm/emulate.c	2016-11-10 10:39:23.000000000 -0500
@@ -791,15 +791,15 @@ enum emulation_result kvm_mips_emul_eret
 	struct mips_coproc *cop0 = vcpu->arch.cop0;
 	enum emulation_result er = EMULATE_DONE;
 
-	if (kvm_read_c0_guest_status(cop0) & ST0_EXL) {
+	if (kvm_read_c0_guest_status(cop0) & ST0_ERL) {
+		kvm_clear_c0_guest_status(cop0, ST0_ERL);
+		vcpu->arch.pc = kvm_read_c0_guest_errorepc(cop0);
+	} else if (kvm_read_c0_guest_status(cop0) & ST0_EXL) {
 		kvm_debug("[%#lx] ERET to %#lx\n", vcpu->arch.pc,
 			  kvm_read_c0_guest_epc(cop0));
 		kvm_clear_c0_guest_status(cop0, ST0_EXL);
 		vcpu->arch.pc = kvm_read_c0_guest_epc(cop0);
 
-	} else if (kvm_read_c0_guest_status(cop0) & ST0_ERL) {
-		kvm_clear_c0_guest_status(cop0, ST0_ERL);
-		vcpu->arch.pc = kvm_read_c0_guest_errorepc(cop0);
 	} else {
 		kvm_err("[%#lx] ERET when MIPS_SR_EXL|MIPS_SR_ERL == 0\n",
 			vcpu->arch.pc);
@@ -1522,13 +1522,25 @@ enum emulation_result kvm_mips_emulate_l
 					    struct kvm_vcpu *vcpu)
 {
 	enum emulation_result er = EMULATE_DO_MMIO;
+	unsigned long curr_pc;
 	u32 op, rt;
 	u32 bytes;
 
 	rt = inst.i_format.rt;
 	op = inst.i_format.opcode;
 
-	vcpu->arch.pending_load_cause = cause;
+	/*
+	 * Find the resume PC now while we have safe and easy access to the
+	 * prior branch instruction, and save it for
+	 * kvm_mips_complete_mmio_load() to restore later.
+	 */
+	curr_pc = vcpu->arch.pc;
+	er = update_pc(vcpu, cause);
+	if (er == EMULATE_FAIL)
+		return er;
+	vcpu->arch.io_pc = vcpu->arch.pc;
+	vcpu->arch.pc = curr_pc;
+
 	vcpu->arch.io_gpr = rt;
 
 	switch (op) {
@@ -2488,9 +2500,8 @@ enum emulation_result kvm_mips_complete_
 		goto done;
 	}
 
-	er = update_pc(vcpu, vcpu->arch.pending_load_cause);
-	if (er == EMULATE_FAIL)
-		return er;
+	/* Restore saved resume PC */
+	vcpu->arch.pc = vcpu->arch.io_pc;
 
 	switch (run->mmio.len) {
 	case 4:
@@ -2512,11 +2523,6 @@ enum emulation_result kvm_mips_complete_
 		break;
 	}
 
-	if (vcpu->arch.pending_load_cause & CAUSEF_BD)
-		kvm_debug("[%#lx] Completing %d byte BD Load to gpr %d (0x%08lx) type %d\n",
-			  vcpu->arch.pc, run->mmio.len, vcpu->arch.io_gpr, *gpr,
-			  vcpu->mmio_needed);
-
 done:
 	return er;
 }
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/parisc/kernel/syscall.S linux-libre-4.8.7-gnu/arch/parisc/kernel/syscall.S
--- linux-libre-4.8.6-gnu/arch/parisc/kernel/syscall.S	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/parisc/kernel/syscall.S	2016-11-10 10:39:23.000000000 -0500
@@ -106,8 +106,6 @@ linux_gateway_entry:
 	mtsp	%r0,%sr4			/* get kernel space into sr4 */
 	mtsp	%r0,%sr5			/* get kernel space into sr5 */
 	mtsp	%r0,%sr6			/* get kernel space into sr6 */
-	mfsp    %sr7,%r1                        /* save user sr7 */
-	mtsp    %r1,%sr3                        /* and store it in sr3 */
 
 #ifdef CONFIG_64BIT
 	/* for now we can *always* set the W bit on entry to the syscall
@@ -133,6 +131,14 @@ linux_gateway_entry:
 	depdi	0, 31, 32, %r21
 1:	
 #endif
+
+	/* We use a rsm/ssm pair to prevent sr3 from being clobbered
+	 * by external interrupts.
+	 */
+	mfsp    %sr7,%r1                        /* save user sr7 */
+	rsm	PSW_SM_I, %r0			/* disable interrupts */
+	mtsp    %r1,%sr3                        /* and store it in sr3 */
+
 	mfctl   %cr30,%r1
 	xor     %r1,%r30,%r30                   /* ye olde xor trick */
 	xor     %r1,%r30,%r1
@@ -147,6 +153,7 @@ linux_gateway_entry:
 	 */
 
 	mtsp	%r0,%sr7			/* get kernel space into sr7 */
+	ssm	PSW_SM_I, %r0			/* enable interrupts */
 	STREGM	%r1,FRAME_SIZE(%r30)		/* save r1 (usp) here for now */
 	mfctl	%cr30,%r1			/* get task ptr in %r1 */
 	LDREG	TI_TASK(%r1),%r1
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/powerpc/include/asm/cpuidle.h linux-libre-4.8.7-gnu/arch/powerpc/include/asm/cpuidle.h
--- linux-libre-4.8.6-gnu/arch/powerpc/include/asm/cpuidle.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/powerpc/include/asm/cpuidle.h	2016-11-10 10:39:23.000000000 -0500
@@ -26,7 +26,7 @@ extern u64 pnv_first_deep_stop_state;
 	std	r0,0(r1);					\
 	ptesync;						\
 	ld	r0,0(r1);					\
-1:	cmp	cr0,r0,r0;					\
+1:	cmpd	cr0,r0,r0;					\
 	bne	1b;						\
 	IDLE_INST;						\
 	b	.
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/powerpc/include/asm/tlb.h linux-libre-4.8.7-gnu/arch/powerpc/include/asm/tlb.h
--- linux-libre-4.8.6-gnu/arch/powerpc/include/asm/tlb.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/powerpc/include/asm/tlb.h	2016-11-10 10:39:23.000000000 -0500
@@ -52,11 +52,23 @@ static inline int mm_is_core_local(struc
 	return cpumask_subset(mm_cpumask(mm),
 			      topology_sibling_cpumask(smp_processor_id()));
 }
+
+static inline int mm_is_thread_local(struct mm_struct *mm)
+{
+	return cpumask_equal(mm_cpumask(mm),
+			      cpumask_of(smp_processor_id()));
+}
+
 #else
 static inline int mm_is_core_local(struct mm_struct *mm)
 {
 	return 1;
 }
+
+static inline int mm_is_thread_local(struct mm_struct *mm)
+{
+	return 1;
+}
 #endif
 
 #endif /* __KERNEL__ */
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/powerpc/kernel/idle_book3s.S linux-libre-4.8.7-gnu/arch/powerpc/kernel/idle_book3s.S
--- linux-libre-4.8.6-gnu/arch/powerpc/kernel/idle_book3s.S	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/powerpc/kernel/idle_book3s.S	2016-11-10 10:39:23.000000000 -0500
@@ -90,6 +90,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_3
  * Threads will spin in HMT_LOW until the lock bit is cleared.
  * r14 - pointer to core_idle_state
  * r15 - used to load contents of core_idle_state
+ * r9  - used as a temporary variable
  */
 
 core_idle_lock_held:
@@ -99,6 +100,8 @@ core_idle_lock_held:
 	bne	3b
 	HMT_MEDIUM
 	lwarx	r15,0,r14
+	andi.	r9,r15,PNV_CORE_IDLE_LOCK_BIT
+	bne	core_idle_lock_held
 	blr
 
 /*
@@ -163,12 +166,6 @@ _GLOBAL(pnv_powersave_common)
 	std	r9,_MSR(r1)
 	std	r1,PACAR1(r13)
 
-#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
-	/* Tell KVM we're entering idle */
-	li	r4,KVM_HWTHREAD_IN_IDLE
-	stb	r4,HSTATE_HWTHREAD_STATE(r13)
-#endif
-
 	/*
 	 * Go to real mode to do the nap, as required by the architecture.
 	 * Also, we need to be in real mode before setting hwthread_state,
@@ -185,6 +182,26 @@ _GLOBAL(pnv_powersave_common)
 
 	.globl pnv_enter_arch207_idle_mode
 pnv_enter_arch207_idle_mode:
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+	/* Tell KVM we're entering idle */
+	li	r4,KVM_HWTHREAD_IN_IDLE
+	/******************************************************/
+	/*  N O T E   W E L L    ! ! !    N O T E   W E L L   */
+	/* The following store to HSTATE_HWTHREAD_STATE(r13)  */
+	/* MUST occur in real mode, i.e. with the MMU off,    */
+	/* and the MMU must stay off until we clear this flag */
+	/* and test HSTATE_HWTHREAD_REQ(r13) in the system    */
+	/* reset interrupt vector in exceptions-64s.S.        */
+	/* The reason is that another thread can switch the   */
+	/* MMU to a guest context whenever this flag is set   */
+	/* to KVM_HWTHREAD_IN_IDLE, and if the MMU was on,    */
+	/* that would potentially cause this thread to start  */
+	/* executing instructions from guest memory in        */
+	/* hypervisor mode, leading to a host crash or data   */
+	/* corruption, or worse.                              */
+	/******************************************************/
+	stb	r4,HSTATE_HWTHREAD_STATE(r13)
+#endif
 	stb	r3,PACA_THREAD_IDLE_STATE(r13)
 	cmpwi	cr3,r3,PNV_THREAD_SLEEP
 	bge	cr3,2f
@@ -250,6 +267,12 @@ enter_winkle:
  * r3 - requested stop state
  */
 power_enter_stop:
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+	/* Tell KVM we're entering idle */
+	li	r4,KVM_HWTHREAD_IN_IDLE
+	/* DO THIS IN REAL MODE!  See comment above. */
+	stb	r4,HSTATE_HWTHREAD_STATE(r13)
+#endif
 /*
  * Check if the requested state is a deep idle state.
  */
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/powerpc/mm/tlb-radix.c linux-libre-4.8.7-gnu/arch/powerpc/mm/tlb-radix.c
--- linux-libre-4.8.6-gnu/arch/powerpc/mm/tlb-radix.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/powerpc/mm/tlb-radix.c	2016-11-10 10:39:23.000000000 -0500
@@ -175,7 +175,7 @@ void radix__flush_tlb_mm(struct mm_struc
 	if (unlikely(pid == MMU_NO_CONTEXT))
 		goto no_context;
 
-	if (!mm_is_core_local(mm)) {
+	if (!mm_is_thread_local(mm)) {
 		int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
 
 		if (lock_tlbie)
@@ -201,7 +201,7 @@ void radix__flush_tlb_pwc(struct mmu_gat
 	if (unlikely(pid == MMU_NO_CONTEXT))
 		goto no_context;
 
-	if (!mm_is_core_local(mm)) {
+	if (!mm_is_thread_local(mm)) {
 		int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
 
 		if (lock_tlbie)
@@ -226,7 +226,7 @@ void radix__flush_tlb_page_psize(struct
 	pid = mm ? mm->context.id : 0;
 	if (unlikely(pid == MMU_NO_CONTEXT))
 		goto bail;
-	if (!mm_is_core_local(mm)) {
+	if (!mm_is_thread_local(mm)) {
 		int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
 
 		if (lock_tlbie)
@@ -321,7 +321,7 @@ void radix__flush_tlb_range_psize(struct
 {
 	unsigned long pid;
 	unsigned long addr;
-	int local = mm_is_core_local(mm);
+	int local = mm_is_thread_local(mm);
 	unsigned long ap = mmu_get_ap(psize);
 	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
 	unsigned long page_size = 1UL << mmu_psize_defs[psize].shift;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/s390/kvm/sthyi.c linux-libre-4.8.7-gnu/arch/s390/kvm/sthyi.c
--- linux-libre-4.8.6-gnu/arch/s390/kvm/sthyi.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/s390/kvm/sthyi.c	2016-11-10 10:39:23.000000000 -0500
@@ -315,7 +315,7 @@ static void fill_diag(struct sthyi_sctns
 	if (r < 0)
 		goto out;
 
-	diag224_buf = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
+	diag224_buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
 	if (!diag224_buf || diag224(diag224_buf))
 		goto out;
 
@@ -378,7 +378,7 @@ static void fill_diag(struct sthyi_sctns
 	sctns->par.infpval1 |= PAR_WGHT_VLD;
 
 out:
-	kfree(diag224_buf);
+	free_page((unsigned long)diag224_buf);
 	vfree(diag204_buf);
 }
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/x86/kernel/cpu/microcode/amd.c linux-libre-4.8.7-gnu/arch/x86/kernel/cpu/microcode/amd.c
--- linux-libre-4.8.6-gnu/arch/x86/kernel/cpu/microcode/amd.c	2016-10-31 17:31:07.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/x86/kernel/cpu/microcode/amd.c	2016-11-10 15:59:50.000000000 -0500
@@ -429,7 +429,7 @@ int __init save_microcode_in_initrd_amd(
 	 * We need the physical address of the container for both bitness since
 	 * boot_params.hdr.ramdisk_image is a physical address.
 	 */
-	cont    = __pa(container);
+	cont    = __pa_nodebug(container);
 	cont_va = container;
 #endif
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/x86/kernel/setup.c linux-libre-4.8.7-gnu/arch/x86/kernel/setup.c
--- linux-libre-4.8.6-gnu/arch/x86/kernel/setup.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/x86/kernel/setup.c	2016-11-10 10:39:23.000000000 -0500
@@ -1222,11 +1222,16 @@ void __init setup_arch(char **cmdline_p)
 	if (smp_found_config)
 		get_smp_config();
 
+	/*
+	 * Systems w/o ACPI and mptables might not have it mapped the local
+	 * APIC yet, but prefill_possible_map() might need to access it.
+	 */
+	init_apic_mappings();
+
 	prefill_possible_map();
 
 	init_cpu_to_node();
 
-	init_apic_mappings();
 	io_apic_init_mappings();
 
 	kvm_guest_init();
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/x86/kvm/emulate.c linux-libre-4.8.7-gnu/arch/x86/kvm/emulate.c
--- linux-libre-4.8.6-gnu/arch/x86/kvm/emulate.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/x86/kvm/emulate.c	2016-11-10 10:39:23.000000000 -0500
@@ -5045,7 +5045,7 @@ done_prefixes:
 	/* Decode and fetch the destination operand: register or memory. */
 	rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask);
 
-	if (ctxt->rip_relative)
+	if (ctxt->rip_relative && likely(ctxt->memopp))
 		ctxt->memopp->addr.mem.ea = address_mask(ctxt,
 					ctxt->memopp->addr.mem.ea + ctxt->_eip);
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/arch/x86/kvm/x86.c linux-libre-4.8.7-gnu/arch/x86/kvm/x86.c
--- linux-libre-4.8.6-gnu/arch/x86/kvm/x86.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/arch/x86/kvm/x86.c	2016-11-10 10:39:23.000000000 -0500
@@ -7372,10 +7372,12 @@ void kvm_put_guest_fpu(struct kvm_vcpu *
 
 void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
 {
+	void *wbinvd_dirty_mask = vcpu->arch.wbinvd_dirty_mask;
+
 	kvmclock_reset(vcpu);
 
-	free_cpumask_var(vcpu->arch.wbinvd_dirty_mask);
 	kvm_x86_ops->vcpu_free(vcpu);
+	free_cpumask_var(wbinvd_dirty_mask);
 }
 
 struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
diff -druNp --no-dereference linux-libre-4.8.6-gnu/Documentation/device-mapper/dm-raid.txt linux-libre-4.8.7-gnu/Documentation/device-mapper/dm-raid.txt
--- linux-libre-4.8.6-gnu/Documentation/device-mapper/dm-raid.txt	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/Documentation/device-mapper/dm-raid.txt	2016-11-10 10:39:23.000000000 -0500
@@ -309,3 +309,4 @@ Version History
 	with a reshape in progress.
 1.9.0   Add support for RAID level takeover/reshape/region size
 	and set size reduction.
+1.9.1   Fix activation of existing RAID 4/10 mapped devices
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/android/binder.c linux-libre-4.8.7-gnu/drivers/android/binder.c
--- linux-libre-4.8.6-gnu/drivers/android/binder.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/android/binder.c	2016-11-10 10:39:23.000000000 -0500
@@ -1003,7 +1003,7 @@ static int binder_dec_node(struct binder
 
 
 static struct binder_ref *binder_get_ref(struct binder_proc *proc,
-					 uint32_t desc)
+					 u32 desc, bool need_strong_ref)
 {
 	struct rb_node *n = proc->refs_by_desc.rb_node;
 	struct binder_ref *ref;
@@ -1011,12 +1011,16 @@ static struct binder_ref *binder_get_ref
 	while (n) {
 		ref = rb_entry(n, struct binder_ref, rb_node_desc);
 
-		if (desc < ref->desc)
+		if (desc < ref->desc) {
 			n = n->rb_left;
-		else if (desc > ref->desc)
+		} else if (desc > ref->desc) {
 			n = n->rb_right;
-		else
+		} else if (need_strong_ref && !ref->strong) {
+			binder_user_error("tried to use weak ref as strong ref\n");
+			return NULL;
+		} else {
 			return ref;
+		}
 	}
 	return NULL;
 }
@@ -1286,7 +1290,10 @@ static void binder_transaction_buffer_re
 		} break;
 		case BINDER_TYPE_HANDLE:
 		case BINDER_TYPE_WEAK_HANDLE: {
-			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+			struct binder_ref *ref;
+
+			ref = binder_get_ref(proc, fp->handle,
+					     fp->type == BINDER_TYPE_HANDLE);
 
 			if (ref == NULL) {
 				pr_err("transaction release %d bad handle %d\n",
@@ -1381,7 +1388,7 @@ static void binder_transaction(struct bi
 		if (tr->target.handle) {
 			struct binder_ref *ref;
 
-			ref = binder_get_ref(proc, tr->target.handle);
+			ref = binder_get_ref(proc, tr->target.handle, true);
 			if (ref == NULL) {
 				binder_user_error("%d:%d got transaction to invalid handle\n",
 					proc->pid, thread->pid);
@@ -1578,7 +1585,9 @@ static void binder_transaction(struct bi
 				fp->type = BINDER_TYPE_HANDLE;
 			else
 				fp->type = BINDER_TYPE_WEAK_HANDLE;
+			fp->binder = 0;
 			fp->handle = ref->desc;
+			fp->cookie = 0;
 			binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE,
 				       &thread->todo);
 
@@ -1590,7 +1599,10 @@ static void binder_transaction(struct bi
 		} break;
 		case BINDER_TYPE_HANDLE:
 		case BINDER_TYPE_WEAK_HANDLE: {
-			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+			struct binder_ref *ref;
+
+			ref = binder_get_ref(proc, fp->handle,
+					     fp->type == BINDER_TYPE_HANDLE);
 
 			if (ref == NULL) {
 				binder_user_error("%d:%d got transaction with invalid handle, %d\n",
@@ -1625,7 +1637,9 @@ static void binder_transaction(struct bi
 					return_error = BR_FAILED_REPLY;
 					goto err_binder_get_ref_for_node_failed;
 				}
+				fp->binder = 0;
 				fp->handle = new_ref->desc;
+				fp->cookie = 0;
 				binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
 				trace_binder_transaction_ref_to_ref(t, ref,
 								    new_ref);
@@ -1679,6 +1693,7 @@ static void binder_transaction(struct bi
 			binder_debug(BINDER_DEBUG_TRANSACTION,
 				     "        fd %d -> %d\n", fp->handle, target_fd);
 			/* TODO: fput? */
+			fp->binder = 0;
 			fp->handle = target_fd;
 		} break;
 
@@ -1801,7 +1816,9 @@ static int binder_thread_write(struct bi
 						ref->desc);
 				}
 			} else
-				ref = binder_get_ref(proc, target);
+				ref = binder_get_ref(proc, target,
+						     cmd == BC_ACQUIRE ||
+						     cmd == BC_RELEASE);
 			if (ref == NULL) {
 				binder_user_error("%d:%d refcount change on invalid ref %d\n",
 					proc->pid, thread->pid, target);
@@ -1997,7 +2014,7 @@ static int binder_thread_write(struct bi
 			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
 				return -EFAULT;
 			ptr += sizeof(binder_uintptr_t);
-			ref = binder_get_ref(proc, target);
+			ref = binder_get_ref(proc, target, false);
 			if (ref == NULL) {
 				binder_user_error("%d:%d %s invalid ref %d\n",
 					proc->pid, thread->pid,
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/char/virtio_console.c linux-libre-4.8.7-gnu/drivers/char/virtio_console.c
--- linux-libre-4.8.6-gnu/drivers/char/virtio_console.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/char/virtio_console.c	2016-11-10 10:39:23.000000000 -0500
@@ -1540,19 +1540,29 @@ static void remove_port_data(struct port
 	spin_lock_irq(&port->inbuf_lock);
 	/* Remove unused data this port might have received. */
 	discard_port_data(port);
+	spin_unlock_irq(&port->inbuf_lock);
 
 	/* Remove buffers we queued up for the Host to send us data in. */
-	while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
-		free_buf(buf, true);
-	spin_unlock_irq(&port->inbuf_lock);
+	do {
+		spin_lock_irq(&port->inbuf_lock);
+		buf = virtqueue_detach_unused_buf(port->in_vq);
+		spin_unlock_irq(&port->inbuf_lock);
+		if (buf)
+			free_buf(buf, true);
+	} while (buf);
 
 	spin_lock_irq(&port->outvq_lock);
 	reclaim_consumed_buffers(port);
+	spin_unlock_irq(&port->outvq_lock);
 
 	/* Free pending buffers from the out-queue. */
-	while ((buf = virtqueue_detach_unused_buf(port->out_vq)))
-		free_buf(buf, true);
-	spin_unlock_irq(&port->outvq_lock);
+	do {
+		spin_lock_irq(&port->outvq_lock);
+		buf = virtqueue_detach_unused_buf(port->out_vq);
+		spin_unlock_irq(&port->outvq_lock);
+		if (buf)
+			free_buf(buf, true);
+	} while (buf);
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/cpufreq/intel_pstate.c linux-libre-4.8.7-gnu/drivers/cpufreq/intel_pstate.c
--- linux-libre-4.8.6-gnu/drivers/cpufreq/intel_pstate.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/cpufreq/intel_pstate.c	2016-11-10 10:39:23.000000000 -0500
@@ -1133,10 +1133,8 @@ static void intel_pstate_get_min_max(str
 	*min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf);
 }
 
-static void intel_pstate_set_min_pstate(struct cpudata *cpu)
+static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
 {
-	int pstate = cpu->pstate.min_pstate;
-
 	trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu);
 	cpu->pstate.current_pstate = pstate;
 	/*
@@ -1148,6 +1146,20 @@ static void intel_pstate_set_min_pstate(
 		      pstate_funcs.get_val(cpu, pstate));
 }
 
+static void intel_pstate_set_min_pstate(struct cpudata *cpu)
+{
+	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
+}
+
+static void intel_pstate_max_within_limits(struct cpudata *cpu)
+{
+	int min_pstate, max_pstate;
+
+	update_turbo_state();
+	intel_pstate_get_min_max(cpu, &min_pstate, &max_pstate);
+	intel_pstate_set_pstate(cpu, max_pstate);
+}
+
 static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
 {
 	cpu->pstate.min_pstate = pstate_funcs.get_min();
@@ -1465,7 +1477,7 @@ static int intel_pstate_set_policy(struc
 	pr_debug("set_policy cpuinfo.max %u policy->max %u\n",
 		 policy->cpuinfo.max_freq, policy->max);
 
-	cpu = all_cpu_data[0];
+	cpu = all_cpu_data[policy->cpu];
 	if (cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate &&
 	    policy->max < policy->cpuinfo.max_freq &&
 	    policy->max > cpu->pstate.max_pstate * cpu->pstate.scaling) {
@@ -1509,6 +1521,15 @@ static int intel_pstate_set_policy(struc
 	limits->max_perf = round_up(limits->max_perf, FRAC_BITS);
 
  out:
+	if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
+		/*
+		 * NOHZ_FULL CPUs need this as the governor callback may not
+		 * be invoked on them.
+		 */
+		intel_pstate_clear_update_util_hook(policy->cpu);
+		intel_pstate_max_within_limits(cpu);
+	}
+
 	intel_pstate_set_update_util_hook(policy->cpu);
 
 	intel_pstate_hwp_set_policy(policy);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/dax/pmem.c linux-libre-4.8.7-gnu/drivers/dax/pmem.c
--- linux-libre-4.8.6-gnu/drivers/dax/pmem.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/dax/pmem.c	2016-11-10 10:39:23.000000000 -0500
@@ -44,7 +44,6 @@ static void dax_pmem_percpu_exit(void *d
 
 	dev_dbg(dax_pmem->dev, "%s\n", __func__);
 	percpu_ref_exit(ref);
-	wait_for_completion(&dax_pmem->cmp);
 }
 
 static void dax_pmem_percpu_kill(void *data)
@@ -54,6 +53,7 @@ static void dax_pmem_percpu_kill(void *d
 
 	dev_dbg(dax_pmem->dev, "%s\n", __func__);
 	percpu_ref_kill(ref);
+	wait_for_completion(&dax_pmem->cmp);
 }
 
 static int dax_pmem_probe(struct device *dev)
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/firewire/net.c linux-libre-4.8.7-gnu/drivers/firewire/net.c
--- linux-libre-4.8.6-gnu/drivers/firewire/net.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/firewire/net.c	2016-11-10 10:39:23.000000000 -0500
@@ -73,13 +73,13 @@ struct rfc2734_header {
 
 #define fwnet_get_hdr_lf(h)		(((h)->w0 & 0xc0000000) >> 30)
 #define fwnet_get_hdr_ether_type(h)	(((h)->w0 & 0x0000ffff))
-#define fwnet_get_hdr_dg_size(h)	(((h)->w0 & 0x0fff0000) >> 16)
+#define fwnet_get_hdr_dg_size(h)	((((h)->w0 & 0x0fff0000) >> 16) + 1)
 #define fwnet_get_hdr_fg_off(h)		(((h)->w0 & 0x00000fff))
 #define fwnet_get_hdr_dgl(h)		(((h)->w1 & 0xffff0000) >> 16)
 
-#define fwnet_set_hdr_lf(lf)		((lf)  << 30)
+#define fwnet_set_hdr_lf(lf)		((lf) << 30)
 #define fwnet_set_hdr_ether_type(et)	(et)
-#define fwnet_set_hdr_dg_size(dgs)	((dgs) << 16)
+#define fwnet_set_hdr_dg_size(dgs)	(((dgs) - 1) << 16)
 #define fwnet_set_hdr_fg_off(fgo)	(fgo)
 
 #define fwnet_set_hdr_dgl(dgl)		((dgl) << 16)
@@ -578,6 +578,9 @@ static int fwnet_incoming_packet(struct
 	int retval;
 	u16 ether_type;
 
+	if (len <= RFC2374_UNFRAG_HDR_SIZE)
+		return 0;
+
 	hdr.w0 = be32_to_cpu(buf[0]);
 	lf = fwnet_get_hdr_lf(&hdr);
 	if (lf == RFC2374_HDR_UNFRAG) {
@@ -602,7 +605,12 @@ static int fwnet_incoming_packet(struct
 		return fwnet_finish_incoming_packet(net, skb, source_node_id,
 						    is_broadcast, ether_type);
 	}
+
 	/* A datagram fragment has been received, now the fun begins. */
+
+	if (len <= RFC2374_FRAG_HDR_SIZE)
+		return 0;
+
 	hdr.w1 = ntohl(buf[1]);
 	buf += 2;
 	len -= RFC2374_FRAG_HDR_SIZE;
@@ -614,7 +622,10 @@ static int fwnet_incoming_packet(struct
 		fg_off = fwnet_get_hdr_fg_off(&hdr);
 	}
 	datagram_label = fwnet_get_hdr_dgl(&hdr);
-	dg_size = fwnet_get_hdr_dg_size(&hdr); /* ??? + 1 */
+	dg_size = fwnet_get_hdr_dg_size(&hdr);
+
+	if (fg_off + len > dg_size)
+		return 0;
 
 	spin_lock_irqsave(&dev->lock, flags);
 
@@ -722,6 +733,22 @@ static void fwnet_receive_packet(struct
 	fw_send_response(card, r, rcode);
 }
 
+static int gasp_source_id(__be32 *p)
+{
+	return be32_to_cpu(p[0]) >> 16;
+}
+
+static u32 gasp_specifier_id(__be32 *p)
+{
+	return (be32_to_cpu(p[0]) & 0xffff) << 8 |
+	       (be32_to_cpu(p[1]) & 0xff000000) >> 24;
+}
+
+static u32 gasp_version(__be32 *p)
+{
+	return be32_to_cpu(p[1]) & 0xffffff;
+}
+
 static void fwnet_receive_broadcast(struct fw_iso_context *context,
 		u32 cycle, size_t header_length, void *header, void *data)
 {
@@ -731,9 +758,6 @@ static void fwnet_receive_broadcast(stru
 	__be32 *buf_ptr;
 	int retval;
 	u32 length;
-	u16 source_node_id;
-	u32 specifier_id;
-	u32 ver;
 	unsigned long offset;
 	unsigned long flags;
 
@@ -750,22 +774,17 @@ static void fwnet_receive_broadcast(stru
 
 	spin_unlock_irqrestore(&dev->lock, flags);
 
-	specifier_id =    (be32_to_cpu(buf_ptr[0]) & 0xffff) << 8
-			| (be32_to_cpu(buf_ptr[1]) & 0xff000000) >> 24;
-	ver = be32_to_cpu(buf_ptr[1]) & 0xffffff;
-	source_node_id = be32_to_cpu(buf_ptr[0]) >> 16;
-
-	if (specifier_id == IANA_SPECIFIER_ID &&
-	    (ver == RFC2734_SW_VERSION
+	if (length > IEEE1394_GASP_HDR_SIZE &&
+	    gasp_specifier_id(buf_ptr) == IANA_SPECIFIER_ID &&
+	    (gasp_version(buf_ptr) == RFC2734_SW_VERSION
 #if IS_ENABLED(CONFIG_IPV6)
-	     || ver == RFC3146_SW_VERSION
+	     || gasp_version(buf_ptr) == RFC3146_SW_VERSION
 #endif
-	    )) {
-		buf_ptr += 2;
-		length -= IEEE1394_GASP_HDR_SIZE;
-		fwnet_incoming_packet(dev, buf_ptr, length, source_node_id,
+	    ))
+		fwnet_incoming_packet(dev, buf_ptr + 2,
+				      length - IEEE1394_GASP_HDR_SIZE,
+				      gasp_source_id(buf_ptr),
 				      context->card->generation, true);
-	}
 
 	packet.payload_length = dev->rcv_buffer_size;
 	packet.interrupt = 1;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpio/gpiolib-acpi.c linux-libre-4.8.7-gnu/drivers/gpio/gpiolib-acpi.c
--- linux-libre-4.8.6-gnu/drivers/gpio/gpiolib-acpi.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpio/gpiolib-acpi.c	2016-11-10 10:39:23.000000000 -0500
@@ -602,14 +602,17 @@ int acpi_dev_gpio_irq_get(struct acpi_de
 {
 	int idx, i;
 	unsigned int irq_flags;
+	int ret = -ENOENT;
 
 	for (i = 0, idx = 0; idx <= index; i++) {
 		struct acpi_gpio_info info;
 		struct gpio_desc *desc;
 
 		desc = acpi_get_gpiod_by_index(adev, NULL, i, &info);
-		if (IS_ERR(desc))
+		if (IS_ERR(desc)) {
+			ret = PTR_ERR(desc);
 			break;
+		}
 		if (info.gpioint && idx++ == index) {
 			int irq = gpiod_to_irq(desc);
 
@@ -628,7 +631,7 @@ int acpi_dev_gpio_irq_get(struct acpi_de
 		}
 
 	}
-	return -ENOENT;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get);
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpio/gpiolib.c linux-libre-4.8.7-gnu/drivers/gpio/gpiolib.c
--- linux-libre-4.8.6-gnu/drivers/gpio/gpiolib.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpio/gpiolib.c	2016-11-10 10:39:23.000000000 -0500
@@ -21,6 +21,7 @@
 #include <linux/uaccess.h>
 #include <linux/compat.h>
 #include <linux/anon_inodes.h>
+#include <linux/file.h>
 #include <linux/kfifo.h>
 #include <linux/poll.h>
 #include <linux/timekeeping.h>
@@ -331,6 +332,13 @@ struct linehandle_state {
 	u32 numdescs;
 };
 
+#define GPIOHANDLE_REQUEST_VALID_FLAGS \
+	(GPIOHANDLE_REQUEST_INPUT | \
+	GPIOHANDLE_REQUEST_OUTPUT | \
+	GPIOHANDLE_REQUEST_ACTIVE_LOW | \
+	GPIOHANDLE_REQUEST_OPEN_DRAIN | \
+	GPIOHANDLE_REQUEST_OPEN_SOURCE)
+
 static long linehandle_ioctl(struct file *filep, unsigned int cmd,
 			     unsigned long arg)
 {
@@ -342,6 +350,8 @@ static long linehandle_ioctl(struct file
 	if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
 		int val;
 
+		memset(&ghd, 0, sizeof(ghd));
+
 		/* TODO: check if descriptors are really input */
 		for (i = 0; i < lh->numdescs; i++) {
 			val = gpiod_get_value_cansleep(lh->descs[i]);
@@ -412,6 +422,7 @@ static int linehandle_create(struct gpio
 {
 	struct gpiohandle_request handlereq;
 	struct linehandle_state *lh;
+	struct file *file;
 	int fd, i, ret;
 
 	if (copy_from_user(&handlereq, ip, sizeof(handlereq)))
@@ -442,6 +453,17 @@ static int linehandle_create(struct gpio
 		u32 lflags = handlereq.flags;
 		struct gpio_desc *desc;
 
+		if (offset >= gdev->ngpio) {
+			ret = -EINVAL;
+			goto out_free_descs;
+		}
+
+		/* Return an error if a unknown flag is set */
+		if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) {
+			ret = -EINVAL;
+			goto out_free_descs;
+		}
+
 		desc = &gdev->descs[offset];
 		ret = gpiod_request(desc, lh->label);
 		if (ret)
@@ -477,26 +499,41 @@ static int linehandle_create(struct gpio
 	i--;
 	lh->numdescs = handlereq.lines;
 
-	fd = anon_inode_getfd("gpio-linehandle",
-			      &linehandle_fileops,
-			      lh,
-			      O_RDONLY | O_CLOEXEC);
+	fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
 	if (fd < 0) {
 		ret = fd;
 		goto out_free_descs;
 	}
 
+	file = anon_inode_getfile("gpio-linehandle",
+				  &linehandle_fileops,
+				  lh,
+				  O_RDONLY | O_CLOEXEC);
+	if (IS_ERR(file)) {
+		ret = PTR_ERR(file);
+		goto out_put_unused_fd;
+	}
+
 	handlereq.fd = fd;
 	if (copy_to_user(ip, &handlereq, sizeof(handlereq))) {
-		ret = -EFAULT;
-		goto out_free_descs;
+		/*
+		 * fput() will trigger the release() callback, so do not go onto
+		 * the regular error cleanup path here.
+		 */
+		fput(file);
+		put_unused_fd(fd);
+		return -EFAULT;
 	}
 
+	fd_install(fd, file);
+
 	dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n",
 		lh->numdescs);
 
 	return 0;
 
+out_put_unused_fd:
+	put_unused_fd(fd);
 out_free_descs:
 	for (; i >= 0; i--)
 		gpiod_free(lh->descs[i]);
@@ -534,6 +571,10 @@ struct lineevent_state {
 	struct mutex read_lock;
 };
 
+#define GPIOEVENT_REQUEST_VALID_FLAGS \
+	(GPIOEVENT_REQUEST_RISING_EDGE | \
+	GPIOEVENT_REQUEST_FALLING_EDGE)
+
 static unsigned int lineevent_poll(struct file *filep,
 				   struct poll_table_struct *wait)
 {
@@ -621,6 +662,8 @@ static long lineevent_ioctl(struct file
 	if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
 		int val;
 
+		memset(&ghd, 0, sizeof(ghd));
+
 		val = gpiod_get_value_cansleep(le->desc);
 		if (val < 0)
 			return val;
@@ -693,6 +736,7 @@ static int lineevent_create(struct gpio_
 	struct gpioevent_request eventreq;
 	struct lineevent_state *le;
 	struct gpio_desc *desc;
+	struct file *file;
 	u32 offset;
 	u32 lflags;
 	u32 eflags;
@@ -724,6 +768,18 @@ static int lineevent_create(struct gpio_
 	lflags = eventreq.handleflags;
 	eflags = eventreq.eventflags;
 
+	if (offset >= gdev->ngpio) {
+		ret = -EINVAL;
+		goto out_free_label;
+	}
+
+	/* Return an error if a unknown flag is set */
+	if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) ||
+	    (eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS)) {
+		ret = -EINVAL;
+		goto out_free_label;
+	}
+
 	/* This is just wrong: we don't look for events on output lines */
 	if (lflags & GPIOHANDLE_REQUEST_OUTPUT) {
 		ret = -EINVAL;
@@ -775,23 +831,38 @@ static int lineevent_create(struct gpio_
 	if (ret)
 		goto out_free_desc;
 
-	fd = anon_inode_getfd("gpio-event",
-			      &lineevent_fileops,
-			      le,
-			      O_RDONLY | O_CLOEXEC);
+	fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
 	if (fd < 0) {
 		ret = fd;
 		goto out_free_irq;
 	}
 
+	file = anon_inode_getfile("gpio-event",
+				  &lineevent_fileops,
+				  le,
+				  O_RDONLY | O_CLOEXEC);
+	if (IS_ERR(file)) {
+		ret = PTR_ERR(file);
+		goto out_put_unused_fd;
+	}
+
 	eventreq.fd = fd;
 	if (copy_to_user(ip, &eventreq, sizeof(eventreq))) {
-		ret = -EFAULT;
-		goto out_free_irq;
+		/*
+		 * fput() will trigger the release() callback, so do not go onto
+		 * the regular error cleanup path here.
+		 */
+		fput(file);
+		put_unused_fd(fd);
+		return -EFAULT;
 	}
 
+	fd_install(fd, file);
+
 	return 0;
 
+out_put_unused_fd:
+	put_unused_fd(fd);
 out_free_irq:
 	free_irq(le->irq, le);
 out_free_desc:
@@ -821,6 +892,8 @@ static long gpio_ioctl(struct file *filp
 	if (cmd == GPIO_GET_CHIPINFO_IOCTL) {
 		struct gpiochip_info chipinfo;
 
+		memset(&chipinfo, 0, sizeof(chipinfo));
+
 		strncpy(chipinfo.name, dev_name(&gdev->dev),
 			sizeof(chipinfo.name));
 		chipinfo.name[sizeof(chipinfo.name)-1] = '\0';
@@ -837,7 +910,7 @@ static long gpio_ioctl(struct file *filp
 
 		if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
 			return -EFAULT;
-		if (lineinfo.line_offset > gdev->ngpio)
+		if (lineinfo.line_offset >= gdev->ngpio)
 			return -EINVAL;
 
 		desc = &gdev->descs[lineinfo.line_offset];
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/drm_atomic.c linux-libre-4.8.7-gnu/drivers/gpu/drm/drm_atomic.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/drm_atomic.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/drm_atomic.c	2016-11-10 10:39:23.000000000 -0500
@@ -420,18 +420,21 @@ drm_atomic_replace_property_blob_from_id
 					 ssize_t expected_size,
 					 bool *replaced)
 {
-	struct drm_device *dev = crtc->dev;
 	struct drm_property_blob *new_blob = NULL;
 
 	if (blob_id != 0) {
-		new_blob = drm_property_lookup_blob(dev, blob_id);
+		new_blob = drm_property_lookup_blob(crtc->dev, blob_id);
 		if (new_blob == NULL)
 			return -EINVAL;
-		if (expected_size > 0 && expected_size != new_blob->length)
+
+		if (expected_size > 0 && expected_size != new_blob->length) {
+			drm_property_unreference_blob(new_blob);
 			return -EINVAL;
+		}
 	}
 
 	drm_atomic_replace_property_blob(blob, new_blob, replaced);
+	drm_property_unreference_blob(new_blob);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/drm_dp_mst_topology.c linux-libre-4.8.7-gnu/drivers/gpu/drm/drm_dp_mst_topology.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/drm_dp_mst_topology.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/drm_dp_mst_topology.c	2016-11-10 10:39:23.000000000 -0500
@@ -914,6 +914,7 @@ static void drm_dp_destroy_port(struct k
 		/* no need to clean up vcpi
 		 * as if we have no connector we never setup a vcpi */
 		drm_dp_port_teardown_pdt(port, port->pdt);
+		port->pdt = DP_PEER_DEVICE_NONE;
 	}
 	kfree(port);
 }
@@ -1159,7 +1160,9 @@ static void drm_dp_add_port(struct drm_d
 			drm_dp_put_port(port);
 			goto out;
 		}
-		if (port->port_num >= DP_MST_LOGICAL_PORT_0) {
+		if ((port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV ||
+		     port->pdt == DP_PEER_DEVICE_SST_SINK) &&
+		    port->port_num >= DP_MST_LOGICAL_PORT_0) {
 			port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc);
 			drm_mode_connector_set_tile_property(port->connector);
 		}
@@ -2919,6 +2922,7 @@ static void drm_dp_destroy_connector_wor
 		mgr->cbs->destroy_connector(mgr, port->connector);
 
 		drm_dp_port_teardown_pdt(port, port->pdt);
+		port->pdt = DP_PEER_DEVICE_NONE;
 
 		if (!port->input && port->vcpi.vcpi > 0) {
 			drm_dp_mst_reset_vcpi_slots(mgr, port);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/drm_fb_helper.c linux-libre-4.8.7-gnu/drivers/gpu/drm/drm_fb_helper.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/drm_fb_helper.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/drm_fb_helper.c	2016-11-10 10:39:23.000000000 -0500
@@ -129,7 +129,12 @@ int drm_fb_helper_single_add_all_connect
 	return 0;
 fail:
 	for (i = 0; i < fb_helper->connector_count; i++) {
-		kfree(fb_helper->connector_info[i]);
+		struct drm_fb_helper_connector *fb_helper_connector =
+			fb_helper->connector_info[i];
+
+		drm_connector_unreference(fb_helper_connector->connector);
+
+		kfree(fb_helper_connector);
 		fb_helper->connector_info[i] = NULL;
 	}
 	fb_helper->connector_count = 0;
@@ -601,6 +606,24 @@ int drm_fb_helper_blank(int blank, struc
 }
 EXPORT_SYMBOL(drm_fb_helper_blank);
 
+static void drm_fb_helper_modeset_release(struct drm_fb_helper *helper,
+					  struct drm_mode_set *modeset)
+{
+	int i;
+
+	for (i = 0; i < modeset->num_connectors; i++) {
+		drm_connector_unreference(modeset->connectors[i]);
+		modeset->connectors[i] = NULL;
+	}
+	modeset->num_connectors = 0;
+
+	drm_mode_destroy(helper->dev, modeset->mode);
+	modeset->mode = NULL;
+
+	/* FIXME should hold a ref? */
+	modeset->fb = NULL;
+}
+
 static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
 {
 	int i;
@@ -610,10 +633,12 @@ static void drm_fb_helper_crtc_free(stru
 		kfree(helper->connector_info[i]);
 	}
 	kfree(helper->connector_info);
+
 	for (i = 0; i < helper->crtc_count; i++) {
-		kfree(helper->crtc_info[i].mode_set.connectors);
-		if (helper->crtc_info[i].mode_set.mode)
-			drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
+		struct drm_mode_set *modeset = &helper->crtc_info[i].mode_set;
+
+		drm_fb_helper_modeset_release(helper, modeset);
+		kfree(modeset->connectors);
 	}
 	kfree(helper->crtc_info);
 }
@@ -632,7 +657,9 @@ static void drm_fb_helper_dirty_work(str
 	clip->x2 = clip->y2 = 0;
 	spin_unlock_irqrestore(&helper->dirty_lock, flags);
 
-	helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1);
+	/* call dirty callback only when it has been really touched */
+	if (clip_copy.x1 < clip_copy.x2 && clip_copy.y1 < clip_copy.y2)
+		helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1);
 }
 
 /**
@@ -2027,7 +2054,6 @@ static void drm_setup_crtcs(struct drm_f
 	struct drm_fb_helper_crtc **crtcs;
 	struct drm_display_mode **modes;
 	struct drm_fb_offset *offsets;
-	struct drm_mode_set *modeset;
 	bool *enabled;
 	int width, height;
 	int i;
@@ -2075,45 +2101,35 @@ static void drm_setup_crtcs(struct drm_f
 
 	/* need to set the modesets up here for use later */
 	/* fill out the connector<->crtc mappings into the modesets */
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		modeset = &fb_helper->crtc_info[i].mode_set;
-		modeset->num_connectors = 0;
-		modeset->fb = NULL;
-	}
+	for (i = 0; i < fb_helper->crtc_count; i++)
+		drm_fb_helper_modeset_release(fb_helper,
+					      &fb_helper->crtc_info[i].mode_set);
 
 	for (i = 0; i < fb_helper->connector_count; i++) {
 		struct drm_display_mode *mode = modes[i];
 		struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
 		struct drm_fb_offset *offset = &offsets[i];
-		modeset = &fb_crtc->mode_set;
+		struct drm_mode_set *modeset = &fb_crtc->mode_set;
 
 		if (mode && fb_crtc) {
+			struct drm_connector *connector =
+				fb_helper->connector_info[i]->connector;
+
 			DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
 				      mode->name, fb_crtc->mode_set.crtc->base.id, offset->x, offset->y);
+
 			fb_crtc->desired_mode = mode;
 			fb_crtc->x = offset->x;
 			fb_crtc->y = offset->y;
-			if (modeset->mode)
-				drm_mode_destroy(dev, modeset->mode);
 			modeset->mode = drm_mode_duplicate(dev,
 							   fb_crtc->desired_mode);
-			modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector;
+			drm_connector_reference(connector);
+			modeset->connectors[modeset->num_connectors++] = connector;
 			modeset->fb = fb_helper->fb;
 			modeset->x = offset->x;
 			modeset->y = offset->y;
 		}
 	}
-
-	/* Clear out any old modes if there are no more connected outputs. */
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		modeset = &fb_helper->crtc_info[i].mode_set;
-		if (modeset->num_connectors == 0) {
-			BUG_ON(modeset->fb);
-			if (modeset->mode)
-				drm_mode_destroy(dev, modeset->mode);
-			modeset->mode = NULL;
-		}
-	}
 out:
 	kfree(crtcs);
 	kfree(modes);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_bios.c linux-libre-4.8.7-gnu/drivers/gpu/drm/i915/intel_bios.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_bios.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/i915/intel_bios.c	2016-11-10 10:39:23.000000000 -0500
@@ -1031,6 +1031,77 @@ static u8 translate_iboost(u8 val)
 	return mapping[val];
 }
 
+static void sanitize_ddc_pin(struct drm_i915_private *dev_priv,
+			     enum port port)
+{
+	const struct ddi_vbt_port_info *info =
+		&dev_priv->vbt.ddi_port_info[port];
+	enum port p;
+
+	if (!info->alternate_ddc_pin)
+		return;
+
+	for_each_port_masked(p, (1 << port) - 1) {
+		struct ddi_vbt_port_info *i = &dev_priv->vbt.ddi_port_info[p];
+
+		if (info->alternate_ddc_pin != i->alternate_ddc_pin)
+			continue;
+
+		DRM_DEBUG_KMS("port %c trying to use the same DDC pin (0x%x) as port %c, "
+			      "disabling port %c DVI/HDMI support\n",
+			      port_name(p), i->alternate_ddc_pin,
+			      port_name(port), port_name(p));
+
+		/*
+		 * If we have multiple ports supposedly sharing the
+		 * pin, then dvi/hdmi couldn't exist on the shared
+		 * port. Otherwise they share the same ddc bin and
+		 * system couldn't communicate with them separately.
+		 *
+		 * Due to parsing the ports in alphabetical order,
+		 * a higher port will always clobber a lower one.
+		 */
+		i->supports_dvi = false;
+		i->supports_hdmi = false;
+		i->alternate_ddc_pin = 0;
+	}
+}
+
+static void sanitize_aux_ch(struct drm_i915_private *dev_priv,
+			    enum port port)
+{
+	const struct ddi_vbt_port_info *info =
+		&dev_priv->vbt.ddi_port_info[port];
+	enum port p;
+
+	if (!info->alternate_aux_channel)
+		return;
+
+	for_each_port_masked(p, (1 << port) - 1) {
+		struct ddi_vbt_port_info *i = &dev_priv->vbt.ddi_port_info[p];
+
+		if (info->alternate_aux_channel != i->alternate_aux_channel)
+			continue;
+
+		DRM_DEBUG_KMS("port %c trying to use the same AUX CH (0x%x) as port %c, "
+			      "disabling port %c DP support\n",
+			      port_name(p), i->alternate_aux_channel,
+			      port_name(port), port_name(p));
+
+		/*
+		 * If we have multiple ports supposedlt sharing the
+		 * aux channel, then DP couldn't exist on the shared
+		 * port. Otherwise they share the same aux channel
+		 * and system couldn't communicate with them separately.
+		 *
+		 * Due to parsing the ports in alphabetical order,
+		 * a higher port will always clobber a lower one.
+		 */
+		i->supports_dp = false;
+		i->alternate_aux_channel = 0;
+	}
+}
+
 static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
 			   const struct bdb_header *bdb)
 {
@@ -1105,54 +1176,15 @@ static void parse_ddi_port(struct drm_i9
 		DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port));
 
 	if (is_dvi) {
-		if (port == PORT_E) {
-			info->alternate_ddc_pin = ddc_pin;
-			/* if DDIE share ddc pin with other port, then
-			 * dvi/hdmi couldn't exist on the shared port.
-			 * Otherwise they share the same ddc bin and system
-			 * couldn't communicate with them seperately. */
-			if (ddc_pin == DDC_PIN_B) {
-				dev_priv->vbt.ddi_port_info[PORT_B].supports_dvi = 0;
-				dev_priv->vbt.ddi_port_info[PORT_B].supports_hdmi = 0;
-			} else if (ddc_pin == DDC_PIN_C) {
-				dev_priv->vbt.ddi_port_info[PORT_C].supports_dvi = 0;
-				dev_priv->vbt.ddi_port_info[PORT_C].supports_hdmi = 0;
-			} else if (ddc_pin == DDC_PIN_D) {
-				dev_priv->vbt.ddi_port_info[PORT_D].supports_dvi = 0;
-				dev_priv->vbt.ddi_port_info[PORT_D].supports_hdmi = 0;
-			}
-		} else if (ddc_pin == DDC_PIN_B && port != PORT_B)
-			DRM_DEBUG_KMS("Unexpected DDC pin for port B\n");
-		else if (ddc_pin == DDC_PIN_C && port != PORT_C)
-			DRM_DEBUG_KMS("Unexpected DDC pin for port C\n");
-		else if (ddc_pin == DDC_PIN_D && port != PORT_D)
-			DRM_DEBUG_KMS("Unexpected DDC pin for port D\n");
+		info->alternate_ddc_pin = ddc_pin;
+
+		sanitize_ddc_pin(dev_priv, port);
 	}
 
 	if (is_dp) {
-		if (port == PORT_E) {
-			info->alternate_aux_channel = aux_channel;
-			/* if DDIE share aux channel with other port, then
-			 * DP couldn't exist on the shared port. Otherwise
-			 * they share the same aux channel and system
-			 * couldn't communicate with them seperately. */
-			if (aux_channel == DP_AUX_A)
-				dev_priv->vbt.ddi_port_info[PORT_A].supports_dp = 0;
-			else if (aux_channel == DP_AUX_B)
-				dev_priv->vbt.ddi_port_info[PORT_B].supports_dp = 0;
-			else if (aux_channel == DP_AUX_C)
-				dev_priv->vbt.ddi_port_info[PORT_C].supports_dp = 0;
-			else if (aux_channel == DP_AUX_D)
-				dev_priv->vbt.ddi_port_info[PORT_D].supports_dp = 0;
-		}
-		else if (aux_channel == DP_AUX_A && port != PORT_A)
-			DRM_DEBUG_KMS("Unexpected AUX channel for port A\n");
-		else if (aux_channel == DP_AUX_B && port != PORT_B)
-			DRM_DEBUG_KMS("Unexpected AUX channel for port B\n");
-		else if (aux_channel == DP_AUX_C && port != PORT_C)
-			DRM_DEBUG_KMS("Unexpected AUX channel for port C\n");
-		else if (aux_channel == DP_AUX_D && port != PORT_D)
-			DRM_DEBUG_KMS("Unexpected AUX channel for port D\n");
+		info->alternate_aux_channel = aux_channel;
+
+		sanitize_aux_ch(dev_priv, port);
 	}
 
 	if (bdb->version >= 158) {
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_display.c linux-libre-4.8.7-gnu/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_display.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/i915/intel_display.c	2016-11-10 10:39:23.000000000 -0500
@@ -13834,7 +13834,7 @@ static void intel_atomic_commit_tail(str
 
 	for_each_plane_in_state(state, plane, plane_state, i) {
 		struct intel_plane_state *intel_plane_state =
-			to_intel_plane_state(plane_state);
+			to_intel_plane_state(plane->state);
 
 		if (!intel_plane_state->wait_req)
 			continue;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_dp.c linux-libre-4.8.7-gnu/drivers/gpu/drm/i915/intel_dp.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_dp.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/i915/intel_dp.c	2016-11-10 10:39:23.000000000 -0500
@@ -1090,6 +1090,44 @@ intel_dp_aux_transfer(struct drm_dp_aux
 	return ret;
 }
 
+static enum port intel_aux_port(struct drm_i915_private *dev_priv,
+				enum port port)
+{
+	const struct ddi_vbt_port_info *info =
+		&dev_priv->vbt.ddi_port_info[port];
+	enum port aux_port;
+
+	if (!info->alternate_aux_channel) {
+		DRM_DEBUG_KMS("using AUX %c for port %c (platform default)\n",
+			      port_name(port), port_name(port));
+		return port;
+	}
+
+	switch (info->alternate_aux_channel) {
+	case DP_AUX_A:
+		aux_port = PORT_A;
+		break;
+	case DP_AUX_B:
+		aux_port = PORT_B;
+		break;
+	case DP_AUX_C:
+		aux_port = PORT_C;
+		break;
+	case DP_AUX_D:
+		aux_port = PORT_D;
+		break;
+	default:
+		MISSING_CASE(info->alternate_aux_channel);
+		aux_port = PORT_A;
+		break;
+	}
+
+	DRM_DEBUG_KMS("using AUX %c for port %c (VBT)\n",
+		      port_name(aux_port), port_name(port));
+
+	return aux_port;
+}
+
 static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv,
 				       enum port port)
 {
@@ -1150,36 +1188,9 @@ static i915_reg_t ilk_aux_data_reg(struc
 	}
 }
 
-/*
- * On SKL we don't have Aux for port E so we rely
- * on VBT to set a proper alternate aux channel.
- */
-static enum port skl_porte_aux_port(struct drm_i915_private *dev_priv)
-{
-	const struct ddi_vbt_port_info *info =
-		&dev_priv->vbt.ddi_port_info[PORT_E];
-
-	switch (info->alternate_aux_channel) {
-	case DP_AUX_A:
-		return PORT_A;
-	case DP_AUX_B:
-		return PORT_B;
-	case DP_AUX_C:
-		return PORT_C;
-	case DP_AUX_D:
-		return PORT_D;
-	default:
-		MISSING_CASE(info->alternate_aux_channel);
-		return PORT_A;
-	}
-}
-
 static i915_reg_t skl_aux_ctl_reg(struct drm_i915_private *dev_priv,
 				       enum port port)
 {
-	if (port == PORT_E)
-		port = skl_porte_aux_port(dev_priv);
-
 	switch (port) {
 	case PORT_A:
 	case PORT_B:
@@ -1195,9 +1206,6 @@ static i915_reg_t skl_aux_ctl_reg(struct
 static i915_reg_t skl_aux_data_reg(struct drm_i915_private *dev_priv,
 					enum port port, int index)
 {
-	if (port == PORT_E)
-		port = skl_porte_aux_port(dev_priv);
-
 	switch (port) {
 	case PORT_A:
 	case PORT_B:
@@ -1235,7 +1243,8 @@ static i915_reg_t intel_aux_data_reg(str
 static void intel_aux_reg_init(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
-	enum port port = dp_to_dig_port(intel_dp)->port;
+	enum port port = intel_aux_port(dev_priv,
+					dp_to_dig_port(intel_dp)->port);
 	int i;
 
 	intel_dp->aux_ch_ctl_reg = intel_aux_ctl_reg(dev_priv, port);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_fbc.c linux-libre-4.8.7-gnu/drivers/gpu/drm/i915/intel_fbc.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_fbc.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/i915/intel_fbc.c	2016-11-10 10:39:23.000000000 -0500
@@ -104,8 +104,10 @@ static int intel_fbc_calculate_cfb_size(
 	int lines;
 
 	intel_fbc_get_plane_source_size(cache, NULL, &lines);
-	if (INTEL_INFO(dev_priv)->gen >= 7)
+	if (INTEL_GEN(dev_priv) == 7)
 		lines = min(lines, 2048);
+	else if (INTEL_GEN(dev_priv) >= 8)
+		lines = min(lines, 2560);
 
 	/* Hardware needs the full buffer stride, not just the active area. */
 	return lines * cache->fb.stride;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_pm.c linux-libre-4.8.7-gnu/drivers/gpu/drm/i915/intel_pm.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_pm.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/i915/intel_pm.c	2016-11-10 10:39:23.000000000 -0500
@@ -3363,13 +3363,15 @@ skl_allocate_pipe_ddb(struct intel_crtc_
 	int num_active;
 	int id, i;
 
+	/* Clear the partitioning for disabled planes. */
+	memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+	memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
+
 	if (WARN_ON(!state))
 		return 0;
 
 	if (!cstate->base.active) {
 		ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0;
-		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
-		memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
 		return 0;
 	}
 
@@ -3469,12 +3471,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_
 	return 0;
 }
 
-static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_state *config)
-{
-	/* TODO: Take into account the scalers once we support them */
-	return config->base.adjusted_mode.crtc_clock;
-}
-
 /*
  * The max latency should be 257 (max the punit can code is 255 and we add 2us
  * for the read latency) and cpp should always be <= 8, so that
@@ -3525,7 +3521,7 @@ static uint32_t skl_adjusted_plane_pixel
 	 * Adjusted plane pixel rate is just the pipe's adjusted pixel rate
 	 * with additional adjustments for plane-specific scaling.
 	 */
-	adjusted_pixel_rate = skl_pipe_pixel_rate(cstate);
+	adjusted_pixel_rate = ilk_pipe_pixel_rate(cstate);
 	downscale_amount = skl_plane_downscale_amount(pstate);
 
 	pixel_rate = adjusted_pixel_rate * downscale_amount >> 16;
@@ -3737,11 +3733,11 @@ skl_compute_linetime_wm(struct intel_crt
 	if (!cstate->base.active)
 		return 0;
 
-	if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0))
+	if (WARN_ON(ilk_pipe_pixel_rate(cstate) == 0))
 		return 0;
 
 	return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000,
-			    skl_pipe_pixel_rate(cstate));
+			    ilk_pipe_pixel_rate(cstate));
 }
 
 static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
@@ -4051,6 +4047,12 @@ skl_compute_ddb(struct drm_atomic_state
 		intel_state->wm_results.dirty_pipes = ~0;
 	}
 
+	/*
+	 * We're not recomputing for the pipes not included in the commit, so
+	 * make sure we start with the current state.
+	 */
+	memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb));
+
 	for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
 		struct intel_crtc_state *cstate;
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/imx/ipuv3-plane.c linux-libre-4.8.7-gnu/drivers/gpu/drm/imx/ipuv3-plane.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/imx/ipuv3-plane.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/imx/ipuv3-plane.c	2016-11-10 10:39:23.000000000 -0500
@@ -108,6 +108,7 @@ static void ipu_plane_atomic_set_base(st
 {
 	struct drm_plane *plane = &ipu_plane->base;
 	struct drm_plane_state *state = plane->state;
+	struct drm_crtc_state *crtc_state = state->crtc->state;
 	struct drm_framebuffer *fb = state->fb;
 	unsigned long eba, ubo, vbo;
 	int active;
@@ -149,7 +150,7 @@ static void ipu_plane_atomic_set_base(st
 		break;
 	}
 
-	if (old_state->fb) {
+	if (!drm_atomic_crtc_needs_modeset(crtc_state)) {
 		active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch);
 		ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba);
 		ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active);
@@ -359,7 +360,9 @@ static int ipu_plane_atomic_check(struct
 		if ((ubo > 0xfffff8) || (vbo > 0xfffff8))
 			return -EINVAL;
 
-		if (old_fb) {
+		if (old_fb &&
+		    (old_fb->pixel_format == DRM_FORMAT_YUV420 ||
+		     old_fb->pixel_format == DRM_FORMAT_YVU420)) {
 			old_ubo = drm_plane_state_to_ubo(old_state);
 			old_vbo = drm_plane_state_to_vbo(old_state);
 			if (ubo != old_ubo || vbo != old_vbo)
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/nouveau/nouveau_acpi.c linux-libre-4.8.7-gnu/drivers/gpu/drm/nouveau/nouveau_acpi.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/nouveau/nouveau_acpi.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/nouveau/nouveau_acpi.c	2016-11-10 10:39:23.000000000 -0500
@@ -240,7 +240,8 @@ static bool nouveau_pr3_present(struct p
 	if (!parent_adev)
 		return false;
 
-	return acpi_has_method(parent_adev->handle, "_PR3");
+	return parent_adev->power.flags.power_resources &&
+		acpi_has_method(parent_adev->handle, "_PR3");
 }
 
 static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out,
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/ni.c linux-libre-4.8.7-gnu/drivers/gpu/drm/radeon/ni.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/ni.c	2016-10-31 17:34:02.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/radeon/ni.c	2016-11-10 16:02:42.000000000 -0500
@@ -1376,9 +1376,7 @@ static void cayman_pcie_gart_fini(struct
 void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
 			      int ring, u32 cp_int_cntl)
 {
-	u32 srbm_gfx_cntl = RREG32(SRBM_GFX_CNTL) & ~3;
-
-	WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl | (ring & 3));
+	WREG32(SRBM_GFX_CNTL, RINGID(ring));
 	WREG32(CP_INT_CNTL, cp_int_cntl);
 }
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/radeon_dp_auxch.c linux-libre-4.8.7-gnu/drivers/gpu/drm/radeon/radeon_dp_auxch.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/radeon_dp_auxch.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/radeon/radeon_dp_auxch.c	2016-11-10 10:39:23.000000000 -0500
@@ -105,7 +105,7 @@ radeon_dp_aux_transfer_native(struct drm
 
 	tmp &= AUX_HPD_SEL(0x7);
 	tmp |= AUX_HPD_SEL(chan->rec.hpd);
-	tmp |= AUX_EN | AUX_LS_READ_EN | AUX_HPD_DISCON(0x1);
+	tmp |= AUX_EN | AUX_LS_READ_EN;
 
 	WREG32(AUX_CONTROL + aux_offset[instance], tmp);
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/si_dpm.c linux-libre-4.8.7-gnu/drivers/gpu/drm/radeon/si_dpm.c
--- linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/si_dpm.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/gpu/drm/radeon/si_dpm.c	2016-11-10 10:39:23.000000000 -0500
@@ -2999,6 +2999,49 @@ static void si_apply_state_adjust_rules(
 	int i;
 	struct si_dpm_quirk *p = si_dpm_quirk_list;
 
+	/* limit all SI kickers */
+	if (rdev->family == CHIP_PITCAIRN) {
+		if ((rdev->pdev->revision == 0x81) ||
+		    (rdev->pdev->device == 0x6810) ||
+		    (rdev->pdev->device == 0x6811) ||
+		    (rdev->pdev->device == 0x6816) ||
+		    (rdev->pdev->device == 0x6817) ||
+		    (rdev->pdev->device == 0x6806))
+			max_mclk = 120000;
+	} else if (rdev->family == CHIP_VERDE) {
+		if ((rdev->pdev->revision == 0x81) ||
+		    (rdev->pdev->revision == 0x83) ||
+		    (rdev->pdev->revision == 0x87) ||
+		    (rdev->pdev->device == 0x6820) ||
+		    (rdev->pdev->device == 0x6821) ||
+		    (rdev->pdev->device == 0x6822) ||
+		    (rdev->pdev->device == 0x6823) ||
+		    (rdev->pdev->device == 0x682A) ||
+		    (rdev->pdev->device == 0x682B)) {
+			max_sclk = 75000;
+			max_mclk = 80000;
+		}
+	} else if (rdev->family == CHIP_OLAND) {
+		if ((rdev->pdev->revision == 0xC7) ||
+		    (rdev->pdev->revision == 0x80) ||
+		    (rdev->pdev->revision == 0x81) ||
+		    (rdev->pdev->revision == 0x83) ||
+		    (rdev->pdev->device == 0x6604) ||
+		    (rdev->pdev->device == 0x6605)) {
+			max_sclk = 75000;
+			max_mclk = 80000;
+		}
+	} else if (rdev->family == CHIP_HAINAN) {
+		if ((rdev->pdev->revision == 0x81) ||
+		    (rdev->pdev->revision == 0x83) ||
+		    (rdev->pdev->revision == 0xC3) ||
+		    (rdev->pdev->device == 0x6664) ||
+		    (rdev->pdev->device == 0x6665) ||
+		    (rdev->pdev->device == 0x6667)) {
+			max_sclk = 75000;
+			max_mclk = 80000;
+		}
+	}
 	/* Apply dpm quirks */
 	while (p && p->chip_device != 0) {
 		if (rdev->pdev->vendor == p->chip_vendor &&
@@ -3011,16 +3054,6 @@ static void si_apply_state_adjust_rules(
 		}
 		++p;
 	}
-	/* limit mclk on all R7 370 parts for stability */
-	if (rdev->pdev->device == 0x6811 &&
-	    rdev->pdev->revision == 0x81)
-		max_mclk = 120000;
-	/* limit sclk/mclk on Jet parts for stability */
-	if (rdev->pdev->device == 0x6665 &&
-	    rdev->pdev->revision == 0xc3) {
-		max_sclk = 75000;
-		max_mclk = 80000;
-	}
 
 	if (rps->vce_active) {
 		rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/hid/hid-ids.h linux-libre-4.8.7-gnu/drivers/hid/hid-ids.h
--- linux-libre-4.8.6-gnu/drivers/hid/hid-ids.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/hid/hid-ids.h	2016-11-10 10:39:23.000000000 -0500
@@ -179,6 +179,7 @@
 #define USB_DEVICE_ID_ATEN_4PORTKVM	0x2205
 #define USB_DEVICE_ID_ATEN_4PORTKVMC	0x2208
 #define USB_DEVICE_ID_ATEN_CS682	0x2213
+#define USB_DEVICE_ID_ATEN_CS692	0x8021
 
 #define USB_VENDOR_ID_ATMEL		0x03eb
 #define USB_DEVICE_ID_ATMEL_MULTITOUCH	0x211c
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/hid/usbhid/hid-quirks.c linux-libre-4.8.7-gnu/drivers/hid/usbhid/hid-quirks.c
--- linux-libre-4.8.6-gnu/drivers/hid/usbhid/hid-quirks.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/hid/usbhid/hid-quirks.c	2016-11-10 10:39:23.000000000 -0500
@@ -63,6 +63,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET },
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/hv/hv_util.c linux-libre-4.8.7-gnu/drivers/hv/hv_util.c
--- linux-libre-4.8.6-gnu/drivers/hv/hv_util.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/hv/hv_util.c	2016-11-10 10:39:23.000000000 -0500
@@ -283,10 +283,14 @@ static void heartbeat_onchannelcallback(
 	u8 *hbeat_txf_buf = util_heartbeat.recv_buffer;
 	struct icmsg_negotiate *negop = NULL;
 
-	vmbus_recvpacket(channel, hbeat_txf_buf,
-			 PAGE_SIZE, &recvlen, &requestid);
+	while (1) {
+
+		vmbus_recvpacket(channel, hbeat_txf_buf,
+				 PAGE_SIZE, &recvlen, &requestid);
+
+		if (!recvlen)
+			break;
 
-	if (recvlen > 0) {
 		icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[
 				sizeof(struct vmbuspipe_hdr)];
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/i2c/busses/i2c-rk3x.c linux-libre-4.8.7-gnu/drivers/i2c/busses/i2c-rk3x.c
--- linux-libre-4.8.6-gnu/drivers/i2c/busses/i2c-rk3x.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/i2c/busses/i2c-rk3x.c	2016-11-10 10:39:23.000000000 -0500
@@ -694,6 +694,8 @@ static int rk3x_i2c_v0_calc_timings(unsi
 	t_calc->div_low--;
 	t_calc->div_high--;
 
+	/* Give the tuning value 0, that would not update con register */
+	t_calc->tuning = 0;
 	/* Maximum divider supported by hw is 0xffff */
 	if (t_calc->div_low > 0xffff) {
 		t_calc->div_low = 0xffff;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/i2c/busses/i2c-xgene-slimpro.c linux-libre-4.8.7-gnu/drivers/i2c/busses/i2c-xgene-slimpro.c
--- linux-libre-4.8.6-gnu/drivers/i2c/busses/i2c-xgene-slimpro.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/i2c/busses/i2c-xgene-slimpro.c	2016-11-10 10:39:23.000000000 -0500
@@ -105,7 +105,7 @@ struct slimpro_i2c_dev {
 	struct mbox_chan *mbox_chan;
 	struct mbox_client mbox_client;
 	struct completion rd_complete;
-	u8 dma_buffer[I2C_SMBUS_BLOCK_MAX];
+	u8 dma_buffer[I2C_SMBUS_BLOCK_MAX + 1]; /* dma_buffer[0] is used for length */
 	u32 *resp_msg;
 };
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/i2c/i2c-core.c linux-libre-4.8.7-gnu/drivers/i2c/i2c-core.c
--- linux-libre-4.8.6-gnu/drivers/i2c/i2c-core.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/i2c/i2c-core.c	2016-11-10 10:39:23.000000000 -0500
@@ -1592,6 +1592,7 @@ static struct i2c_client *of_i2c_registe
 static void of_i2c_register_devices(struct i2c_adapter *adap)
 {
 	struct device_node *node;
+	struct i2c_client *client;
 
 	/* Only register child devices if the adapter has a node pointer set */
 	if (!adap->dev.of_node)
@@ -1602,7 +1603,14 @@ static void of_i2c_register_devices(stru
 	for_each_available_child_of_node(adap->dev.of_node, node) {
 		if (of_node_test_and_set_flag(node, OF_POPULATED))
 			continue;
-		of_i2c_register_device(adap, node);
+
+		client = of_i2c_register_device(adap, node);
+		if (IS_ERR(client)) {
+			dev_warn(&adap->dev,
+				 "Failed to create I2C device for %s\n",
+				 node->full_name);
+			of_node_clear_flag(node, OF_POPULATED);
+		}
 	}
 }
 
@@ -2073,6 +2081,7 @@ int i2c_register_driver(struct module *o
 	/* add the driver to the list of i2c drivers in the driver core */
 	driver->driver.owner = owner;
 	driver->driver.bus = &i2c_bus_type;
+	INIT_LIST_HEAD(&driver->clients);
 
 	/* When registration returns, the driver core
 	 * will have called probe() for all matching-but-unbound devices.
@@ -2083,7 +2092,6 @@ int i2c_register_driver(struct module *o
 
 	pr_debug("driver [%s] registered\n", driver->driver.name);
 
-	INIT_LIST_HEAD(&driver->clients);
 	/* Walk the adapters that are already present */
 	i2c_for_each_dev(driver, __process_new_driver);
 
@@ -2201,6 +2209,7 @@ static int of_i2c_notify(struct notifier
 		if (IS_ERR(client)) {
 			dev_err(&adap->dev, "failed to create client for '%s'\n",
 				 rd->dn->full_name);
+			of_node_clear_flag(rd->dn, OF_POPULATED);
 			return notifier_from_errno(PTR_ERR(client));
 		}
 		break;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/iio/chemical/atlas-ph-sensor.c linux-libre-4.8.7-gnu/drivers/iio/chemical/atlas-ph-sensor.c
--- linux-libre-4.8.6-gnu/drivers/iio/chemical/atlas-ph-sensor.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/iio/chemical/atlas-ph-sensor.c	2016-11-10 10:39:23.000000000 -0500
@@ -207,13 +207,14 @@ static int atlas_check_ec_calibration(st
 	struct device *dev = &data->client->dev;
 	int ret;
 	unsigned int val;
+	__be16	rval;
 
-	ret = regmap_bulk_read(data->regmap, ATLAS_REG_EC_PROBE, &val, 2);
+	ret = regmap_bulk_read(data->regmap, ATLAS_REG_EC_PROBE, &rval, 2);
 	if (ret)
 		return ret;
 
-	dev_info(dev, "probe set to K = %d.%.2d", be16_to_cpu(val) / 100,
-						 be16_to_cpu(val) % 100);
+	val = be16_to_cpu(rval);
+	dev_info(dev, "probe set to K = %d.%.2d", val / 100, val % 100);
 
 	ret = regmap_read(data->regmap, ATLAS_REG_EC_CALIB_STATUS, &val);
 	if (ret)
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/input/serio/i8042-x86ia64io.h linux-libre-4.8.7-gnu/drivers/input/serio/i8042-x86ia64io.h
--- linux-libre-4.8.6-gnu/drivers/input/serio/i8042-x86ia64io.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/input/serio/i8042-x86ia64io.h	2016-11-10 10:39:23.000000000 -0500
@@ -877,6 +877,13 @@ static const struct dmi_system_id __init
 			DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
 		},
 	},
+	{
+		/* Schenker XMG C504 - Elantech touchpad */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "XMG"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "C504"),
+		},
+	},
 	{ }
 };
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/md/dm.c linux-libre-4.8.7-gnu/drivers/md/dm.c
--- linux-libre-4.8.6-gnu/drivers/md/dm.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/md/dm.c	2016-11-10 10:39:23.000000000 -0500
@@ -1423,8 +1423,6 @@ static void cleanup_mapped_device(struct
 	if (md->bs)
 		bioset_free(md->bs);
 
-	cleanup_srcu_struct(&md->io_barrier);
-
 	if (md->disk) {
 		spin_lock(&_minor_lock);
 		md->disk->private_data = NULL;
@@ -1436,6 +1434,8 @@ static void cleanup_mapped_device(struct
 	if (md->queue)
 		blk_cleanup_queue(md->queue);
 
+	cleanup_srcu_struct(&md->io_barrier);
+
 	if (md->bdev) {
 		bdput(md->bdev);
 		md->bdev = NULL;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/md/dm-raid1.c linux-libre-4.8.7-gnu/drivers/md/dm-raid1.c
--- linux-libre-4.8.6-gnu/drivers/md/dm-raid1.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/md/dm-raid1.c	2016-11-10 10:39:23.000000000 -0500
@@ -1292,6 +1292,7 @@ static int mirror_end_io(struct dm_targe
 
 			dm_bio_restore(bd, bio);
 			bio_record->details.bi_bdev = NULL;
+			bio->bi_error = 0;
 
 			queue_bio(ms, bio, rw);
 			return DM_ENDIO_INCOMPLETE;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/md/dm-raid.c linux-libre-4.8.7-gnu/drivers/md/dm-raid.c
--- linux-libre-4.8.6-gnu/drivers/md/dm-raid.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/md/dm-raid.c	2016-11-10 10:39:23.000000000 -0500
@@ -266,7 +266,7 @@ static struct raid_type {
 	{"raid10_offset", "raid10 offset (striped mirrors)",	    0, 2, 10, ALGORITHM_RAID10_OFFSET},
 	{"raid10_near",	  "raid10 near (striped mirrors)",	    0, 2, 10, ALGORITHM_RAID10_NEAR},
 	{"raid10",	  "raid10 (striped mirrors)",		    0, 2, 10, ALGORITHM_RAID10_DEFAULT},
-	{"raid4",	  "raid4 (dedicated last parity disk)",	    1, 2, 4,  ALGORITHM_PARITY_N}, /* raid4 layout = raid5_n */
+	{"raid4",	  "raid4 (dedicated first parity disk)",    1, 2, 5,  ALGORITHM_PARITY_0}, /* raid4 layout = raid5_0 */
 	{"raid5_n",	  "raid5 (dedicated last parity disk)",	    1, 2, 5,  ALGORITHM_PARITY_N},
 	{"raid5_ls",	  "raid5 (left symmetric)",		    1, 2, 5,  ALGORITHM_LEFT_SYMMETRIC},
 	{"raid5_rs",	  "raid5 (right symmetric)",		    1, 2, 5,  ALGORITHM_RIGHT_SYMMETRIC},
@@ -2087,11 +2087,11 @@ static int super_init_validation(struct
 		/*
 		 * No takeover/reshaping, because we don't have the extended v1.9.0 metadata
 		 */
-		if (le32_to_cpu(sb->level) != mddev->level) {
+		if (le32_to_cpu(sb->level) != mddev->new_level) {
 			DMERR("Reshaping/takeover raid sets not yet supported. (raid level/stripes/size change)");
 			return -EINVAL;
 		}
-		if (le32_to_cpu(sb->layout) != mddev->layout) {
+		if (le32_to_cpu(sb->layout) != mddev->new_layout) {
 			DMERR("Reshaping raid sets not yet supported. (raid layout change)");
 			DMERR("	 0x%X vs 0x%X", le32_to_cpu(sb->layout), mddev->layout);
 			DMERR("	 Old layout: %s w/ %d copies",
@@ -2102,7 +2102,7 @@ static int super_init_validation(struct
 			      raid10_md_layout_to_copies(mddev->layout));
 			return -EINVAL;
 		}
-		if (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors) {
+		if (le32_to_cpu(sb->stripe_sectors) != mddev->new_chunk_sectors) {
 			DMERR("Reshaping raid sets not yet supported. (stripe sectors change)");
 			return -EINVAL;
 		}
@@ -2115,6 +2115,8 @@ static int super_init_validation(struct
 			return -EINVAL;
 		}
 
+		DMINFO("Discovered old metadata format; upgrading to extended metadata format");
+
 		/* Table line is checked vs. authoritative superblock */
 		rs_set_new(rs);
 	}
@@ -2258,7 +2260,8 @@ static int super_validate(struct raid_se
 	if (!mddev->events && super_init_validation(rs, rdev))
 		return -EINVAL;
 
-	if (le32_to_cpu(sb->compat_features) != FEATURE_FLAG_SUPPORTS_V190) {
+	if (le32_to_cpu(sb->compat_features) &&
+	    le32_to_cpu(sb->compat_features) != FEATURE_FLAG_SUPPORTS_V190) {
 		rs->ti->error = "Unable to assemble array: Unknown flag(s) in compatible feature flags";
 		return -EINVAL;
 	}
@@ -3646,7 +3649,7 @@ static void raid_resume(struct dm_target
 
 static struct target_type raid_target = {
 	.name = "raid",
-	.version = {1, 9, 0},
+	.version = {1, 9, 1},
 	.module = THIS_MODULE,
 	.ctr = raid_ctr,
 	.dtr = raid_dtr,
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/md/dm-rq.c linux-libre-4.8.7-gnu/drivers/md/dm-rq.c
--- linux-libre-4.8.6-gnu/drivers/md/dm-rq.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/md/dm-rq.c	2016-11-10 10:39:23.000000000 -0500
@@ -835,8 +835,11 @@ int dm_old_init_request_queue(struct map
 	init_kthread_worker(&md->kworker);
 	md->kworker_task = kthread_run(kthread_worker_fn, &md->kworker,
 				       "kdmwork-%s", dm_device_name(md));
-	if (IS_ERR(md->kworker_task))
-		return PTR_ERR(md->kworker_task);
+	if (IS_ERR(md->kworker_task)) {
+		int error = PTR_ERR(md->kworker_task);
+		md->kworker_task = NULL;
+		return error;
+	}
 
 	elv_register_queue(md->queue);
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/md/dm-table.c linux-libre-4.8.7-gnu/drivers/md/dm-table.c
--- linux-libre-4.8.6-gnu/drivers/md/dm-table.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/md/dm-table.c	2016-11-10 10:39:23.000000000 -0500
@@ -695,37 +695,32 @@ int dm_table_add_target(struct dm_table
 
 	tgt->type = dm_get_target_type(type);
 	if (!tgt->type) {
-		DMERR("%s: %s: unknown target type", dm_device_name(t->md),
-		      type);
+		DMERR("%s: %s: unknown target type", dm_device_name(t->md), type);
 		return -EINVAL;
 	}
 
 	if (dm_target_needs_singleton(tgt->type)) {
 		if (t->num_targets) {
-			DMERR("%s: target type %s must appear alone in table",
-			      dm_device_name(t->md), type);
-			return -EINVAL;
+			tgt->error = "singleton target type must appear alone in table";
+			goto bad;
 		}
 		t->singleton = true;
 	}
 
 	if (dm_target_always_writeable(tgt->type) && !(t->mode & FMODE_WRITE)) {
-		DMERR("%s: target type %s may not be included in read-only tables",
-		      dm_device_name(t->md), type);
-		return -EINVAL;
+		tgt->error = "target type may not be included in a read-only table";
+		goto bad;
 	}
 
 	if (t->immutable_target_type) {
 		if (t->immutable_target_type != tgt->type) {
-			DMERR("%s: immutable target type %s cannot be mixed with other target types",
-			      dm_device_name(t->md), t->immutable_target_type->name);
-			return -EINVAL;
+			tgt->error = "immutable target type cannot be mixed with other target types";
+			goto bad;
 		}
 	} else if (dm_target_is_immutable(tgt->type)) {
 		if (t->num_targets) {
-			DMERR("%s: immutable target type %s cannot be mixed with other target types",
-			      dm_device_name(t->md), tgt->type->name);
-			return -EINVAL;
+			tgt->error = "immutable target type cannot be mixed with other target types";
+			goto bad;
 		}
 		t->immutable_target_type = tgt->type;
 	}
@@ -740,7 +735,6 @@ int dm_table_add_target(struct dm_table
 	 */
 	if (!adjoin(t, tgt)) {
 		tgt->error = "Gap in table";
-		r = -EINVAL;
 		goto bad;
 	}
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/md/md.c linux-libre-4.8.7-gnu/drivers/md/md.c
--- linux-libre-4.8.6-gnu/drivers/md/md.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/md/md.c	2016-11-10 10:39:23.000000000 -0500
@@ -8120,14 +8120,14 @@ void md_do_sync(struct md_thread *thread
 
 	if (!test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
 	    !test_bit(MD_RECOVERY_INTR, &mddev->recovery) &&
-	    mddev->curr_resync > 2) {
+	    mddev->curr_resync > 3) {
 		mddev->curr_resync_completed = mddev->curr_resync;
 		sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 	}
 	mddev->pers->sync_request(mddev, max_sectors, &skipped);
 
 	if (!test_bit(MD_RECOVERY_CHECK, &mddev->recovery) &&
-	    mddev->curr_resync > 2) {
+	    mddev->curr_resync > 3) {
 		if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
 			if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
 				if (mddev->curr_resync >= mddev->recovery_cp) {
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/md/raid10.c linux-libre-4.8.7-gnu/drivers/md/raid10.c
--- linux-libre-4.8.6-gnu/drivers/md/raid10.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/md/raid10.c	2016-11-10 10:39:23.000000000 -0500
@@ -447,6 +447,9 @@ static void raid10_end_write_request(str
 	struct r10conf *conf = r10_bio->mddev->private;
 	int slot, repl;
 	struct md_rdev *rdev = NULL;
+	bool discard_error;
+
+	discard_error = bio->bi_error && bio_op(bio) == REQ_OP_DISCARD;
 
 	dev = find_bio_disk(conf, r10_bio, bio, &slot, &repl);
 
@@ -460,7 +463,7 @@ static void raid10_end_write_request(str
 	/*
 	 * this branch is our 'one mirror IO has finished' event handler:
 	 */
-	if (bio->bi_error) {
+	if (bio->bi_error && !discard_error) {
 		if (repl)
 			/* Never record new bad blocks to replacement,
 			 * just fail it.
@@ -503,7 +506,7 @@ static void raid10_end_write_request(str
 		if (is_badblock(rdev,
 				r10_bio->devs[slot].addr,
 				r10_bio->sectors,
-				&first_bad, &bad_sectors)) {
+				&first_bad, &bad_sectors) && !discard_error) {
 			bio_put(bio);
 			if (repl)
 				r10_bio->devs[slot].repl_bio = IO_MADE_GOOD;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/md/raid1.c linux-libre-4.8.7-gnu/drivers/md/raid1.c
--- linux-libre-4.8.6-gnu/drivers/md/raid1.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/md/raid1.c	2016-11-10 10:39:23.000000000 -0500
@@ -407,11 +407,14 @@ static void raid1_end_write_request(stru
 	struct bio *to_put = NULL;
 	int mirror = find_bio_disk(r1_bio, bio);
 	struct md_rdev *rdev = conf->mirrors[mirror].rdev;
+	bool discard_error;
+
+	discard_error = bio->bi_error && bio_op(bio) == REQ_OP_DISCARD;
 
 	/*
 	 * 'one mirror IO has finished' event handler:
 	 */
-	if (bio->bi_error) {
+	if (bio->bi_error && !discard_error) {
 		set_bit(WriteErrorSeen,	&rdev->flags);
 		if (!test_and_set_bit(WantReplacement, &rdev->flags))
 			set_bit(MD_RECOVERY_NEEDED, &
@@ -448,7 +451,7 @@ static void raid1_end_write_request(stru
 
 		/* Maybe we can clear some bad blocks. */
 		if (is_badblock(rdev, r1_bio->sector, r1_bio->sectors,
-				&first_bad, &bad_sectors)) {
+				&first_bad, &bad_sectors) && !discard_error) {
 			r1_bio->bios[mirror] = IO_MADE_GOOD;
 			set_bit(R1BIO_MadeGood, &r1_bio->state);
 		}
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/media/platform/vsp1/vsp1_video.c linux-libre-4.8.7-gnu/drivers/media/platform/vsp1/vsp1_video.c
--- linux-libre-4.8.6-gnu/drivers/media/platform/vsp1/vsp1_video.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/media/platform/vsp1/vsp1_video.c	2016-11-10 10:39:23.000000000 -0500
@@ -675,6 +675,13 @@ static void vsp1_video_stop_streaming(st
 	unsigned long flags;
 	int ret;
 
+	/* Clear the buffers ready flag to make sure the device won't be started
+	 * by a QBUF on the video node on the other side of the pipeline.
+	 */
+	spin_lock_irqsave(&video->irqlock, flags);
+	pipe->buffers_ready &= ~(1 << video->pipe_index);
+	spin_unlock_irqrestore(&video->irqlock, flags);
+
 	mutex_lock(&pipe->lock);
 	if (--pipe->stream_count == pipe->num_inputs) {
 		/* Stop the pipeline. */
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/misc/cxl/api.c linux-libre-4.8.7-gnu/drivers/misc/cxl/api.c
--- linux-libre-4.8.6-gnu/drivers/misc/cxl/api.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/misc/cxl/api.c	2016-11-10 10:39:23.000000000 -0500
@@ -247,7 +247,9 @@ int cxl_start_context(struct cxl_context
 	cxl_ctx_get();
 
 	if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
+		put_pid(ctx->glpid);
 		put_pid(ctx->pid);
+		ctx->glpid = ctx->pid = NULL;
 		cxl_adapter_context_put(ctx->afu->adapter);
 		cxl_ctx_put();
 		goto out;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/misc/cxl/file.c linux-libre-4.8.7-gnu/drivers/misc/cxl/file.c
--- linux-libre-4.8.6-gnu/drivers/misc/cxl/file.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/misc/cxl/file.c	2016-11-10 10:39:23.000000000 -0500
@@ -194,6 +194,16 @@ static long afu_ioctl_start_work(struct
 	ctx->mmio_err_ff = !!(work.flags & CXL_START_WORK_ERR_FF);
 
 	/*
+	 * Increment the mapped context count for adapter. This also checks
+	 * if adapter_context_lock is taken.
+	 */
+	rc = cxl_adapter_context_get(ctx->afu->adapter);
+	if (rc) {
+		afu_release_irqs(ctx, ctx);
+		goto out;
+	}
+
+	/*
 	 * We grab the PID here and not in the file open to allow for the case
 	 * where a process (master, some daemon, etc) has opened the chardev on
 	 * behalf of another process, so the AFU's mm gets bound to the process
@@ -205,15 +215,6 @@ static long afu_ioctl_start_work(struct
 	ctx->pid = get_task_pid(current, PIDTYPE_PID);
 	ctx->glpid = get_task_pid(current->group_leader, PIDTYPE_PID);
 
-	/*
-	 * Increment the mapped context count for adapter. This also checks
-	 * if adapter_context_lock is taken.
-	 */
-	rc = cxl_adapter_context_get(ctx->afu->adapter);
-	if (rc) {
-		afu_release_irqs(ctx, ctx);
-		goto out;
-	}
 
 	trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
 
@@ -221,6 +222,9 @@ static long afu_ioctl_start_work(struct
 							amr))) {
 		afu_release_irqs(ctx, ctx);
 		cxl_adapter_context_put(ctx->afu->adapter);
+		put_pid(ctx->glpid);
+		put_pid(ctx->pid);
+		ctx->glpid = ctx->pid = NULL;
 		goto out;
 	}
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/misc/genwqe/card_utils.c linux-libre-4.8.7-gnu/drivers/misc/genwqe/card_utils.c
--- linux-libre-4.8.6-gnu/drivers/misc/genwqe/card_utils.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/misc/genwqe/card_utils.c	2016-11-10 10:39:23.000000000 -0500
@@ -352,17 +352,27 @@ int genwqe_alloc_sync_sgl(struct genwqe_
 		if (copy_from_user(sgl->lpage, user_addr + user_size -
 				   sgl->lpage_size, sgl->lpage_size)) {
 			rc = -EFAULT;
-			goto err_out1;
+			goto err_out2;
 		}
 	}
 	return 0;
 
+ err_out2:
+	__genwqe_free_consistent(cd, PAGE_SIZE, sgl->lpage,
+				 sgl->lpage_dma_addr);
+	sgl->lpage = NULL;
+	sgl->lpage_dma_addr = 0;
  err_out1:
 	__genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage,
 				 sgl->fpage_dma_addr);
+	sgl->fpage = NULL;
+	sgl->fpage_dma_addr = 0;
  err_out:
 	__genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl,
 				 sgl->sgl_dma_addr);
+	sgl->sgl = NULL;
+	sgl->sgl_dma_addr = 0;
+	sgl->sgl_size = 0;
 	return -ENOMEM;
 }
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/misc/mei/hw-txe.c linux-libre-4.8.7-gnu/drivers/misc/mei/hw-txe.c
--- linux-libre-4.8.6-gnu/drivers/misc/mei/hw-txe.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/misc/mei/hw-txe.c	2016-11-10 10:39:23.000000000 -0500
@@ -978,11 +978,13 @@ static bool mei_txe_check_and_ack_intrs(
 	hisr = mei_txe_br_reg_read(hw, HISR_REG);
 
 	aliveness = mei_txe_aliveness_get(dev);
-	if (hhisr & IPC_HHIER_SEC && aliveness)
+	if (hhisr & IPC_HHIER_SEC && aliveness) {
 		ipc_isr = mei_txe_sec_reg_read_silent(hw,
 				SEC_IPC_HOST_INT_STATUS_REG);
-	else
+	} else {
 		ipc_isr = 0;
+		hhisr &= ~IPC_HHIER_SEC;
+	}
 
 	generated = generated ||
 		(hisr & HISR_INT_STS_MSK) ||
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/mmc/host/dw_mmc-pltfm.c linux-libre-4.8.7-gnu/drivers/mmc/host/dw_mmc-pltfm.c
--- linux-libre-4.8.6-gnu/drivers/mmc/host/dw_mmc-pltfm.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/mmc/host/dw_mmc-pltfm.c	2016-11-10 10:39:23.000000000 -0500
@@ -46,12 +46,13 @@ int dw_mci_pltfm_register(struct platfor
 	host->pdata = pdev->dev.platform_data;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	/* Get registers' physical base address */
-	host->phy_regs = regs->start;
 	host->regs = devm_ioremap_resource(&pdev->dev, regs);
 	if (IS_ERR(host->regs))
 		return PTR_ERR(host->regs);
 
+	/* Get registers' physical base address */
+	host->phy_regs = regs->start;
+
 	platform_set_drvdata(pdev, host);
 	return dw_mci_probe(host);
 }
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/mtd/ubi/fastmap.c linux-libre-4.8.7-gnu/drivers/mtd/ubi/fastmap.c
--- linux-libre-4.8.6-gnu/drivers/mtd/ubi/fastmap.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/mtd/ubi/fastmap.c	2016-11-10 10:39:23.000000000 -0500
@@ -515,10 +515,11 @@ static int scan_pool(struct ubi_device *
 			unsigned long long ec = be64_to_cpu(ech->ec);
 			unmap_peb(ai, pnum);
 			dbg_bld("Adding PEB to free: %i", pnum);
+
 			if (err == UBI_IO_FF_BITFLIPS)
-				add_aeb(ai, free, pnum, ec, 1);
-			else
-				add_aeb(ai, free, pnum, ec, 0);
+				scrub = 1;
+
+			add_aeb(ai, free, pnum, ec, scrub);
 			continue;
 		} else if (err == 0 || err == UBI_IO_BITFLIPS) {
 			dbg_bld("Found non empty PEB:%i in pool", pnum);
@@ -750,11 +751,11 @@ static int ubi_attach_fastmap(struct ubi
 			     fmvhdr->vol_type,
 			     be32_to_cpu(fmvhdr->last_eb_bytes));
 
-		if (!av)
-			goto fail_bad;
-		if (PTR_ERR(av) == -EINVAL) {
-			ubi_err(ubi, "volume (ID %i) already exists",
-				fmvhdr->vol_id);
+		if (IS_ERR(av)) {
+			if (PTR_ERR(av) == -EEXIST)
+				ubi_err(ubi, "volume (ID %i) already exists",
+					fmvhdr->vol_id);
+
 			goto fail_bad;
 		}
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/core.h linux-libre-4.8.7-gnu/drivers/net/wireless/ath/ath10k/core.h
--- linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/core.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/net/wireless/ath/ath10k/core.h	2016-11-10 10:39:23.000000000 -0500
@@ -445,6 +445,7 @@ struct ath10k_debug {
 	u32 pktlog_filter;
 	u32 reg_addr;
 	u32 nf_cal_period;
+	void *cal_data;
 
 	struct ath10k_fw_crash_data *fw_crash_data;
 };
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/debug.c linux-libre-4.8.7-gnu/drivers/net/wireless/ath/ath10k/debug.c
--- linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/debug.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/net/wireless/ath/ath10k/debug.c	2016-11-10 10:39:23.000000000 -0500
@@ -30,6 +30,8 @@
 /* ms */
 #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
 
+#define ATH10K_DEBUG_CAL_DATA_LEN 12064
+
 #define ATH10K_FW_CRASH_DUMP_VERSION 1
 
 /**
@@ -1450,56 +1452,51 @@ static const struct file_operations fops
 	.llseek = default_llseek,
 };
 
-static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file)
+static int ath10k_debug_cal_data_fetch(struct ath10k *ar)
 {
-	struct ath10k *ar = inode->i_private;
-	void *buf;
 	u32 hi_addr;
 	__le32 addr;
 	int ret;
 
-	mutex_lock(&ar->conf_mutex);
-
-	if (ar->state != ATH10K_STATE_ON &&
-	    ar->state != ATH10K_STATE_UTF) {
-		ret = -ENETDOWN;
-		goto err;
-	}
+	lockdep_assert_held(&ar->conf_mutex);
 
-	buf = vmalloc(ar->hw_params.cal_data_len);
-	if (!buf) {
-		ret = -ENOMEM;
-		goto err;
-	}
+	if (WARN_ON(ar->hw_params.cal_data_len > ATH10K_DEBUG_CAL_DATA_LEN))
+		return -EINVAL;
 
 	hi_addr = host_interest_item_address(HI_ITEM(hi_board_data));
 
 	ret = ath10k_hif_diag_read(ar, hi_addr, &addr, sizeof(addr));
 	if (ret) {
-		ath10k_warn(ar, "failed to read hi_board_data address: %d\n", ret);
-		goto err_vfree;
+		ath10k_warn(ar, "failed to read hi_board_data address: %d\n",
+			    ret);
+		return ret;
 	}
 
-	ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), buf,
+	ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), ar->debug.cal_data,
 				   ar->hw_params.cal_data_len);
 	if (ret) {
 		ath10k_warn(ar, "failed to read calibration data: %d\n", ret);
-		goto err_vfree;
+		return ret;
 	}
 
-	file->private_data = buf;
+	return 0;
+}
 
-	mutex_unlock(&ar->conf_mutex);
+static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file)
+{
+	struct ath10k *ar = inode->i_private;
 
-	return 0;
+	mutex_lock(&ar->conf_mutex);
 
-err_vfree:
-	vfree(buf);
+	if (ar->state == ATH10K_STATE_ON ||
+	    ar->state == ATH10K_STATE_UTF) {
+		ath10k_debug_cal_data_fetch(ar);
+	}
 
-err:
+	file->private_data = ar;
 	mutex_unlock(&ar->conf_mutex);
 
-	return ret;
+	return 0;
 }
 
 static ssize_t ath10k_debug_cal_data_read(struct file *file,
@@ -1507,18 +1504,16 @@ static ssize_t ath10k_debug_cal_data_rea
 					  size_t count, loff_t *ppos)
 {
 	struct ath10k *ar = file->private_data;
-	void *buf = file->private_data;
 
-	return simple_read_from_buffer(user_buf, count, ppos,
-				       buf, ar->hw_params.cal_data_len);
-}
+	mutex_lock(&ar->conf_mutex);
 
-static int ath10k_debug_cal_data_release(struct inode *inode,
-					 struct file *file)
-{
-	vfree(file->private_data);
+	count = simple_read_from_buffer(user_buf, count, ppos,
+					ar->debug.cal_data,
+					ar->hw_params.cal_data_len);
 
-	return 0;
+	mutex_unlock(&ar->conf_mutex);
+
+	return count;
 }
 
 static ssize_t ath10k_write_ani_enable(struct file *file,
@@ -1579,7 +1574,6 @@ static const struct file_operations fops
 static const struct file_operations fops_cal_data = {
 	.open = ath10k_debug_cal_data_open,
 	.read = ath10k_debug_cal_data_read,
-	.release = ath10k_debug_cal_data_release,
 	.owner = THIS_MODULE,
 	.llseek = default_llseek,
 };
@@ -1931,6 +1925,8 @@ void ath10k_debug_stop(struct ath10k *ar
 {
 	lockdep_assert_held(&ar->conf_mutex);
 
+	ath10k_debug_cal_data_fetch(ar);
+
 	/* Must not use _sync to avoid deadlock, we do that in
 	 * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid
 	 * warning from del_timer(). */
@@ -2343,6 +2339,10 @@ int ath10k_debug_create(struct ath10k *a
 	if (!ar->debug.fw_crash_data)
 		return -ENOMEM;
 
+	ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN);
+	if (!ar->debug.cal_data)
+		return -ENOMEM;
+
 	INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
 	INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
 	INIT_LIST_HEAD(&ar->debug.fw_stats.peers);
@@ -2356,6 +2356,9 @@ void ath10k_debug_destroy(struct ath10k
 	vfree(ar->debug.fw_crash_data);
 	ar->debug.fw_crash_data = NULL;
 
+	vfree(ar->debug.cal_data);
+	ar->debug.cal_data = NULL;
+
 	ath10k_debug_fw_stats_reset(ar);
 
 	kfree(ar->debug.tpc_stats);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath9k/ar9003_calib.c linux-libre-4.8.7-gnu/drivers/net/wireless/ath/ath9k/ar9003_calib.c
--- linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath9k/ar9003_calib.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/net/wireless/ath/ath9k/ar9003_calib.c	2016-11-10 10:39:23.000000000 -0500
@@ -33,7 +33,6 @@ struct coeff {
 
 enum ar9003_cal_types {
 	IQ_MISMATCH_CAL = BIT(0),
-	TEMP_COMP_CAL = BIT(1),
 };
 
 static void ar9003_hw_setup_calibration(struct ath_hw *ah,
@@ -59,12 +58,6 @@ static void ar9003_hw_setup_calibration(
 		/* Kick-off cal */
 		REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
 		break;
-	case TEMP_COMP_CAL:
-		ath_dbg(common, CALIBRATE,
-			"starting Temperature Compensation Calibration\n");
-		REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_LOCAL);
-		REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_START);
-		break;
 	default:
 		ath_err(common, "Invalid calibration type\n");
 		break;
@@ -93,8 +86,7 @@ static bool ar9003_hw_per_calibration(st
 		/*
 		* Accumulate cal measures for active chains
 		*/
-		if (cur_caldata->calCollect)
-			cur_caldata->calCollect(ah);
+		cur_caldata->calCollect(ah);
 		ah->cal_samples++;
 
 		if (ah->cal_samples >= cur_caldata->calNumSamples) {
@@ -107,8 +99,7 @@ static bool ar9003_hw_per_calibration(st
 			/*
 			* Process accumulated data
 			*/
-			if (cur_caldata->calPostProc)
-				cur_caldata->calPostProc(ah, numChains);
+			cur_caldata->calPostProc(ah, numChains);
 
 			/* Calibration has finished. */
 			caldata->CalValid |= cur_caldata->calType;
@@ -323,16 +314,9 @@ static const struct ath9k_percal_data iq
 	ar9003_hw_iqcalibrate
 };
 
-static const struct ath9k_percal_data temp_cal_single_sample = {
-	TEMP_COMP_CAL,
-	MIN_CAL_SAMPLES,
-	PER_MAX_LOG_COUNT,
-};
-
 static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
 {
 	ah->iq_caldata.calData = &iq_cal_single_sample;
-	ah->temp_caldata.calData = &temp_cal_single_sample;
 
 	if (AR_SREV_9300_20_OR_LATER(ah)) {
 		ah->enabled_cals |= TX_IQ_CAL;
@@ -340,7 +324,7 @@ static void ar9003_hw_init_cal_settings(
 			ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
 	}
 
-	ah->supp_cals = IQ_MISMATCH_CAL | TEMP_COMP_CAL;
+	ah->supp_cals = IQ_MISMATCH_CAL;
 }
 
 #define OFF_UPPER_LT 24
@@ -1399,9 +1383,6 @@ static void ar9003_hw_init_cal_common(st
 	INIT_CAL(&ah->iq_caldata);
 	INSERT_CAL(ah, &ah->iq_caldata);
 
-	INIT_CAL(&ah->temp_caldata);
-	INSERT_CAL(ah, &ah->temp_caldata);
-
 	/* Initialize current pointer to first element in list */
 	ah->cal_list_curr = ah->cal_list;
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath9k/hw.h linux-libre-4.8.7-gnu/drivers/net/wireless/ath/ath9k/hw.h
--- linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath9k/hw.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/net/wireless/ath/ath9k/hw.h	2016-11-10 10:39:23.000000000 -0500
@@ -830,7 +830,6 @@ struct ath_hw {
 	/* Calibration */
 	u32 supp_cals;
 	struct ath9k_cal_list iq_caldata;
-	struct ath9k_cal_list temp_caldata;
 	struct ath9k_cal_list adcgain_caldata;
 	struct ath9k_cal_list adcdc_caldata;
 	struct ath9k_cal_list *cal_list;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c linux-libre-4.8.7-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
--- linux-libre-4.8.6-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c	2016-10-31 17:47:49.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c	2016-11-10 16:15:17.000000000 -0500
@@ -1498,6 +1498,10 @@ static void rtl8723b_enable_rf(struct rt
 	u32 val32;
 	u8 val8;
 
+	val32 = rtl8xxxu_read32(priv, REG_RX_WAIT_CCA);
+	val32 |= (BIT(22) | BIT(23));
+	rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, val32);
+
 	/*
 	 * No indication anywhere as to what 0x0790 does. The 2 antenna
 	 * vendor code preserves bits 6-7 here.
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c linux-libre-4.8.7-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
--- linux-libre-4.8.6-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c	2016-10-31 17:47:38.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c	2016-11-10 16:15:06.000000000 -0500
@@ -5193,7 +5193,12 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8x
 		pkt_offset = roundup(pkt_len + drvinfo_sz + desc_shift +
 				     sizeof(struct rtl8xxxu_rxdesc16), 128);
 
-		if (pkt_cnt > 1)
+		/*
+		 * Only clone the skb if there's enough data at the end to
+		 * at least cover the rx descriptor
+		 */
+		if (pkt_cnt > 1 &&
+		    urb_len > (pkt_offset + sizeof(struct rtl8xxxu_rxdesc16)))
 			next_skb = skb_clone(skb, GFP_ATOMIC);
 
 		rx_status = IEEE80211_SKB_RXCB(skb);
@@ -5211,7 +5216,7 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8x
 			rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats,
 						   rx_desc->rxmcs);
 
-		rx_status->mactime = le32_to_cpu(rx_desc->tsfl);
+		rx_status->mactime = rx_desc->tsfl;
 		rx_status->flag |= RX_FLAG_MACTIME_START;
 
 		if (!rx_desc->swdec)
@@ -5281,7 +5286,7 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8x
 		rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats,
 					   rx_desc->rxmcs);
 
-	rx_status->mactime = le32_to_cpu(rx_desc->tsfl);
+	rx_status->mactime = rx_desc->tsfl;
 	rx_status->flag |= RX_FLAG_MACTIME_START;
 
 	if (!rx_desc->swdec)
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h linux-libre-4.8.7-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
--- linux-libre-4.8.6-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h	2016-11-10 10:39:23.000000000 -0500
@@ -231,7 +231,7 @@ struct rtl8xxxu_rxdesc16 {
 	u32 pattern1match:1;
 	u32 pattern0match:1;
 #endif
-	__le32 tsfl;
+	u32 tsfl;
 #if 0
 	u32 bassn:12;
 	u32 bavld:1;
@@ -361,7 +361,7 @@ struct rtl8xxxu_rxdesc24 {
 	u32 ldcp:1;
 	u32 splcp:1;
 #endif
-	__le32 tsfl;
+	u32 tsfl;
 };
 
 struct rtl8xxxu_txdesc32 {
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/pwm/core.c linux-libre-4.8.7-gnu/drivers/pwm/core.c
--- linux-libre-4.8.6-gnu/drivers/pwm/core.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/pwm/core.c	2016-11-10 10:39:23.000000000 -0500
@@ -339,6 +339,8 @@ int pwmchip_remove(struct pwm_chip *chip
 	unsigned int i;
 	int ret = 0;
 
+	pwmchip_sysfs_unexport_children(chip);
+
 	mutex_lock(&pwm_lock);
 
 	for (i = 0; i < chip->npwm; i++) {
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/pwm/sysfs.c linux-libre-4.8.7-gnu/drivers/pwm/sysfs.c
--- linux-libre-4.8.6-gnu/drivers/pwm/sysfs.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/pwm/sysfs.c	2016-11-10 10:39:23.000000000 -0500
@@ -409,6 +409,24 @@ void pwmchip_sysfs_unexport(struct pwm_c
 	}
 }
 
+void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
+{
+	struct device *parent;
+	unsigned int i;
+
+	parent = class_find_device(&pwm_class, NULL, chip,
+				   pwmchip_sysfs_match);
+	if (!parent)
+		return;
+
+	for (i = 0; i < chip->npwm; i++) {
+		struct pwm_device *pwm = &chip->pwms[i];
+
+		if (test_bit(PWMF_EXPORTED, &pwm->flags))
+			pwm_unexport_child(parent, pwm);
+	}
+}
+
 static int __init pwm_sysfs_init(void)
 {
 	return class_register(&pwm_class);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/scsi/arcmsr/arcmsr_hba.c linux-libre-4.8.7-gnu/drivers/scsi/arcmsr/arcmsr_hba.c
--- linux-libre-4.8.6-gnu/drivers/scsi/arcmsr/arcmsr_hba.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/scsi/arcmsr/arcmsr_hba.c	2016-11-10 10:39:23.000000000 -0500
@@ -2636,18 +2636,9 @@ static int arcmsr_queue_command_lck(stru
 	struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
 	struct CommandControlBlock *ccb;
 	int target = cmd->device->id;
-	int lun = cmd->device->lun;
-	uint8_t scsicmd = cmd->cmnd[0];
 	cmd->scsi_done = done;
 	cmd->host_scribble = NULL;
 	cmd->result = 0;
-	if ((scsicmd == SYNCHRONIZE_CACHE) ||(scsicmd == SEND_DIAGNOSTIC)){
-		if(acb->devstate[target][lun] == ARECA_RAID_GONE) {
-    			cmd->result = (DID_NO_CONNECT << 16);
-		}
-		cmd->scsi_done(cmd);
-		return 0;
-	}
 	if (target == 16) {
 		/* virtual device for iop message transfer */
 		arcmsr_handle_virtual_command(acb, cmd);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/scsi/scsi_debug.c linux-libre-4.8.7-gnu/drivers/scsi/scsi_debug.c
--- linux-libre-4.8.6-gnu/drivers/scsi/scsi_debug.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/scsi/scsi_debug.c	2016-11-10 10:39:23.000000000 -0500
@@ -5134,6 +5134,7 @@ static void __exit scsi_debug_exit(void)
 	bus_unregister(&pseudo_lld_bus);
 	root_device_unregister(pseudo_primary);
 
+	vfree(map_storep);
 	vfree(dif_storep);
 	vfree(fake_storep);
 	kfree(sdebug_q_arr);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/spi/spi.c linux-libre-4.8.7-gnu/drivers/spi/spi.c
--- linux-libre-4.8.6-gnu/drivers/spi/spi.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/spi/spi.c	2016-11-10 10:39:23.000000000 -0500
@@ -1607,9 +1607,11 @@ static void of_register_spi_devices(stru
 		if (of_node_test_and_set_flag(nc, OF_POPULATED))
 			continue;
 		spi = of_register_spi_device(master, nc);
-		if (IS_ERR(spi))
+		if (IS_ERR(spi)) {
 			dev_warn(&master->dev, "Failed to create SPI device for %s\n",
 				nc->full_name);
+			of_node_clear_flag(nc, OF_POPULATED);
+		}
 	}
 }
 #else
@@ -3120,6 +3122,7 @@ static int of_spi_notify(struct notifier
 		if (IS_ERR(spi)) {
 			pr_err("%s: failed to create for '%s'\n",
 					__func__, rd->dn->full_name);
+			of_node_clear_flag(rd->dn, OF_POPULATED);
 			return notifier_from_errno(PTR_ERR(spi));
 		}
 		break;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/spi/spi-fsl-espi.c linux-libre-4.8.7-gnu/drivers/spi/spi-fsl-espi.c
--- linux-libre-4.8.6-gnu/drivers/spi/spi-fsl-espi.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/spi/spi-fsl-espi.c	2016-11-10 10:39:23.000000000 -0500
@@ -581,7 +581,7 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi
 
 		mspi->len -= rx_nr_bytes;
 
-		if (mspi->rx)
+		if (rx_nr_bytes && mspi->rx)
 			mspi->get_rx(rx_data, mspi);
 	}
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/staging/wilc1000/host_interface.c linux-libre-4.8.7-gnu/drivers/staging/wilc1000/host_interface.c
--- linux-libre-4.8.6-gnu/drivers/staging/wilc1000/host_interface.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/staging/wilc1000/host_interface.c	2016-11-10 10:39:23.000000000 -0500
@@ -3391,7 +3391,6 @@ int wilc_init(struct net_device *dev, st
 
 	clients_count++;
 
-	destroy_workqueue(hif_workqueue);
 _fail_:
 	return result;
 }
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/thermal/intel_powerclamp.c linux-libre-4.8.7-gnu/drivers/thermal/intel_powerclamp.c
--- linux-libre-4.8.6-gnu/drivers/thermal/intel_powerclamp.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/thermal/intel_powerclamp.c	2016-11-10 10:39:23.000000000 -0500
@@ -669,20 +669,10 @@ static struct thermal_cooling_device_ops
 	.set_cur_state = powerclamp_set_cur_state,
 };
 
-static const struct x86_cpu_id intel_powerclamp_ids[] __initconst = {
-	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_MWAIT },
-	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ARAT },
-	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_NONSTOP_TSC },
-	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_CONSTANT_TSC},
-	{}
-};
-MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids);
-
 static int __init powerclamp_probe(void)
 {
-	if (!x86_match_cpu(intel_powerclamp_ids)) {
-		pr_err("Intel powerclamp does not run on family %d model %d\n",
-				boot_cpu_data.x86, boot_cpu_data.x86_model);
+	if (!boot_cpu_has(X86_FEATURE_MWAIT)) {
+		pr_err("CPU does not support MWAIT");
 		return -ENODEV;
 	}
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/tty/vt/vt.c linux-libre-4.8.7-gnu/drivers/tty/vt/vt.c
--- linux-libre-4.8.6-gnu/drivers/tty/vt/vt.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/tty/vt/vt.c	2016-11-10 10:39:23.000000000 -0500
@@ -870,10 +870,15 @@ static int vc_do_resize(struct tty_struc
 	if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
 		return 0;
 
+	if (new_screen_size > (4 << 20))
+		return -EINVAL;
 	newscreen = kmalloc(new_screen_size, GFP_USER);
 	if (!newscreen)
 		return -ENOMEM;
 
+	if (vc == sel_cons)
+		clear_selection();
+
 	old_rows = vc->vc_rows;
 	old_row_size = vc->vc_size_row;
 
@@ -1176,7 +1181,7 @@ static void csi_J(struct vc_data *vc, in
 			break;
 		case 3: /* erase scroll-back buffer (and whole display) */
 			scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
-				    vc->vc_screenbuf_size >> 1);
+				    vc->vc_screenbuf_size);
 			set_origin(vc);
 			if (con_is_visible(vc))
 				update_screen(vc);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/chipidea/host.c linux-libre-4.8.7-gnu/drivers/usb/chipidea/host.c
--- linux-libre-4.8.6-gnu/drivers/usb/chipidea/host.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/chipidea/host.c	2016-11-10 10:39:23.000000000 -0500
@@ -185,6 +185,8 @@ static void host_stop(struct ci_hdrc *ci
 
 	if (hcd) {
 		usb_remove_hcd(hcd);
+		ci->role = CI_ROLE_END;
+		synchronize_irq(ci->irq);
 		usb_put_hcd(hcd);
 		if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
 			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/dwc3/gadget.c linux-libre-4.8.7-gnu/drivers/usb/dwc3/gadget.c
--- linux-libre-4.8.6-gnu/drivers/usb/dwc3/gadget.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/dwc3/gadget.c	2016-11-10 10:39:23.000000000 -0500
@@ -3055,7 +3055,7 @@ err3:
 	kfree(dwc->setup_buf);
 
 err2:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
 			dwc->ep0_trb, dwc->ep0_trb_addr);
 
 err1:
@@ -3080,7 +3080,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
 	kfree(dwc->setup_buf);
 	kfree(dwc->zlp_buf);
 
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
 			dwc->ep0_trb, dwc->ep0_trb_addr);
 
 	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/gadget/function/u_ether.c linux-libre-4.8.7-gnu/drivers/usb/gadget/function/u_ether.c
--- linux-libre-4.8.6-gnu/drivers/usb/gadget/function/u_ether.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/gadget/function/u_ether.c	2016-11-10 10:39:23.000000000 -0500
@@ -587,8 +587,9 @@ static netdev_tx_t eth_start_xmit(struct
 
 	/* throttle high/super speed IRQ rate back slightly */
 	if (gadget_is_dualspeed(dev->gadget))
-		req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH ||
-				     dev->gadget->speed == USB_SPEED_SUPER)
+		req->no_interrupt = (((dev->gadget->speed == USB_SPEED_HIGH ||
+				       dev->gadget->speed == USB_SPEED_SUPER)) &&
+					!list_empty(&dev->tx_reqs))
 			? ((atomic_read(&dev->tx_qlen) % dev->qmult) != 0)
 			: 0;
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/gadget/udc/atmel_usba_udc.c linux-libre-4.8.7-gnu/drivers/usb/gadget/udc/atmel_usba_udc.c
--- linux-libre-4.8.6-gnu/drivers/usb/gadget/udc/atmel_usba_udc.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/gadget/udc/atmel_usba_udc.c	2016-11-10 10:39:23.000000000 -0500
@@ -1978,7 +1978,7 @@ static struct usba_ep * atmel_udc_of_ini
 			dev_err(&pdev->dev, "of_probe: name error(%d)\n", ret);
 			goto err;
 		}
-		ep->ep.name = name;
+		ep->ep.name = kasprintf(GFP_KERNEL, "ep%d", ep->index);
 
 		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
 		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/host/ohci-hcd.c linux-libre-4.8.7-gnu/drivers/usb/host/ohci-hcd.c
--- linux-libre-4.8.6-gnu/drivers/usb/host/ohci-hcd.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/host/ohci-hcd.c	2016-11-10 10:39:23.000000000 -0500
@@ -72,7 +72,7 @@
 static const char	hcd_name [] = "ohci_hcd";
 
 #define	STATECHANGE_DELAY	msecs_to_jiffies(300)
-#define	IO_WATCHDOG_DELAY	msecs_to_jiffies(250)
+#define	IO_WATCHDOG_DELAY	msecs_to_jiffies(275)
 
 #include "ohci.h"
 #include "pci-quirks.h"
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/host/xhci.h linux-libre-4.8.7-gnu/drivers/usb/host/xhci.h
--- linux-libre-4.8.6-gnu/drivers/usb/host/xhci.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/host/xhci.h	2016-11-10 10:39:23.000000000 -0500
@@ -314,6 +314,8 @@ struct xhci_op_regs {
 #define XDEV_U2		(0x2 << 5)
 #define XDEV_U3		(0x3 << 5)
 #define XDEV_INACTIVE	(0x6 << 5)
+#define XDEV_POLLING	(0x7 << 5)
+#define XDEV_COMP_MODE  (0xa << 5)
 #define XDEV_RESUME	(0xf << 5)
 /* true: port has power (see HCC_PPC) */
 #define PORT_POWER	(1 << 9)
@@ -1653,6 +1655,7 @@ struct xhci_hcd {
 #define XHCI_MTK_HOST		(1 << 21)
 #define XHCI_SSIC_PORT_UNUSED	(1 << 22)
 #define XHCI_NO_64BIT_SUPPORT	(1 << 23)
+#define XHCI_MISSING_CAS	(1 << 24)
 	unsigned int		num_active_eps;
 	unsigned int		limit_active_eps;
 	/* There are two roothubs to keep track of bus suspend info for */
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/host/xhci-hub.c linux-libre-4.8.7-gnu/drivers/usb/host/xhci-hub.c
--- linux-libre-4.8.6-gnu/drivers/usb/host/xhci-hub.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/host/xhci-hub.c	2016-11-10 10:39:23.000000000 -0500
@@ -1166,7 +1166,7 @@ int xhci_hub_control(struct usb_hcd *hcd
 				xhci_set_link_state(xhci, port_array, wIndex,
 							XDEV_RESUME);
 				spin_unlock_irqrestore(&xhci->lock, flags);
-				msleep(20);
+				msleep(USB_RESUME_TIMEOUT);
 				spin_lock_irqsave(&xhci->lock, flags);
 				xhci_set_link_state(xhci, port_array, wIndex,
 							XDEV_U0);
@@ -1355,6 +1355,35 @@ int xhci_bus_suspend(struct usb_hcd *hcd
 	return 0;
 }
 
+/*
+ * Workaround for missing Cold Attach Status (CAS) if device re-plugged in S3.
+ * warm reset a USB3 device stuck in polling or compliance mode after resume.
+ * See Intel 100/c230 series PCH specification update Doc #332692-006 Errata #8
+ */
+static bool xhci_port_missing_cas_quirk(int port_index,
+					     __le32 __iomem **port_array)
+{
+	u32 portsc;
+
+	portsc = readl(port_array[port_index]);
+
+	/* if any of these are set we are not stuck */
+	if (portsc & (PORT_CONNECT | PORT_CAS))
+		return false;
+
+	if (((portsc & PORT_PLS_MASK) != XDEV_POLLING) &&
+	    ((portsc & PORT_PLS_MASK) != XDEV_COMP_MODE))
+		return false;
+
+	/* clear wakeup/change bits, and do a warm port reset */
+	portsc &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
+	portsc |= PORT_WR;
+	writel(portsc, port_array[port_index]);
+	/* flush write */
+	readl(port_array[port_index]);
+	return true;
+}
+
 int xhci_bus_resume(struct usb_hcd *hcd)
 {
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
@@ -1392,6 +1421,14 @@ int xhci_bus_resume(struct usb_hcd *hcd)
 		u32 temp;
 
 		temp = readl(port_array[port_index]);
+
+		/* warm reset CAS limited ports stuck in polling/compliance */
+		if ((xhci->quirks & XHCI_MISSING_CAS) &&
+		    (hcd->speed >= HCD_USB3) &&
+		    xhci_port_missing_cas_quirk(port_index, port_array)) {
+			xhci_dbg(xhci, "reset stuck port %d\n", port_index);
+			continue;
+		}
 		if (DEV_SUPERSPEED_ANY(temp))
 			temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
 		else
@@ -1410,7 +1447,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
 
 	if (need_usb2_u3_exit) {
 		spin_unlock_irqrestore(&xhci->lock, flags);
-		msleep(20);
+		msleep(USB_RESUME_TIMEOUT);
 		spin_lock_irqsave(&xhci->lock, flags);
 	}
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/host/xhci-pci.c linux-libre-4.8.7-gnu/drivers/usb/host/xhci-pci.c
--- linux-libre-4.8.6-gnu/drivers/usb/host/xhci-pci.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/host/xhci-pci.c	2016-11-10 10:39:23.000000000 -0500
@@ -45,11 +45,13 @@
 
 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI	0x8c31
 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI	0x9c31
+#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI	0x9cb1
 #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI		0x22b5
 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI		0xa12f
 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI	0x9d2f
 #define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI		0x0aa8
 #define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI		0x1aa8
+#define PCI_DEVICE_ID_INTEL_APL_XHCI			0x5aa8
 
 static const char hcd_name[] = "xhci_hcd";
 
@@ -153,7 +155,8 @@ static void xhci_pci_quirks(struct devic
 		xhci->quirks |= XHCI_SPURIOUS_REBOOT;
 	}
 	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
-		pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
+		(pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI ||
+		 pdev->device == PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI)) {
 		xhci->quirks |= XHCI_SPURIOUS_REBOOT;
 		xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
 	}
@@ -169,6 +172,11 @@ static void xhci_pci_quirks(struct devic
 		 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) {
 		xhci->quirks |= XHCI_SSIC_PORT_UNUSED;
 	}
+	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+	    (pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
+	     pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI))
+		xhci->quirks |= XHCI_MISSING_CAS;
+
 	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
 			pdev->device == PCI_DEVICE_ID_EJ168) {
 		xhci->quirks |= XHCI_RESET_ON_RESUME;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/musb/omap2430.c linux-libre-4.8.7-gnu/drivers/usb/musb/omap2430.c
--- linux-libre-4.8.6-gnu/drivers/usb/musb/omap2430.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/musb/omap2430.c	2016-11-10 10:39:23.000000000 -0500
@@ -337,6 +337,7 @@ static int omap2430_musb_init(struct mus
 	}
 	musb->isr = omap2430_musb_interrupt;
 	phy_init(musb->phy);
+	phy_power_on(musb->phy);
 
 	l = musb_readl(musb->mregs, OTG_INTERFSEL);
 
@@ -373,8 +374,6 @@ static void omap2430_musb_enable(struct
 	struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev);
 	struct omap_musb_board_data *data = pdata->board_data;
 
-	if (!WARN_ON(!musb->phy))
-		phy_power_on(musb->phy);
 
 	omap2430_set_power(musb, true, glue->cable_connected);
 
@@ -413,9 +412,6 @@ static void omap2430_musb_disable(struct
 	struct device *dev = musb->controller;
 	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
 
-	if (!WARN_ON(!musb->phy))
-		phy_power_off(musb->phy);
-
 	if (glue->status != MUSB_UNKNOWN)
 		omap_control_usb_set_mode(glue->control_otghs,
 			USB_MODE_DISCONNECT);
@@ -429,6 +425,7 @@ static int omap2430_musb_exit(struct mus
 	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
 
 	omap2430_low_level_exit(musb);
+	phy_power_off(musb->phy);
 	phy_exit(musb->phy);
 	musb->phy = NULL;
 	cancel_work_sync(&glue->omap_musb_mailbox_work);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/renesas_usbhs/rcar3.c linux-libre-4.8.7-gnu/drivers/usb/renesas_usbhs/rcar3.c
--- linux-libre-4.8.6-gnu/drivers/usb/renesas_usbhs/rcar3.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/renesas_usbhs/rcar3.c	2016-11-10 10:39:23.000000000 -0500
@@ -9,6 +9,7 @@
  *
  */
 
+#include <linux/delay.h>
 #include <linux/io.h>
 #include "common.h"
 #include "rcar3.h"
@@ -35,10 +36,13 @@ static int usbhs_rcar3_power_ctrl(struct
 
 	usbhs_write32(priv, UGCTRL2, UGCTRL2_RESERVED_3 | UGCTRL2_USB0SEL_OTG);
 
-	if (enable)
+	if (enable) {
 		usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM);
-	else
+		/* The controller on R-Car Gen3 needs to wait up to 45 usec */
+		udelay(45);
+	} else {
 		usbhs_bset(priv, LPSTS, LPSTS_SUSPM, 0);
+	}
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/serial/cp210x.c linux-libre-4.8.7-gnu/drivers/usb/serial/cp210x.c
--- linux-libre-4.8.6-gnu/drivers/usb/serial/cp210x.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/serial/cp210x.c	2016-11-10 10:39:23.000000000 -0500
@@ -1077,7 +1077,9 @@ static int cp210x_tiocmget(struct tty_st
 	u8 control;
 	int result;
 
-	cp210x_read_u8_reg(port, CP210X_GET_MDMSTS, &control);
+	result = cp210x_read_u8_reg(port, CP210X_GET_MDMSTS, &control);
+	if (result)
+		return result;
 
 	result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0)
 		|((control & CONTROL_RTS) ? TIOCM_RTS : 0)
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/serial/ftdi_sio.c linux-libre-4.8.7-gnu/drivers/usb/serial/ftdi_sio.c
--- linux-libre-4.8.6-gnu/drivers/usb/serial/ftdi_sio.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/serial/ftdi_sio.c	2016-11-10 10:39:23.000000000 -0500
@@ -986,7 +986,8 @@ static const struct usb_device_id id_tab
 	/* ekey Devices */
 	{ USB_DEVICE(FTDI_VID, FTDI_EKEY_CONV_USB_PID) },
 	/* Infineon Devices */
-	{ USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) },
+	{ USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_TC1798_PID, 1) },
+	{ USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_TC2X7_PID, 1) },
 	/* GE Healthcare devices */
 	{ USB_DEVICE(GE_HEALTHCARE_VID, GE_HEALTHCARE_NEMO_TRACKER_PID) },
 	/* Active Research (Actisense) devices */
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/serial/ftdi_sio_ids.h linux-libre-4.8.7-gnu/drivers/usb/serial/ftdi_sio_ids.h
--- linux-libre-4.8.6-gnu/drivers/usb/serial/ftdi_sio_ids.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/serial/ftdi_sio_ids.h	2016-11-10 10:39:23.000000000 -0500
@@ -626,8 +626,9 @@
 /*
  * Infineon Technologies
  */
-#define INFINEON_VID		0x058b
-#define INFINEON_TRIBOARD_PID	0x0028 /* DAS JTAG TriBoard TC1798 V1.0 */
+#define INFINEON_VID		        0x058b
+#define INFINEON_TRIBOARD_TC1798_PID	0x0028 /* DAS JTAG TriBoard TC1798 V1.0 */
+#define INFINEON_TRIBOARD_TC2X7_PID	0x0043 /* DAS JTAG TriBoard TC2X7 V1.0 */
 
 /*
  * Acton Research Corp.
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/usb/serial/usb-serial.c linux-libre-4.8.7-gnu/drivers/usb/serial/usb-serial.c
--- linux-libre-4.8.6-gnu/drivers/usb/serial/usb-serial.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/usb/serial/usb-serial.c	2016-11-10 10:39:23.000000000 -0500
@@ -1078,7 +1078,8 @@ static int usb_serial_probe(struct usb_i
 
 	serial->disconnected = 0;
 
-	usb_serial_console_init(serial->port[0]->minor);
+	if (num_ports > 0)
+		usb_serial_console_init(serial->port[0]->minor);
 exit:
 	module_put(type->driver.owner);
 	return 0;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/video/fbdev/omap2/omapfb/dss/dsi.c linux-libre-4.8.7-gnu/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
--- linux-libre-4.8.6-gnu/drivers/video/fbdev/omap2/omapfb/dss/dsi.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/video/fbdev/omap2/omapfb/dss/dsi.c	2016-11-10 10:39:23.000000000 -0500
@@ -5348,7 +5348,7 @@ static int dsi_bind(struct device *dev,
 
 	dsi->phy_base = devm_ioremap(&dsidev->dev, res->start,
 		resource_size(res));
-	if (!dsi->proto_base) {
+	if (!dsi->phy_base) {
 		DSSERR("can't ioremap DSI PHY\n");
 		return -ENOMEM;
 	}
@@ -5368,7 +5368,7 @@ static int dsi_bind(struct device *dev,
 
 	dsi->pll_base = devm_ioremap(&dsidev->dev, res->start,
 		resource_size(res));
-	if (!dsi->proto_base) {
+	if (!dsi->pll_base) {
 		DSSERR("can't ioremap DSI PLL\n");
 		return -ENOMEM;
 	}
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/video/fbdev/pxafb.c linux-libre-4.8.7-gnu/drivers/video/fbdev/pxafb.c
--- linux-libre-4.8.6-gnu/drivers/video/fbdev/pxafb.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/video/fbdev/pxafb.c	2016-11-10 10:39:23.000000000 -0500
@@ -2125,7 +2125,7 @@ static int of_get_pxafb_display(struct d
 
 	timings = of_get_display_timings(disp);
 	if (!timings)
-		goto out;
+		return -EINVAL;
 
 	ret = -ENOMEM;
 	info->modes = kmalloc_array(timings->num_timings,
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/virtio/virtio_pci_legacy.c linux-libre-4.8.7-gnu/drivers/virtio/virtio_pci_legacy.c
--- linux-libre-4.8.6-gnu/drivers/virtio/virtio_pci_legacy.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/virtio/virtio_pci_legacy.c	2016-11-10 10:39:23.000000000 -0500
@@ -212,10 +212,18 @@ int virtio_pci_legacy_probe(struct virti
 		return -ENODEV;
 	}
 
-	rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(64));
-	if (rc)
-		rc = dma_set_mask_and_coherent(&pci_dev->dev,
-						DMA_BIT_MASK(32));
+	rc = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(64));
+	if (rc) {
+		rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
+	} else {
+		/*
+		 * The virtio ring base address is expressed as a 32-bit PFN,
+		 * with a page size of 1 << VIRTIO_PCI_QUEUE_ADDR_SHIFT.
+		 */
+		dma_set_coherent_mask(&pci_dev->dev,
+				DMA_BIT_MASK(32 + VIRTIO_PCI_QUEUE_ADDR_SHIFT));
+	}
+
 	if (rc)
 		dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA.  Trying to continue, but this might not work.\n");
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/drivers/virtio/virtio_ring.c linux-libre-4.8.7-gnu/drivers/virtio/virtio_ring.c
--- linux-libre-4.8.6-gnu/drivers/virtio/virtio_ring.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/drivers/virtio/virtio_ring.c	2016-11-10 10:39:23.000000000 -0500
@@ -732,7 +732,8 @@ void virtqueue_disable_cb(struct virtque
 
 	if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) {
 		vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
-		vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+		if (!vq->event)
+			vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
 	}
 
 }
@@ -764,7 +765,8 @@ unsigned virtqueue_enable_cb_prepare(str
 	 * entry. Always do both to keep code simple. */
 	if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
 		vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
-		vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+		if (!vq->event)
+			vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
 	}
 	vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, last_used_idx = vq->last_used_idx);
 	END_USE(vq);
@@ -832,10 +834,11 @@ bool virtqueue_enable_cb_delayed(struct
 	 * more to do. */
 	/* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to
 	 * either clear the flags bit or point the event index at the next
-	 * entry. Always do both to keep code simple. */
+	 * entry. Always update the event index to keep code simple. */
 	if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
 		vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
-		vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+		if (!vq->event)
+			vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
 	}
 	/* TODO: tune this threshold */
 	bufs = (u16)(vq->avail_idx_shadow - vq->last_used_idx) * 3 / 4;
@@ -953,7 +956,8 @@ struct virtqueue *__vring_new_virtqueue(
 	/* No callback?  Tell other side not to bother us. */
 	if (!callback) {
 		vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
-		vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow);
+		if (!vq->event)
+			vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow);
 	}
 
 	/* Put everything in free lists. */
diff -druNp --no-dereference linux-libre-4.8.6-gnu/fs/btrfs/inode.c linux-libre-4.8.7-gnu/fs/btrfs/inode.c
--- linux-libre-4.8.6-gnu/fs/btrfs/inode.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/fs/btrfs/inode.c	2016-11-10 10:39:23.000000000 -0500
@@ -8915,9 +8915,14 @@ again:
 	 *    So even we call qgroup_free_data(), it won't decrease reserved
 	 *    space.
 	 * 2) Not written to disk
-	 *    This means the reserved space should be freed here.
+	 *    This means the reserved space should be freed here. However,
+	 *    if a truncate invalidates the page (by clearing PageDirty)
+	 *    and the page is accounted for while allocating extent
+	 *    in btrfs_check_data_free_space() we let delayed_ref to
+	 *    free the entire extent.
 	 */
-	btrfs_qgroup_free_data(inode, page_start, PAGE_SIZE);
+	if (PageDirty(page))
+		btrfs_qgroup_free_data(inode, page_start, PAGE_SIZE);
 	if (!inode_evicting) {
 		clear_extent_bit(tree, page_start, page_end,
 				 EXTENT_LOCKED | EXTENT_DIRTY |
diff -druNp --no-dereference linux-libre-4.8.6-gnu/fs/btrfs/tree-log.c linux-libre-4.8.7-gnu/fs/btrfs/tree-log.c
--- linux-libre-4.8.6-gnu/fs/btrfs/tree-log.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/fs/btrfs/tree-log.c	2016-11-10 10:39:23.000000000 -0500
@@ -2713,14 +2713,12 @@ static inline void btrfs_remove_all_log_
 					     int index, int error)
 {
 	struct btrfs_log_ctx *ctx;
+	struct btrfs_log_ctx *safe;
 
-	if (!error) {
-		INIT_LIST_HEAD(&root->log_ctxs[index]);
-		return;
-	}
-
-	list_for_each_entry(ctx, &root->log_ctxs[index], list)
+	list_for_each_entry_safe(ctx, safe, &root->log_ctxs[index], list) {
+		list_del_init(&ctx->list);
 		ctx->log_ret = error;
+	}
 
 	INIT_LIST_HEAD(&root->log_ctxs[index]);
 }
@@ -2961,13 +2959,9 @@ int btrfs_sync_log(struct btrfs_trans_ha
 	mutex_unlock(&root->log_mutex);
 
 out_wake_log_root:
-	/*
-	 * We needn't get log_mutex here because we are sure all
-	 * the other tasks are blocked.
-	 */
+	mutex_lock(&log_root_tree->log_mutex);
 	btrfs_remove_all_log_ctxs(log_root_tree, index2, ret);
 
-	mutex_lock(&log_root_tree->log_mutex);
 	log_root_tree->log_transid_committed++;
 	atomic_set(&log_root_tree->log_commit[index2], 0);
 	mutex_unlock(&log_root_tree->log_mutex);
@@ -2978,10 +2972,8 @@ out_wake_log_root:
 	if (waitqueue_active(&log_root_tree->log_commit_wait[index2]))
 		wake_up(&log_root_tree->log_commit_wait[index2]);
 out:
-	/* See above. */
-	btrfs_remove_all_log_ctxs(root, index1, ret);
-
 	mutex_lock(&root->log_mutex);
+	btrfs_remove_all_log_ctxs(root, index1, ret);
 	root->log_transid_committed++;
 	atomic_set(&root->log_commit[index1], 0);
 	mutex_unlock(&root->log_mutex);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/fs/nfsd/nfs4state.c linux-libre-4.8.7-gnu/fs/nfsd/nfs4state.c
--- linux-libre-4.8.6-gnu/fs/nfsd/nfs4state.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/fs/nfsd/nfs4state.c	2016-11-10 10:39:23.000000000 -0500
@@ -1147,9 +1147,7 @@ static void put_ol_stateid_locked(struct
 
 static bool unhash_lock_stateid(struct nfs4_ol_stateid *stp)
 {
-	struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);
-
-	lockdep_assert_held(&oo->oo_owner.so_client->cl_lock);
+	lockdep_assert_held(&stp->st_stid.sc_client->cl_lock);
 
 	list_del_init(&stp->st_locks);
 	nfs4_unhash_stid(&stp->st_stid);
@@ -1158,12 +1156,12 @@ static bool unhash_lock_stateid(struct n
 
 static void release_lock_stateid(struct nfs4_ol_stateid *stp)
 {
-	struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);
+	struct nfs4_client *clp = stp->st_stid.sc_client;
 	bool unhashed;
 
-	spin_lock(&oo->oo_owner.so_client->cl_lock);
+	spin_lock(&clp->cl_lock);
 	unhashed = unhash_lock_stateid(stp);
-	spin_unlock(&oo->oo_owner.so_client->cl_lock);
+	spin_unlock(&clp->cl_lock);
 	if (unhashed)
 		nfs4_put_stid(&stp->st_stid);
 }
diff -druNp --no-dereference linux-libre-4.8.6-gnu/fs/overlayfs/copy_up.c linux-libre-4.8.7-gnu/fs/overlayfs/copy_up.c
--- linux-libre-4.8.6-gnu/fs/overlayfs/copy_up.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/fs/overlayfs/copy_up.c	2016-11-10 10:39:23.000000000 -0500
@@ -171,6 +171,8 @@ static int ovl_copy_up_data(struct path
 		len -= bytes;
 	}
 
+	if (!error)
+		error = vfs_fsync(new_file, 0);
 	fput(new_file);
 out_fput:
 	fput(old_file);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/fs/overlayfs/inode.c linux-libre-4.8.7-gnu/fs/overlayfs/inode.c
--- linux-libre-4.8.6-gnu/fs/overlayfs/inode.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/fs/overlayfs/inode.c	2016-11-10 10:39:23.000000000 -0500
@@ -294,9 +294,6 @@ struct posix_acl *ovl_get_acl(struct ino
 	if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !IS_POSIXACL(realinode))
 		return NULL;
 
-	if (!realinode->i_op->get_acl)
-		return NULL;
-
 	old_cred = ovl_override_creds(inode->i_sb);
 	acl = get_acl(realinode, type);
 	revert_creds(old_cred);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/fs/overlayfs/super.c linux-libre-4.8.7-gnu/fs/overlayfs/super.c
--- linux-libre-4.8.6-gnu/fs/overlayfs/super.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/fs/overlayfs/super.c	2016-11-10 10:39:23.000000000 -0500
@@ -1026,6 +1026,21 @@ ovl_posix_acl_xattr_set(const struct xat
 
 	posix_acl_release(acl);
 
+	/*
+	 * Check if sgid bit needs to be cleared (actual setacl operation will
+	 * be done with mounter's capabilities and so that won't do it for us).
+	 */
+	if (unlikely(inode->i_mode & S_ISGID) &&
+	    handler->flags == ACL_TYPE_ACCESS &&
+	    !in_group_p(inode->i_gid) &&
+	    !capable_wrt_inode_uidgid(inode, CAP_FSETID)) {
+		struct iattr iattr = { .ia_valid = ATTR_KILL_SGID };
+
+		err = ovl_setattr(dentry, &iattr);
+		if (err)
+			return err;
+	}
+
 	err = ovl_xattr_set(dentry, handler->name, value, size, flags);
 	if (!err)
 		ovl_copyattr(ovl_inode_real(inode, NULL), inode);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/fs/ubifs/dir.c linux-libre-4.8.7-gnu/fs/ubifs/dir.c
--- linux-libre-4.8.6-gnu/fs/ubifs/dir.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/fs/ubifs/dir.c	2016-11-10 10:39:23.000000000 -0500
@@ -350,7 +350,7 @@ static unsigned int vfs_dent_type(uint8_
  */
 static int ubifs_readdir(struct file *file, struct dir_context *ctx)
 {
-	int err;
+	int err = 0;
 	struct qstr nm;
 	union ubifs_key key;
 	struct ubifs_dent_node *dent;
@@ -452,14 +452,20 @@ out:
 	kfree(file->private_data);
 	file->private_data = NULL;
 
-	if (err != -ENOENT) {
+	if (err != -ENOENT)
 		ubifs_err(c, "cannot find next direntry, error %d", err);
-		return err;
-	}
+	else
+		/*
+		 * -ENOENT is a non-fatal error in this context, the TNC uses
+		 * it to indicate that the cursor moved past the current directory
+		 * and readdir() has to stop.
+		 */
+		err = 0;
+
 
 	/* 2 is a special value indicating that there are no more direntries */
 	ctx->pos = 2;
-	return 0;
+	return err;
 }
 
 /* Free saved readdir() state when the directory is closed */
diff -druNp --no-dereference linux-libre-4.8.6-gnu/fs/xfs/libxfs/xfs_dquot_buf.c linux-libre-4.8.7-gnu/fs/xfs/libxfs/xfs_dquot_buf.c
--- linux-libre-4.8.6-gnu/fs/xfs/libxfs/xfs_dquot_buf.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/fs/xfs/libxfs/xfs_dquot_buf.c	2016-11-10 10:39:23.000000000 -0500
@@ -191,8 +191,7 @@ xfs_dquot_buf_verify_crc(
 	if (mp->m_quotainfo)
 		ndquots = mp->m_quotainfo->qi_dqperchunk;
 	else
-		ndquots = xfs_calc_dquots_per_chunk(
-					XFS_BB_TO_FSB(mp, bp->b_length));
+		ndquots = xfs_calc_dquots_per_chunk(bp->b_length);
 
 	for (i = 0; i < ndquots; i++, d++) {
 		if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),
diff -druNp --no-dereference linux-libre-4.8.6-gnu/include/linux/pwm.h linux-libre-4.8.7-gnu/include/linux/pwm.h
--- linux-libre-4.8.6-gnu/include/linux/pwm.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/include/linux/pwm.h	2016-11-10 10:39:23.000000000 -0500
@@ -641,6 +641,7 @@ static inline void pwm_remove_table(stru
 #ifdef CONFIG_PWM_SYSFS
 void pwmchip_sysfs_export(struct pwm_chip *chip);
 void pwmchip_sysfs_unexport(struct pwm_chip *chip);
+void pwmchip_sysfs_unexport_children(struct pwm_chip *chip);
 #else
 static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
 {
@@ -649,6 +650,10 @@ static inline void pwmchip_sysfs_export(
 static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip)
 {
 }
+
+static inline void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
+{
+}
 #endif /* CONFIG_PWM_SYSFS */
 
 #endif /* __LINUX_PWM_H */
diff -druNp --no-dereference linux-libre-4.8.6-gnu/include/uapi/linux/Kbuild linux-libre-4.8.7-gnu/include/uapi/linux/Kbuild
--- linux-libre-4.8.6-gnu/include/uapi/linux/Kbuild	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/include/uapi/linux/Kbuild	2016-11-10 10:39:23.000000000 -0500
@@ -396,6 +396,7 @@ header-y += string.h
 header-y += suspend_ioctls.h
 header-y += swab.h
 header-y += synclink.h
+header-y += sync_file.h
 header-y += sysctl.h
 header-y += sysinfo.h
 header-y += target_core_user.h
diff -druNp --no-dereference linux-libre-4.8.6-gnu/kernel/time/timer.c linux-libre-4.8.7-gnu/kernel/time/timer.c
--- linux-libre-4.8.6-gnu/kernel/time/timer.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/kernel/time/timer.c	2016-11-10 10:39:23.000000000 -0500
@@ -878,7 +878,7 @@ static inline struct timer_base *get_tim
 
 #ifdef CONFIG_NO_HZ_COMMON
 static inline struct timer_base *
-__get_target_base(struct timer_base *base, unsigned tflags)
+get_target_base(struct timer_base *base, unsigned tflags)
 {
 #ifdef CONFIG_SMP
 	if ((tflags & TIMER_PINNED) || !base->migration_enabled)
@@ -891,25 +891,27 @@ __get_target_base(struct timer_base *bas
 
 static inline void forward_timer_base(struct timer_base *base)
 {
+	unsigned long jnow = READ_ONCE(jiffies);
+
 	/*
 	 * We only forward the base when it's idle and we have a delta between
 	 * base clock and jiffies.
 	 */
-	if (!base->is_idle || (long) (jiffies - base->clk) < 2)
+	if (!base->is_idle || (long) (jnow - base->clk) < 2)
 		return;
 
 	/*
 	 * If the next expiry value is > jiffies, then we fast forward to
 	 * jiffies otherwise we forward to the next expiry value.
 	 */
-	if (time_after(base->next_expiry, jiffies))
-		base->clk = jiffies;
+	if (time_after(base->next_expiry, jnow))
+		base->clk = jnow;
 	else
 		base->clk = base->next_expiry;
 }
 #else
 static inline struct timer_base *
-__get_target_base(struct timer_base *base, unsigned tflags)
+get_target_base(struct timer_base *base, unsigned tflags)
 {
 	return get_timer_this_cpu_base(tflags);
 }
@@ -917,14 +919,6 @@ __get_target_base(struct timer_base *bas
 static inline void forward_timer_base(struct timer_base *base) { }
 #endif
 
-static inline struct timer_base *
-get_target_base(struct timer_base *base, unsigned tflags)
-{
-	struct timer_base *target = __get_target_base(base, tflags);
-
-	forward_timer_base(target);
-	return target;
-}
 
 /*
  * We are using hashed locking: Holding per_cpu(timer_bases[x]).lock means
@@ -943,7 +937,14 @@ static struct timer_base *lock_timer_bas
 {
 	for (;;) {
 		struct timer_base *base;
-		u32 tf = timer->flags;
+		u32 tf;
+
+		/*
+		 * We need to use READ_ONCE() here, otherwise the compiler
+		 * might re-read @tf between the check for TIMER_MIGRATING
+		 * and spin_lock().
+		 */
+		tf = READ_ONCE(timer->flags);
 
 		if (!(tf & TIMER_MIGRATING)) {
 			base = get_timer_base(tf);
@@ -964,6 +965,8 @@ __mod_timer(struct timer_list *timer, un
 	unsigned long clk = 0, flags;
 	int ret = 0;
 
+	BUG_ON(!timer->function);
+
 	/*
 	 * This is a common optimization triggered by the networking code - if
 	 * the timer is re-modified to have the same timeout or ends up in the
@@ -972,13 +975,16 @@ __mod_timer(struct timer_list *timer, un
 	if (timer_pending(timer)) {
 		if (timer->expires == expires)
 			return 1;
+
 		/*
-		 * Take the current timer_jiffies of base, but without holding
-		 * the lock!
+		 * We lock timer base and calculate the bucket index right
+		 * here. If the timer ends up in the same bucket, then we
+		 * just update the expiry time and avoid the whole
+		 * dequeue/enqueue dance.
 		 */
-		base = get_timer_base(timer->flags);
-		clk = base->clk;
+		base = lock_timer_base(timer, &flags);
 
+		clk = base->clk;
 		idx = calc_wheel_index(expires, clk);
 
 		/*
@@ -988,14 +994,14 @@ __mod_timer(struct timer_list *timer, un
 		 */
 		if (idx == timer_get_idx(timer)) {
 			timer->expires = expires;
-			return 1;
+			ret = 1;
+			goto out_unlock;
 		}
+	} else {
+		base = lock_timer_base(timer, &flags);
 	}
 
 	timer_stats_timer_set_start_info(timer);
-	BUG_ON(!timer->function);
-
-	base = lock_timer_base(timer, &flags);
 
 	ret = detach_if_pending(timer, base, false);
 	if (!ret && pending_only)
@@ -1025,12 +1031,16 @@ __mod_timer(struct timer_list *timer, un
 		}
 	}
 
+	/* Try to forward a stale timer base clock */
+	forward_timer_base(base);
+
 	timer->expires = expires;
 	/*
 	 * If 'idx' was calculated above and the base time did not advance
-	 * between calculating 'idx' and taking the lock, only enqueue_timer()
-	 * and trigger_dyntick_cpu() is required. Otherwise we need to
-	 * (re)calculate the wheel index via internal_add_timer().
+	 * between calculating 'idx' and possibly switching the base, only
+	 * enqueue_timer() and trigger_dyntick_cpu() is required. Otherwise
+	 * we need to (re)calculate the wheel index via
+	 * internal_add_timer().
 	 */
 	if (idx != UINT_MAX && clk == base->clk) {
 		enqueue_timer(base, timer, idx);
@@ -1510,12 +1520,16 @@ u64 get_next_timer_interrupt(unsigned lo
 	is_max_delta = (nextevt == base->clk + NEXT_TIMER_MAX_DELTA);
 	base->next_expiry = nextevt;
 	/*
-	 * We have a fresh next event. Check whether we can forward the base:
+	 * We have a fresh next event. Check whether we can forward the
+	 * base. We can only do that when @basej is past base->clk
+	 * otherwise we might rewind base->clk.
 	 */
-	if (time_after(nextevt, jiffies))
-		base->clk = jiffies;
-	else if (time_after(nextevt, base->clk))
-		base->clk = nextevt;
+	if (time_after(basej, base->clk)) {
+		if (time_after(nextevt, basej))
+			base->clk = basej;
+		else if (time_after(nextevt, base->clk))
+			base->clk = nextevt;
+	}
 
 	if (time_before_eq(nextevt, basej)) {
 		expires = basem;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/Makefile linux-libre-4.8.7-gnu/Makefile
--- linux-libre-4.8.6-gnu/Makefile	2016-10-31 17:30:35.000000000 -0400
+++ linux-libre-4.8.7-gnu/Makefile	2016-11-10 15:59:46.000000000 -0500
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 8
-SUBLEVEL = 6
+SUBLEVEL = 7
 EXTRAVERSION = -gnu
 NAME = Psychotic Stoned Sheep
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/mm/list_lru.c linux-libre-4.8.7-gnu/mm/list_lru.c
--- linux-libre-4.8.6-gnu/mm/list_lru.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/mm/list_lru.c	2016-11-10 10:39:23.000000000 -0500
@@ -554,6 +554,8 @@ int __list_lru_init(struct list_lru *lru
 	err = memcg_init_list_lru(lru, memcg_aware);
 	if (err) {
 		kfree(lru->node);
+		/* Do this so a list_lru_destroy() doesn't crash: */
+		lru->node = NULL;
 		goto out;
 	}
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/mm/memcontrol.c linux-libre-4.8.7-gnu/mm/memcontrol.c
--- linux-libre-4.8.6-gnu/mm/memcontrol.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/mm/memcontrol.c	2016-11-10 10:39:23.000000000 -0500
@@ -1947,6 +1947,15 @@ retry:
 		     current->flags & PF_EXITING))
 		goto force;
 
+	/*
+	 * Prevent unbounded recursion when reclaim operations need to
+	 * allocate memory. This might exceed the limits temporarily,
+	 * but we prefer facilitating memory reclaim and getting back
+	 * under the limit over triggering OOM kills in these cases.
+	 */
+	if (unlikely(current->flags & PF_MEMALLOC))
+		goto force;
+
 	if (unlikely(task_in_memcg_oom(current)))
 		goto nomem;
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/mm/slab.c linux-libre-4.8.7-gnu/mm/slab.c
--- linux-libre-4.8.6-gnu/mm/slab.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/mm/slab.c	2016-11-10 10:39:23.000000000 -0500
@@ -964,7 +964,7 @@ static int setup_kmem_cache_node(struct
 	 * guaranteed to be valid until irq is re-enabled, because it will be
 	 * freed after synchronize_sched().
 	 */
-	if (force_change)
+	if (old_shared && force_change)
 		synchronize_sched();
 
 fail:
diff -druNp --no-dereference linux-libre-4.8.6-gnu/mm/vmscan.c linux-libre-4.8.7-gnu/mm/vmscan.c
--- linux-libre-4.8.6-gnu/mm/vmscan.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/mm/vmscan.c	2016-11-10 10:39:23.000000000 -0500
@@ -3048,7 +3048,9 @@ unsigned long try_to_free_mem_cgroup_pag
 					    sc.gfp_mask,
 					    sc.reclaim_idx);
 
+	current->flags |= PF_MEMALLOC;
 	nr_reclaimed = do_try_to_free_pages(zonelist, &sc);
+	current->flags &= ~PF_MEMALLOC;
 
 	trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed);
 
diff -druNp --no-dereference linux-libre-4.8.6-gnu/net/mac80211/rx.c linux-libre-4.8.7-gnu/net/mac80211/rx.c
--- linux-libre-4.8.6-gnu/net/mac80211/rx.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/net/mac80211/rx.c	2016-11-10 10:39:23.000000000 -0500
@@ -2253,16 +2253,22 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
 	if (!(status->rx_flags & IEEE80211_RX_AMSDU))
 		return RX_CONTINUE;
 
-	if (ieee80211_has_a4(hdr->frame_control) &&
-	    rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
-	    !rx->sdata->u.vlan.sta)
-		return RX_DROP_UNUSABLE;
+	if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
+		switch (rx->sdata->vif.type) {
+		case NL80211_IFTYPE_AP_VLAN:
+			if (!rx->sdata->u.vlan.sta)
+				return RX_DROP_UNUSABLE;
+			break;
+		case NL80211_IFTYPE_STATION:
+			if (!rx->sdata->u.mgd.use_4addr)
+				return RX_DROP_UNUSABLE;
+			break;
+		default:
+			return RX_DROP_UNUSABLE;
+		}
+	}
 
-	if (is_multicast_ether_addr(hdr->addr1) &&
-	    ((rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
-	      rx->sdata->u.vlan.sta) ||
-	     (rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
-	      rx->sdata->u.mgd.use_4addr)))
+	if (is_multicast_ether_addr(hdr->addr1))
 		return RX_DROP_UNUSABLE;
 
 	skb->dev = dev;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/net/netfilter/xt_NFLOG.c linux-libre-4.8.7-gnu/net/netfilter/xt_NFLOG.c
--- linux-libre-4.8.6-gnu/net/netfilter/xt_NFLOG.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/net/netfilter/xt_NFLOG.c	2016-11-10 10:39:23.000000000 -0500
@@ -32,6 +32,7 @@ nflog_tg(struct sk_buff *skb, const stru
 	li.u.ulog.copy_len   = info->len;
 	li.u.ulog.group	     = info->group;
 	li.u.ulog.qthreshold = info->threshold;
+	li.u.ulog.flags	     = 0;
 
 	if (info->flags & XT_NFLOG_F_COPY_LEN)
 		li.u.ulog.flags |= NF_LOG_F_COPY_LEN;
diff -druNp --no-dereference linux-libre-4.8.6-gnu/security/keys/big_key.c linux-libre-4.8.7-gnu/security/keys/big_key.c
--- linux-libre-4.8.6-gnu/security/keys/big_key.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/security/keys/big_key.c	2016-11-10 10:39:23.000000000 -0500
@@ -9,6 +9,7 @@
  * 2 of the Licence, or (at your option) any later version.
  */
 
+#define pr_fmt(fmt) "big_key: "fmt
 #include <linux/init.h>
 #include <linux/seq_file.h>
 #include <linux/file.h>
@@ -341,44 +342,48 @@ error:
  */
 static int __init big_key_init(void)
 {
-	return register_key_type(&key_type_big_key);
-}
-
-/*
- * Initialize big_key crypto and RNG algorithms
- */
-static int __init big_key_crypto_init(void)
-{
-	int ret = -EINVAL;
+	struct crypto_skcipher *cipher;
+	struct crypto_rng *rng;
+	int ret;
 
-	/* init RNG */
-	big_key_rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
-	if (IS_ERR(big_key_rng)) {
-		big_key_rng = NULL;
-		return -EFAULT;
+	rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
+	if (IS_ERR(rng)) {
+		pr_err("Can't alloc rng: %ld\n", PTR_ERR(rng));
+		return PTR_ERR(rng);
 	}
 
+	big_key_rng = rng;
+
 	/* seed RNG */
-	ret = crypto_rng_reset(big_key_rng, NULL, crypto_rng_seedsize(big_key_rng));
-	if (ret)
-		goto error;
+	ret = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
+	if (ret) {
+		pr_err("Can't reset rng: %d\n", ret);
+		goto error_rng;
+	}
 
 	/* init block cipher */
-	big_key_skcipher = crypto_alloc_skcipher(big_key_alg_name,
-						 0, CRYPTO_ALG_ASYNC);
-	if (IS_ERR(big_key_skcipher)) {
-		big_key_skcipher = NULL;
-		ret = -EFAULT;
-		goto error;
+	cipher = crypto_alloc_skcipher(big_key_alg_name, 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(cipher)) {
+		ret = PTR_ERR(cipher);
+		pr_err("Can't alloc crypto: %d\n", ret);
+		goto error_rng;
+	}
+
+	big_key_skcipher = cipher;
+
+	ret = register_key_type(&key_type_big_key);
+	if (ret < 0) {
+		pr_err("Can't register type: %d\n", ret);
+		goto error_cipher;
 	}
 
 	return 0;
 
-error:
+error_cipher:
+	crypto_free_skcipher(big_key_skcipher);
+error_rng:
 	crypto_free_rng(big_key_rng);
-	big_key_rng = NULL;
 	return ret;
 }
 
-device_initcall(big_key_init);
-late_initcall(big_key_crypto_init);
+late_initcall(big_key_init);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/security/keys/Kconfig linux-libre-4.8.7-gnu/security/keys/Kconfig
--- linux-libre-4.8.6-gnu/security/keys/Kconfig	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/security/keys/Kconfig	2016-11-10 10:39:23.000000000 -0500
@@ -41,7 +41,7 @@ config BIG_KEYS
 	bool "Large payload keys"
 	depends on KEYS
 	depends on TMPFS
-	select CRYPTO
+	depends on (CRYPTO_ANSI_CPRNG = y || CRYPTO_DRBG = y)
 	select CRYPTO_AES
 	select CRYPTO_ECB
 	select CRYPTO_RNG
diff -druNp --no-dereference linux-libre-4.8.6-gnu/security/keys/proc.c linux-libre-4.8.7-gnu/security/keys/proc.c
--- linux-libre-4.8.6-gnu/security/keys/proc.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/security/keys/proc.c	2016-11-10 10:39:23.000000000 -0500
@@ -181,7 +181,7 @@ static int proc_keys_show(struct seq_fil
 	struct timespec now;
 	unsigned long timo;
 	key_ref_t key_ref, skey_ref;
-	char xbuf[12];
+	char xbuf[16];
 	int rc;
 
 	struct keyring_search_context ctx = {
diff -druNp --no-dereference linux-libre-4.8.6-gnu/sound/core/seq/seq_timer.c linux-libre-4.8.7-gnu/sound/core/seq/seq_timer.c
--- linux-libre-4.8.6-gnu/sound/core/seq/seq_timer.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/sound/core/seq/seq_timer.c	2016-11-10 10:39:23.000000000 -0500
@@ -448,8 +448,8 @@ snd_seq_real_time_t snd_seq_timer_get_cu
 
 		ktime_get_ts64(&tm);
 		tm = timespec64_sub(tm, tmr->last_update);
-		cur_time.tv_nsec = tm.tv_nsec;
-		cur_time.tv_sec = tm.tv_sec;
+		cur_time.tv_nsec += tm.tv_nsec;
+		cur_time.tv_sec += tm.tv_sec;
 		snd_seq_sanity_real_time(&cur_time);
 	}
 	spin_unlock_irqrestore(&tmr->lock, flags);
diff -druNp --no-dereference linux-libre-4.8.6-gnu/sound/pci/hda/hda_intel.c linux-libre-4.8.7-gnu/sound/pci/hda/hda_intel.c
--- linux-libre-4.8.6-gnu/sound/pci/hda/hda_intel.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/sound/pci/hda/hda_intel.c	2016-11-10 10:39:23.000000000 -0500
@@ -340,8 +340,7 @@ enum {
 
 /* quirks for Nvidia */
 #define AZX_DCAPS_PRESET_NVIDIA \
-	(AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \
-	 AZX_DCAPS_NO_64BIT | AZX_DCAPS_CORBRP_SELF_CLEAR |\
+	(AZX_DCAPS_NO_MSI | AZX_DCAPS_CORBRP_SELF_CLEAR |\
 	 AZX_DCAPS_SNOOP_TYPE(NVIDIA))
 
 #define AZX_DCAPS_PRESET_CTHDA \
@@ -1699,6 +1698,10 @@ static int azx_first_init(struct azx *ch
 		}
 	}
 
+	/* NVidia hardware normally only supports up to 40 bits of DMA */
+	if (chip->pci->vendor == PCI_VENDOR_ID_NVIDIA)
+		dma_bits = 40;
+
 	/* disable 64bit DMA address on some devices */
 	if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
 		dev_dbg(card->dev, "Disabling 64bit DMA\n");
diff -druNp --no-dereference linux-libre-4.8.6-gnu/sound/pci/hda/patch_realtek.c linux-libre-4.8.7-gnu/sound/pci/hda/patch_realtek.c
--- linux-libre-4.8.6-gnu/sound/pci/hda/patch_realtek.c	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/sound/pci/hda/patch_realtek.c	2016-11-10 10:39:23.000000000 -0500
@@ -5809,8 +5809,6 @@ static const struct hda_model_fixup alc2
 #define ALC295_STANDARD_PINS \
 	{0x12, 0xb7a60130}, \
 	{0x14, 0x90170110}, \
-	{0x17, 0x21014020}, \
-	{0x18, 0x21a19030}, \
 	{0x21, 0x04211020}
 
 #define ALC298_STANDARD_PINS \
@@ -5857,11 +5855,19 @@ static const struct snd_hda_pin_quirk al
 		{0x1b, 0x02011020},
 		{0x21, 0x0221101f}),
 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+		{0x14, 0x90170110},
+		{0x1b, 0x01011020},
+		{0x21, 0x0221101f}),
+	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
 		{0x14, 0x90170130},
 		{0x1b, 0x01014020},
 		{0x21, 0x0221103f}),
 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
 		{0x14, 0x90170130},
+		{0x1b, 0x01011020},
+		{0x21, 0x0221103f}),
+	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+		{0x14, 0x90170130},
 		{0x1b, 0x02011020},
 		{0x21, 0x0221103f}),
 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
@@ -6037,7 +6043,13 @@ static const struct snd_hda_pin_quirk al
 		ALC292_STANDARD_PINS,
 		{0x13, 0x90a60140}),
 	SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
-		ALC295_STANDARD_PINS),
+		ALC295_STANDARD_PINS,
+		{0x17, 0x21014020},
+		{0x18, 0x21a19030}),
+	SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
+		ALC295_STANDARD_PINS,
+		{0x17, 0x21014040},
+		{0x18, 0x21a19050}),
 	SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
 		ALC298_STANDARD_PINS,
 		{0x17, 0x90170110}),
@@ -6611,6 +6623,7 @@ enum {
 	ALC891_FIXUP_HEADSET_MODE,
 	ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
 	ALC662_FIXUP_ACER_VERITON,
+	ALC892_FIXUP_ASROCK_MOBO,
 };
 
 static const struct hda_fixup alc662_fixups[] = {
@@ -6887,6 +6900,16 @@ static const struct hda_fixup alc662_fix
 			{ }
 		}
 	},
+	[ALC892_FIXUP_ASROCK_MOBO] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			{ 0x15, 0x40f000f0 }, /* disabled */
+			{ 0x16, 0x40f000f0 }, /* disabled */
+			{ 0x18, 0x01014011 }, /* LO */
+			{ 0x1a, 0x01014012 }, /* LO */
+			{ }
+		}
+	},
 };
 
 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -6924,6 +6947,7 @@ static const struct snd_pci_quirk alc662
 	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
+	SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
 	SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
 	SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
 	SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
diff -druNp --no-dereference linux-libre-4.8.6-gnu/sound/usb/quirks-table.h linux-libre-4.8.7-gnu/sound/usb/quirks-table.h
--- linux-libre-4.8.6-gnu/sound/usb/quirks-table.h	2016-10-31 07:26:46.000000000 -0400
+++ linux-libre-4.8.7-gnu/sound/usb/quirks-table.h	2016-11-10 10:39:23.000000000 -0500
@@ -2907,6 +2907,23 @@ AU0828_DEVICE(0x2040, 0x7260, "Hauppauge
 AU0828_DEVICE(0x2040, 0x7213, "Hauppauge", "HVR-950Q"),
 AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
 
+/* Syntek STK1160 */
+{
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+		       USB_DEVICE_ID_MATCH_INT_CLASS |
+		       USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+	.idVendor = 0x05e1,
+	.idProduct = 0x0408,
+	.bInterfaceClass = USB_CLASS_AUDIO,
+	.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
+	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+		.vendor_name = "Syntek",
+		.product_name = "STK1160",
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_AUDIO_ALIGN_TRANSFER
+	}
+},
+
 /* Digidesign Mbox */
 {
 	/* Thanks to Clemens Ladisch <clemens@ladisch.de> */
