diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/arm/boot/dts/arm-realview-eb.dtsi linux-libre-4.8.6-gnu/arch/arm/boot/dts/arm-realview-eb.dtsi
--- linux-libre-4.8.5-gnu/arch/arm/boot/dts/arm-realview-eb.dtsi	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/arm/boot/dts/arm-realview-eb.dtsi	2016-10-31 07:26:46.000000000 -0400
@@ -51,14 +51,6 @@
 		regulator-boot-on;
         };
 
-	veth: fixedregulator@0 {
-		compatible = "regulator-fixed";
-		regulator-name = "veth";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-boot-on;
-	};
-
 	xtal24mhz: xtal24mhz@24M {
 		#clock-cells = <0>;
 		compatible = "fixed-clock";
@@ -134,16 +126,15 @@
 		bank-width = <4>;
 	};
 
-	/* SMSC 9118 ethernet with PHY and EEPROM */
+	/* SMSC LAN91C111 ethernet with PHY and EEPROM */
 	ethernet: ethernet@4e000000 {
-		compatible = "smsc,lan9118", "smsc,lan9115";
+		compatible = "smsc,lan91c111";
 		reg = <0x4e000000 0x10000>;
-		phy-mode = "mii";
-		reg-io-width = <4>;
-		smsc,irq-active-high;
-		smsc,irq-push-pull;
-		vdd33a-supply = <&veth>;
-		vddvario-supply = <&veth>;
+		/*
+		 * This means the adapter can be accessed with 8, 16 or
+		 * 32 bit reads/writes.
+		 */
+		reg-io-width = <7>;
 	};
 
 	usb: usb@4f000000 {
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/arm/boot/dts/bcm958625hr.dts linux-libre-4.8.6-gnu/arch/arm/boot/dts/bcm958625hr.dts
--- linux-libre-4.8.5-gnu/arch/arm/boot/dts/bcm958625hr.dts	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/arm/boot/dts/bcm958625hr.dts	2016-10-31 07:26:46.000000000 -0400
@@ -47,7 +47,8 @@
 	};
 
 	memory {
-		reg = <0x60000000 0x20000000>;
+		device_type = "memory";
+		reg = <0x60000000 0x80000000>;
 	};
 };
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi linux-libre-4.8.6-gnu/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
--- linux-libre-4.8.5-gnu/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi	2016-10-31 07:26:46.000000000 -0400
@@ -119,7 +119,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcspi1_pins>;
 
-	lcd0: display {
+	lcd0: display@1 {
 		compatible = "lgphilips,lb035q02";
 		label = "lcd35";
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/arm/boot/dts/sun9i-a80.dtsi linux-libre-4.8.6-gnu/arch/arm/boot/dts/sun9i-a80.dtsi
--- linux-libre-4.8.5-gnu/arch/arm/boot/dts/sun9i-a80.dtsi	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/arm/boot/dts/sun9i-a80.dtsi	2016-10-31 07:26:46.000000000 -0400
@@ -899,8 +899,7 @@
 			resets = <&apbs_rst 0>;
 			gpio-controller;
 			interrupt-controller;
-			#address-cells = <1>;
-			#size-cells = <0>;
+			#interrupt-cells = <3>;
 			#gpio-cells = <3>;
 
 			r_ir_pins: r_ir {
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/arm/crypto/ghash-ce-glue.c linux-libre-4.8.6-gnu/arch/arm/crypto/ghash-ce-glue.c
--- linux-libre-4.8.5-gnu/arch/arm/crypto/ghash-ce-glue.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/arm/crypto/ghash-ce-glue.c	2016-10-31 07:26:46.000000000 -0400
@@ -220,6 +220,27 @@ static int ghash_async_digest(struct aha
 	}
 }
 
+static int ghash_async_import(struct ahash_request *req, const void *in)
+{
+	struct ahash_request *cryptd_req = ahash_request_ctx(req);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+
+	desc->tfm = cryptd_ahash_child(ctx->cryptd_tfm);
+	desc->flags = req->base.flags;
+
+	return crypto_shash_import(desc, in);
+}
+
+static int ghash_async_export(struct ahash_request *req, void *out)
+{
+	struct ahash_request *cryptd_req = ahash_request_ctx(req);
+	struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+
+	return crypto_shash_export(desc, out);
+}
+
 static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
 			      unsigned int keylen)
 {
@@ -268,7 +289,10 @@ static struct ahash_alg ghash_async_alg
 	.final			= ghash_async_final,
 	.setkey			= ghash_async_setkey,
 	.digest			= ghash_async_digest,
+	.import			= ghash_async_import,
+	.export			= ghash_async_export,
 	.halg.digestsize	= GHASH_DIGEST_SIZE,
+	.halg.statesize		= sizeof(struct ghash_desc_ctx),
 	.halg.base		= {
 		.cra_name	= "ghash",
 		.cra_driver_name = "ghash-ce",
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/arm/mach-pxa/corgi_pm.c linux-libre-4.8.6-gnu/arch/arm/mach-pxa/corgi_pm.c
--- linux-libre-4.8.5-gnu/arch/arm/mach-pxa/corgi_pm.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/arm/mach-pxa/corgi_pm.c	2016-10-31 07:26:46.000000000 -0400
@@ -131,16 +131,11 @@ static int corgi_should_wakeup(unsigned
 	return is_resume;
 }
 
-static unsigned long corgi_charger_wakeup(void)
+static bool corgi_charger_wakeup(void)
 {
-	unsigned long ret;
-
-	ret = (!gpio_get_value(CORGI_GPIO_AC_IN) << GPIO_bit(CORGI_GPIO_AC_IN))
-		| (!gpio_get_value(CORGI_GPIO_KEY_INT)
-		<< GPIO_bit(CORGI_GPIO_KEY_INT))
-		| (!gpio_get_value(CORGI_GPIO_WAKEUP)
-		<< GPIO_bit(CORGI_GPIO_WAKEUP));
-	return ret;
+	return !gpio_get_value(CORGI_GPIO_AC_IN) ||
+		!gpio_get_value(CORGI_GPIO_KEY_INT) ||
+		!gpio_get_value(CORGI_GPIO_WAKEUP);
 }
 
 unsigned long corgipm_read_devdata(int type)
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/arm/mach-pxa/pxa_cplds_irqs.c linux-libre-4.8.6-gnu/arch/arm/mach-pxa/pxa_cplds_irqs.c
--- linux-libre-4.8.5-gnu/arch/arm/mach-pxa/pxa_cplds_irqs.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/arm/mach-pxa/pxa_cplds_irqs.c	2016-10-31 07:26:46.000000000 -0400
@@ -41,30 +41,35 @@ static irqreturn_t cplds_irq_handler(int
 	unsigned long pending;
 	unsigned int bit;
 
-	pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
-	for_each_set_bit(bit, &pending, CPLDS_NB_IRQ)
-		generic_handle_irq(irq_find_mapping(fpga->irqdomain, bit));
+	do {
+		pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
+		for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) {
+			generic_handle_irq(irq_find_mapping(fpga->irqdomain,
+							    bit));
+		}
+	} while (pending);
 
 	return IRQ_HANDLED;
 }
 
-static void cplds_irq_mask_ack(struct irq_data *d)
+static void cplds_irq_mask(struct irq_data *d)
 {
 	struct cplds *fpga = irq_data_get_irq_chip_data(d);
 	unsigned int cplds_irq = irqd_to_hwirq(d);
-	unsigned int set, bit = BIT(cplds_irq);
+	unsigned int bit = BIT(cplds_irq);
 
 	fpga->irq_mask &= ~bit;
 	writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
-	set = readl(fpga->base + FPGA_IRQ_SET_CLR);
-	writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR);
 }
 
 static void cplds_irq_unmask(struct irq_data *d)
 {
 	struct cplds *fpga = irq_data_get_irq_chip_data(d);
 	unsigned int cplds_irq = irqd_to_hwirq(d);
-	unsigned int bit = BIT(cplds_irq);
+	unsigned int set, bit = BIT(cplds_irq);
+
+	set = readl(fpga->base + FPGA_IRQ_SET_CLR);
+	writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR);
 
 	fpga->irq_mask |= bit;
 	writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
@@ -72,7 +77,8 @@ static void cplds_irq_unmask(struct irq_
 
 static struct irq_chip cplds_irq_chip = {
 	.name		= "pxa_cplds",
-	.irq_mask_ack	= cplds_irq_mask_ack,
+	.irq_ack	= cplds_irq_mask,
+	.irq_mask	= cplds_irq_mask,
 	.irq_unmask	= cplds_irq_unmask,
 	.flags		= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
 };
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/arm/mach-pxa/sharpsl_pm.c linux-libre-4.8.6-gnu/arch/arm/mach-pxa/sharpsl_pm.c
--- linux-libre-4.8.5-gnu/arch/arm/mach-pxa/sharpsl_pm.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/arm/mach-pxa/sharpsl_pm.c	2016-10-31 07:26:46.000000000 -0400
@@ -744,7 +744,7 @@ static int sharpsl_off_charge_battery(vo
 		time = RCNR;
 		while (1) {
 			/* Check if any wakeup event had occurred */
-			if (sharpsl_pm.machinfo->charger_wakeup() != 0)
+			if (sharpsl_pm.machinfo->charger_wakeup())
 				return 0;
 			/* Check for timeout */
 			if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/arm/mach-pxa/sharpsl_pm.h linux-libre-4.8.6-gnu/arch/arm/mach-pxa/sharpsl_pm.h
--- linux-libre-4.8.5-gnu/arch/arm/mach-pxa/sharpsl_pm.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/arm/mach-pxa/sharpsl_pm.h	2016-10-31 07:26:46.000000000 -0400
@@ -34,7 +34,7 @@ struct sharpsl_charger_machinfo {
 #define SHARPSL_STATUS_LOCK     5
 #define SHARPSL_STATUS_CHRGFULL 6
 #define SHARPSL_STATUS_FATAL    7
-	unsigned long (*charger_wakeup)(void);
+	bool (*charger_wakeup)(void);
 	int (*should_wakeup)(unsigned int resume_on_alarm);
 	void (*backlight_limit)(int);
 	int (*backlight_get_status) (void);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/arm/mach-pxa/spitz_pm.c linux-libre-4.8.6-gnu/arch/arm/mach-pxa/spitz_pm.c
--- linux-libre-4.8.5-gnu/arch/arm/mach-pxa/spitz_pm.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/arm/mach-pxa/spitz_pm.c	2016-10-31 07:26:46.000000000 -0400
@@ -165,13 +165,10 @@ static int spitz_should_wakeup(unsigned
 	return is_resume;
 }
 
-static unsigned long spitz_charger_wakeup(void)
+static bool spitz_charger_wakeup(void)
 {
-	unsigned long ret;
-	ret = ((!gpio_get_value(SPITZ_GPIO_KEY_INT)
-		<< GPIO_bit(SPITZ_GPIO_KEY_INT))
-		| gpio_get_value(SPITZ_GPIO_SYNC));
-	return ret;
+	return !gpio_get_value(SPITZ_GPIO_KEY_INT) ||
+		gpio_get_value(SPITZ_GPIO_SYNC);
 }
 
 unsigned long spitzpm_read_devdata(int type)
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/powerpc/include/asm/book3s/64/pgtable.h linux-libre-4.8.6-gnu/arch/powerpc/include/asm/book3s/64/pgtable.h
--- linux-libre-4.8.5-gnu/arch/powerpc/include/asm/book3s/64/pgtable.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/powerpc/include/asm/book3s/64/pgtable.h	2016-10-31 07:26:46.000000000 -0400
@@ -6,6 +6,8 @@
  */
 #define _PAGE_BIT_SWAP_TYPE	0
 
+#define _PAGE_RO		0
+
 #define _PAGE_EXEC		0x00001 /* execute permission */
 #define _PAGE_WRITE		0x00002 /* write access allowed */
 #define _PAGE_READ		0x00004	/* read access allowed */
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/powerpc/kernel/nvram_64.c linux-libre-4.8.6-gnu/arch/powerpc/kernel/nvram_64.c
--- linux-libre-4.8.5-gnu/arch/powerpc/kernel/nvram_64.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/powerpc/kernel/nvram_64.c	2016-10-31 07:26:46.000000000 -0400
@@ -956,7 +956,7 @@ int __init nvram_remove_partition(const
 
 		/* Make partition a free partition */
 		part->header.signature = NVRAM_SIG_FREE;
-		strncpy(part->header.name, "wwwwwwwwwwww", 12);
+		memset(part->header.name, 'w', 12);
 		part->header.checksum = nvram_checksum(&part->header);
 		rc = nvram_write_header(part);
 		if (rc <= 0) {
@@ -974,8 +974,8 @@ int __init nvram_remove_partition(const
 		}
 		if (prev) {
 			prev->header.length += part->header.length;
-			prev->header.checksum = nvram_checksum(&part->header);
-			rc = nvram_write_header(part);
+			prev->header.checksum = nvram_checksum(&prev->header);
+			rc = nvram_write_header(prev);
 			if (rc <= 0) {
 				printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc);
 				return rc;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/powerpc/kernel/process.c linux-libre-4.8.6-gnu/arch/powerpc/kernel/process.c
--- linux-libre-4.8.5-gnu/arch/powerpc/kernel/process.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/powerpc/kernel/process.c	2016-10-31 07:26:46.000000000 -0400
@@ -88,7 +88,13 @@ static void check_if_tm_restore_required
 		set_thread_flag(TIF_RESTORE_TM);
 	}
 }
+
+static inline bool msr_tm_active(unsigned long msr)
+{
+	return MSR_TM_ACTIVE(msr);
+}
 #else
+static inline bool msr_tm_active(unsigned long msr) { return false; }
 static inline void check_if_tm_restore_required(struct task_struct *tsk) { }
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 
@@ -208,7 +214,7 @@ void enable_kernel_fp(void)
 EXPORT_SYMBOL(enable_kernel_fp);
 
 static int restore_fp(struct task_struct *tsk) {
-	if (tsk->thread.load_fp) {
+	if (tsk->thread.load_fp || msr_tm_active(tsk->thread.regs->msr)) {
 		load_fp_state(&current->thread.fp_state);
 		current->thread.load_fp++;
 		return 1;
@@ -278,7 +284,8 @@ EXPORT_SYMBOL_GPL(flush_altivec_to_threa
 
 static int restore_altivec(struct task_struct *tsk)
 {
-	if (cpu_has_feature(CPU_FTR_ALTIVEC) && tsk->thread.load_vec) {
+	if (cpu_has_feature(CPU_FTR_ALTIVEC) &&
+		(tsk->thread.load_vec || msr_tm_active(tsk->thread.regs->msr))) {
 		load_vr_state(&tsk->thread.vr_state);
 		tsk->thread.used_vr = 1;
 		tsk->thread.load_vec++;
@@ -438,6 +445,7 @@ void giveup_all(struct task_struct *tsk)
 		return;
 
 	msr_check_and_set(msr_all_available);
+	check_if_tm_restore_required(tsk);
 
 #ifdef CONFIG_PPC_FPU
 	if (usermsr & MSR_FP)
@@ -464,7 +472,8 @@ void restore_math(struct pt_regs *regs)
 {
 	unsigned long msr;
 
-	if (!current->thread.load_fp && !loadvec(current->thread))
+	if (!msr_tm_active(regs->msr) &&
+		!current->thread.load_fp && !loadvec(current->thread))
 		return;
 
 	msr = regs->msr;
@@ -983,6 +992,13 @@ void restore_tm_state(struct pt_regs *re
 	msr_diff = current->thread.ckpt_regs.msr & ~regs->msr;
 	msr_diff &= MSR_FP | MSR_VEC | MSR_VSX;
 
+	/* Ensure that restore_math() will restore */
+	if (msr_diff & MSR_FP)
+		current->thread.load_fp = 1;
+#ifdef CONFIG_ALIVEC
+	if (cpu_has_feature(CPU_FTR_ALTIVEC) && msr_diff & MSR_VEC)
+		current->thread.load_vec = 1;
+#endif
 	restore_math(regs);
 
 	regs->msr |= msr_diff;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/powerpc/mm/hugetlbpage.c linux-libre-4.8.6-gnu/arch/powerpc/mm/hugetlbpage.c
--- linux-libre-4.8.5-gnu/arch/powerpc/mm/hugetlbpage.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/powerpc/mm/hugetlbpage.c	2016-10-31 07:26:46.000000000 -0400
@@ -1019,8 +1019,15 @@ int gup_hugepte(pte_t *ptep, unsigned lo
 
 	pte = READ_ONCE(*ptep);
 	mask = _PAGE_PRESENT | _PAGE_READ;
+
+	/*
+	 * On some CPUs like the 8xx, _PAGE_RW hence _PAGE_WRITE is defined
+	 * as 0 and _PAGE_RO has to be set when a page is not writable
+	 */
 	if (write)
 		mask |= _PAGE_WRITE;
+	else
+		mask |= _PAGE_RO;
 
 	if ((pte_val(pte) & mask) != mask)
 		return 0;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/arch/x86/kernel/early-quirks.c linux-libre-4.8.6-gnu/arch/x86/kernel/early-quirks.c
--- linux-libre-4.8.5-gnu/arch/x86/kernel/early-quirks.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/arch/x86/kernel/early-quirks.c	2016-10-31 07:26:46.000000000 -0400
@@ -317,16 +317,11 @@ static phys_addr_t __init i85x_stolen_ba
 static phys_addr_t __init i865_stolen_base(int num, int slot, int func,
 					   size_t stolen_size)
 {
-	u16 toud;
+	u16 toud = 0;
 
-	/*
-	 * FIXME is the graphics stolen memory region
-	 * always at TOUD? Ie. is it always the last
-	 * one to be allocated by the BIOS?
-	 */
 	toud = read_pci_config_16(0, 0, 0, I865_TOUD);
 
-	return (phys_addr_t)toud << 16;
+	return (phys_addr_t)(toud << 16) + i845_tseg_size();
 }
 
 static phys_addr_t __init gen3_stolen_base(int num, int slot, int func,
diff -druNp --no-dereference linux-libre-4.8.5-gnu/crypto/gcm.c linux-libre-4.8.6-gnu/crypto/gcm.c
--- linux-libre-4.8.5-gnu/crypto/gcm.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/crypto/gcm.c	2016-10-31 07:26:46.000000000 -0400
@@ -117,7 +117,7 @@ static int crypto_gcm_setkey(struct cryp
 	struct crypto_skcipher *ctr = ctx->ctr;
 	struct {
 		be128 hash;
-		u8 iv[8];
+		u8 iv[16];
 
 		struct crypto_gcm_setkey_result result;
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/char/hw_random/omap-rng.c linux-libre-4.8.6-gnu/drivers/char/hw_random/omap-rng.c
--- linux-libre-4.8.5-gnu/drivers/char/hw_random/omap-rng.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/char/hw_random/omap-rng.c	2016-10-31 07:26:46.000000000 -0400
@@ -385,7 +385,7 @@ static int omap_rng_probe(struct platfor
 
 	pm_runtime_enable(&pdev->dev);
 	ret = pm_runtime_get_sync(&pdev->dev);
-	if (ret) {
+	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret);
 		pm_runtime_put_noidle(&pdev->dev);
 		goto err_ioremap;
@@ -443,7 +443,7 @@ static int __maybe_unused omap_rng_resum
 	int ret;
 
 	ret = pm_runtime_get_sync(dev);
-	if (ret) {
+	if (ret < 0) {
 		dev_err(dev, "Failed to runtime_get device: %d\n", ret);
 		pm_runtime_put_noidle(dev);
 		return ret;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/clk/bcm/clk-bcm2835.c linux-libre-4.8.6-gnu/drivers/clk/bcm/clk-bcm2835.c
--- linux-libre-4.8.5-gnu/drivers/clk/bcm/clk-bcm2835.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/clk/bcm/clk-bcm2835.c	2016-10-31 07:26:46.000000000 -0400
@@ -1006,16 +1006,28 @@ static int bcm2835_clock_set_rate(struct
 	return 0;
 }
 
+static bool
+bcm2835_clk_is_pllc(struct clk_hw *hw)
+{
+	if (!hw)
+		return false;
+
+	return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0;
+}
+
 static int bcm2835_clock_determine_rate(struct clk_hw *hw,
 					struct clk_rate_request *req)
 {
 	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
 	struct clk_hw *parent, *best_parent = NULL;
+	bool current_parent_is_pllc;
 	unsigned long rate, best_rate = 0;
 	unsigned long prate, best_prate = 0;
 	size_t i;
 	u32 div;
 
+	current_parent_is_pllc = bcm2835_clk_is_pllc(clk_hw_get_parent(hw));
+
 	/*
 	 * Select parent clock that results in the closest but lower rate
 	 */
@@ -1023,6 +1035,17 @@ static int bcm2835_clock_determine_rate(
 		parent = clk_hw_get_parent_by_index(hw, i);
 		if (!parent)
 			continue;
+
+		/*
+		 * Don't choose a PLLC-derived clock as our parent
+		 * unless it had been manually set that way.  PLLC's
+		 * frequency gets adjusted by the firmware due to
+		 * over-temp or under-voltage conditions, without
+		 * prior notification to our clock consumer.
+		 */
+		if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc)
+			continue;
+
 		prate = clk_hw_get_rate(parent);
 		div = bcm2835_clock_choose_div(hw, req->rate, prate, true);
 		rate = bcm2835_clock_rate_from_divisor(clock, prate, div);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/clk/clk.c linux-libre-4.8.6-gnu/drivers/clk/clk.c
--- linux-libre-4.8.5-gnu/drivers/clk/clk.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/clk/clk.c	2016-10-31 07:26:46.000000000 -0400
@@ -1908,10 +1908,6 @@ int clk_set_phase(struct clk *clk, int d
 
 	clk_prepare_lock();
 
-	/* bail early if nothing to do */
-	if (degrees == clk->core->phase)
-		goto out;
-
 	trace_clk_set_phase(clk->core, degrees);
 
 	if (clk->core->ops->set_phase)
@@ -1922,7 +1918,6 @@ int clk_set_phase(struct clk *clk, int d
 	if (!ret)
 		clk->core->phase = degrees;
 
-out:
 	clk_prepare_unlock();
 
 	return ret;
@@ -3186,7 +3181,7 @@ struct clk *__of_clk_get_from_provider(s
 {
 	struct of_clk_provider *provider;
 	struct clk *clk = ERR_PTR(-EPROBE_DEFER);
-	struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
+	struct clk_hw *hw;
 
 	if (!clkspec)
 		return ERR_PTR(-EINVAL);
@@ -3194,12 +3189,13 @@ struct clk *__of_clk_get_from_provider(s
 	/* Check if we have such a provider in our array */
 	mutex_lock(&of_clk_mutex);
 	list_for_each_entry(provider, &of_clk_providers, link) {
-		if (provider->node == clkspec->np)
+		if (provider->node == clkspec->np) {
 			hw = __of_clk_get_hw_from_provider(provider, clkspec);
-		if (!IS_ERR(hw)) {
 			clk = __clk_create_clk(hw, dev_id, con_id);
+		}
 
-			if (!IS_ERR(clk) && !__clk_get(clk)) {
+		if (!IS_ERR(clk)) {
+			if (!__clk_get(clk)) {
 				__clk_free_clk(clk);
 				clk = ERR_PTR(-ENOENT);
 			}
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/clk/clk-divider.c linux-libre-4.8.6-gnu/drivers/clk/clk-divider.c
--- linux-libre-4.8.5-gnu/drivers/clk/clk-divider.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/clk/clk-divider.c	2016-10-31 07:26:46.000000000 -0400
@@ -352,7 +352,7 @@ static long clk_divider_round_rate(struc
 
 	/* if read only, just return current value */
 	if (divider->flags & CLK_DIVIDER_READ_ONLY) {
-		bestdiv = readl(divider->reg) >> divider->shift;
+		bestdiv = clk_readl(divider->reg) >> divider->shift;
 		bestdiv &= div_mask(divider->width);
 		bestdiv = _get_div(divider->table, bestdiv, divider->flags,
 			divider->width);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/clk/clk-qoriq.c linux-libre-4.8.6-gnu/drivers/clk/clk-qoriq.c
--- linux-libre-4.8.5-gnu/drivers/clk/clk-qoriq.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/clk/clk-qoriq.c	2016-10-31 07:26:46.000000000 -0400
@@ -766,7 +766,11 @@ static struct clk * __init create_one_cm
 	if (!hwc)
 		return NULL;
 
-	hwc->reg = cg->regs + 0x20 * idx;
+	if (cg->info.flags & CG_VER3)
+		hwc->reg = cg->regs + 0x70000 + 0x20 * idx;
+	else
+		hwc->reg = cg->regs + 0x20 * idx;
+
 	hwc->info = cg->info.cmux_groups[cg->info.cmux_to_group[idx]];
 
 	/*
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/clk/imx/clk-imx35.c linux-libre-4.8.6-gnu/drivers/clk/imx/clk-imx35.c
--- linux-libre-4.8.5-gnu/drivers/clk/imx/clk-imx35.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/clk/imx/clk-imx35.c	2016-10-31 07:26:46.000000000 -0400
@@ -115,7 +115,7 @@ static void __init _mx35_clocks_init(voi
 	}
 
 	clk[ckih] = imx_clk_fixed("ckih", 24000000);
-	clk[ckil] = imx_clk_fixed("ckih", 32768);
+	clk[ckil] = imx_clk_fixed("ckil", 32768);
 	clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "mpll", "ckih", base + MX35_CCM_MPCTL);
 	clk[ppll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "ppll", "ckih", base + MX35_CCM_PPCTL);
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/clk/qcom/gcc-msm8996.c linux-libre-4.8.6-gnu/drivers/clk/qcom/gcc-msm8996.c
--- linux-libre-4.8.5-gnu/drivers/clk/qcom/gcc-msm8996.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/clk/qcom/gcc-msm8996.c	2016-10-31 07:26:46.000000000 -0400
@@ -2592,9 +2592,9 @@ static struct clk_branch gcc_pcie_2_aux_
 };
 
 static struct clk_branch gcc_pcie_2_pipe_clk = {
-	.halt_reg = 0x6e108,
+	.halt_reg = 0x6e018,
 	.clkr = {
-		.enable_reg = 0x6e108,
+		.enable_reg = 0x6e018,
 		.enable_mask = BIT(0),
 		.hw.init = &(struct clk_init_data){
 			.name = "gcc_pcie_2_pipe_clk",
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/clk/qcom/Kconfig linux-libre-4.8.6-gnu/drivers/clk/qcom/Kconfig
--- linux-libre-4.8.5-gnu/drivers/clk/qcom/Kconfig	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/clk/qcom/Kconfig	2016-10-31 07:26:46.000000000 -0400
@@ -117,6 +117,7 @@ config MSM_MMCC_8974
 
 config MSM_GCC_8996
 	tristate "MSM8996 Global Clock Controller"
+	select QCOM_GDSC
 	depends on COMMON_CLK_QCOM
 	help
 	  Support for the global clock controller on msm8996 devices.
@@ -126,6 +127,7 @@ config MSM_GCC_8996
 config MSM_MMCC_8996
 	tristate "MSM8996 Multimedia Clock Controller"
 	select MSM_GCC_8996
+	select QCOM_GDSC
 	depends on COMMON_CLK_QCOM
 	help
 	  Support for the multimedia clock controller on msm8996 devices.
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/crypto/ccp/ccp-dmaengine.c linux-libre-4.8.6-gnu/drivers/crypto/ccp/ccp-dmaengine.c
--- linux-libre-4.8.5-gnu/drivers/crypto/ccp/ccp-dmaengine.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/crypto/ccp/ccp-dmaengine.c	2016-10-31 07:26:46.000000000 -0400
@@ -650,7 +650,7 @@ int ccp_dmaengine_register(struct ccp_de
 	dma_desc_cache_name = devm_kasprintf(ccp->dev, GFP_KERNEL,
 					     "%s-dmaengine-desc-cache",
 					     ccp->name);
-	if (!dma_cmd_cache_name)
+	if (!dma_desc_cache_name)
 		return -ENOMEM;
 	ccp->dma_desc_cache = kmem_cache_create(dma_desc_cache_name,
 						sizeof(struct ccp_dma_desc),
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/crypto/marvell/cesa.c linux-libre-4.8.6-gnu/drivers/crypto/marvell/cesa.c
--- linux-libre-4.8.5-gnu/drivers/crypto/marvell/cesa.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/crypto/marvell/cesa.c	2016-10-31 07:26:46.000000000 -0400
@@ -166,6 +166,7 @@ static irqreturn_t mv_cesa_int(int irq,
 			if (!req)
 				break;
 
+			ctx = crypto_tfm_ctx(req->tfm);
 			mv_cesa_complete_req(ctx, req, 0);
 		}
 	}
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/crypto/marvell/hash.c linux-libre-4.8.6-gnu/drivers/crypto/marvell/hash.c
--- linux-libre-4.8.5-gnu/drivers/crypto/marvell/hash.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/crypto/marvell/hash.c	2016-10-31 07:26:46.000000000 -0400
@@ -805,13 +805,14 @@ static int mv_cesa_md5_init(struct ahash
 	struct mv_cesa_op_ctx tmpl = { };
 
 	mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_MD5);
+
+	mv_cesa_ahash_init(req, &tmpl, true);
+
 	creq->state[0] = MD5_H0;
 	creq->state[1] = MD5_H1;
 	creq->state[2] = MD5_H2;
 	creq->state[3] = MD5_H3;
 
-	mv_cesa_ahash_init(req, &tmpl, true);
-
 	return 0;
 }
 
@@ -873,14 +874,15 @@ static int mv_cesa_sha1_init(struct ahas
 	struct mv_cesa_op_ctx tmpl = { };
 
 	mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA1);
+
+	mv_cesa_ahash_init(req, &tmpl, false);
+
 	creq->state[0] = SHA1_H0;
 	creq->state[1] = SHA1_H1;
 	creq->state[2] = SHA1_H2;
 	creq->state[3] = SHA1_H3;
 	creq->state[4] = SHA1_H4;
 
-	mv_cesa_ahash_init(req, &tmpl, false);
-
 	return 0;
 }
 
@@ -942,6 +944,9 @@ static int mv_cesa_sha256_init(struct ah
 	struct mv_cesa_op_ctx tmpl = { };
 
 	mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA256);
+
+	mv_cesa_ahash_init(req, &tmpl, false);
+
 	creq->state[0] = SHA256_H0;
 	creq->state[1] = SHA256_H1;
 	creq->state[2] = SHA256_H2;
@@ -951,8 +956,6 @@ static int mv_cesa_sha256_init(struct ah
 	creq->state[6] = SHA256_H6;
 	creq->state[7] = SHA256_H7;
 
-	mv_cesa_ahash_init(req, &tmpl, false);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/dma/ipu/ipu_irq.c linux-libre-4.8.6-gnu/drivers/dma/ipu/ipu_irq.c
--- linux-libre-4.8.5-gnu/drivers/dma/ipu/ipu_irq.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/dma/ipu/ipu_irq.c	2016-10-31 07:26:46.000000000 -0400
@@ -286,22 +286,21 @@ static void ipu_irq_handler(struct irq_d
 		raw_spin_unlock(&bank_lock);
 		while ((line = ffs(status))) {
 			struct ipu_irq_map *map;
-			unsigned int irq = NO_IRQ;
+			unsigned int irq;
 
 			line--;
 			status &= ~(1UL << line);
 
 			raw_spin_lock(&bank_lock);
 			map = src2map(32 * i + line);
-			if (map)
-				irq = map->irq;
-			raw_spin_unlock(&bank_lock);
-
 			if (!map) {
+				raw_spin_unlock(&bank_lock);
 				pr_err("IPU: Interrupt on unmapped source %u bank %d\n",
 				       line, i);
 				continue;
 			}
+			irq = map->irq;
+			raw_spin_unlock(&bank_lock);
 			generic_handle_irq(irq);
 		}
 	}
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c	2016-10-31 07:26:46.000000000 -0400
@@ -43,6 +43,9 @@ static int amdgpu_ctx_init(struct amdgpu
 		ctx->rings[i].sequence = 1;
 		ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i];
 	}
+
+	ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
+
 	/* create context entity for each ring */
 	for (i = 0; i < adev->num_rings; i++) {
 		struct amdgpu_ring *ring = adev->rings[i];
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c	2016-10-31 07:26:46.000000000 -0400
@@ -113,24 +113,26 @@ void amdgpu_dpm_print_ps_status(struct a
 	printk("\n");
 }
 
+
 u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)
 {
 	struct drm_device *dev = adev->ddev;
 	struct drm_crtc *crtc;
 	struct amdgpu_crtc *amdgpu_crtc;
-	u32 line_time_us, vblank_lines;
+	u32 vblank_in_pixels;
 	u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
 
 	if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
 		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 			amdgpu_crtc = to_amdgpu_crtc(crtc);
 			if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
-				line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
-					amdgpu_crtc->hw_mode.clock;
-				vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
+				vblank_in_pixels =
+					amdgpu_crtc->hw_mode.crtc_htotal *
+					(amdgpu_crtc->hw_mode.crtc_vblank_end -
 					amdgpu_crtc->hw_mode.crtc_vdisplay +
-					(amdgpu_crtc->v_border * 2);
-				vblank_time_us = vblank_lines * line_time_us;
+					(amdgpu_crtc->v_border * 2));
+
+				vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock;
 				break;
 			}
 		}
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c	2016-10-31 07:26:46.000000000 -0400
@@ -292,7 +292,7 @@ static int amdgpu_info_ioctl(struct drm_
 			type = AMD_IP_BLOCK_TYPE_UVD;
 			ring_mask = adev->uvd.ring.ready ? 1 : 0;
 			ib_start_alignment = AMDGPU_GPU_PAGE_SIZE;
-			ib_size_alignment = 8;
+			ib_size_alignment = 16;
 			break;
 		case AMDGPU_HW_IP_VCE:
 			type = AMD_IP_BLOCK_TYPE_VCE;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c	2016-10-31 07:26:46.000000000 -0400
@@ -425,16 +425,6 @@ static void dce_v10_0_hpd_init(struct am
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
 
-		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
-		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
-			/* don't try to enable hpd on eDP or LVDS avoid breaking the
-			 * aux dp channel on imac and help (but not completely fix)
-			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
-			 * also avoid interrupt storms during dpms.
-			 */
-			continue;
-		}
-
 		switch (amdgpu_connector->hpd.hpd) {
 		case AMDGPU_HPD_1:
 			idx = 0;
@@ -458,6 +448,19 @@ static void dce_v10_0_hpd_init(struct am
 			continue;
 		}
 
+		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
+		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
+			/* don't try to enable hpd on eDP or LVDS avoid breaking the
+			 * aux dp channel on imac and help (but not completely fix)
+			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
+			 * also avoid interrupt storms during dpms.
+			 */
+			tmp = RREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx]);
+			tmp = REG_SET_FIELD(tmp, DC_HPD_INT_CONTROL, DC_HPD_INT_EN, 0);
+			WREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx], tmp);
+			continue;
+		}
+
 		tmp = RREG32(mmDC_HPD_CONTROL + hpd_offsets[idx]);
 		tmp = REG_SET_FIELD(tmp, DC_HPD_CONTROL, DC_HPD_EN, 1);
 		WREG32(mmDC_HPD_CONTROL + hpd_offsets[idx], tmp);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c	2016-10-31 07:26:46.000000000 -0400
@@ -443,16 +443,6 @@ static void dce_v11_0_hpd_init(struct am
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
 
-		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
-		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
-			/* don't try to enable hpd on eDP or LVDS avoid breaking the
-			 * aux dp channel on imac and help (but not completely fix)
-			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
-			 * also avoid interrupt storms during dpms.
-			 */
-			continue;
-		}
-
 		switch (amdgpu_connector->hpd.hpd) {
 		case AMDGPU_HPD_1:
 			idx = 0;
@@ -476,6 +466,19 @@ static void dce_v11_0_hpd_init(struct am
 			continue;
 		}
 
+		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
+		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
+			/* don't try to enable hpd on eDP or LVDS avoid breaking the
+			 * aux dp channel on imac and help (but not completely fix)
+			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
+			 * also avoid interrupt storms during dpms.
+			 */
+			tmp = RREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx]);
+			tmp = REG_SET_FIELD(tmp, DC_HPD_INT_CONTROL, DC_HPD_INT_EN, 0);
+			WREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx], tmp);
+			continue;
+		}
+
 		tmp = RREG32(mmDC_HPD_CONTROL + hpd_offsets[idx]);
 		tmp = REG_SET_FIELD(tmp, DC_HPD_CONTROL, DC_HPD_EN, 1);
 		WREG32(mmDC_HPD_CONTROL + hpd_offsets[idx], tmp);
@@ -3109,6 +3112,7 @@ static int dce_v11_0_sw_fini(void *handl
 
 	dce_v11_0_afmt_fini(adev);
 
+	drm_mode_config_cleanup(adev->ddev);
 	adev->mode_info.mode_config_initialized = false;
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c	2016-10-31 07:26:46.000000000 -0400
@@ -395,15 +395,6 @@ static void dce_v8_0_hpd_init(struct amd
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
 
-		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
-		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
-			/* don't try to enable hpd on eDP or LVDS avoid breaking the
-			 * aux dp channel on imac and help (but not completely fix)
-			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
-			 * also avoid interrupt storms during dpms.
-			 */
-			continue;
-		}
 		switch (amdgpu_connector->hpd.hpd) {
 		case AMDGPU_HPD_1:
 			WREG32(mmDC_HPD1_CONTROL, tmp);
@@ -426,6 +417,45 @@ static void dce_v8_0_hpd_init(struct amd
 		default:
 			break;
 		}
+
+		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
+		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
+			/* don't try to enable hpd on eDP or LVDS avoid breaking the
+			 * aux dp channel on imac and help (but not completely fix)
+			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
+			 * also avoid interrupt storms during dpms.
+			 */
+			u32 dc_hpd_int_cntl_reg, dc_hpd_int_cntl;
+
+			switch (amdgpu_connector->hpd.hpd) {
+			case AMDGPU_HPD_1:
+				dc_hpd_int_cntl_reg = mmDC_HPD1_INT_CONTROL;
+				break;
+			case AMDGPU_HPD_2:
+				dc_hpd_int_cntl_reg = mmDC_HPD2_INT_CONTROL;
+				break;
+			case AMDGPU_HPD_3:
+				dc_hpd_int_cntl_reg = mmDC_HPD3_INT_CONTROL;
+				break;
+			case AMDGPU_HPD_4:
+				dc_hpd_int_cntl_reg = mmDC_HPD4_INT_CONTROL;
+				break;
+			case AMDGPU_HPD_5:
+				dc_hpd_int_cntl_reg = mmDC_HPD5_INT_CONTROL;
+				break;
+			case AMDGPU_HPD_6:
+				dc_hpd_int_cntl_reg = mmDC_HPD6_INT_CONTROL;
+				break;
+			default:
+				continue;
+			}
+
+			dc_hpd_int_cntl = RREG32(dc_hpd_int_cntl_reg);
+			dc_hpd_int_cntl &= ~DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK;
+			WREG32(dc_hpd_int_cntl_reg, dc_hpd_int_cntl);
+			continue;
+		}
+
 		dce_v8_0_hpd_set_polarity(adev, amdgpu_connector->hpd.hpd);
 		amdgpu_irq_get(adev, &adev->hpd_irq, amdgpu_connector->hpd.hpd);
 	}
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c	2016-10-31 07:26:46.000000000 -0400
@@ -262,6 +262,8 @@ static const pem_event_action * const di
 	unblock_adjust_power_state_tasks,
 	set_cpu_power_state,
 	notify_hw_power_source_tasks,
+	get_2d_performance_state_tasks,
+	set_performance_state_tasks,
 	/* updateDALConfigurationTasks,
 	variBrightDisplayConfigurationChangeTasks, */
 	adjust_power_state_tasks,
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c	2016-10-31 07:26:46.000000000 -0400
@@ -100,11 +100,12 @@ int psm_adjust_power_state_dynamic(struc
 	if (requested == NULL)
 		return 0;
 
+	phm_apply_state_adjust_rules(hwmgr, requested, pcurrent);
+
 	if (pcurrent == NULL || (0 != phm_check_states_equal(hwmgr, &pcurrent->hardware, &requested->hardware, &equal)))
 		equal = false;
 
 	if (!equal || phm_check_smc_update_required_for_display_configuration(hwmgr)) {
-		phm_apply_state_adjust_rules(hwmgr, requested, pcurrent);
 		phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware);
 		hwmgr->current_ps = requested;
 	}
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/drm_prime.c linux-libre-4.8.6-gnu/drivers/gpu/drm/drm_prime.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/drm_prime.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/drm_prime.c	2016-10-31 07:26:46.000000000 -0400
@@ -335,14 +335,17 @@ static const struct dma_buf_ops drm_gem_
  * using the PRIME helpers.
  */
 struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
-				     struct drm_gem_object *obj, int flags)
+				     struct drm_gem_object *obj,
+				     int flags)
 {
-	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
-
-	exp_info.ops = &drm_gem_prime_dmabuf_ops;
-	exp_info.size = obj->size;
-	exp_info.flags = flags;
-	exp_info.priv = obj;
+	struct dma_buf_export_info exp_info = {
+		.exp_name = KBUILD_MODNAME, /* white lie for debug */
+		.owner = dev->driver->fops->owner,
+		.ops = &drm_gem_prime_dmabuf_ops,
+		.size = obj->size,
+		.flags = flags,
+		.priv = obj,
+	};
 
 	if (dev->driver->gem_prime_res_obj)
 		exp_info.resv = dev->driver->gem_prime_res_obj(obj);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c linux-libre-4.8.6-gnu/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c	2016-10-31 07:26:46.000000000 -0400
@@ -330,6 +330,7 @@ static int fsl_dcu_drm_probe(struct plat
 	const char *pix_clk_in_name;
 	const struct of_device_id *id;
 	int ret;
+	u8 div_ratio_shift = 0;
 
 	fsl_dev = devm_kzalloc(dev, sizeof(*fsl_dev), GFP_KERNEL);
 	if (!fsl_dev)
@@ -382,11 +383,14 @@ static int fsl_dcu_drm_probe(struct plat
 		pix_clk_in = fsl_dev->clk;
 	}
 
+	if (of_property_read_bool(dev->of_node, "big-endian"))
+		div_ratio_shift = 24;
+
 	pix_clk_in_name = __clk_get_name(pix_clk_in);
 	snprintf(pix_clk_name, sizeof(pix_clk_name), "%s_pix", pix_clk_in_name);
 	fsl_dev->pix_clk = clk_register_divider(dev, pix_clk_name,
 			pix_clk_in_name, 0, base + DCU_DIV_RATIO,
-			0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL);
+			div_ratio_shift, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL);
 	if (IS_ERR(fsl_dev->pix_clk)) {
 		dev_err(dev, "failed to register pix clk\n");
 		ret = PTR_ERR(fsl_dev->pix_clk);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/i915_drv.h linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/i915_drv.h
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/i915_drv.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/i915_drv.h	2016-10-31 07:26:46.000000000 -0400
@@ -631,6 +631,8 @@ struct drm_i915_display_funcs {
 				  struct intel_crtc_state *crtc_state);
 	void (*crtc_enable)(struct drm_crtc *crtc);
 	void (*crtc_disable)(struct drm_crtc *crtc);
+	void (*update_crtcs)(struct drm_atomic_state *state,
+			     unsigned int *crtc_vblank_mask);
 	void (*audio_codec_enable)(struct drm_connector *connector,
 				   struct intel_encoder *encoder,
 				   const struct drm_display_mode *adjusted_mode);
@@ -1965,11 +1967,11 @@ struct drm_i915_private {
 	struct vlv_s0ix_state vlv_s0ix_state;
 
 	enum {
-		I915_SKL_SAGV_UNKNOWN = 0,
-		I915_SKL_SAGV_DISABLED,
-		I915_SKL_SAGV_ENABLED,
-		I915_SKL_SAGV_NOT_CONTROLLED
-	} skl_sagv_status;
+		I915_SAGV_UNKNOWN = 0,
+		I915_SAGV_DISABLED,
+		I915_SAGV_ENABLED,
+		I915_SAGV_NOT_CONTROLLED
+	} sagv_status;
 
 	struct {
 		/*
@@ -2280,21 +2282,19 @@ struct drm_i915_gem_object {
 	/** Record of address bit 17 of each page at last unbind. */
 	unsigned long *bit_17;
 
-	union {
-		/** for phy allocated objects */
-		struct drm_dma_handle *phys_handle;
-
-		struct i915_gem_userptr {
-			uintptr_t ptr;
-			unsigned read_only :1;
-			unsigned workers :4;
+	struct i915_gem_userptr {
+		uintptr_t ptr;
+		unsigned read_only :1;
+		unsigned workers :4;
 #define I915_GEM_USERPTR_MAX_WORKERS 15
 
-			struct i915_mm_struct *mm;
-			struct i915_mmu_object *mmu_object;
-			struct work_struct *work;
-		} userptr;
-	};
+		struct i915_mm_struct *mm;
+		struct i915_mmu_object *mmu_object;
+		struct work_struct *work;
+	} userptr;
+
+	/** for phys allocated objects */
+	struct drm_dma_handle *phys_handle;
 };
 #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base)
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/i915_gem_stolen.c linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/i915_gem_stolen.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/i915_gem_stolen.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/i915_gem_stolen.c	2016-10-31 07:26:46.000000000 -0400
@@ -115,17 +115,28 @@ static unsigned long i915_stolen_to_phys
 
 		base = bsm & INTEL_BSM_MASK;
 	} else if (IS_I865G(dev)) {
+		u32 tseg_size = 0;
 		u16 toud = 0;
+		u8 tmp;
+
+		pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0),
+					 I845_ESMRAMC, &tmp);
+
+		if (tmp & TSEG_ENABLE) {
+			switch (tmp & I845_TSEG_SIZE_MASK) {
+			case I845_TSEG_SIZE_512K:
+				tseg_size = KB(512);
+				break;
+			case I845_TSEG_SIZE_1M:
+				tseg_size = MB(1);
+				break;
+			}
+		}
 
-		/*
-		 * FIXME is the graphics stolen memory region
-		 * always at TOUD? Ie. is it always the last
-		 * one to be allocated by the BIOS?
-		 */
 		pci_bus_read_config_word(dev->pdev->bus, PCI_DEVFN(0, 0),
 					 I865_TOUD, &toud);
 
-		base = toud << 16;
+		base = (toud << 16) + tseg_size;
 	} else if (IS_I85X(dev)) {
 		u32 tseg_size = 0;
 		u32 tom;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_display.c linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_display.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_display.c	2016-10-31 07:26:46.000000000 -0400
@@ -2980,6 +2980,7 @@ static void skylake_update_primary_plane
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
 	struct drm_framebuffer *fb = plane_state->base.fb;
 	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
 	int pipe = intel_crtc->pipe;
 	u32 plane_ctl, stride_div, stride;
 	u32 tile_height, plane_offset, plane_size;
@@ -3031,6 +3032,9 @@ static void skylake_update_primary_plane
 	intel_crtc->adjusted_x = x_offset;
 	intel_crtc->adjusted_y = y_offset;
 
+	if (wm->dirty_pipes & drm_crtc_mask(&intel_crtc->base))
+		skl_write_plane_wm(intel_crtc, wm, 0);
+
 	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
 	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
 	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
@@ -3061,7 +3065,15 @@ static void skylake_disable_primary_plan
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	int pipe = to_intel_crtc(crtc)->pipe;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+
+	/*
+	 * We only populate skl_results on watermark updates, and if the
+	 * plane's visiblity isn't actually changing neither is its watermarks.
+	 */
+	if (!to_intel_plane_state(crtc->primary->state)->visible)
+		skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0);
 
 	I915_WRITE(PLANE_CTL(pipe, 0), 0);
 	I915_WRITE(PLANE_SURF(pipe, 0), 0);
@@ -8995,6 +9007,24 @@ static void ironlake_compute_dpll(struct
 	if (intel_crtc_has_dp_encoder(crtc_state))
 		dpll |= DPLL_SDVO_HIGH_SPEED;
 
+	/*
+	 * The high speed IO clock is only really required for
+	 * SDVO/HDMI/DP, but we also enable it for CRT to make it
+	 * possible to share the DPLL between CRT and HDMI. Enabling
+	 * the clock needlessly does no real harm, except use up a
+	 * bit of power potentially.
+	 *
+	 * We'll limit this to IVB with 3 pipes, since it has only two
+	 * DPLLs and so DPLL sharing is the only way to get three pipes
+	 * driving PCH ports at the same time. On SNB we could do this,
+	 * and potentially avoid enabling the second DPLL, but it's not
+	 * clear if it''s a win or loss power wise. No point in doing
+	 * this on ILK at all since it has a fixed DPLL<->pipe mapping.
+	 */
+	if (INTEL_INFO(dev_priv)->num_pipes == 3 &&
+	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG))
+		dpll |= DPLL_SDVO_HIGH_SPEED;
+
 	/* compute bitmask from p1 value */
 	dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
 	/* also FPA1 */
@@ -10306,9 +10336,13 @@ static void i9xx_update_cursor(struct dr
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
 	int pipe = intel_crtc->pipe;
 	uint32_t cntl = 0;
 
+	if (INTEL_GEN(dev_priv) >= 9 && wm->dirty_pipes & drm_crtc_mask(crtc))
+		skl_write_cursor_wm(intel_crtc, wm);
+
 	if (plane_state && plane_state->visible) {
 		cntl = MCURSOR_GAMMA_ENABLE;
 		switch (plane_state->base.crtc_w) {
@@ -12956,16 +12990,23 @@ static void verify_wm_state(struct drm_c
 			  hw_entry->start, hw_entry->end);
 	}
 
-	/* cursor */
-	hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
-	sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
+	/*
+	 * cursor
+	 * If the cursor plane isn't active, we may not have updated it's ddb
+	 * allocation. In that case since the ddb allocation will be updated
+	 * once the plane becomes visible, we can skip this check
+	 */
+	if (intel_crtc->cursor_addr) {
+		hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
+		sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
 
-	if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
-		DRM_ERROR("mismatch in DDB state pipe %c cursor "
-			  "(expected (%u,%u), found (%u,%u))\n",
-			  pipe_name(pipe),
-			  sw_entry->start, sw_entry->end,
-			  hw_entry->start, hw_entry->end);
+		if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
+			DRM_ERROR("mismatch in DDB state pipe %c cursor "
+				  "(expected (%u,%u), found (%u,%u))\n",
+				  pipe_name(pipe),
+				  sw_entry->start, sw_entry->end,
+				  hw_entry->start, hw_entry->end);
+		}
 	}
 }
 
@@ -13671,6 +13712,111 @@ static bool needs_vblank_wait(struct int
 	return false;
 }
 
+static void intel_update_crtc(struct drm_crtc *crtc,
+			      struct drm_atomic_state *state,
+			      struct drm_crtc_state *old_crtc_state,
+			      unsigned int *crtc_vblank_mask)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->state);
+	bool modeset = needs_modeset(crtc->state);
+
+	if (modeset) {
+		update_scanline_offset(intel_crtc);
+		dev_priv->display.crtc_enable(crtc);
+	} else {
+		intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
+	}
+
+	if (drm_atomic_get_existing_plane_state(state, crtc->primary)) {
+		intel_fbc_enable(
+		    intel_crtc, pipe_config,
+		    to_intel_plane_state(crtc->primary->state));
+	}
+
+	drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
+
+	if (needs_vblank_wait(pipe_config))
+		*crtc_vblank_mask |= drm_crtc_mask(crtc);
+}
+
+static void intel_update_crtcs(struct drm_atomic_state *state,
+			       unsigned int *crtc_vblank_mask)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *old_crtc_state;
+	int i;
+
+	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+		if (!crtc->state->active)
+			continue;
+
+		intel_update_crtc(crtc, state, old_crtc_state,
+				  crtc_vblank_mask);
+	}
+}
+
+static void skl_update_crtcs(struct drm_atomic_state *state,
+			     unsigned int *crtc_vblank_mask)
+{
+	struct drm_device *dev = state->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *old_crtc_state;
+	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
+	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
+	unsigned int updated = 0;
+	bool progress;
+	enum pipe pipe;
+
+	/*
+	 * Whenever the number of active pipes changes, we need to make sure we
+	 * update the pipes in the right order so that their ddb allocations
+	 * never overlap with eachother inbetween CRTC updates. Otherwise we'll
+	 * cause pipe underruns and other bad stuff.
+	 */
+	do {
+		int i;
+		progress = false;
+
+		for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+			bool vbl_wait = false;
+			unsigned int cmask = drm_crtc_mask(crtc);
+			pipe = to_intel_crtc(crtc)->pipe;
+
+			if (updated & cmask || !crtc->state->active)
+				continue;
+			if (skl_ddb_allocation_overlaps(state, cur_ddb, new_ddb,
+							pipe))
+				continue;
+
+			updated |= cmask;
+
+			/*
+			 * If this is an already active pipe, it's DDB changed,
+			 * and this isn't the last pipe that needs updating
+			 * then we need to wait for a vblank to pass for the
+			 * new ddb allocation to take effect.
+			 */
+			if (!skl_ddb_allocation_equals(cur_ddb, new_ddb, pipe) &&
+			    !crtc->state->active_changed &&
+			    intel_state->wm_results.dirty_pipes != updated)
+				vbl_wait = true;
+
+			intel_update_crtc(crtc, state, old_crtc_state,
+					  crtc_vblank_mask);
+
+			if (vbl_wait)
+				intel_wait_for_vblank(dev, pipe);
+
+			progress = true;
+		}
+	} while (progress);
+}
+
 static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 {
 	struct drm_device *dev = state->dev;
@@ -13763,23 +13909,15 @@ static void intel_atomic_commit_tail(str
 		 * SKL workaround: bspec recommends we disable the SAGV when we
 		 * have more then one pipe enabled
 		 */
-		if (IS_SKYLAKE(dev_priv) && !skl_can_enable_sagv(state))
-			skl_disable_sagv(dev_priv);
+		if (!intel_can_enable_sagv(state))
+			intel_disable_sagv(dev_priv);
 
 		intel_modeset_verify_disabled(dev);
 	}
 
-	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
+	/* Complete the events for pipes that have now been disabled */
 	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
-		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 		bool modeset = needs_modeset(crtc->state);
-		struct intel_crtc_state *pipe_config =
-			to_intel_crtc_state(crtc->state);
-
-		if (modeset && crtc->state->active) {
-			update_scanline_offset(to_intel_crtc(crtc));
-			dev_priv->display.crtc_enable(crtc);
-		}
 
 		/* Complete events for now disable pipes here. */
 		if (modeset && !crtc->state->active && crtc->state->event) {
@@ -13789,21 +13927,11 @@ static void intel_atomic_commit_tail(str
 
 			crtc->state->event = NULL;
 		}
-
-		if (!modeset)
-			intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
-
-		if (crtc->state->active &&
-		    drm_atomic_get_existing_plane_state(state, crtc->primary))
-			intel_fbc_enable(intel_crtc, pipe_config, to_intel_plane_state(crtc->primary->state));
-
-		if (crtc->state->active)
-			drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
-
-		if (pipe_config->base.active && needs_vblank_wait(pipe_config))
-			crtc_vblank_mask |= 1 << i;
 	}
 
+	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
+	dev_priv->display.update_crtcs(state, &crtc_vblank_mask);
+
 	/* FIXME: We should call drm_atomic_helper_commit_hw_done() here
 	 * already, but still need the state for the delayed optimization. To
 	 * fix this:
@@ -13839,9 +13967,8 @@ static void intel_atomic_commit_tail(str
 		intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state);
 	}
 
-	if (IS_SKYLAKE(dev_priv) && intel_state->modeset &&
-	    skl_can_enable_sagv(state))
-		skl_enable_sagv(dev_priv);
+	if (intel_state->modeset && intel_can_enable_sagv(state))
+		intel_enable_sagv(dev_priv);
 
 	drm_atomic_helper_commit_hw_done(state);
 
@@ -14221,10 +14348,12 @@ static void intel_begin_crtc_commit(stru
 				    struct drm_crtc_state *old_crtc_state)
 {
 	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *old_intel_state =
 		to_intel_crtc_state(old_crtc_state);
 	bool modeset = needs_modeset(crtc->state);
+	enum pipe pipe = intel_crtc->pipe;
 
 	/* Perform vblank evasion around commit operation */
 	intel_pipe_update_start(intel_crtc);
@@ -14239,8 +14368,12 @@ static void intel_begin_crtc_commit(stru
 
 	if (to_intel_crtc_state(crtc->state)->update_pipe)
 		intel_update_pipe_config(intel_crtc, old_intel_state);
-	else if (INTEL_INFO(dev)->gen >= 9)
+	else if (INTEL_GEN(dev_priv) >= 9) {
 		skl_detach_scalers(intel_crtc);
+
+		I915_WRITE(PIPE_WM_LINETIME(pipe),
+			   dev_priv->wm.skl_hw.wm_linetime[pipe]);
+	}
 }
 
 static void intel_finish_crtc_commit(struct drm_crtc *crtc,
@@ -15347,6 +15480,11 @@ void intel_init_display_hooks(struct drm
 			skl_modeset_calc_cdclk;
 	}
 
+	if (dev_priv->info.gen >= 9)
+		dev_priv->display.update_crtcs = skl_update_crtcs;
+	else
+		dev_priv->display.update_crtcs = intel_update_crtcs;
+
 	switch (INTEL_INFO(dev_priv)->gen) {
 	case 2:
 		dev_priv->display.queue_flip = intel_gen2_queue_flip;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_dp.c linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_dp.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_dp.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_dp.c	2016-10-31 07:26:46.000000000 -0400
@@ -4148,7 +4148,7 @@ static bool bxt_digital_port_connected(s
  *
  * Return %true if @port is connected, %false otherwise.
  */
-bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+static bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
 					 struct intel_digital_port *port)
 {
 	if (HAS_PCH_IBX(dev_priv))
@@ -4207,7 +4207,7 @@ intel_dp_unset_edid(struct intel_dp *int
 	intel_dp->has_audio = false;
 }
 
-static void
+static enum drm_connector_status
 intel_dp_long_pulse(struct intel_connector *intel_connector)
 {
 	struct drm_connector *connector = &intel_connector->base;
@@ -4232,7 +4232,7 @@ intel_dp_long_pulse(struct intel_connect
 	else
 		status = connector_status_disconnected;
 
-	if (status != connector_status_connected) {
+	if (status == connector_status_disconnected) {
 		intel_dp->compliance_test_active = 0;
 		intel_dp->compliance_test_type = 0;
 		intel_dp->compliance_test_data = 0;
@@ -4284,8 +4284,8 @@ intel_dp_long_pulse(struct intel_connect
 	intel_dp->aux.i2c_defer_count = 0;
 
 	intel_dp_set_edid(intel_dp);
-
-	status = connector_status_connected;
+	if (is_edp(intel_dp) || intel_connector->detect_edid)
+		status = connector_status_connected;
 	intel_dp->detect_done = true;
 
 	/* Try to read the source of the interrupt */
@@ -4303,12 +4303,11 @@ intel_dp_long_pulse(struct intel_connect
 	}
 
 out:
-	if ((status != connector_status_connected) &&
-	    (intel_dp->is_mst == false))
+	if (status != connector_status_connected && !intel_dp->is_mst)
 		intel_dp_unset_edid(intel_dp);
 
 	intel_display_power_put(to_i915(dev), power_domain);
-	return;
+	return status;
 }
 
 static enum drm_connector_status
@@ -4317,7 +4316,7 @@ intel_dp_detect(struct drm_connector *co
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct intel_encoder *intel_encoder = &intel_dig_port->base;
-	struct intel_connector *intel_connector = to_intel_connector(connector);
+	enum drm_connector_status status = connector->status;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, connector->name);
@@ -4332,14 +4331,11 @@ intel_dp_detect(struct drm_connector *co
 
 	/* If full detect is not performed yet, do a full detect */
 	if (!intel_dp->detect_done)
-		intel_dp_long_pulse(intel_dp->attached_connector);
+		status = intel_dp_long_pulse(intel_dp->attached_connector);
 
 	intel_dp->detect_done = false;
 
-	if (is_edp(intel_dp) || intel_connector->detect_edid)
-		return connector_status_connected;
-	else
-		return connector_status_disconnected;
+	return status;
 }
 
 static void
@@ -4696,36 +4692,34 @@ intel_dp_hpd_pulse(struct intel_digital_
 		      port_name(intel_dig_port->port),
 		      long_hpd ? "long" : "short");
 
+	if (long_hpd) {
+		intel_dp->detect_done = false;
+		return IRQ_NONE;
+	}
+
 	power_domain = intel_display_port_aux_power_domain(intel_encoder);
 	intel_display_power_get(dev_priv, power_domain);
 
-	if (long_hpd) {
-		intel_dp_long_pulse(intel_dp->attached_connector);
-		if (intel_dp->is_mst)
-			ret = IRQ_HANDLED;
-		goto put_power;
-
-	} else {
-		if (intel_dp->is_mst) {
-			if (intel_dp_check_mst_status(intel_dp) == -EINVAL) {
-				/*
-				 * If we were in MST mode, and device is not
-				 * there, get out of MST mode
-				 */
-				DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n",
-					      intel_dp->is_mst, intel_dp->mst_mgr.mst_state);
-				intel_dp->is_mst = false;
-				drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
-								intel_dp->is_mst);
-				goto put_power;
-			}
+	if (intel_dp->is_mst) {
+		if (intel_dp_check_mst_status(intel_dp) == -EINVAL) {
+			/*
+			 * If we were in MST mode, and device is not
+			 * there, get out of MST mode
+			 */
+			DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n",
+				      intel_dp->is_mst, intel_dp->mst_mgr.mst_state);
+			intel_dp->is_mst = false;
+			drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
+							intel_dp->is_mst);
+			intel_dp->detect_done = false;
+			goto put_power;
 		}
+	}
 
-		if (!intel_dp->is_mst) {
-			if (!intel_dp_short_pulse(intel_dp)) {
-				intel_dp_long_pulse(intel_dp->attached_connector);
-				goto put_power;
-			}
+	if (!intel_dp->is_mst) {
+		if (!intel_dp_short_pulse(intel_dp)) {
+			intel_dp->detect_done = false;
+			goto put_power;
 		}
 	}
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_drv.h linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_drv.h
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_drv.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_drv.h	2016-10-31 07:26:46.000000000 -0400
@@ -236,6 +236,7 @@ struct intel_panel {
 		bool enabled;
 		bool combination_mode;	/* gen 2/4 only */
 		bool active_low_pwm;
+		bool alternate_pwm_increment;	/* lpt+ */
 
 		/* PWM chip */
 		bool util_pin_active_low;	/* bxt+ */
@@ -1387,8 +1388,6 @@ void intel_edp_drrs_disable(struct intel
 void intel_edp_drrs_invalidate(struct drm_device *dev,
 		unsigned frontbuffer_bits);
 void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
-bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
-					 struct intel_digital_port *port);
 
 void
 intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
@@ -1716,9 +1715,21 @@ void ilk_wm_get_hw_state(struct drm_devi
 void skl_wm_get_hw_state(struct drm_device *dev);
 void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
 			  struct skl_ddb_allocation *ddb /* out */);
-bool skl_can_enable_sagv(struct drm_atomic_state *state);
-int skl_enable_sagv(struct drm_i915_private *dev_priv);
-int skl_disable_sagv(struct drm_i915_private *dev_priv);
+bool intel_can_enable_sagv(struct drm_atomic_state *state);
+int intel_enable_sagv(struct drm_i915_private *dev_priv);
+int intel_disable_sagv(struct drm_i915_private *dev_priv);
+bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old,
+			       const struct skl_ddb_allocation *new,
+			       enum pipe pipe);
+bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state,
+				 const struct skl_ddb_allocation *old,
+				 const struct skl_ddb_allocation *new,
+				 enum pipe pipe);
+void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
+			 const struct skl_wm_values *wm);
+void skl_write_plane_wm(struct intel_crtc *intel_crtc,
+			const struct skl_wm_values *wm,
+			int plane);
 uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config);
 bool ilk_disable_lp_wm(struct drm_device *dev);
 int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_hdmi.c linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_hdmi.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_hdmi.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_hdmi.c	2016-10-31 07:26:46.000000000 -0400
@@ -1422,24 +1422,22 @@ intel_hdmi_dp_dual_mode_detect(struct dr
 }
 
 static bool
-intel_hdmi_set_edid(struct drm_connector *connector, bool force)
+intel_hdmi_set_edid(struct drm_connector *connector)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
-	struct edid *edid = NULL;
+	struct edid *edid;
 	bool connected = false;
 
-	if (force) {
-		intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
+	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
-		edid = drm_get_edid(connector,
-				    intel_gmbus_get_adapter(dev_priv,
-				    intel_hdmi->ddc_bus));
+	edid = drm_get_edid(connector,
+			    intel_gmbus_get_adapter(dev_priv,
+			    intel_hdmi->ddc_bus));
 
-		intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
+	intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
 
-		intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
-	}
+	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
 	to_intel_connector(connector)->detect_edid = edid;
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
@@ -1465,37 +1463,16 @@ static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector, bool force)
 {
 	enum drm_connector_status status;
-	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
-	bool live_status = false;
-	unsigned int try;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, connector->name);
 
 	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
-	for (try = 0; !live_status && try < 9; try++) {
-		if (try)
-			msleep(10);
-		live_status = intel_digital_port_connected(dev_priv,
-				hdmi_to_dig_port(intel_hdmi));
-	}
-
-	if (!live_status) {
-		DRM_DEBUG_KMS("HDMI live status down\n");
-		/*
-		 * Live status register is not reliable on all intel platforms.
-		 * So consider live_status only for certain platforms, for
-		 * others, read EDID to determine presence of sink.
-		 */
-		if (INTEL_INFO(dev_priv)->gen < 7 || IS_IVYBRIDGE(dev_priv))
-			live_status = true;
-	}
-
 	intel_hdmi_unset_edid(connector);
 
-	if (intel_hdmi_set_edid(connector, live_status)) {
+	if (intel_hdmi_set_edid(connector)) {
 		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
 		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
@@ -1521,7 +1498,7 @@ intel_hdmi_force(struct drm_connector *c
 	if (connector->status != connector_status_connected)
 		return;
 
-	intel_hdmi_set_edid(connector, true);
+	intel_hdmi_set_edid(connector);
 	hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 }
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_panel.c linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_panel.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_panel.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_panel.c	2016-10-31 07:26:46.000000000 -0400
@@ -841,7 +841,7 @@ static void lpt_enable_backlight(struct
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_panel *panel = &connector->panel;
-	u32 pch_ctl1, pch_ctl2;
+	u32 pch_ctl1, pch_ctl2, schicken;
 
 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
 	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
@@ -850,6 +850,22 @@ static void lpt_enable_backlight(struct
 		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
 	}
 
+	if (HAS_PCH_LPT(dev_priv)) {
+		schicken = I915_READ(SOUTH_CHICKEN2);
+		if (panel->backlight.alternate_pwm_increment)
+			schicken |= LPT_PWM_GRANULARITY;
+		else
+			schicken &= ~LPT_PWM_GRANULARITY;
+		I915_WRITE(SOUTH_CHICKEN2, schicken);
+	} else {
+		schicken = I915_READ(SOUTH_CHICKEN1);
+		if (panel->backlight.alternate_pwm_increment)
+			schicken |= SPT_PWM_GRANULARITY;
+		else
+			schicken &= ~SPT_PWM_GRANULARITY;
+		I915_WRITE(SOUTH_CHICKEN1, schicken);
+	}
+
 	pch_ctl2 = panel->backlight.max << 16;
 	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
 
@@ -1242,10 +1258,10 @@ static u32 bxt_hz_to_pwm(struct intel_co
  */
 static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
 {
-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
 	u32 mul;
 
-	if (I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY)
+	if (panel->backlight.alternate_pwm_increment)
 		mul = 128;
 	else
 		mul = 16;
@@ -1261,9 +1277,10 @@ static u32 spt_hz_to_pwm(struct intel_co
 static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_panel *panel = &connector->panel;
 	u32 mul, clock;
 
-	if (I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY)
+	if (panel->backlight.alternate_pwm_increment)
 		mul = 16;
 	else
 		mul = 128;
@@ -1414,6 +1431,13 @@ static int lpt_setup_backlight(struct in
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_panel *panel = &connector->panel;
 	u32 pch_ctl1, pch_ctl2, val;
+	bool alt;
+
+	if (HAS_PCH_LPT(dev_priv))
+		alt = I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
+	else
+		alt = I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
+	panel->backlight.alternate_pwm_increment = alt;
 
 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
 	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_pm.c linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_pm.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_pm.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_pm.c	2016-10-31 07:26:46.000000000 -0400
@@ -2119,32 +2119,34 @@ static void intel_read_wm_latency(struct
 				GEN9_MEM_LATENCY_LEVEL_MASK;
 
 		/*
+		 * If a level n (n > 1) has a 0us latency, all levels m (m >= n)
+		 * need to be disabled. We make sure to sanitize the values out
+		 * of the punit to satisfy this requirement.
+		 */
+		for (level = 1; level <= max_level; level++) {
+			if (wm[level] == 0) {
+				for (i = level + 1; i <= max_level; i++)
+					wm[i] = 0;
+				break;
+			}
+		}
+
+		/*
 		 * WaWmMemoryReadLatency:skl
 		 *
 		 * punit doesn't take into account the read latency so we need
-		 * to add 2us to the various latency levels we retrieve from
-		 * the punit.
-		 *   - W0 is a bit special in that it's the only level that
-		 *   can't be disabled if we want to have display working, so
-		 *   we always add 2us there.
-		 *   - For levels >=1, punit returns 0us latency when they are
-		 *   disabled, so we respect that and don't add 2us then
-		 *
-		 * Additionally, if a level n (n > 1) has a 0us latency, all
-		 * levels m (m >= n) need to be disabled. We make sure to
-		 * sanitize the values out of the punit to satisfy this
-		 * requirement.
+		 * to add 2us to the various latency levels we retrieve from the
+		 * punit when level 0 response data us 0us.
 		 */
-		wm[0] += 2;
-		for (level = 1; level <= max_level; level++)
-			if (wm[level] != 0)
+		if (wm[0] == 0) {
+			wm[0] += 2;
+			for (level = 1; level <= max_level; level++) {
+				if (wm[level] == 0)
+					break;
 				wm[level] += 2;
-			else {
-				for (i = level + 1; i <= max_level; i++)
-					wm[i] = 0;
-
-				break;
 			}
+		}
+
 	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
 		uint64_t sskpd = I915_READ64(MCH_SSKPD);
 
@@ -2876,6 +2878,19 @@ skl_wm_plane_id(const struct intel_plane
 	}
 }
 
+static bool
+intel_has_sagv(struct drm_i915_private *dev_priv)
+{
+	if (IS_KABYLAKE(dev_priv))
+		return true;
+
+	if (IS_SKYLAKE(dev_priv) &&
+	    dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED)
+		return true;
+
+	return false;
+}
+
 /*
  * SAGV dynamically adjusts the system agent voltage and clock frequencies
  * depending on power and performance requirements. The display engine access
@@ -2888,12 +2903,14 @@ skl_wm_plane_id(const struct intel_plane
  *  - We're not using an interlaced display configuration
  */
 int
-skl_enable_sagv(struct drm_i915_private *dev_priv)
+intel_enable_sagv(struct drm_i915_private *dev_priv)
 {
 	int ret;
 
-	if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED ||
-	    dev_priv->skl_sagv_status == I915_SKL_SAGV_ENABLED)
+	if (!intel_has_sagv(dev_priv))
+		return 0;
+
+	if (dev_priv->sagv_status == I915_SAGV_ENABLED)
 		return 0;
 
 	DRM_DEBUG_KMS("Enabling the SAGV\n");
@@ -2909,21 +2926,21 @@ skl_enable_sagv(struct drm_i915_private
 	 * Some skl systems, pre-release machines in particular,
 	 * don't actually have an SAGV.
 	 */
-	if (ret == -ENXIO) {
+	if (IS_SKYLAKE(dev_priv) && ret == -ENXIO) {
 		DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n");
-		dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED;
+		dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
 		return 0;
 	} else if (ret < 0) {
 		DRM_ERROR("Failed to enable the SAGV\n");
 		return ret;
 	}
 
-	dev_priv->skl_sagv_status = I915_SKL_SAGV_ENABLED;
+	dev_priv->sagv_status = I915_SAGV_ENABLED;
 	return 0;
 }
 
 static int
-skl_do_sagv_disable(struct drm_i915_private *dev_priv)
+intel_do_sagv_disable(struct drm_i915_private *dev_priv)
 {
 	int ret;
 	uint32_t temp = GEN9_SAGV_DISABLE;
@@ -2937,19 +2954,21 @@ skl_do_sagv_disable(struct drm_i915_priv
 }
 
 int
-skl_disable_sagv(struct drm_i915_private *dev_priv)
+intel_disable_sagv(struct drm_i915_private *dev_priv)
 {
 	int ret, result;
 
-	if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED ||
-	    dev_priv->skl_sagv_status == I915_SKL_SAGV_DISABLED)
+	if (!intel_has_sagv(dev_priv))
+		return 0;
+
+	if (dev_priv->sagv_status == I915_SAGV_DISABLED)
 		return 0;
 
 	DRM_DEBUG_KMS("Disabling the SAGV\n");
 	mutex_lock(&dev_priv->rps.hw_lock);
 
 	/* bspec says to keep retrying for at least 1 ms */
-	ret = wait_for(result = skl_do_sagv_disable(dev_priv), 1);
+	ret = wait_for(result = intel_do_sagv_disable(dev_priv), 1);
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
 	if (ret == -ETIMEDOUT) {
@@ -2961,20 +2980,20 @@ skl_disable_sagv(struct drm_i915_private
 	 * Some skl systems, pre-release machines in particular,
 	 * don't actually have an SAGV.
 	 */
-	if (result == -ENXIO) {
+	if (IS_SKYLAKE(dev_priv) && result == -ENXIO) {
 		DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n");
-		dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED;
+		dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
 		return 0;
 	} else if (result < 0) {
 		DRM_ERROR("Failed to disable the SAGV\n");
 		return result;
 	}
 
-	dev_priv->skl_sagv_status = I915_SKL_SAGV_DISABLED;
+	dev_priv->sagv_status = I915_SAGV_DISABLED;
 	return 0;
 }
 
-bool skl_can_enable_sagv(struct drm_atomic_state *state)
+bool intel_can_enable_sagv(struct drm_atomic_state *state)
 {
 	struct drm_device *dev = state->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
@@ -2983,6 +3002,9 @@ bool skl_can_enable_sagv(struct drm_atom
 	enum pipe pipe;
 	int level, plane;
 
+	if (!intel_has_sagv(dev_priv))
+		return false;
+
 	/*
 	 * SKL workaround: bspec recommends we disable the SAGV when we have
 	 * more then one pipe enabled
@@ -3473,29 +3495,14 @@ static uint32_t skl_wm_method1(uint32_t
 }
 
 static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
-			       uint32_t horiz_pixels, uint8_t cpp,
-			       uint64_t tiling, uint32_t latency)
+			       uint32_t latency, uint32_t plane_blocks_per_line)
 {
 	uint32_t ret;
-	uint32_t plane_bytes_per_line, plane_blocks_per_line;
 	uint32_t wm_intermediate_val;
 
 	if (latency == 0)
 		return UINT_MAX;
 
-	plane_bytes_per_line = horiz_pixels * cpp;
-
-	if (tiling == I915_FORMAT_MOD_Y_TILED ||
-	    tiling == I915_FORMAT_MOD_Yf_TILED) {
-		plane_bytes_per_line *= 4;
-		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
-		plane_blocks_per_line /= 4;
-	} else if (tiling == DRM_FORMAT_MOD_NONE) {
-		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1;
-	} else {
-		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
-	}
-
 	wm_intermediate_val = latency * pixel_rate;
 	ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
 				plane_blocks_per_line;
@@ -3546,6 +3553,7 @@ static int skl_compute_plane_wm(const st
 	uint8_t cpp;
 	uint32_t width = 0, height = 0;
 	uint32_t plane_pixel_rate;
+	uint32_t y_tile_minimum, y_min_scanlines;
 
 	if (latency == 0 || !cstate->base.active || !intel_pstate->visible) {
 		*enabled = false;
@@ -3561,38 +3569,51 @@ static int skl_compute_plane_wm(const st
 	cpp = drm_format_plane_cpp(fb->pixel_format, 0);
 	plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate);
 
+	if (intel_rotation_90_or_270(pstate->rotation)) {
+		int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
+			drm_format_plane_cpp(fb->pixel_format, 1) :
+			drm_format_plane_cpp(fb->pixel_format, 0);
+
+		switch (cpp) {
+		case 1:
+			y_min_scanlines = 16;
+			break;
+		case 2:
+			y_min_scanlines = 8;
+			break;
+		default:
+			WARN(1, "Unsupported pixel depth for rotation");
+		case 4:
+			y_min_scanlines = 4;
+			break;
+		}
+	} else {
+		y_min_scanlines = 4;
+	}
+
+	plane_bytes_per_line = width * cpp;
+	if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+	    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+		plane_blocks_per_line =
+		      DIV_ROUND_UP(plane_bytes_per_line * y_min_scanlines, 512);
+		plane_blocks_per_line /= y_min_scanlines;
+	} else if (fb->modifier[0] == DRM_FORMAT_MOD_NONE) {
+		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512)
+					+ 1;
+	} else {
+		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+	}
+
 	method1 = skl_wm_method1(plane_pixel_rate, cpp, latency);
 	method2 = skl_wm_method2(plane_pixel_rate,
 				 cstate->base.adjusted_mode.crtc_htotal,
-				 width,
-				 cpp,
-				 fb->modifier[0],
-				 latency);
+				 latency,
+				 plane_blocks_per_line);
 
-	plane_bytes_per_line = width * cpp;
-	plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+	y_tile_minimum = plane_blocks_per_line * y_min_scanlines;
 
 	if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
 	    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
-		uint32_t min_scanlines = 4;
-		uint32_t y_tile_minimum;
-		if (intel_rotation_90_or_270(pstate->rotation)) {
-			int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
-				drm_format_plane_cpp(fb->pixel_format, 1) :
-				drm_format_plane_cpp(fb->pixel_format, 0);
-
-			switch (cpp) {
-			case 1:
-				min_scanlines = 16;
-				break;
-			case 2:
-				min_scanlines = 8;
-				break;
-			case 8:
-				WARN(1, "Unsupported pixel depth for rotation");
-			}
-		}
-		y_tile_minimum = plane_blocks_per_line * min_scanlines;
 		selected_result = max(method2, y_tile_minimum);
 	} else {
 		if ((ddb_allocation / plane_blocks_per_line) >= 1)
@@ -3606,10 +3627,12 @@ static int skl_compute_plane_wm(const st
 
 	if (level >= 1 && level <= 7) {
 		if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
-		    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)
-			res_lines += 4;
-		else
+		    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+			res_blocks += y_tile_minimum;
+			res_lines += y_min_scanlines;
+		} else {
 			res_blocks++;
+		}
 	}
 
 	if (res_blocks >= ddb_allocation || res_lines > 31) {
@@ -3828,183 +3851,82 @@ static void skl_ddb_entry_write(struct d
 		I915_WRITE(reg, 0);
 }
 
-static void skl_write_wm_values(struct drm_i915_private *dev_priv,
-				const struct skl_wm_values *new)
+void skl_write_plane_wm(struct intel_crtc *intel_crtc,
+			const struct skl_wm_values *wm,
+			int plane)
 {
-	struct drm_device *dev = &dev_priv->drm;
-	struct intel_crtc *crtc;
-
-	for_each_intel_crtc(dev, crtc) {
-		int i, level, max_level = ilk_wm_max_level(dev);
-		enum pipe pipe = crtc->pipe;
-
-		if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0)
-			continue;
-		if (!crtc->active)
-			continue;
-
-		I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]);
-
-		for (level = 0; level <= max_level; level++) {
-			for (i = 0; i < intel_num_planes(crtc); i++)
-				I915_WRITE(PLANE_WM(pipe, i, level),
-					   new->plane[pipe][i][level]);
-			I915_WRITE(CUR_WM(pipe, level),
-				   new->plane[pipe][PLANE_CURSOR][level]);
-		}
-		for (i = 0; i < intel_num_planes(crtc); i++)
-			I915_WRITE(PLANE_WM_TRANS(pipe, i),
-				   new->plane_trans[pipe][i]);
-		I915_WRITE(CUR_WM_TRANS(pipe),
-			   new->plane_trans[pipe][PLANE_CURSOR]);
-
-		for (i = 0; i < intel_num_planes(crtc); i++) {
-			skl_ddb_entry_write(dev_priv,
-					    PLANE_BUF_CFG(pipe, i),
-					    &new->ddb.plane[pipe][i]);
-			skl_ddb_entry_write(dev_priv,
-					    PLANE_NV12_BUF_CFG(pipe, i),
-					    &new->ddb.y_plane[pipe][i]);
-		}
+	struct drm_crtc *crtc = &intel_crtc->base;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	int level, max_level = ilk_wm_max_level(dev);
+	enum pipe pipe = intel_crtc->pipe;
 
-		skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
-				    &new->ddb.plane[pipe][PLANE_CURSOR]);
+	for (level = 0; level <= max_level; level++) {
+		I915_WRITE(PLANE_WM(pipe, plane, level),
+			   wm->plane[pipe][plane][level]);
 	}
-}
+	I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm->plane_trans[pipe][plane]);
 
-/*
- * When setting up a new DDB allocation arrangement, we need to correctly
- * sequence the times at which the new allocations for the pipes are taken into
- * account or we'll have pipes fetching from space previously allocated to
- * another pipe.
- *
- * Roughly the sequence looks like:
- *  1. re-allocate the pipe(s) with the allocation being reduced and not
- *     overlapping with a previous light-up pipe (another way to put it is:
- *     pipes with their new allocation strickly included into their old ones).
- *  2. re-allocate the other pipes that get their allocation reduced
- *  3. allocate the pipes having their allocation increased
- *
- * Steps 1. and 2. are here to take care of the following case:
- * - Initially DDB looks like this:
- *     |   B    |   C    |
- * - enable pipe A.
- * - pipe B has a reduced DDB allocation that overlaps with the old pipe C
- *   allocation
- *     |  A  |  B  |  C  |
- *
- * We need to sequence the re-allocation: C, B, A (and not B, C, A).
- */
+	skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane),
+			    &wm->ddb.plane[pipe][plane]);
+	skl_ddb_entry_write(dev_priv, PLANE_NV12_BUF_CFG(pipe, plane),
+			    &wm->ddb.y_plane[pipe][plane]);
+}
 
-static void
-skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, int pass)
+void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
+			 const struct skl_wm_values *wm)
 {
-	int plane;
-
-	DRM_DEBUG_KMS("flush pipe %c (pass %d)\n", pipe_name(pipe), pass);
+	struct drm_crtc *crtc = &intel_crtc->base;
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	int level, max_level = ilk_wm_max_level(dev);
+	enum pipe pipe = intel_crtc->pipe;
 
-	for_each_plane(dev_priv, pipe, plane) {
-		I915_WRITE(PLANE_SURF(pipe, plane),
-			   I915_READ(PLANE_SURF(pipe, plane)));
+	for (level = 0; level <= max_level; level++) {
+		I915_WRITE(CUR_WM(pipe, level),
+			   wm->plane[pipe][PLANE_CURSOR][level]);
 	}
-	I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
+	I915_WRITE(CUR_WM_TRANS(pipe), wm->plane_trans[pipe][PLANE_CURSOR]);
+
+	skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
+			    &wm->ddb.plane[pipe][PLANE_CURSOR]);
 }
 
-static bool
-skl_ddb_allocation_included(const struct skl_ddb_allocation *old,
-			    const struct skl_ddb_allocation *new,
-			    enum pipe pipe)
+bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old,
+			       const struct skl_ddb_allocation *new,
+			       enum pipe pipe)
 {
-	uint16_t old_size, new_size;
-
-	old_size = skl_ddb_entry_size(&old->pipe[pipe]);
-	new_size = skl_ddb_entry_size(&new->pipe[pipe]);
-
-	return old_size != new_size &&
-	       new->pipe[pipe].start >= old->pipe[pipe].start &&
-	       new->pipe[pipe].end <= old->pipe[pipe].end;
+	return new->pipe[pipe].start == old->pipe[pipe].start &&
+	       new->pipe[pipe].end == old->pipe[pipe].end;
 }
 
-static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
-				struct skl_wm_values *new_values)
+static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a,
+					   const struct skl_ddb_entry *b)
 {
-	struct drm_device *dev = &dev_priv->drm;
-	struct skl_ddb_allocation *cur_ddb, *new_ddb;
-	bool reallocated[I915_MAX_PIPES] = {};
-	struct intel_crtc *crtc;
-	enum pipe pipe;
-
-	new_ddb = &new_values->ddb;
-	cur_ddb = &dev_priv->wm.skl_hw.ddb;
-
-	/*
-	 * First pass: flush the pipes with the new allocation contained into
-	 * the old space.
-	 *
-	 * We'll wait for the vblank on those pipes to ensure we can safely
-	 * re-allocate the freed space without this pipe fetching from it.
-	 */
-	for_each_intel_crtc(dev, crtc) {
-		if (!crtc->active)
-			continue;
-
-		pipe = crtc->pipe;
-
-		if (!skl_ddb_allocation_included(cur_ddb, new_ddb, pipe))
-			continue;
-
-		skl_wm_flush_pipe(dev_priv, pipe, 1);
-		intel_wait_for_vblank(dev, pipe);
-
-		reallocated[pipe] = true;
-	}
-
+	return a->start < b->end && b->start < a->end;
+}
 
-	/*
-	 * Second pass: flush the pipes that are having their allocation
-	 * reduced, but overlapping with a previous allocation.
-	 *
-	 * Here as well we need to wait for the vblank to make sure the freed
-	 * space is not used anymore.
-	 */
-	for_each_intel_crtc(dev, crtc) {
-		if (!crtc->active)
-			continue;
+bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state,
+				 const struct skl_ddb_allocation *old,
+				 const struct skl_ddb_allocation *new,
+				 enum pipe pipe)
+{
+	struct drm_device *dev = state->dev;
+	struct intel_crtc *intel_crtc;
+	enum pipe otherp;
 
-		pipe = crtc->pipe;
+	for_each_intel_crtc(dev, intel_crtc) {
+		otherp = intel_crtc->pipe;
 
-		if (reallocated[pipe])
+		if (otherp == pipe)
 			continue;
 
-		if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) <
-		    skl_ddb_entry_size(&cur_ddb->pipe[pipe])) {
-			skl_wm_flush_pipe(dev_priv, pipe, 2);
-			intel_wait_for_vblank(dev, pipe);
-			reallocated[pipe] = true;
-		}
+		if (skl_ddb_entries_overlap(&new->pipe[pipe],
+					    &old->pipe[otherp]))
+			return true;
 	}
 
-	/*
-	 * Third pass: flush the pipes that got more space allocated.
-	 *
-	 * We don't need to actively wait for the update here, next vblank
-	 * will just get more DDB space with the correct WM values.
-	 */
-	for_each_intel_crtc(dev, crtc) {
-		if (!crtc->active)
-			continue;
-
-		pipe = crtc->pipe;
-
-		/*
-		 * At this point, only the pipes more space than before are
-		 * left to re-allocate.
-		 */
-		if (reallocated[pipe])
-			continue;
-
-		skl_wm_flush_pipe(dev_priv, pipe, 3);
-	}
+	return false;
 }
 
 static int skl_update_pipe_wm(struct drm_crtc_state *cstate,
@@ -4041,6 +3963,41 @@ pipes_modified(struct drm_atomic_state *
 	return ret;
 }
 
+int
+skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
+{
+	struct drm_atomic_state *state = cstate->base.state;
+	struct drm_device *dev = state->dev;
+	struct drm_crtc *crtc = cstate->base.crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
+	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
+	struct drm_plane_state *plane_state;
+	struct drm_plane *plane;
+	enum pipe pipe = intel_crtc->pipe;
+	int id;
+
+	WARN_ON(!drm_atomic_get_existing_crtc_state(state, crtc));
+
+	drm_for_each_plane_mask(plane, dev, crtc->state->plane_mask) {
+		id = skl_wm_plane_id(to_intel_plane(plane));
+
+		if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][id],
+					&new_ddb->plane[pipe][id]) &&
+		    skl_ddb_entry_equal(&cur_ddb->y_plane[pipe][id],
+					&new_ddb->y_plane[pipe][id]))
+			continue;
+
+		plane_state = drm_atomic_get_plane_state(state, plane);
+		if (IS_ERR(plane_state))
+			return PTR_ERR(plane_state);
+	}
+
+	return 0;
+}
+
 static int
 skl_compute_ddb(struct drm_atomic_state *state)
 {
@@ -4105,6 +4062,10 @@ skl_compute_ddb(struct drm_atomic_state
 		if (ret)
 			return ret;
 
+		ret = skl_ddb_add_affected_planes(cstate);
+		if (ret)
+			return ret;
+
 		ret = drm_atomic_add_affected_planes(state, &intel_crtc->base);
 		if (ret)
 			return ret;
@@ -4206,7 +4167,7 @@ static void skl_update_wm(struct drm_crt
 	struct skl_wm_values *hw_vals = &dev_priv->wm.skl_hw;
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
 	struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
-	int pipe;
+	enum pipe pipe = intel_crtc->pipe;
 
 	if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0)
 		return;
@@ -4215,15 +4176,22 @@ static void skl_update_wm(struct drm_crt
 
 	mutex_lock(&dev_priv->wm.wm_mutex);
 
-	skl_write_wm_values(dev_priv, results);
-	skl_flush_wm_values(dev_priv, results);
-
 	/*
-	 * Store the new configuration (but only for the pipes that have
-	 * changed; the other values weren't recomputed).
+	 * If this pipe isn't active already, we're going to be enabling it
+	 * very soon. Since it's safe to update a pipe's ddb allocation while
+	 * the pipe's shut off, just do so here. Already active pipes will have
+	 * their watermarks updated once we update their planes.
 	 */
-	for_each_pipe_masked(dev_priv, pipe, results->dirty_pipes)
-		skl_copy_wm_for_pipe(hw_vals, results, pipe);
+	if (crtc->state->active_changed) {
+		int plane;
+
+		for (plane = 0; plane < intel_num_planes(intel_crtc); plane++)
+			skl_write_plane_wm(intel_crtc, results, plane);
+
+		skl_write_cursor_wm(intel_crtc, results);
+	}
+
+	skl_copy_wm_for_pipe(hw_vals, results, pipe);
 
 	mutex_unlock(&dev_priv->wm.wm_mutex);
 }
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_sprite.c linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_sprite.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_sprite.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_sprite.c	2016-10-31 07:26:46.000000000 -0400
@@ -203,6 +203,9 @@ skl_update_plane(struct drm_plane *drm_p
 	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
 	struct drm_framebuffer *fb = plane_state->base.fb;
 	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
+	struct drm_crtc *crtc = crtc_state->base.crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	const int pipe = intel_plane->pipe;
 	const int plane = intel_plane->plane + 1;
 	u32 plane_ctl, stride_div, stride;
@@ -238,6 +241,9 @@ skl_update_plane(struct drm_plane *drm_p
 	crtc_w--;
 	crtc_h--;
 
+	if (wm->dirty_pipes & drm_crtc_mask(crtc))
+		skl_write_plane_wm(intel_crtc, wm, plane);
+
 	if (key->flags) {
 		I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
 		I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
@@ -308,6 +314,14 @@ skl_disable_plane(struct drm_plane *dpla
 	const int pipe = intel_plane->pipe;
 	const int plane = intel_plane->plane + 1;
 
+	/*
+	 * We only populate skl_results on watermark updates, and if the
+	 * plane's visiblity isn't actually changing neither is its watermarks.
+	 */
+	if (!to_intel_plane_state(dplane->state)->visible)
+		skl_write_plane_wm(to_intel_crtc(crtc),
+				   &dev_priv->wm.skl_results, plane);
+
 	I915_WRITE(PLANE_CTL(pipe, plane), 0);
 
 	I915_WRITE(PLANE_SURF(pipe, plane), 0);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_uncore.c linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_uncore.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/i915/intel_uncore.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/i915/intel_uncore.c	2016-10-31 07:26:46.000000000 -0400
@@ -796,10 +796,9 @@ __unclaimed_reg_debug(struct drm_i915_pr
 		      const bool read,
 		      const bool before)
 {
-	if (WARN(check_for_unclaimed_mmio(dev_priv),
-		 "Unclaimed register detected %s %s register 0x%x\n",
-		 before ? "before" : "after",
-		 read ? "reading" : "writing to",
+	if (WARN(check_for_unclaimed_mmio(dev_priv) && !before,
+		 "Unclaimed %s register 0x%x\n",
+		 read ? "read from" : "write to",
 		 i915_mmio_reg_offset(reg)))
 		i915.mmio_debug--; /* Only report the first N failures */
 }
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/radeon/r600_dpm.c linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/r600_dpm.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/radeon/r600_dpm.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/r600_dpm.c	2016-10-31 07:26:46.000000000 -0400
@@ -156,19 +156,20 @@ u32 r600_dpm_get_vblank_time(struct rade
 	struct drm_device *dev = rdev->ddev;
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
-	u32 line_time_us, vblank_lines;
+	u32 vblank_in_pixels;
 	u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
 
 	if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
 		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 			radeon_crtc = to_radeon_crtc(crtc);
 			if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
-				line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) /
-					radeon_crtc->hw_mode.clock;
-				vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end -
-					radeon_crtc->hw_mode.crtc_vdisplay +
-					(radeon_crtc->v_border * 2);
-				vblank_time_us = vblank_lines * line_time_us;
+				vblank_in_pixels =
+					radeon_crtc->hw_mode.crtc_htotal *
+					(radeon_crtc->hw_mode.crtc_vblank_end -
+					 radeon_crtc->hw_mode.crtc_vdisplay +
+					 (radeon_crtc->v_border * 2));
+
+				vblank_time_us = vblank_in_pixels * 1000 / radeon_crtc->hw_mode.clock;
 				break;
 			}
 		}
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/radeon/radeon_device.c linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/radeon_device.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/radeon/radeon_device.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/radeon_device.c	2016-10-31 07:26:46.000000000 -0400
@@ -661,8 +661,9 @@ bool radeon_card_posted(struct radeon_de
 {
 	uint32_t reg;
 
-	/* for pass through, always force asic_init */
-	if (radeon_device_is_virtual())
+	/* for pass through, always force asic_init for CI */
+	if (rdev->family >= CHIP_BONAIRE &&
+	    radeon_device_is_virtual())
 		return false;
 
 	/* required for EFI mode on macbook2,1 which uses an r5xx asic */
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/radeon/si_dpm.c linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/si_dpm.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/radeon/si_dpm.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/si_dpm.c	2016-10-31 07:26:46.000000000 -0400
@@ -4112,7 +4112,7 @@ static int si_populate_smc_voltage_table
 							      &rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) {
 				si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table);
 
-				table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =
+				table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] =
 					cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low);
 
 				si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay,
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/radeon/sislands_smc.h linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/sislands_smc.h
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/radeon/sislands_smc.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/radeon/sislands_smc.h	2016-10-31 07:26:46.000000000 -0400
@@ -194,6 +194,7 @@ typedef struct SISLANDS_SMC_SWSTATE SISL
 #define SISLANDS_SMC_VOLTAGEMASK_VDDC  0
 #define SISLANDS_SMC_VOLTAGEMASK_MVDD  1
 #define SISLANDS_SMC_VOLTAGEMASK_VDDCI 2
+#define SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING 3
 #define SISLANDS_SMC_VOLTAGEMASK_MAX   4
 
 struct SISLANDS_SMC_VOLTAGEMASKTABLE
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/vc4/vc4_drv.h linux-libre-4.8.6-gnu/drivers/gpu/drm/vc4/vc4_drv.h
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/vc4/vc4_drv.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/vc4/vc4_drv.h	2016-10-31 07:26:46.000000000 -0400
@@ -122,9 +122,16 @@ to_vc4_dev(struct drm_device *dev)
 struct vc4_bo {
 	struct drm_gem_cma_object base;
 
-	/* seqno of the last job to render to this BO. */
+	/* seqno of the last job to render using this BO. */
 	uint64_t seqno;
 
+	/* seqno of the last job to use the RCL to write to this BO.
+	 *
+	 * Note that this doesn't include binner overflow memory
+	 * writes.
+	 */
+	uint64_t write_seqno;
+
 	/* List entry for the BO's position in either
 	 * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list
 	 */
@@ -216,6 +223,9 @@ struct vc4_exec_info {
 	/* Sequence number for this bin/render job. */
 	uint64_t seqno;
 
+	/* Latest write_seqno of any BO that binning depends on. */
+	uint64_t bin_dep_seqno;
+
 	/* Last current addresses the hardware was processing when the
 	 * hangcheck timer checked on us.
 	 */
@@ -230,6 +240,13 @@ struct vc4_exec_info {
 	struct drm_gem_cma_object **bo;
 	uint32_t bo_count;
 
+	/* List of BOs that are being written by the RCL.  Other than
+	 * the binner temporary storage, this is all the BOs written
+	 * by the job.
+	 */
+	struct drm_gem_cma_object *rcl_write_bo[4];
+	uint32_t rcl_write_bo_count;
+
 	/* Pointers for our position in vc4->job_list */
 	struct list_head head;
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/vc4/vc4_gem.c linux-libre-4.8.6-gnu/drivers/gpu/drm/vc4/vc4_gem.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/vc4/vc4_gem.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/vc4/vc4_gem.c	2016-10-31 07:26:46.000000000 -0400
@@ -471,6 +471,11 @@ vc4_update_bo_seqnos(struct vc4_exec_inf
 	list_for_each_entry(bo, &exec->unref_list, unref_head) {
 		bo->seqno = seqno;
 	}
+
+	for (i = 0; i < exec->rcl_write_bo_count; i++) {
+		bo = to_vc4_bo(&exec->rcl_write_bo[i]->base);
+		bo->write_seqno = seqno;
+	}
 }
 
 /* Queues a struct vc4_exec_info for execution.  If no job is
@@ -673,6 +678,14 @@ vc4_get_bcl(struct drm_device *dev, stru
 		goto fail;
 
 	ret = vc4_validate_shader_recs(dev, exec);
+	if (ret)
+		goto fail;
+
+	/* Block waiting on any previous rendering into the CS's VBO,
+	 * IB, or textures, so that pixels are actually written by the
+	 * time we try to read them.
+	 */
+	ret = vc4_wait_for_seqno(dev, exec->bin_dep_seqno, ~0ull, true);
 
 fail:
 	drm_free_large(temp);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/vc4/vc4_render_cl.c linux-libre-4.8.6-gnu/drivers/gpu/drm/vc4/vc4_render_cl.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/vc4/vc4_render_cl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/vc4/vc4_render_cl.c	2016-10-31 07:26:46.000000000 -0400
@@ -45,6 +45,8 @@ struct vc4_rcl_setup {
 
 	struct drm_gem_cma_object *rcl;
 	u32 next_offset;
+
+	u32 next_write_bo_index;
 };
 
 static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val)
@@ -407,6 +409,8 @@ static int vc4_rcl_msaa_surface_setup(st
 	if (!*obj)
 		return -EINVAL;
 
+	exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
+
 	if (surf->offset & 0xf) {
 		DRM_ERROR("MSAA write must be 16b aligned.\n");
 		return -EINVAL;
@@ -417,7 +421,8 @@ static int vc4_rcl_msaa_surface_setup(st
 
 static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
 				 struct drm_gem_cma_object **obj,
-				 struct drm_vc4_submit_rcl_surface *surf)
+				 struct drm_vc4_submit_rcl_surface *surf,
+				 bool is_write)
 {
 	uint8_t tiling = VC4_GET_FIELD(surf->bits,
 				       VC4_LOADSTORE_TILE_BUFFER_TILING);
@@ -440,6 +445,9 @@ static int vc4_rcl_surface_setup(struct
 	if (!*obj)
 		return -EINVAL;
 
+	if (is_write)
+		exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
+
 	if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
 		if (surf == &exec->args->zs_write) {
 			DRM_ERROR("general zs write may not be a full-res.\n");
@@ -542,6 +550,8 @@ vc4_rcl_render_config_surface_setup(stru
 	if (!*obj)
 		return -EINVAL;
 
+	exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
+
 	if (tiling > VC4_TILING_FORMAT_LT) {
 		DRM_ERROR("Bad tiling format\n");
 		return -EINVAL;
@@ -599,15 +609,18 @@ int vc4_get_rcl(struct drm_device *dev,
 	if (ret)
 		return ret;
 
-	ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read);
+	ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read,
+				    false);
 	if (ret)
 		return ret;
 
-	ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read);
+	ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read,
+				    false);
 	if (ret)
 		return ret;
 
-	ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write);
+	ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write,
+				    true);
 	if (ret)
 		return ret;
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/vc4/vc4_validate.c linux-libre-4.8.6-gnu/drivers/gpu/drm/vc4/vc4_validate.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/vc4/vc4_validate.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/vc4/vc4_validate.c	2016-10-31 07:26:46.000000000 -0400
@@ -267,6 +267,9 @@ validate_indexed_prim_list(VALIDATE_ARGS
 	if (!ib)
 		return -EINVAL;
 
+	exec->bin_dep_seqno = max(exec->bin_dep_seqno,
+				  to_vc4_bo(&ib->base)->write_seqno);
+
 	if (offset > ib->base.size ||
 	    (ib->base.size - offset) / index_size < length) {
 		DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n",
@@ -555,8 +558,7 @@ static bool
 reloc_tex(struct vc4_exec_info *exec,
 	  void *uniform_data_u,
 	  struct vc4_texture_sample_info *sample,
-	  uint32_t texture_handle_index)
-
+	  uint32_t texture_handle_index, bool is_cs)
 {
 	struct drm_gem_cma_object *tex;
 	uint32_t p0 = *(uint32_t *)(uniform_data_u + sample->p_offset[0]);
@@ -714,6 +716,11 @@ reloc_tex(struct vc4_exec_info *exec,
 
 	*validated_p0 = tex->paddr + p0;
 
+	if (is_cs) {
+		exec->bin_dep_seqno = max(exec->bin_dep_seqno,
+					  to_vc4_bo(&tex->base)->write_seqno);
+	}
+
 	return true;
  fail:
 	DRM_INFO("Texture p0 at %d: 0x%08x\n", sample->p_offset[0], p0);
@@ -835,7 +842,8 @@ validate_gl_shader_rec(struct drm_device
 			if (!reloc_tex(exec,
 				       uniform_data_u,
 				       &validated_shader->texture_samples[tex],
-				       texture_handles_u[tex])) {
+				       texture_handles_u[tex],
+				       i == 2)) {
 				return -EINVAL;
 			}
 		}
@@ -867,6 +875,9 @@ validate_gl_shader_rec(struct drm_device
 		uint32_t stride = *(uint8_t *)(pkt_u + o + 5);
 		uint32_t max_index;
 
+		exec->bin_dep_seqno = max(exec->bin_dep_seqno,
+					  to_vc4_bo(&vbo->base)->write_seqno);
+
 		if (state->addr & 0x8)
 			stride |= (*(uint32_t *)(pkt_u + 100 + i * 4)) & ~0xff;
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c linux-libre-4.8.6-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
--- linux-libre-4.8.5-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c	2016-10-31 07:26:46.000000000 -0400
@@ -34,6 +34,24 @@
 
 #define VMW_RES_HT_ORDER 12
 
+ /**
+ * enum vmw_resource_relocation_type - Relocation type for resources
+ *
+ * @vmw_res_rel_normal: Traditional relocation. The resource id in the
+ * command stream is replaced with the actual id after validation.
+ * @vmw_res_rel_nop: NOP relocation. The command is unconditionally replaced
+ * with a NOP.
+ * @vmw_res_rel_cond_nop: Conditional NOP relocation. If the resource id
+ * after validation is -1, the command is replaced with a NOP. Otherwise no
+ * action.
+ */
+enum vmw_resource_relocation_type {
+	vmw_res_rel_normal,
+	vmw_res_rel_nop,
+	vmw_res_rel_cond_nop,
+	vmw_res_rel_max
+};
+
 /**
  * struct vmw_resource_relocation - Relocation info for resources
  *
@@ -41,11 +59,13 @@
  * @res: Non-ref-counted pointer to the resource.
  * @offset: Offset of 4 byte entries into the command buffer where the
  * id that needs fixup is located.
+ * @rel_type: Type of relocation.
  */
 struct vmw_resource_relocation {
 	struct list_head head;
 	const struct vmw_resource *res;
-	unsigned long offset;
+	u32 offset:29;
+	enum vmw_resource_relocation_type rel_type:3;
 };
 
 /**
@@ -410,10 +430,13 @@ static int vmw_resource_context_res_add(
  * @res: The resource.
  * @offset: Offset into the command buffer currently being parsed where the
  * id that needs fixup is located. Granularity is 4 bytes.
+ * @rel_type: Relocation type.
  */
 static int vmw_resource_relocation_add(struct list_head *list,
 				       const struct vmw_resource *res,
-				       unsigned long offset)
+				       unsigned long offset,
+				       enum vmw_resource_relocation_type
+				       rel_type)
 {
 	struct vmw_resource_relocation *rel;
 
@@ -425,6 +448,7 @@ static int vmw_resource_relocation_add(s
 
 	rel->res = res;
 	rel->offset = offset;
+	rel->rel_type = rel_type;
 	list_add_tail(&rel->head, list);
 
 	return 0;
@@ -459,11 +483,23 @@ static void vmw_resource_relocations_app
 {
 	struct vmw_resource_relocation *rel;
 
+	/* Validate the struct vmw_resource_relocation member size */
+	BUILD_BUG_ON(SVGA_CB_MAX_SIZE >= (1 << 29));
+	BUILD_BUG_ON(vmw_res_rel_max >= (1 << 3));
+
 	list_for_each_entry(rel, list, head) {
-		if (likely(rel->res != NULL))
+		switch (rel->rel_type) {
+		case vmw_res_rel_normal:
 			cb[rel->offset] = rel->res->id;
-		else
+			break;
+		case vmw_res_rel_nop:
 			cb[rel->offset] = SVGA_3D_CMD_NOP;
+			break;
+		default:
+			if (rel->res->id == -1)
+				cb[rel->offset] = SVGA_3D_CMD_NOP;
+			break;
+		}
 	}
 }
 
@@ -655,7 +691,8 @@ static int vmw_cmd_res_reloc_add(struct
 	*p_val = NULL;
 	ret = vmw_resource_relocation_add(&sw_context->res_relocations,
 					  res,
-					  id_loc - sw_context->buf_start);
+					  id_loc - sw_context->buf_start,
+					  vmw_res_rel_normal);
 	if (unlikely(ret != 0))
 		return ret;
 
@@ -721,7 +758,8 @@ vmw_cmd_res_check(struct vmw_private *de
 
 		return vmw_resource_relocation_add
 			(&sw_context->res_relocations, res,
-			 id_loc - sw_context->buf_start);
+			 id_loc - sw_context->buf_start,
+			 vmw_res_rel_normal);
 	}
 
 	ret = vmw_user_resource_lookup_handle(dev_priv,
@@ -2144,7 +2182,8 @@ static int vmw_cmd_shader_define(struct
 
 	return vmw_resource_relocation_add(&sw_context->res_relocations,
 					   NULL, &cmd->header.id -
-					   sw_context->buf_start);
+					   sw_context->buf_start,
+					   vmw_res_rel_nop);
 
 	return 0;
 }
@@ -2189,7 +2228,8 @@ static int vmw_cmd_shader_destroy(struct
 
 	return vmw_resource_relocation_add(&sw_context->res_relocations,
 					   NULL, &cmd->header.id -
-					   sw_context->buf_start);
+					   sw_context->buf_start,
+					   vmw_res_rel_nop);
 
 	return 0;
 }
@@ -2848,8 +2888,7 @@ static int vmw_cmd_dx_cid_check(struct v
  * @header: Pointer to the command header in the command stream.
  *
  * Check that the view exists, and if it was not created using this
- * command batch, make sure it's validated (present in the device) so that
- * the remove command will not confuse the device.
+ * command batch, conditionally make this command a NOP.
  */
 static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv,
 				  struct vmw_sw_context *sw_context,
@@ -2877,10 +2916,15 @@ static int vmw_cmd_dx_view_remove(struct
 		return ret;
 
 	/*
-	 * Add view to the validate list iff it was not created using this
-	 * command batch.
+	 * If the view wasn't created during this command batch, it might
+	 * have been removed due to a context swapout, so add a
+	 * relocation to conditionally make this command a NOP to avoid
+	 * device errors.
 	 */
-	return vmw_view_res_val_add(sw_context, view);
+	return vmw_resource_relocation_add(&sw_context->res_relocations,
+					   view,
+					   &cmd->header.id - sw_context->buf_start,
+					   vmw_res_rel_cond_nop);
 }
 
 /**
@@ -3848,14 +3892,14 @@ static void *vmw_execbuf_cmdbuf(struct v
 	int ret;
 
 	*header = NULL;
-	if (!dev_priv->cman || kernel_commands)
-		return kernel_commands;
-
 	if (command_size > SVGA_CB_MAX_SIZE) {
 		DRM_ERROR("Command buffer is too large.\n");
 		return ERR_PTR(-EINVAL);
 	}
 
+	if (!dev_priv->cman || kernel_commands)
+		return kernel_commands;
+
 	/* If possible, add a little space for fencing. */
 	cmdbuf_size = command_size + 512;
 	cmdbuf_size = min_t(size_t, cmdbuf_size, SVGA_CB_MAX_SIZE);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/hid/hid-ids.h linux-libre-4.8.6-gnu/drivers/hid/hid-ids.h
--- linux-libre-4.8.5-gnu/drivers/hid/hid-ids.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/hid/hid-ids.h	2016-10-31 07:26:46.000000000 -0400
@@ -64,6 +64,9 @@
 #define USB_VENDOR_ID_AKAI		0x2011
 #define USB_DEVICE_ID_AKAI_MPKMINI2	0x0715
 
+#define USB_VENDOR_ID_AKAI_09E8		0x09E8
+#define USB_DEVICE_ID_AKAI_09E8_MIDIMIX	0x0031
+
 #define USB_VENDOR_ID_ALCOR		0x058f
 #define USB_DEVICE_ID_ALCOR_USBRS232	0x9720
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/hid/usbhid/hid-quirks.c linux-libre-4.8.6-gnu/drivers/hid/usbhid/hid-quirks.c
--- linux-libre-4.8.5-gnu/drivers/hid/usbhid/hid-quirks.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/hid/usbhid/hid-quirks.c	2016-10-31 07:26:46.000000000 -0400
@@ -56,6 +56,7 @@ static const struct hid_blacklist {
 
 	{ USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS },
+	{ USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/hwtracing/coresight/coresight-tmc.c linux-libre-4.8.6-gnu/drivers/hwtracing/coresight/coresight-tmc.c
--- linux-libre-4.8.5-gnu/drivers/hwtracing/coresight/coresight-tmc.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/hwtracing/coresight/coresight-tmc.c	2016-10-31 07:26:46.000000000 -0400
@@ -388,9 +388,6 @@ static int tmc_probe(struct amba_device
 err_misc_register:
 	coresight_unregister(drvdata->csdev);
 err_devm_kzalloc:
-	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
-		dma_free_coherent(dev, drvdata->size,
-				drvdata->vaddr, drvdata->paddr);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/iio/dac/ad5755.c linux-libre-4.8.6-gnu/drivers/iio/dac/ad5755.c
--- linux-libre-4.8.5-gnu/drivers/iio/dac/ad5755.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/iio/dac/ad5755.c	2016-10-31 07:26:46.000000000 -0400
@@ -655,7 +655,7 @@ static struct ad5755_platform_data *ad57
 
 	devnr = 0;
 	for_each_child_of_node(np, pp) {
-		if (devnr > AD5755_NUM_CHANNELS) {
+		if (devnr >= AD5755_NUM_CHANNELS) {
 			dev_err(dev,
 				"There is to many channels defined in DT\n");
 			goto error_out;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/iio/light/us5182d.c linux-libre-4.8.6-gnu/drivers/iio/light/us5182d.c
--- linux-libre-4.8.5-gnu/drivers/iio/light/us5182d.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/iio/light/us5182d.c	2016-10-31 07:26:46.000000000 -0400
@@ -894,7 +894,7 @@ static int us5182d_probe(struct i2c_clie
 		goto out_err;
 
 	if (data->default_continuous) {
-		pm_runtime_set_active(&client->dev);
+		ret = pm_runtime_set_active(&client->dev);
 		if (ret < 0)
 			goto out_err;
 	}
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/infiniband/hw/hfi1/qp.c linux-libre-4.8.6-gnu/drivers/infiniband/hw/hfi1/qp.c
--- linux-libre-4.8.5-gnu/drivers/infiniband/hw/hfi1/qp.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/infiniband/hw/hfi1/qp.c	2016-10-31 07:26:46.000000000 -0400
@@ -808,6 +808,13 @@ void *qp_priv_alloc(struct rvt_dev_info
 		kfree(priv);
 		return ERR_PTR(-ENOMEM);
 	}
+	iowait_init(
+		&priv->s_iowait,
+		1,
+		_hfi1_do_send,
+		iowait_sleep,
+		iowait_wakeup,
+		iowait_sdma_drained);
 	setup_timer(&priv->s_rnr_timer, hfi1_rc_rnr_retry, (unsigned long)qp);
 	qp->s_timer.function = hfi1_rc_timeout;
 	return priv;
@@ -873,13 +880,6 @@ void notify_qp_reset(struct rvt_qp *qp)
 {
 	struct hfi1_qp_priv *priv = qp->priv;
 
-	iowait_init(
-		&priv->s_iowait,
-		1,
-		_hfi1_do_send,
-		iowait_sleep,
-		iowait_wakeup,
-		iowait_sdma_drained);
 	priv->r_adefered = 0;
 	clear_ahg(qp);
 }
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/infiniband/hw/mlx5/main.c linux-libre-4.8.6-gnu/drivers/infiniband/hw/mlx5/main.c
--- linux-libre-4.8.5-gnu/drivers/infiniband/hw/mlx5/main.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/infiniband/hw/mlx5/main.c	2016-10-31 07:26:46.000000000 -0400
@@ -1843,6 +1843,7 @@ static struct mlx5_ib_flow_handler *crea
 						 &leftovers_specs[LEFTOVERS_UC].flow_attr,
 						 dst);
 		if (IS_ERR(handler_ucast)) {
+			mlx5_del_flow_rule(handler->rule);
 			kfree(handler);
 			handler = handler_ucast;
 		} else {
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/infiniband/hw/qib/qib.h linux-libre-4.8.6-gnu/drivers/infiniband/hw/qib/qib.h
--- linux-libre-4.8.5-gnu/drivers/infiniband/hw/qib/qib.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/infiniband/hw/qib/qib.h	2016-10-31 07:26:46.000000000 -0400
@@ -1131,7 +1131,6 @@ extern spinlock_t qib_devs_lock;
 extern struct qib_devdata *qib_lookup(int unit);
 extern u32 qib_cpulist_count;
 extern unsigned long *qib_cpulist;
-extern u16 qpt_mask;
 extern unsigned qib_cc_table_size;
 
 int qib_init(struct qib_devdata *, int);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/infiniband/hw/qib/qib_qp.c linux-libre-4.8.6-gnu/drivers/infiniband/hw/qib/qib_qp.c
--- linux-libre-4.8.5-gnu/drivers/infiniband/hw/qib/qib_qp.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/infiniband/hw/qib/qib_qp.c	2016-10-31 07:26:46.000000000 -0400
@@ -41,14 +41,6 @@
 
 #include "qib.h"
 
-/*
- * mask field which was present in now deleted qib_qpn_table
- * is not present in rvt_qpn_table. Defining the same field
- * as qpt_mask here instead of adding the mask field to
- * rvt_qpn_table.
- */
-u16 qpt_mask;
-
 static inline unsigned mk_qpn(struct rvt_qpn_table *qpt,
 			      struct rvt_qpn_map *map, unsigned off)
 {
@@ -57,7 +49,7 @@ static inline unsigned mk_qpn(struct rvt
 
 static inline unsigned find_next_offset(struct rvt_qpn_table *qpt,
 					struct rvt_qpn_map *map, unsigned off,
-					unsigned n)
+					unsigned n, u16 qpt_mask)
 {
 	if (qpt_mask) {
 		off++;
@@ -179,6 +171,7 @@ int qib_alloc_qpn(struct rvt_dev_info *r
 	struct qib_ibdev *verbs_dev = container_of(rdi, struct qib_ibdev, rdi);
 	struct qib_devdata *dd = container_of(verbs_dev, struct qib_devdata,
 					      verbs_dev);
+	u16 qpt_mask = dd->qpn_mask;
 
 	if (type == IB_QPT_SMI || type == IB_QPT_GSI) {
 		unsigned n;
@@ -215,7 +208,7 @@ int qib_alloc_qpn(struct rvt_dev_info *r
 				goto bail;
 			}
 			offset = find_next_offset(qpt, map, offset,
-				dd->n_krcv_queues);
+				dd->n_krcv_queues, qpt_mask);
 			qpn = mk_qpn(qpt, map, offset);
 			/*
 			 * This test differs from alloc_pidmap().
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/infiniband/hw/qib/qib_verbs.c linux-libre-4.8.6-gnu/drivers/infiniband/hw/qib/qib_verbs.c
--- linux-libre-4.8.5-gnu/drivers/infiniband/hw/qib/qib_verbs.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/infiniband/hw/qib/qib_verbs.c	2016-10-31 07:26:46.000000000 -0400
@@ -1606,8 +1606,6 @@ int qib_register_ib_device(struct qib_de
 	/* Only need to initialize non-zero fields. */
 	setup_timer(&dev->mem_timer, mem_timer, (unsigned long)dev);
 
-	qpt_mask = dd->qpn_mask;
-
 	INIT_LIST_HEAD(&dev->piowait);
 	INIT_LIST_HEAD(&dev->dmawait);
 	INIT_LIST_HEAD(&dev->txwait);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/infiniband/sw/rdmavt/qp.c linux-libre-4.8.6-gnu/drivers/infiniband/sw/rdmavt/qp.c
--- linux-libre-4.8.5-gnu/drivers/infiniband/sw/rdmavt/qp.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/infiniband/sw/rdmavt/qp.c	2016-10-31 07:26:46.000000000 -0400
@@ -501,12 +501,9 @@ static void rvt_remove_qp(struct rvt_dev
  */
 static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,
 		  enum ib_qp_type type)
-	__releases(&qp->s_lock)
-	__releases(&qp->s_hlock)
-	__releases(&qp->r_lock)
-	__acquires(&qp->r_lock)
-	__acquires(&qp->s_hlock)
-	__acquires(&qp->s_lock)
+	__must_hold(&qp->r_lock)
+	__must_hold(&qp->s_hlock)
+	__must_hold(&qp->s_lock)
 {
 	if (qp->state != IB_QPS_RESET) {
 		qp->state = IB_QPS_RESET;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/ethernet/intel/i40e/i40e_client.c linux-libre-4.8.6-gnu/drivers/net/ethernet/intel/i40e/i40e_client.c
--- linux-libre-4.8.5-gnu/drivers/net/ethernet/intel/i40e/i40e_client.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/ethernet/intel/i40e/i40e_client.c	2016-10-31 07:26:46.000000000 -0400
@@ -1009,7 +1009,6 @@ int i40e_unregister_client(struct i40e_c
 	if (!i40e_client_is_registered(client)) {
 		pr_info("i40e: Client %s has not been registered\n",
 			client->name);
-		mutex_unlock(&i40e_client_mutex);
 		ret = -ENODEV;
 		goto out;
 	}
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/ethernet/intel/i40e/i40e_main.c linux-libre-4.8.6-gnu/drivers/net/ethernet/intel/i40e/i40e_main.c
--- linux-libre-4.8.5-gnu/drivers/net/ethernet/intel/i40e/i40e_main.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/ethernet/intel/i40e/i40e_main.c	2016-10-31 07:26:46.000000000 -0400
@@ -7990,45 +7990,34 @@ static int i40e_setup_misc_vector(struct
 static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
 			      u8 *lut, u16 lut_size)
 {
-	struct i40e_aqc_get_set_rss_key_data rss_key;
 	struct i40e_pf *pf = vsi->back;
 	struct i40e_hw *hw = &pf->hw;
-	bool pf_lut = false;
-	u8 *rss_lut;
-	int ret, i;
-
-	memcpy(&rss_key, seed, sizeof(rss_key));
-
-	rss_lut = kzalloc(pf->rss_table_size, GFP_KERNEL);
-	if (!rss_lut)
-		return -ENOMEM;
-
-	/* Populate the LUT with max no. of queues in round robin fashion */
-	for (i = 0; i < vsi->rss_table_size; i++)
-		rss_lut[i] = i % vsi->rss_size;
+	int ret = 0;
 
-	ret = i40e_aq_set_rss_key(hw, vsi->id, &rss_key);
-	if (ret) {
-		dev_info(&pf->pdev->dev,
-			 "Cannot set RSS key, err %s aq_err %s\n",
-			 i40e_stat_str(&pf->hw, ret),
-			 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
-		goto config_rss_aq_out;
+	if (seed) {
+		struct i40e_aqc_get_set_rss_key_data *seed_dw =
+			(struct i40e_aqc_get_set_rss_key_data *)seed;
+		ret = i40e_aq_set_rss_key(hw, vsi->id, seed_dw);
+		if (ret) {
+			dev_info(&pf->pdev->dev,
+				 "Cannot set RSS key, err %s aq_err %s\n",
+				 i40e_stat_str(hw, ret),
+				 i40e_aq_str(hw, hw->aq.asq_last_status));
+			return ret;
+		}
 	}
+	if (lut) {
+		bool pf_lut = vsi->type == I40E_VSI_MAIN ? true : false;
 
-	if (vsi->type == I40E_VSI_MAIN)
-		pf_lut = true;
-
-	ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, rss_lut,
-				  vsi->rss_table_size);
-	if (ret)
-		dev_info(&pf->pdev->dev,
-			 "Cannot set RSS lut, err %s aq_err %s\n",
-			 i40e_stat_str(&pf->hw, ret),
-			 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
-
-config_rss_aq_out:
-	kfree(rss_lut);
+		ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, lut, lut_size);
+		if (ret) {
+			dev_info(&pf->pdev->dev,
+				 "Cannot set RSS lut, err %s aq_err %s\n",
+				 i40e_stat_str(hw, ret),
+				 i40e_aq_str(hw, hw->aq.asq_last_status));
+			return ret;
+		}
+	}
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/ath/ath10k/htt_rx.c linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/htt_rx.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/ath/ath10k/htt_rx.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/htt_rx.c	2016-10-31 07:26:46.000000000 -0400
@@ -2394,6 +2394,8 @@ static void ath10k_htt_txrx_compl_task(u
 	skb_queue_splice_init(&htt->rx_in_ord_compl_q, &rx_ind_q);
 	spin_unlock_irqrestore(&htt->rx_in_ord_compl_q.lock, flags);
 
+	ath10k_mac_tx_push_pending(ar);
+
 	spin_lock_irqsave(&htt->tx_fetch_ind_q.lock, flags);
 	skb_queue_splice_init(&htt->tx_fetch_ind_q, &tx_ind_q);
 	spin_unlock_irqrestore(&htt->tx_fetch_ind_q.lock, flags);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/ath/ath10k/mac.c linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/mac.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/ath/ath10k/mac.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/mac.c	2016-10-31 07:26:46.000000000 -0400
@@ -3777,7 +3777,9 @@ int ath10k_mac_tx_push_txq(struct ieee80
 	enum ath10k_hw_txrx_mode txmode;
 	enum ath10k_mac_tx_path txpath;
 	struct sk_buff *skb;
+	struct ieee80211_hdr *hdr;
 	size_t skb_len;
+	bool is_mgmt, is_presp;
 	int ret;
 
 	spin_lock_bh(&ar->htt.tx_lock);
@@ -3801,6 +3803,22 @@ int ath10k_mac_tx_push_txq(struct ieee80
 	skb_len = skb->len;
 	txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
 	txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
+	is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
+
+	if (is_mgmt) {
+		hdr = (struct ieee80211_hdr *)skb->data;
+		is_presp = ieee80211_is_probe_resp(hdr->frame_control);
+
+		spin_lock_bh(&ar->htt.tx_lock);
+		ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
+
+		if (ret) {
+			ath10k_htt_tx_dec_pending(htt);
+			spin_unlock_bh(&ar->htt.tx_lock);
+			return ret;
+		}
+		spin_unlock_bh(&ar->htt.tx_lock);
+	}
 
 	ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
 	if (unlikely(ret)) {
@@ -3808,6 +3826,8 @@ int ath10k_mac_tx_push_txq(struct ieee80
 
 		spin_lock_bh(&ar->htt.tx_lock);
 		ath10k_htt_tx_dec_pending(htt);
+		if (is_mgmt)
+			ath10k_htt_tx_mgmt_dec_pending(htt);
 		spin_unlock_bh(&ar->htt.tx_lock);
 
 		return ret;
@@ -6538,7 +6558,7 @@ static int ath10k_get_survey(struct ieee
 		goto exit;
 	}
 
-	ath10k_mac_update_bss_chan_survey(ar, survey->channel);
+	ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
 
 	spin_lock_bh(&ar->data_lock);
 	memcpy(survey, ar_survey, sizeof(*survey));
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/ath/ath10k/txrx.c linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/txrx.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/ath/ath10k/txrx.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/txrx.c	2016-10-31 07:26:46.000000000 -0400
@@ -119,8 +119,6 @@ int ath10k_txrx_tx_unref(struct ath10k_h
 	ieee80211_tx_status(htt->ar->hw, msdu);
 	/* we do not own the msdu anymore */
 
-	ath10k_mac_tx_push_pending(ar);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/ath/ath10k/wmi.h linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/wmi.h
--- linux-libre-4.8.5-gnu/drivers/net/wireless/ath/ath10k/wmi.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/ath/ath10k/wmi.h	2016-10-31 07:26:46.000000000 -0400
@@ -180,6 +180,7 @@ enum wmi_service {
 	WMI_SERVICE_MESH_NON_11S,
 	WMI_SERVICE_PEER_STATS,
 	WMI_SERVICE_RESTRT_CHNL_SUPPORT,
+	WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
 	WMI_SERVICE_TX_MODE_PUSH_ONLY,
 	WMI_SERVICE_TX_MODE_PUSH_PULL,
 	WMI_SERVICE_TX_MODE_DYNAMIC,
@@ -305,6 +306,7 @@ enum wmi_10_4_service {
 	WMI_10_4_SERVICE_RESTRT_CHNL_SUPPORT,
 	WMI_10_4_SERVICE_PEER_STATS,
 	WMI_10_4_SERVICE_MESH_11S,
+	WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
 	WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY,
 	WMI_10_4_SERVICE_TX_MODE_PUSH_PULL,
 	WMI_10_4_SERVICE_TX_MODE_DYNAMIC,
@@ -402,6 +404,7 @@ static inline char *wmi_service_name(int
 	SVCSTR(WMI_SERVICE_MESH_NON_11S);
 	SVCSTR(WMI_SERVICE_PEER_STATS);
 	SVCSTR(WMI_SERVICE_RESTRT_CHNL_SUPPORT);
+	SVCSTR(WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT);
 	SVCSTR(WMI_SERVICE_TX_MODE_PUSH_ONLY);
 	SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL);
 	SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC);
@@ -652,6 +655,8 @@ static inline void wmi_10_4_svc_map(cons
 	       WMI_SERVICE_PEER_STATS, len);
 	SVCMAP(WMI_10_4_SERVICE_MESH_11S,
 	       WMI_SERVICE_MESH_11S, len);
+	SVCMAP(WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
+	       WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, len);
 	SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY,
 	       WMI_SERVICE_TX_MODE_PUSH_ONLY, len);
 	SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_PULL,
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c	2016-10-31 07:26:46.000000000 -0400
@@ -564,11 +564,16 @@ static void iwl_set_hw_address_from_csr(
 	__le32 mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_STRAP));
 	__le32 mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_STRAP));
 
-	/* If OEM did not fuse address - get it from OTP */
-	if (!mac_addr0 && !mac_addr1) {
-		mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP));
-		mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP));
-	}
+	iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
+	/*
+	 * If the OEM fused a valid address, use it instead of the one in the
+	 * OTP
+	 */
+	if (is_valid_ether_addr(data->hw_addr))
+		return;
+
+	mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP));
+	mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP));
 
 	iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
 }
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/mvm/fw.c linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/mvm/fw.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/mvm/fw.c	2016-10-31 07:26:46.000000000 -0400
@@ -1214,9 +1214,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
 	}
 
 	/* TODO: read the budget from BIOS / Platform NVM */
-	if (iwl_mvm_is_ctdp_supported(mvm) && mvm->cooling_dev.cur_state > 0)
+	if (iwl_mvm_is_ctdp_supported(mvm) && mvm->cooling_dev.cur_state > 0) {
 		ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START,
 					   mvm->cooling_dev.cur_state);
+		if (ret)
+			goto error;
+	}
 #else
 	/* Initialize tx backoffs to the minimal possible */
 	iwl_mvm_tt_tx_backoff(mvm, 0);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c	2016-10-31 07:26:46.000000000 -0400
@@ -539,6 +539,11 @@ void iwl_mvm_mac_ctxt_release(struct iwl
 			iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE,
 					    IWL_MVM_OFFCHANNEL_QUEUE,
 					    IWL_MAX_TID_COUNT, 0);
+		else
+			iwl_mvm_disable_txq(mvm,
+					    IWL_MVM_DQA_P2P_DEVICE_QUEUE,
+					    vif->hw_queue[0], IWL_MAX_TID_COUNT,
+					    0);
 
 		break;
 	case NL80211_IFTYPE_AP:
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c	2016-10-31 07:26:46.000000000 -0400
@@ -598,9 +598,10 @@ static bool iwl_mvm_reorder(struct iwl_m
 
 	mvm_sta = iwl_mvm_sta_from_mac80211(sta);
 
-	/* not a data packet */
-	if (!ieee80211_is_data_qos(hdr->frame_control) ||
-	    is_multicast_ether_addr(hdr->addr1))
+	/* not a data packet or a bar */
+	if (!ieee80211_is_back_req(hdr->frame_control) &&
+	    (!ieee80211_is_data_qos(hdr->frame_control) ||
+	     is_multicast_ether_addr(hdr->addr1)))
 		return false;
 
 	if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
@@ -624,6 +625,11 @@ static bool iwl_mvm_reorder(struct iwl_m
 
 	spin_lock_bh(&buffer->lock);
 
+	if (ieee80211_is_back_req(hdr->frame_control)) {
+		iwl_mvm_release_frames(mvm, sta, napi, buffer, nssn);
+		goto drop;
+	}
+
 	/*
 	 * If there was a significant jump in the nssn - adjust.
 	 * If the SN is smaller than the NSSN it might need to first go into
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/mvm/sta.c linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/mvm/sta.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/mvm/sta.c	2016-10-31 07:26:46.000000000 -0400
@@ -576,9 +576,7 @@ static int iwl_mvm_scd_queue_redirect(st
 			ret);
 
 	/* Make sure the SCD wrptr is correctly set before reconfiguring */
-	iwl_trans_txq_enable(mvm->trans, queue, iwl_mvm_ac_to_tx_fifo[ac],
-			     cmd.sta_id, tid, LINK_QUAL_AGG_FRAME_LIMIT_DEF,
-			     ssn, wdg_timeout);
+	iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL, wdg_timeout);
 
 	/* TODO: Work-around SCD bug when moving back by multiples of 0x40 */
 
@@ -1270,9 +1268,31 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
 		ret = iwl_mvm_drain_sta(mvm, mvm_sta, false);
 
 		/* If DQA is supported - the queues can be disabled now */
-		if (iwl_mvm_is_dqa_supported(mvm))
+		if (iwl_mvm_is_dqa_supported(mvm)) {
+			u8 reserved_txq = mvm_sta->reserved_queue;
+			enum iwl_mvm_queue_status *status;
+
 			iwl_mvm_disable_sta_queues(mvm, vif, mvm_sta);
 
+			/*
+			 * If no traffic has gone through the reserved TXQ - it
+			 * is still marked as IWL_MVM_QUEUE_RESERVED, and
+			 * should be manually marked as free again
+			 */
+			spin_lock_bh(&mvm->queue_info_lock);
+			status = &mvm->queue_info[reserved_txq].status;
+			if (WARN((*status != IWL_MVM_QUEUE_RESERVED) &&
+				 (*status != IWL_MVM_QUEUE_FREE),
+				 "sta_id %d reserved txq %d status %d",
+				 mvm_sta->sta_id, reserved_txq, *status)) {
+				spin_unlock_bh(&mvm->queue_info_lock);
+				return -EINVAL;
+			}
+
+			*status = IWL_MVM_QUEUE_FREE;
+			spin_unlock_bh(&mvm->queue_info_lock);
+		}
+
 		if (vif->type == NL80211_IFTYPE_STATION &&
 		    mvmvif->ap_sta_id == mvm_sta->sta_id) {
 			/* if associated - we can't remove the AP STA now */
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c	2016-10-31 07:26:46.000000000 -0400
@@ -903,9 +903,13 @@ static int iwl_mvm_tx_mpdu(struct iwl_mv
 		tid = IWL_MAX_TID_COUNT;
 	}
 
-	if (iwl_mvm_is_dqa_supported(mvm))
+	if (iwl_mvm_is_dqa_supported(mvm)) {
 		txq_id = mvmsta->tid_data[tid].txq_id;
 
+		if (ieee80211_is_mgmt(fc))
+			tx_cmd->tid_tspec = IWL_TID_NON_QOS;
+	}
+
 	/* Copy MAC header from skb into command buffer */
 	memcpy(tx_cmd->hdr, hdr, hdrlen);
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/marvell/mwifiex/join.c linux-libre-4.8.6-gnu/drivers/net/wireless/marvell/mwifiex/join.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/marvell/mwifiex/join.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/marvell/mwifiex/join.c	2016-10-31 07:26:46.000000000 -0400
@@ -669,9 +669,8 @@ int mwifiex_ret_802_11_associate(struct
 	priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN,
 				   sizeof(priv->assoc_rsp_buf));
 
-	memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
-
 	assoc_rsp->a_id = cpu_to_le16(aid);
+	memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
 
 	if (status_code) {
 		priv->adapter->dbg.num_cmd_assoc_failure++;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/marvell/mwifiex/sta_event.c linux-libre-4.8.6-gnu/drivers/net/wireless/marvell/mwifiex/sta_event.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/marvell/mwifiex/sta_event.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/marvell/mwifiex/sta_event.c	2016-10-31 07:26:46.000000000 -0400
@@ -708,7 +708,11 @@ int mwifiex_process_sta_event(struct mwi
 
 	case EVENT_EXT_SCAN_REPORT:
 		mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n");
-		if (adapter->ext_scan && !priv->scan_aborting)
+		/* We intend to skip this event during suspend, but handle
+		 * it in interface disabled case
+		 */
+		if (adapter->ext_scan && (!priv->scan_aborting ||
+					  !netif_running(priv->netdev)))
 			ret = mwifiex_handle_event_ext_scan_report(priv,
 						adapter->event_skb->data);
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c linux-libre-4.8.6-gnu/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
--- linux-libre-4.8.5-gnu/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c	2016-10-31 07:26:46.000000000 -0400
@@ -831,8 +831,10 @@ int rt2x00usb_probe(struct usb_interface
 	rt2x00dev->anchor = devm_kmalloc(&usb_dev->dev,
 					sizeof(struct usb_anchor),
 					GFP_KERNEL);
-	if (!rt2x00dev->anchor)
+	if (!rt2x00dev->anchor) {
+		retval = -ENOMEM;
 		goto exit_free_reg;
+	}
 
 	init_usb_anchor(rt2x00dev->anchor);
 	return 0;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/nvdimm/bus.c linux-libre-4.8.6-gnu/drivers/nvdimm/bus.c
--- linux-libre-4.8.5-gnu/drivers/nvdimm/bus.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/nvdimm/bus.c	2016-10-31 07:26:46.000000000 -0400
@@ -217,6 +217,8 @@ long nvdimm_clear_poison(struct device *
 		return rc;
 	if (cmd_rc < 0)
 		return cmd_rc;
+
+	nvdimm_clear_from_poison_list(nvdimm_bus, phys, len);
 	return clear_err.cleared;
 }
 EXPORT_SYMBOL_GPL(nvdimm_clear_poison);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/nvdimm/core.c linux-libre-4.8.6-gnu/drivers/nvdimm/core.c
--- linux-libre-4.8.5-gnu/drivers/nvdimm/core.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/nvdimm/core.c	2016-10-31 07:26:46.000000000 -0400
@@ -547,11 +547,12 @@ void nvdimm_badblocks_populate(struct nd
 }
 EXPORT_SYMBOL_GPL(nvdimm_badblocks_populate);
 
-static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
+static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length,
+			gfp_t flags)
 {
 	struct nd_poison *pl;
 
-	pl = kzalloc(sizeof(*pl), GFP_KERNEL);
+	pl = kzalloc(sizeof(*pl), flags);
 	if (!pl)
 		return -ENOMEM;
 
@@ -567,7 +568,7 @@ static int bus_add_poison(struct nvdimm_
 	struct nd_poison *pl;
 
 	if (list_empty(&nvdimm_bus->poison_list))
-		return add_poison(nvdimm_bus, addr, length);
+		return add_poison(nvdimm_bus, addr, length, GFP_KERNEL);
 
 	/*
 	 * There is a chance this is a duplicate, check for those first.
@@ -587,7 +588,7 @@ static int bus_add_poison(struct nvdimm_
 	 * as any overlapping ranges will get resolved when the list is consumed
 	 * and converted to badblocks
 	 */
-	return add_poison(nvdimm_bus, addr, length);
+	return add_poison(nvdimm_bus, addr, length, GFP_KERNEL);
 }
 
 int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
@@ -602,6 +603,70 @@ int nvdimm_bus_add_poison(struct nvdimm_
 }
 EXPORT_SYMBOL_GPL(nvdimm_bus_add_poison);
 
+void nvdimm_clear_from_poison_list(struct nvdimm_bus *nvdimm_bus,
+		phys_addr_t start, unsigned int len)
+{
+	struct list_head *poison_list = &nvdimm_bus->poison_list;
+	u64 clr_end = start + len - 1;
+	struct nd_poison *pl, *next;
+
+	nvdimm_bus_lock(&nvdimm_bus->dev);
+	WARN_ON_ONCE(list_empty(poison_list));
+
+	/*
+	 * [start, clr_end] is the poison interval being cleared.
+	 * [pl->start, pl_end] is the poison_list entry we're comparing
+	 * the above interval against. The poison list entry may need
+	 * to be modified (update either start or length), deleted, or
+	 * split into two based on the overlap characteristics
+	 */
+
+	list_for_each_entry_safe(pl, next, poison_list, list) {
+		u64 pl_end = pl->start + pl->length - 1;
+
+		/* Skip intervals with no intersection */
+		if (pl_end < start)
+			continue;
+		if (pl->start >  clr_end)
+			continue;
+		/* Delete completely overlapped poison entries */
+		if ((pl->start >= start) && (pl_end <= clr_end)) {
+			list_del(&pl->list);
+			kfree(pl);
+			continue;
+		}
+		/* Adjust start point of partially cleared entries */
+		if ((start <= pl->start) && (clr_end > pl->start)) {
+			pl->length -= clr_end - pl->start + 1;
+			pl->start = clr_end + 1;
+			continue;
+		}
+		/* Adjust pl->length for partial clearing at the tail end */
+		if ((pl->start < start) && (pl_end <= clr_end)) {
+			/* pl->start remains the same */
+			pl->length = start - pl->start;
+			continue;
+		}
+		/*
+		 * If clearing in the middle of an entry, we split it into
+		 * two by modifying the current entry to represent one half of
+		 * the split, and adding a new entry for the second half.
+		 */
+		if ((pl->start < start) && (pl_end > clr_end)) {
+			u64 new_start = clr_end + 1;
+			u64 new_len = pl_end - new_start + 1;
+
+			/* Add new entry covering the right half */
+			add_poison(nvdimm_bus, new_start, new_len, GFP_NOIO);
+			/* Adjust this entry to cover the left half */
+			pl->length = start - pl->start;
+			continue;
+		}
+	}
+	nvdimm_bus_unlock(&nvdimm_bus->dev);
+}
+EXPORT_SYMBOL_GPL(nvdimm_clear_from_poison_list);
+
 #ifdef CONFIG_BLK_DEV_INTEGRITY
 int nd_integrity_init(struct gendisk *disk, unsigned long meta_size)
 {
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/pci/host/pci-aardvark.c linux-libre-4.8.6-gnu/drivers/pci/host/pci-aardvark.c
--- linux-libre-4.8.5-gnu/drivers/pci/host/pci-aardvark.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/pci/host/pci-aardvark.c	2016-10-31 07:26:46.000000000 -0400
@@ -848,7 +848,7 @@ static int advk_pcie_parse_request_of_pc
 	int err, res_valid = 0;
 	struct device *dev = &pcie->pdev->dev;
 	struct device_node *np = dev->of_node;
-	struct resource_entry *win;
+	struct resource_entry *win, *tmp;
 	resource_size_t iobase;
 
 	INIT_LIST_HEAD(&pcie->resources);
@@ -862,7 +862,7 @@ static int advk_pcie_parse_request_of_pc
 	if (err)
 		goto out_release_res;
 
-	resource_list_for_each_entry(win, &pcie->resources) {
+	resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
 		struct resource *res = win->res;
 
 		switch (resource_type(res)) {
@@ -874,9 +874,11 @@ static int advk_pcie_parse_request_of_pc
 					     lower_32_bits(res->start),
 					     OB_PCIE_IO);
 			err = pci_remap_iospace(res, iobase);
-			if (err)
+			if (err) {
 				dev_warn(dev, "error %d: failed to map resource %pR\n",
 					 err, res);
+				resource_list_destroy_entry(win);
+			}
 			break;
 		case IORESOURCE_MEM:
 			advk_pcie_set_ob_win(pcie, 0,
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/pci/host/pcie-designware.c linux-libre-4.8.6-gnu/drivers/pci/host/pcie-designware.c
--- linux-libre-4.8.5-gnu/drivers/pci/host/pcie-designware.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/pci/host/pcie-designware.c	2016-10-31 07:26:46.000000000 -0400
@@ -436,7 +436,7 @@ int dw_pcie_host_init(struct pcie_port *
 	struct resource *cfg_res;
 	int i, ret;
 	LIST_HEAD(res);
-	struct resource_entry *win;
+	struct resource_entry *win, *tmp;
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
 	if (cfg_res) {
@@ -457,17 +457,20 @@ int dw_pcie_host_init(struct pcie_port *
 		goto error;
 
 	/* Get the I/O and memory ranges from DT */
-	resource_list_for_each_entry(win, &res) {
+	resource_list_for_each_entry_safe(win, tmp, &res) {
 		switch (resource_type(win->res)) {
 		case IORESOURCE_IO:
-			pp->io = win->res;
-			pp->io->name = "I/O";
-			pp->io_size = resource_size(pp->io);
-			pp->io_bus_addr = pp->io->start - win->offset;
-			ret = pci_remap_iospace(pp->io, pp->io_base);
-			if (ret)
+			ret = pci_remap_iospace(win->res, pp->io_base);
+			if (ret) {
 				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
-					 ret, pp->io);
+					 ret, win->res);
+				resource_list_destroy_entry(win);
+			} else {
+				pp->io = win->res;
+				pp->io->name = "I/O";
+				pp->io_size = resource_size(pp->io);
+				pp->io_bus_addr = pp->io->start - win->offset;
+			}
 			break;
 		case IORESOURCE_MEM:
 			pp->mem = win->res;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/pci/host/pcie-rcar.c linux-libre-4.8.6-gnu/drivers/pci/host/pcie-rcar.c
--- linux-libre-4.8.5-gnu/drivers/pci/host/pcie-rcar.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/pci/host/pcie-rcar.c	2016-10-31 07:26:46.000000000 -0400
@@ -945,7 +945,7 @@ static int rcar_pcie_parse_request_of_pc
 	struct device *dev = pci->dev;
 	struct device_node *np = dev->of_node;
 	resource_size_t iobase;
-	struct resource_entry *win;
+	struct resource_entry *win, *tmp;
 
 	err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources, &iobase);
 	if (err)
@@ -955,14 +955,17 @@ static int rcar_pcie_parse_request_of_pc
 	if (err)
 		goto out_release_res;
 
-	resource_list_for_each_entry(win, &pci->resources) {
+	resource_list_for_each_entry_safe(win, tmp, &pci->resources) {
 		struct resource *res = win->res;
 
 		if (resource_type(res) == IORESOURCE_IO) {
 			err = pci_remap_iospace(res, iobase);
-			if (err)
+			if (err) {
 				dev_warn(dev, "error %d: failed to map resource %pR\n",
 					 err, res);
+
+				resource_list_destroy_entry(win);
+			}
 		}
 	}
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/pci/host/pci-host-common.c linux-libre-4.8.6-gnu/drivers/pci/host/pci-host-common.c
--- linux-libre-4.8.5-gnu/drivers/pci/host/pci-host-common.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/pci/host/pci-host-common.c	2016-10-31 07:26:46.000000000 -0400
@@ -29,7 +29,7 @@ static int gen_pci_parse_request_of_pci_
 	int err, res_valid = 0;
 	struct device_node *np = dev->of_node;
 	resource_size_t iobase;
-	struct resource_entry *win;
+	struct resource_entry *win, *tmp;
 
 	err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase);
 	if (err)
@@ -39,15 +39,17 @@ static int gen_pci_parse_request_of_pci_
 	if (err)
 		return err;
 
-	resource_list_for_each_entry(win, resources) {
+	resource_list_for_each_entry_safe(win, tmp, resources) {
 		struct resource *res = win->res;
 
 		switch (resource_type(res)) {
 		case IORESOURCE_IO:
 			err = pci_remap_iospace(res, iobase);
-			if (err)
+			if (err) {
 				dev_warn(dev, "error %d: failed to map resource %pR\n",
 					 err, res);
+				resource_list_destroy_entry(win);
+			}
 			break;
 		case IORESOURCE_MEM:
 			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/pci/host/pci-tegra.c linux-libre-4.8.6-gnu/drivers/pci/host/pci-tegra.c
--- linux-libre-4.8.5-gnu/drivers/pci/host/pci-tegra.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/pci/host/pci-tegra.c	2016-10-31 07:26:46.000000000 -0400
@@ -621,7 +621,11 @@ static int tegra_pcie_setup(int nr, stru
 	if (err < 0)
 		return err;
 
-	pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset);
+	err = pci_remap_iospace(&pcie->pio, pcie->io.start);
+	if (!err)
+		pci_add_resource_offset(&sys->resources, &pcie->pio,
+					sys->io_offset);
+
 	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
 	pci_add_resource_offset(&sys->resources, &pcie->prefetch,
 				sys->mem_offset);
@@ -631,7 +635,6 @@ static int tegra_pcie_setup(int nr, stru
 	if (err < 0)
 		return err;
 
-	pci_remap_iospace(&pcie->pio, pcie->io.start);
 	return 1;
 }
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/pci/host/pci-versatile.c linux-libre-4.8.6-gnu/drivers/pci/host/pci-versatile.c
--- linux-libre-4.8.5-gnu/drivers/pci/host/pci-versatile.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/pci/host/pci-versatile.c	2016-10-31 07:26:46.000000000 -0400
@@ -74,7 +74,7 @@ static int versatile_pci_parse_request_o
 	int err, mem = 1, res_valid = 0;
 	struct device_node *np = dev->of_node;
 	resource_size_t iobase;
-	struct resource_entry *win;
+	struct resource_entry *win, *tmp;
 
 	err = of_pci_get_host_bridge_resources(np, 0, 0xff, res, &iobase);
 	if (err)
@@ -84,15 +84,17 @@ static int versatile_pci_parse_request_o
 	if (err)
 		goto out_release_res;
 
-	resource_list_for_each_entry(win, res) {
+	resource_list_for_each_entry_safe(win, tmp, res) {
 		struct resource *res = win->res;
 
 		switch (resource_type(res)) {
 		case IORESOURCE_IO:
 			err = pci_remap_iospace(res, iobase);
-			if (err)
+			if (err) {
 				dev_warn(dev, "error %d: failed to map resource %pR\n",
 					 err, res);
+				resource_list_destroy_entry(win);
+			}
 			break;
 		case IORESOURCE_MEM:
 			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/pinctrl/qcom/pinctrl-msm.c linux-libre-4.8.6-gnu/drivers/pinctrl/qcom/pinctrl-msm.c
--- linux-libre-4.8.5-gnu/drivers/pinctrl/qcom/pinctrl-msm.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/pinctrl/qcom/pinctrl-msm.c	2016-10-31 07:26:46.000000000 -0400
@@ -156,7 +156,7 @@ static int msm_pinmux_set_mux(struct pin
 	spin_lock_irqsave(&pctrl->lock, flags);
 
 	val = readl(pctrl->regs + g->ctl_reg);
-	val &= mask;
+	val &= ~mask;
 	val |= i << g->mux_bit;
 	writel(val, pctrl->regs + g->ctl_reg);
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/power/bq24257_charger.c linux-libre-4.8.6-gnu/drivers/power/bq24257_charger.c
--- linux-libre-4.8.5-gnu/drivers/power/bq24257_charger.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/power/bq24257_charger.c	2016-10-31 07:26:46.000000000 -0400
@@ -1068,6 +1068,12 @@ static int bq24257_probe(struct i2c_clie
 		return ret;
 	}
 
+	ret = bq24257_power_supply_init(bq);
+	if (ret < 0) {
+		dev_err(dev, "Failed to register power supply\n");
+		return ret;
+	}
+
 	ret = devm_request_threaded_irq(dev, client->irq, NULL,
 					bq24257_irq_handler_thread,
 					IRQF_TRIGGER_FALLING |
@@ -1078,12 +1084,6 @@ static int bq24257_probe(struct i2c_clie
 		return ret;
 	}
 
-	ret = bq24257_power_supply_init(bq);
-	if (ret < 0) {
-		dev_err(dev, "Failed to register power supply\n");
-		return ret;
-	}
-
 	ret = sysfs_create_group(&bq->charger->dev.kobj, &bq24257_attr_group);
 	if (ret < 0) {
 		dev_err(dev, "Can't create sysfs entries\n");
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/s390/char/con3270.c linux-libre-4.8.6-gnu/drivers/s390/char/con3270.c
--- linux-libre-4.8.5-gnu/drivers/s390/char/con3270.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/s390/char/con3270.c	2016-10-31 07:26:46.000000000 -0400
@@ -124,7 +124,12 @@ con3270_create_status(struct con3270 *cp
 static void
 con3270_update_string(struct con3270 *cp, struct string *s, int nr)
 {
-	if (s->len >= cp->view.cols - 5)
+	if (s->len < 4) {
+		/* This indicates a bug, but printing a warning would
+		 * cause a deadlock. */
+		return;
+	}
+	if (s->string[s->len - 4] != TO_RA)
 		return;
 	raw3270_buffer_address(cp->view.dev, s->string + s->len - 3,
 			       cp->view.cols * (nr + 1));
@@ -460,11 +465,11 @@ con3270_cline_end(struct con3270 *cp)
 		cp->cline->len + 4 : cp->view.cols;
 	s = con3270_alloc_string(cp, size);
 	memcpy(s->string, cp->cline->string, cp->cline->len);
-	if (s->len < cp->view.cols - 5) {
+	if (cp->cline->len < cp->view.cols - 5) {
 		s->string[s->len - 4] = TO_RA;
 		s->string[s->len - 1] = 0;
 	} else {
-		while (--size > cp->cline->len)
+		while (--size >= cp->cline->len)
 			s->string[size] = cp->view.ascebc[' '];
 	}
 	/* Replace cline with allocated line s and reset cline. */
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/s390/cio/chsc.c linux-libre-4.8.6-gnu/drivers/s390/cio/chsc.c
--- linux-libre-4.8.5-gnu/drivers/s390/cio/chsc.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/s390/cio/chsc.c	2016-10-31 07:26:46.000000000 -0400
@@ -95,12 +95,13 @@ struct chsc_ssd_area {
 int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd)
 {
 	struct chsc_ssd_area *ssd_area;
+	unsigned long flags;
 	int ccode;
 	int ret;
 	int i;
 	int mask;
 
-	spin_lock_irq(&chsc_page_lock);
+	spin_lock_irqsave(&chsc_page_lock, flags);
 	memset(chsc_page, 0, PAGE_SIZE);
 	ssd_area = chsc_page;
 	ssd_area->request.length = 0x0010;
@@ -144,7 +145,7 @@ int chsc_get_ssd_info(struct subchannel_
 			ssd->fla[i] = ssd_area->fla[i];
 	}
 out:
-	spin_unlock_irq(&chsc_page_lock);
+	spin_unlock_irqrestore(&chsc_page_lock, flags);
 	return ret;
 }
 
@@ -832,9 +833,10 @@ int __chsc_do_secm(struct channel_subsys
 		u32 fmt : 4;
 		u32 : 16;
 	} __attribute__ ((packed)) *secm_area;
+	unsigned long flags;
 	int ret, ccode;
 
-	spin_lock_irq(&chsc_page_lock);
+	spin_lock_irqsave(&chsc_page_lock, flags);
 	memset(chsc_page, 0, PAGE_SIZE);
 	secm_area = chsc_page;
 	secm_area->request.length = 0x0050;
@@ -864,7 +866,7 @@ int __chsc_do_secm(struct channel_subsys
 		CIO_CRW_EVENT(2, "chsc: secm failed (rc=%04x)\n",
 			      secm_area->response.code);
 out:
-	spin_unlock_irq(&chsc_page_lock);
+	spin_unlock_irqrestore(&chsc_page_lock, flags);
 	return ret;
 }
 
@@ -992,6 +994,7 @@ chsc_initialize_cmg_chars(struct channel
 
 int chsc_get_channel_measurement_chars(struct channel_path *chp)
 {
+	unsigned long flags;
 	int ccode, ret;
 
 	struct {
@@ -1021,7 +1024,7 @@ int chsc_get_channel_measurement_chars(s
 	if (!css_chsc_characteristics.scmc || !css_chsc_characteristics.secm)
 		return -EINVAL;
 
-	spin_lock_irq(&chsc_page_lock);
+	spin_lock_irqsave(&chsc_page_lock, flags);
 	memset(chsc_page, 0, PAGE_SIZE);
 	scmc_area = chsc_page;
 	scmc_area->request.length = 0x0010;
@@ -1053,7 +1056,7 @@ int chsc_get_channel_measurement_chars(s
 	chsc_initialize_cmg_chars(chp, scmc_area->cmcv,
 				  (struct cmg_chars *) &scmc_area->data);
 out:
-	spin_unlock_irq(&chsc_page_lock);
+	spin_unlock_irqrestore(&chsc_page_lock, flags);
 	return ret;
 }
 
@@ -1134,6 +1137,7 @@ struct css_chsc_char css_chsc_characteri
 int __init
 chsc_determine_css_characteristics(void)
 {
+	unsigned long flags;
 	int result;
 	struct {
 		struct chsc_header request;
@@ -1146,7 +1150,7 @@ chsc_determine_css_characteristics(void)
 		u32 chsc_char[508];
 	} __attribute__ ((packed)) *scsc_area;
 
-	spin_lock_irq(&chsc_page_lock);
+	spin_lock_irqsave(&chsc_page_lock, flags);
 	memset(chsc_page, 0, PAGE_SIZE);
 	scsc_area = chsc_page;
 	scsc_area->request.length = 0x0010;
@@ -1168,7 +1172,7 @@ chsc_determine_css_characteristics(void)
 		CIO_CRW_EVENT(2, "chsc: scsc failed (rc=%04x)\n",
 			      scsc_area->response.code);
 exit:
-	spin_unlock_irq(&chsc_page_lock);
+	spin_unlock_irqrestore(&chsc_page_lock, flags);
 	return result;
 }
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/scsi/cxlflash/main.c linux-libre-4.8.6-gnu/drivers/scsi/cxlflash/main.c
--- linux-libre-4.8.5-gnu/drivers/scsi/cxlflash/main.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/scsi/cxlflash/main.c	2016-10-31 07:26:46.000000000 -0400
@@ -823,17 +823,6 @@ static void notify_shutdown(struct cxlfl
 }
 
 /**
- * cxlflash_shutdown() - shutdown handler
- * @pdev:	PCI device associated with the host.
- */
-static void cxlflash_shutdown(struct pci_dev *pdev)
-{
-	struct cxlflash_cfg *cfg = pci_get_drvdata(pdev);
-
-	notify_shutdown(cfg, false);
-}
-
-/**
  * cxlflash_remove() - PCI entry point to tear down host
  * @pdev:	PCI device associated with the host.
  *
@@ -844,6 +833,11 @@ static void cxlflash_remove(struct pci_d
 	struct cxlflash_cfg *cfg = pci_get_drvdata(pdev);
 	ulong lock_flags;
 
+	if (!pci_is_enabled(pdev)) {
+		pr_debug("%s: Device is disabled\n", __func__);
+		return;
+	}
+
 	/* If a Task Management Function is active, wait for it to complete
 	 * before continuing with remove.
 	 */
@@ -2685,7 +2679,7 @@ static struct pci_driver cxlflash_driver
 	.id_table = cxlflash_pci_table,
 	.probe = cxlflash_probe,
 	.remove = cxlflash_remove,
-	.shutdown = cxlflash_shutdown,
+	.shutdown = cxlflash_remove,
 	.err_handler = &cxlflash_err_handler,
 };
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c linux-libre-4.8.6-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c
--- linux-libre-4.8.5-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c	2016-10-31 07:26:46.000000000 -0400
@@ -4701,7 +4701,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *i
 			    le16_to_cpu(mpi_reply->DevHandle));
 		mpt3sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq);
 
-		if (!(ioc->logging_level & MPT_DEBUG_REPLY) &&
+		if ((ioc->logging_level & MPT_DEBUG_REPLY) &&
 		     ((scmd->sense_buffer[2] == UNIT_ATTENTION) ||
 		     (scmd->sense_buffer[2] == MEDIUM_ERROR) ||
 		     (scmd->sense_buffer[2] == HARDWARE_ERROR)))
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/spi/spi-fsl-dspi.c linux-libre-4.8.6-gnu/drivers/spi/spi-fsl-dspi.c
--- linux-libre-4.8.5-gnu/drivers/spi/spi-fsl-dspi.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/spi/spi-fsl-dspi.c	2016-10-31 07:26:46.000000000 -0400
@@ -760,7 +760,6 @@ static int dspi_remove(struct platform_d
 	/* Disconnect from the SPI framework */
 	clk_disable_unprepare(dspi->clk);
 	spi_unregister_master(dspi->master);
-	spi_master_put(dspi->master);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/staging/android/ion/Kconfig linux-libre-4.8.6-gnu/drivers/staging/android/ion/Kconfig
--- linux-libre-4.8.5-gnu/drivers/staging/android/ion/Kconfig	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/staging/android/ion/Kconfig	2016-10-31 07:26:46.000000000 -0400
@@ -36,6 +36,7 @@ config ION_TEGRA
 config ION_HISI
 	tristate "Ion for Hisilicon"
 	depends on ARCH_HISI && ION
+	select ION_OF
 	help
 	  Choose this option if you wish to use ion on Hisilicon Platform.
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/staging/ks7010/ks_hostif.c linux-libre-4.8.6-gnu/drivers/staging/ks7010/ks_hostif.c
--- linux-libre-4.8.5-gnu/drivers/staging/ks7010/ks_hostif.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/staging/ks7010/ks_hostif.c	2016-10-31 07:26:46.000000000 -0400
@@ -69,16 +69,20 @@ inline u32 get_DWORD(struct ks_wlan_priv
 	return data;
 }
 
-void ks_wlan_hw_wakeup_task(struct work_struct *work)
+static void ks_wlan_hw_wakeup_task(struct work_struct *work)
 {
 	struct ks_wlan_private *priv =
 	    container_of(work, struct ks_wlan_private, ks_wlan_wakeup_task);
 	int ps_status = atomic_read(&priv->psstatus.status);
+	long time_left;
 
 	if (ps_status == PS_SNOOZE) {
 		ks_wlan_hw_wakeup_request(priv);
-		if (!wait_for_completion_interruptible_timeout(&priv->psstatus.wakeup_wait, HZ / 50)) {	/* 20ms timeout */
-			DPRINTK(1, "wake up timeout !!!\n");
+		time_left = wait_for_completion_interruptible_timeout(
+				&priv->psstatus.wakeup_wait,
+				msecs_to_jiffies(20));
+		if (time_left <= 0) {
+			DPRINTK(1, "wake up timeout or interrupted !!!\n");
 			schedule_work(&priv->ks_wlan_wakeup_task);
 			return;
 		}
@@ -1505,7 +1509,7 @@ void hostif_infrastructure_set_request(s
 	ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
 }
 
-void hostif_infrastructure_set2_request(struct ks_wlan_private *priv)
+static void hostif_infrastructure_set2_request(struct ks_wlan_private *priv)
 {
 	struct hostif_infrastructure_set2_request_t *pp;
 	uint16_t capability;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/staging/rtl8188eu/core/rtw_cmd.c linux-libre-4.8.6-gnu/drivers/staging/rtl8188eu/core/rtw_cmd.c
--- linux-libre-4.8.5-gnu/drivers/staging/rtl8188eu/core/rtw_cmd.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/staging/rtl8188eu/core/rtw_cmd.c	2016-10-31 07:26:46.000000000 -0400
@@ -670,13 +670,13 @@ u8 rtw_addbareq_cmd(struct adapter *pada
 	u8	res = _SUCCESS;
 
 
-	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
+	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
 	if (!ph2c) {
 		res = _FAIL;
 		goto exit;
 	}
 
-	paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_KERNEL);
+	paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC);
 	if (!paddbareq_parm) {
 		kfree(ph2c);
 		res = _FAIL;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/staging/sm750fb/ddk750_mode.c linux-libre-4.8.6-gnu/drivers/staging/sm750fb/ddk750_mode.c
--- linux-libre-4.8.5-gnu/drivers/staging/sm750fb/ddk750_mode.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/staging/sm750fb/ddk750_mode.c	2016-10-31 07:26:46.000000000 -0400
@@ -63,7 +63,7 @@ static unsigned long displayControlAdjus
 	dispControl |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT);
 
 	/* Set bit 14 of display controller */
-	dispControl = DISPLAY_CTRL_CLOCK_PHASE;
+	dispControl |= DISPLAY_CTRL_CLOCK_PHASE;
 
 	POKE32(CRT_DISPLAY_CTRL, dispControl);
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/drivers/uio/uio_dmem_genirq.c linux-libre-4.8.6-gnu/drivers/uio/uio_dmem_genirq.c
--- linux-libre-4.8.5-gnu/drivers/uio/uio_dmem_genirq.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/drivers/uio/uio_dmem_genirq.c	2016-10-31 07:26:46.000000000 -0400
@@ -229,7 +229,7 @@ static int uio_dmem_genirq_probe(struct
 		++uiomem;
 	}
 
-	priv->dmem_region_start = i;
+	priv->dmem_region_start = uiomem - &uioinfo->mem[0];
 	priv->num_dmem_regions = pdata->num_dynamic_regions;
 
 	for (i = 0; i < pdata->num_dynamic_regions; ++i) {
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/9p/acl.c linux-libre-4.8.6-gnu/fs/9p/acl.c
--- linux-libre-4.8.5-gnu/fs/9p/acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/9p/acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -276,32 +276,26 @@ static int v9fs_xattr_set_acl(const stru
 	switch (handler->flags) {
 	case ACL_TYPE_ACCESS:
 		if (acl) {
-			umode_t mode = inode->i_mode;
-			retval = posix_acl_equiv_mode(acl, &mode);
-			if (retval < 0)
+			struct iattr iattr;
+
+			retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
+			if (retval)
 				goto err_out;
-			else {
-				struct iattr iattr;
-				if (retval == 0) {
-					/*
-					 * ACL can be represented
-					 * by the mode bits. So don't
-					 * update ACL.
-					 */
-					acl = NULL;
-					value = NULL;
-					size = 0;
-				}
-				/* Updte the mode bits */
-				iattr.ia_mode = ((mode & S_IALLUGO) |
-						 (inode->i_mode & ~S_IALLUGO));
-				iattr.ia_valid = ATTR_MODE;
-				/* FIXME should we update ctime ?
-				 * What is the following setxattr update the
-				 * mode ?
+			if (!acl) {
+				/*
+				 * ACL can be represented
+				 * by the mode bits. So don't
+				 * update ACL.
 				 */
-				v9fs_vfs_setattr_dotl(dentry, &iattr);
+				value = NULL;
+				size = 0;
 			}
+			iattr.ia_valid = ATTR_MODE;
+			/* FIXME should we update ctime ?
+			 * What is the following setxattr update the
+			 * mode ?
+			 */
+			v9fs_vfs_setattr_dotl(dentry, &iattr);
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/btrfs/acl.c linux-libre-4.8.6-gnu/fs/btrfs/acl.c
--- linux-libre-4.8.5-gnu/fs/btrfs/acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/btrfs/acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -79,11 +79,9 @@ static int __btrfs_set_acl(struct btrfs_
 	case ACL_TYPE_ACCESS:
 		name = XATTR_NAME_POSIX_ACL_ACCESS;
 		if (acl) {
-			ret = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (ret < 0)
+			ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (ret)
 				return ret;
-			if (ret == 0)
-				acl = NULL;
 		}
 		ret = 0;
 		break;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/ceph/acl.c linux-libre-4.8.6-gnu/fs/ceph/acl.c
--- linux-libre-4.8.5-gnu/fs/ceph/acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/ceph/acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -95,11 +95,9 @@ int ceph_set_acl(struct inode *inode, st
 	case ACL_TYPE_ACCESS:
 		name = XATTR_NAME_POSIX_ACL_ACCESS;
 		if (acl) {
-			ret = posix_acl_equiv_mode(acl, &new_mode);
-			if (ret < 0)
+			ret = posix_acl_update_mode(inode, &new_mode, &acl);
+			if (ret)
 				goto out;
-			if (ret == 0)
-				acl = NULL;
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/ext2/acl.c linux-libre-4.8.6-gnu/fs/ext2/acl.c
--- linux-libre-4.8.5-gnu/fs/ext2/acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/ext2/acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -190,15 +190,11 @@ ext2_set_acl(struct inode *inode, struct
 		case ACL_TYPE_ACCESS:
 			name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
 			if (acl) {
-				error = posix_acl_equiv_mode(acl, &inode->i_mode);
-				if (error < 0)
+				error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+				if (error)
 					return error;
-				else {
-					inode->i_ctime = CURRENT_TIME_SEC;
-					mark_inode_dirty(inode);
-					if (error == 0)
-						acl = NULL;
-				}
+				inode->i_ctime = CURRENT_TIME_SEC;
+				mark_inode_dirty(inode);
 			}
 			break;
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/ext4/acl.c linux-libre-4.8.6-gnu/fs/ext4/acl.c
--- linux-libre-4.8.5-gnu/fs/ext4/acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/ext4/acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -193,15 +193,11 @@ __ext4_set_acl(handle_t *handle, struct
 	case ACL_TYPE_ACCESS:
 		name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
 		if (acl) {
-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (error < 0)
+			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (error)
 				return error;
-			else {
-				inode->i_ctime = ext4_current_time(inode);
-				ext4_mark_inode_dirty(handle, inode);
-				if (error == 0)
-					acl = NULL;
-			}
+			inode->i_ctime = ext4_current_time(inode);
+			ext4_mark_inode_dirty(handle, inode);
 		}
 		break;
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/f2fs/acl.c linux-libre-4.8.6-gnu/fs/f2fs/acl.c
--- linux-libre-4.8.5-gnu/fs/f2fs/acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/f2fs/acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -210,12 +210,10 @@ static int __f2fs_set_acl(struct inode *
 	case ACL_TYPE_ACCESS:
 		name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
 		if (acl) {
-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (error < 0)
+			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (error)
 				return error;
 			set_acl_inode(inode, inode->i_mode);
-			if (error == 0)
-				acl = NULL;
 		}
 		break;
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/gfs2/acl.c linux-libre-4.8.6-gnu/fs/gfs2/acl.c
--- linux-libre-4.8.5-gnu/fs/gfs2/acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/gfs2/acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -92,17 +92,11 @@ int __gfs2_set_acl(struct inode *inode,
 	if (type == ACL_TYPE_ACCESS) {
 		umode_t mode = inode->i_mode;
 
-		error = posix_acl_equiv_mode(acl, &mode);
-		if (error < 0)
+		error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+		if (error)
 			return error;
-
-		if (error == 0)
-			acl = NULL;
-
-		if (mode != inode->i_mode) {
-			inode->i_mode = mode;
+		if (mode != inode->i_mode)
 			mark_inode_dirty(inode);
-		}
 	}
 
 	if (acl) {
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/hfsplus/posix_acl.c linux-libre-4.8.6-gnu/fs/hfsplus/posix_acl.c
--- linux-libre-4.8.5-gnu/fs/hfsplus/posix_acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/hfsplus/posix_acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -65,8 +65,8 @@ int hfsplus_set_posix_acl(struct inode *
 	case ACL_TYPE_ACCESS:
 		xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
 		if (acl) {
-			err = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (err < 0)
+			err = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (err)
 				return err;
 		}
 		err = 0;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/jffs2/acl.c linux-libre-4.8.6-gnu/fs/jffs2/acl.c
--- linux-libre-4.8.5-gnu/fs/jffs2/acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/jffs2/acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -233,9 +233,10 @@ int jffs2_set_acl(struct inode *inode, s
 	case ACL_TYPE_ACCESS:
 		xprefix = JFFS2_XPREFIX_ACL_ACCESS;
 		if (acl) {
-			umode_t mode = inode->i_mode;
-			rc = posix_acl_equiv_mode(acl, &mode);
-			if (rc < 0)
+			umode_t mode;
+
+			rc = posix_acl_update_mode(inode, &mode, &acl);
+			if (rc)
 				return rc;
 			if (inode->i_mode != mode) {
 				struct iattr attr;
@@ -247,8 +248,6 @@ int jffs2_set_acl(struct inode *inode, s
 				if (rc < 0)
 					return rc;
 			}
-			if (rc == 0)
-				acl = NULL;
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/jfs/acl.c linux-libre-4.8.6-gnu/fs/jfs/acl.c
--- linux-libre-4.8.5-gnu/fs/jfs/acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/jfs/acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -78,13 +78,11 @@ static int __jfs_set_acl(tid_t tid, stru
 	case ACL_TYPE_ACCESS:
 		ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
 		if (acl) {
-			rc = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (rc < 0)
+			rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (rc)
 				return rc;
 			inode->i_ctime = CURRENT_TIME;
 			mark_inode_dirty(inode);
-			if (rc == 0)
-				acl = NULL;
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/ocfs2/acl.c linux-libre-4.8.6-gnu/fs/ocfs2/acl.c
--- linux-libre-4.8.5-gnu/fs/ocfs2/acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/ocfs2/acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -241,13 +241,11 @@ int ocfs2_set_acl(handle_t *handle,
 	case ACL_TYPE_ACCESS:
 		name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
 		if (acl) {
-			umode_t mode = inode->i_mode;
-			ret = posix_acl_equiv_mode(acl, &mode);
-			if (ret < 0)
-				return ret;
+			umode_t mode;
 
-			if (ret == 0)
-				acl = NULL;
+			ret = posix_acl_update_mode(inode, &mode, &acl);
+			if (ret)
+				return ret;
 
 			ret = ocfs2_acl_set_mode(inode, di_bh,
 						 handle, mode);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/orangefs/acl.c linux-libre-4.8.6-gnu/fs/orangefs/acl.c
--- linux-libre-4.8.5-gnu/fs/orangefs/acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/orangefs/acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -73,14 +73,11 @@ int orangefs_set_acl(struct inode *inode
 	case ACL_TYPE_ACCESS:
 		name = XATTR_NAME_POSIX_ACL_ACCESS;
 		if (acl) {
-			umode_t mode = inode->i_mode;
-			/*
-			 * can we represent this with the traditional file
-			 * mode permission bits?
-			 */
-			error = posix_acl_equiv_mode(acl, &mode);
-			if (error < 0) {
-				gossip_err("%s: posix_acl_equiv_mode err: %d\n",
+			umode_t mode;
+
+			error = posix_acl_update_mode(inode, &mode, &acl);
+			if (error) {
+				gossip_err("%s: posix_acl_update_mode err: %d\n",
 					   __func__,
 					   error);
 				return error;
@@ -90,8 +87,6 @@ int orangefs_set_acl(struct inode *inode
 				SetModeFlag(orangefs_inode);
 			inode->i_mode = mode;
 			mark_inode_dirty_sync(inode);
-			if (error == 0)
-				acl = NULL;
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/posix_acl.c linux-libre-4.8.6-gnu/fs/posix_acl.c
--- linux-libre-4.8.5-gnu/fs/posix_acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/posix_acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -626,6 +626,37 @@ no_mem:
 }
 EXPORT_SYMBOL_GPL(posix_acl_create);
 
+/**
+ * posix_acl_update_mode  -  update mode in set_acl
+ *
+ * Update the file mode when setting an ACL: compute the new file permission
+ * bits based on the ACL.  In addition, if the ACL is equivalent to the new
+ * file mode, set *acl to NULL to indicate that no ACL should be set.
+ *
+ * As with chmod, clear the setgit bit if the caller is not in the owning group
+ * or capable of CAP_FSETID (see inode_change_ok).
+ *
+ * Called from set_acl inode operations.
+ */
+int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
+			  struct posix_acl **acl)
+{
+	umode_t mode = inode->i_mode;
+	int error;
+
+	error = posix_acl_equiv_mode(*acl, &mode);
+	if (error < 0)
+		return error;
+	if (error == 0)
+		*acl = NULL;
+	if (!in_group_p(inode->i_gid) &&
+	    !capable_wrt_inode_uidgid(inode, CAP_FSETID))
+		mode &= ~S_ISGID;
+	*mode_p = mode;
+	return 0;
+}
+EXPORT_SYMBOL(posix_acl_update_mode);
+
 /*
  * Fix up the uids and gids in posix acl extended attributes in place.
  */
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/reiserfs/xattr_acl.c linux-libre-4.8.6-gnu/fs/reiserfs/xattr_acl.c
--- linux-libre-4.8.5-gnu/fs/reiserfs/xattr_acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/reiserfs/xattr_acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -242,13 +242,9 @@ __reiserfs_set_acl(struct reiserfs_trans
 	case ACL_TYPE_ACCESS:
 		name = XATTR_NAME_POSIX_ACL_ACCESS;
 		if (acl) {
-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (error < 0)
+			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (error)
 				return error;
-			else {
-				if (error == 0)
-					acl = NULL;
-			}
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-4.8.5-gnu/fs/xfs/xfs_acl.c linux-libre-4.8.6-gnu/fs/xfs/xfs_acl.c
--- linux-libre-4.8.5-gnu/fs/xfs/xfs_acl.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/fs/xfs/xfs_acl.c	2016-10-31 07:26:46.000000000 -0400
@@ -257,16 +257,11 @@ xfs_set_acl(struct inode *inode, struct
 		return error;
 
 	if (type == ACL_TYPE_ACCESS) {
-		umode_t mode = inode->i_mode;
-		error = posix_acl_equiv_mode(acl, &mode);
-
-		if (error <= 0) {
-			acl = NULL;
-
-			if (error < 0)
-				return error;
-		}
+		umode_t mode;
 
+		error = posix_acl_update_mode(inode, &mode, &acl);
+		if (error)
+			return error;
 		error = xfs_set_mode(inode, mode);
 		if (error)
 			return error;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/include/drm/drmP.h linux-libre-4.8.6-gnu/include/drm/drmP.h
--- linux-libre-4.8.5-gnu/include/drm/drmP.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/include/drm/drmP.h	2016-10-31 07:26:46.000000000 -0400
@@ -938,7 +938,8 @@ static inline int drm_debugfs_remove_fil
 #endif
 
 extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
-		struct drm_gem_object *obj, int flags);
+					    struct drm_gem_object *obj,
+					    int flags);
 extern int drm_gem_prime_handle_to_fd(struct drm_device *dev,
 		struct drm_file *file_priv, uint32_t handle, uint32_t flags,
 		int *prime_fd);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/include/linux/hugetlb.h linux-libre-4.8.6-gnu/include/linux/hugetlb.h
--- linux-libre-4.8.5-gnu/include/linux/hugetlb.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/include/linux/hugetlb.h	2016-10-31 07:26:46.000000000 -0400
@@ -450,8 +450,8 @@ static inline pgoff_t basepage_index(str
 	return __basepage_index(page);
 }
 
-extern void dissolve_free_huge_pages(unsigned long start_pfn,
-				     unsigned long end_pfn);
+extern int dissolve_free_huge_pages(unsigned long start_pfn,
+				    unsigned long end_pfn);
 static inline bool hugepage_migration_supported(struct hstate *h)
 {
 #ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION
@@ -518,7 +518,7 @@ static inline pgoff_t basepage_index(str
 {
 	return page->index;
 }
-#define dissolve_free_huge_pages(s, e)	do {} while (0)
+#define dissolve_free_huge_pages(s, e)	0
 #define hugepage_migration_supported(h)	false
 
 static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
diff -druNp --no-dereference linux-libre-4.8.5-gnu/include/linux/libnvdimm.h linux-libre-4.8.6-gnu/include/linux/libnvdimm.h
--- linux-libre-4.8.5-gnu/include/linux/libnvdimm.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/include/linux/libnvdimm.h	2016-10-31 07:26:46.000000000 -0400
@@ -129,6 +129,8 @@ static inline struct nd_blk_region_desc
 }
 
 int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length);
+void nvdimm_clear_from_poison_list(struct nvdimm_bus *nvdimm_bus,
+		phys_addr_t start, unsigned int len);
 struct nvdimm_bus *nvdimm_bus_register(struct device *parent,
 		struct nvdimm_bus_descriptor *nfit_desc);
 void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/include/linux/posix_acl.h linux-libre-4.8.6-gnu/include/linux/posix_acl.h
--- linux-libre-4.8.5-gnu/include/linux/posix_acl.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/include/linux/posix_acl.h	2016-10-31 07:26:46.000000000 -0400
@@ -93,6 +93,7 @@ extern int set_posix_acl(struct inode *,
 extern int posix_acl_chmod(struct inode *, umode_t);
 extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **,
 		struct posix_acl **);
+extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **);
 
 extern int simple_set_acl(struct inode *, struct posix_acl *, int);
 extern int simple_acl_create(struct inode *, struct inode *);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/kernel/irq/generic-chip.c linux-libre-4.8.6-gnu/kernel/irq/generic-chip.c
--- linux-libre-4.8.5-gnu/kernel/irq/generic-chip.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/kernel/irq/generic-chip.c	2016-10-31 07:26:46.000000000 -0400
@@ -411,8 +411,29 @@ int irq_map_generic_chip(struct irq_doma
 }
 EXPORT_SYMBOL_GPL(irq_map_generic_chip);
 
+static void irq_unmap_generic_chip(struct irq_domain *d, unsigned int virq)
+{
+	struct irq_data *data = irq_domain_get_irq_data(d, virq);
+	struct irq_domain_chip_generic *dgc = d->gc;
+	unsigned int hw_irq = data->hwirq;
+	struct irq_chip_generic *gc;
+	int irq_idx;
+
+	gc = irq_get_domain_generic_chip(d, hw_irq);
+	if (!gc)
+		return;
+
+	irq_idx = hw_irq % dgc->irqs_per_chip;
+
+	clear_bit(irq_idx, &gc->installed);
+	irq_domain_set_info(d, virq, hw_irq, &no_irq_chip, NULL, NULL, NULL,
+			    NULL);
+
+}
+
 struct irq_domain_ops irq_generic_chip_ops = {
 	.map	= irq_map_generic_chip,
+	.unmap  = irq_unmap_generic_chip,
 	.xlate	= irq_domain_xlate_onetwocell,
 };
 EXPORT_SYMBOL_GPL(irq_generic_chip_ops);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/Makefile linux-libre-4.8.6-gnu/Makefile
--- linux-libre-4.8.5-gnu/Makefile	2016-10-28 05:54:14.000000000 -0400
+++ linux-libre-4.8.6-gnu/Makefile	2016-10-31 17:30:35.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 8
-SUBLEVEL = 5
+SUBLEVEL = 6
 EXTRAVERSION = -gnu
 NAME = Psychotic Stoned Sheep
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/mm/hugetlb.c linux-libre-4.8.6-gnu/mm/hugetlb.c
--- linux-libre-4.8.5-gnu/mm/hugetlb.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/mm/hugetlb.c	2016-10-31 07:26:46.000000000 -0400
@@ -1437,22 +1437,32 @@ static int free_pool_huge_page(struct hs
 
 /*
  * Dissolve a given free hugepage into free buddy pages. This function does
- * nothing for in-use (including surplus) hugepages.
+ * nothing for in-use (including surplus) hugepages. Returns -EBUSY if the
+ * number of free hugepages would be reduced below the number of reserved
+ * hugepages.
  */
-static void dissolve_free_huge_page(struct page *page)
+static int dissolve_free_huge_page(struct page *page)
 {
+	int rc = 0;
+
 	spin_lock(&hugetlb_lock);
 	if (PageHuge(page) && !page_count(page)) {
 		struct page *head = compound_head(page);
 		struct hstate *h = page_hstate(head);
 		int nid = page_to_nid(head);
+		if (h->free_huge_pages - h->resv_huge_pages == 0) {
+			rc = -EBUSY;
+			goto out;
+		}
 		list_del(&head->lru);
 		h->free_huge_pages--;
 		h->free_huge_pages_node[nid]--;
 		h->max_huge_pages--;
 		update_and_free_page(h, head);
 	}
+out:
 	spin_unlock(&hugetlb_lock);
+	return rc;
 }
 
 /*
@@ -1460,16 +1470,28 @@ static void dissolve_free_huge_page(stru
  * make specified memory blocks removable from the system.
  * Note that this will dissolve a free gigantic hugepage completely, if any
  * part of it lies within the given range.
+ * Also note that if dissolve_free_huge_page() returns with an error, all
+ * free hugepages that were dissolved before that error are lost.
  */
-void dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
+int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
 {
 	unsigned long pfn;
+	struct page *page;
+	int rc = 0;
 
 	if (!hugepages_supported())
-		return;
+		return rc;
 
-	for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order)
-		dissolve_free_huge_page(pfn_to_page(pfn));
+	for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order) {
+		page = pfn_to_page(pfn);
+		if (PageHuge(page) && !page_count(page)) {
+			rc = dissolve_free_huge_page(page);
+			if (rc)
+				break;
+		}
+	}
+
+	return rc;
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.8.5-gnu/mm/memory_hotplug.c linux-libre-4.8.6-gnu/mm/memory_hotplug.c
--- linux-libre-4.8.5-gnu/mm/memory_hotplug.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/mm/memory_hotplug.c	2016-10-31 07:26:46.000000000 -0400
@@ -1945,7 +1945,9 @@ repeat:
 	 * dissolve free hugepages in the memory block before doing offlining
 	 * actually in order to make hugetlbfs's object counting consistent.
 	 */
-	dissolve_free_huge_pages(start_pfn, end_pfn);
+	ret = dissolve_free_huge_pages(start_pfn, end_pfn);
+	if (ret)
+		goto failed_removal;
 	/* check again */
 	offlined_pages = check_pages_isolated(start_pfn, end_pfn);
 	if (offlined_pages < 0) {
diff -druNp --no-dereference linux-libre-4.8.5-gnu/sound/soc/intel/boards/bxt_da7219_max98357a.c linux-libre-4.8.6-gnu/sound/soc/intel/boards/bxt_da7219_max98357a.c
--- linux-libre-4.8.5-gnu/sound/soc/intel/boards/bxt_da7219_max98357a.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/sound/soc/intel/boards/bxt_da7219_max98357a.c	2016-10-31 07:26:46.000000000 -0400
@@ -255,7 +255,7 @@ static struct snd_soc_ops broxton_da7219
 /* broxton digital audio interface glue - connects codec <--> CPU */
 static struct snd_soc_dai_link broxton_dais[] = {
 	/* Front End DAI links */
-	[BXT_DPCM_AUDIO_PB]
+	[BXT_DPCM_AUDIO_PB] =
 	{
 		.name = "Bxt Audio Port",
 		.stream_name = "Audio",
@@ -271,7 +271,7 @@ static struct snd_soc_dai_link broxton_d
 		.dpcm_playback = 1,
 		.ops = &broxton_da7219_fe_ops,
 	},
-	[BXT_DPCM_AUDIO_CP]
+	[BXT_DPCM_AUDIO_CP] =
 	{
 		.name = "Bxt Audio Capture Port",
 		.stream_name = "Audio Record",
@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_d
 		.dpcm_capture = 1,
 		.ops = &broxton_da7219_fe_ops,
 	},
-	[BXT_DPCM_AUDIO_REF_CP]
+	[BXT_DPCM_AUDIO_REF_CP] =
 	{
 		.name = "Bxt Audio Reference cap",
 		.stream_name = "Refcap",
@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_d
 		.nonatomic = 1,
 		.dynamic = 1,
 	},
-	[BXT_DPCM_AUDIO_HDMI1_PB]
+	[BXT_DPCM_AUDIO_HDMI1_PB] =
 	{
 		.name = "Bxt HDMI Port1",
 		.stream_name = "Hdmi1",
@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_d
 		.nonatomic = 1,
 		.dynamic = 1,
 	},
-	[BXT_DPCM_AUDIO_HDMI2_PB]
+	[BXT_DPCM_AUDIO_HDMI2_PB] =
 	{
 		.name = "Bxt HDMI Port2",
 		.stream_name = "Hdmi2",
@@ -326,7 +326,7 @@ static struct snd_soc_dai_link broxton_d
 		.nonatomic = 1,
 		.dynamic = 1,
 	},
-	[BXT_DPCM_AUDIO_HDMI3_PB]
+	[BXT_DPCM_AUDIO_HDMI3_PB] =
 	{
 		.name = "Bxt HDMI Port3",
 		.stream_name = "Hdmi3",
diff -druNp --no-dereference linux-libre-4.8.5-gnu/sound/soc/intel/boards/bxt_rt298.c linux-libre-4.8.6-gnu/sound/soc/intel/boards/bxt_rt298.c
--- linux-libre-4.8.5-gnu/sound/soc/intel/boards/bxt_rt298.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/sound/soc/intel/boards/bxt_rt298.c	2016-10-31 07:26:46.000000000 -0400
@@ -271,7 +271,7 @@ static const struct snd_soc_ops broxton_
 /* broxton digital audio interface glue - connects codec <--> CPU */
 static struct snd_soc_dai_link broxton_rt298_dais[] = {
 	/* Front End DAI links */
-	[BXT_DPCM_AUDIO_PB]
+	[BXT_DPCM_AUDIO_PB] =
 	{
 		.name = "Bxt Audio Port",
 		.stream_name = "Audio",
@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_r
 		.dpcm_playback = 1,
 		.ops = &broxton_rt286_fe_ops,
 	},
-	[BXT_DPCM_AUDIO_CP]
+	[BXT_DPCM_AUDIO_CP] =
 	{
 		.name = "Bxt Audio Capture Port",
 		.stream_name = "Audio Record",
@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_r
 		.dpcm_capture = 1,
 		.ops = &broxton_rt286_fe_ops,
 	},
-	[BXT_DPCM_AUDIO_REF_CP]
+	[BXT_DPCM_AUDIO_REF_CP] =
 	{
 		.name = "Bxt Audio Reference cap",
 		.stream_name = "refcap",
@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_r
 		.nonatomic = 1,
 		.dynamic = 1,
 	},
-	[BXT_DPCM_AUDIO_DMIC_CP]
+	[BXT_DPCM_AUDIO_DMIC_CP] =
 	{
 		.name = "Bxt Audio DMIC cap",
 		.stream_name = "dmiccap",
@@ -327,7 +327,7 @@ static struct snd_soc_dai_link broxton_r
 		.dynamic = 1,
 		.ops = &broxton_dmic_ops,
 	},
-	[BXT_DPCM_AUDIO_HDMI1_PB]
+	[BXT_DPCM_AUDIO_HDMI1_PB] =
 	{
 		.name = "Bxt HDMI Port1",
 		.stream_name = "Hdmi1",
@@ -340,7 +340,7 @@ static struct snd_soc_dai_link broxton_r
 		.nonatomic = 1,
 		.dynamic = 1,
 	},
-	[BXT_DPCM_AUDIO_HDMI2_PB]
+	[BXT_DPCM_AUDIO_HDMI2_PB] =
 	{
 		.name = "Bxt HDMI Port2",
 		.stream_name = "Hdmi2",
@@ -353,7 +353,7 @@ static struct snd_soc_dai_link broxton_r
 		.nonatomic = 1,
 		.dynamic = 1,
 	},
-	[BXT_DPCM_AUDIO_HDMI3_PB]
+	[BXT_DPCM_AUDIO_HDMI3_PB] =
 	{
 		.name = "Bxt HDMI Port3",
 		.stream_name = "Hdmi3",
diff -druNp --no-dereference linux-libre-4.8.5-gnu/sound/soc/soc-dapm.c linux-libre-4.8.6-gnu/sound/soc/soc-dapm.c
--- linux-libre-4.8.5-gnu/sound/soc/soc-dapm.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/sound/soc/soc-dapm.c	2016-10-31 07:26:46.000000000 -0400
@@ -823,6 +823,7 @@ static int dapm_create_or_share_kcontrol
 			case snd_soc_dapm_switch:
 			case snd_soc_dapm_mixer:
 			case snd_soc_dapm_pga:
+			case snd_soc_dapm_out_drv:
 				wname_in_long_name = true;
 				kcname_in_long_name = true;
 				break;
@@ -3049,6 +3050,9 @@ int snd_soc_dapm_get_volsw(struct snd_kc
 	}
 	mutex_unlock(&card->dapm_mutex);
 
+	if (ret)
+		return ret;
+
 	if (invert)
 		ucontrol->value.integer.value[0] = max - val;
 	else
@@ -3200,7 +3204,7 @@ int snd_soc_dapm_put_enum_double(struct
 	if (e->shift_l != e->shift_r) {
 		if (item[1] > e->items)
 			return -EINVAL;
-		val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l;
+		val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r;
 		mask |= e->mask << e->shift_r;
 	}
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/sound/soc/soc-topology.c linux-libre-4.8.6-gnu/sound/soc/soc-topology.c
--- linux-libre-4.8.5-gnu/sound/soc/soc-topology.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/sound/soc/soc-topology.c	2016-10-31 07:26:46.000000000 -0400
@@ -1475,6 +1475,7 @@ widget:
 	if (widget == NULL) {
 		dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n",
 			w->name);
+		ret = -ENOMEM;
 		goto hdr_err;
 	}
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/tools/perf/perf-sys.h linux-libre-4.8.6-gnu/tools/perf/perf-sys.h
--- linux-libre-4.8.5-gnu/tools/perf/perf-sys.h	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/tools/perf/perf-sys.h	2016-10-31 07:26:46.000000000 -0400
@@ -20,7 +20,6 @@
 #endif
 
 #ifdef __powerpc__
-#include "../../arch/powerpc/include/uapi/asm/unistd.h"
 #define CPUINFO_PROC	{"cpu"}
 #endif
 
diff -druNp --no-dereference linux-libre-4.8.5-gnu/tools/perf/ui/browsers/hists.c linux-libre-4.8.6-gnu/tools/perf/ui/browsers/hists.c
--- linux-libre-4.8.5-gnu/tools/perf/ui/browsers/hists.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/tools/perf/ui/browsers/hists.c	2016-10-31 07:26:46.000000000 -0400
@@ -1091,7 +1091,6 @@ static int __hpp__slsmg_color_printf(str
 	ret = scnprintf(hpp->buf, hpp->size, fmt, len, percent);
 	ui_browser__printf(arg->b, "%s", hpp->buf);
 
-	advance_hpp(hpp, ret);
 	return ret;
 }
 
@@ -2046,6 +2045,7 @@ void hist_browser__init(struct hist_brow
 			struct hists *hists)
 {
 	struct perf_hpp_fmt *fmt;
+	struct perf_hpp_list_node *node;
 
 	browser->hists			= hists;
 	browser->b.refresh		= hist_browser__refresh;
@@ -2058,6 +2058,11 @@ void hist_browser__init(struct hist_brow
 		perf_hpp__reset_width(fmt, hists);
 		++browser->b.columns;
 	}
+	/* hierarchy entries have their own hpp list */
+	list_for_each_entry(node, &hists->hpp_formats, list) {
+		perf_hpp_list__for_each_format(&node->hpp, fmt)
+			perf_hpp__reset_width(fmt, hists);
+	}
 }
 
 struct hist_browser *hist_browser__new(struct hists *hists)
diff -druNp --no-dereference linux-libre-4.8.5-gnu/tools/perf/ui/stdio/hist.c linux-libre-4.8.6-gnu/tools/perf/ui/stdio/hist.c
--- linux-libre-4.8.5-gnu/tools/perf/ui/stdio/hist.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/tools/perf/ui/stdio/hist.c	2016-10-31 07:26:46.000000000 -0400
@@ -628,14 +628,6 @@ hists__fprintf_hierarchy_headers(struct
 				 struct perf_hpp *hpp,
 				 FILE *fp)
 {
-	struct perf_hpp_list_node *fmt_node;
-	struct perf_hpp_fmt *fmt;
-
-	list_for_each_entry(fmt_node, &hists->hpp_formats, list) {
-		perf_hpp_list__for_each_format(&fmt_node->hpp, fmt)
-			perf_hpp__reset_width(fmt, hists);
-	}
-
 	return print_hierarchy_header(hists, hpp, symbol_conf.field_sep, fp);
 }
 
@@ -714,6 +706,7 @@ size_t hists__fprintf(struct hists *hist
 		      bool use_callchain)
 {
 	struct perf_hpp_fmt *fmt;
+	struct perf_hpp_list_node *node;
 	struct rb_node *nd;
 	size_t ret = 0;
 	const char *sep = symbol_conf.field_sep;
@@ -726,6 +719,11 @@ size_t hists__fprintf(struct hists *hist
 
 	hists__for_each_format(hists, fmt)
 		perf_hpp__reset_width(fmt, hists);
+	/* hierarchy entries have their own hpp list */
+	list_for_each_entry(node, &hists->hpp_formats, list) {
+		perf_hpp_list__for_each_format(&node->hpp, fmt)
+			perf_hpp__reset_width(fmt, hists);
+	}
 
 	if (symbol_conf.col_width_list_str)
 		perf_hpp__set_user_width(symbol_conf.col_width_list_str);
diff -druNp --no-dereference linux-libre-4.8.5-gnu/tools/perf/util/data-convert-bt.c linux-libre-4.8.6-gnu/tools/perf/util/data-convert-bt.c
--- linux-libre-4.8.5-gnu/tools/perf/util/data-convert-bt.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/tools/perf/util/data-convert-bt.c	2016-10-31 07:26:46.000000000 -0400
@@ -437,7 +437,7 @@ add_bpf_output_values(struct bt_ctf_even
 	int ret;
 
 	if (nr_elements * sizeof(u32) != raw_size)
-		pr_warning("Incorrect raw_size (%u) in bpf output event, skip %lu bytes\n",
+		pr_warning("Incorrect raw_size (%u) in bpf output event, skip %zu bytes\n",
 			   raw_size, nr_elements * sizeof(u32) - raw_size);
 
 	len_type = bt_ctf_event_class_get_field_by_name(event_class, "raw_len");
diff -druNp --no-dereference linux-libre-4.8.5-gnu/tools/perf/util/symbol.c linux-libre-4.8.6-gnu/tools/perf/util/symbol.c
--- linux-libre-4.8.5-gnu/tools/perf/util/symbol.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/tools/perf/util/symbol.c	2016-10-31 07:26:46.000000000 -0400
@@ -152,6 +152,9 @@ void symbols__fixup_duplicate(struct rb_
 	struct rb_node *nd;
 	struct symbol *curr, *next;
 
+	if (symbol_conf.allow_aliases)
+		return;
+
 	nd = rb_first(symbols);
 
 	while (nd) {
@@ -1234,8 +1237,8 @@ int __dso__load_kallsyms(struct dso *dso
 	if (kallsyms__delta(map, filename, &delta))
 		return -1;
 
-	symbols__fixup_duplicate(&dso->symbols[map->type]);
 	symbols__fixup_end(&dso->symbols[map->type]);
+	symbols__fixup_duplicate(&dso->symbols[map->type]);
 
 	if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
 		dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
diff -druNp --no-dereference linux-libre-4.8.5-gnu/tools/perf/util/symbol-elf.c linux-libre-4.8.6-gnu/tools/perf/util/symbol-elf.c
--- linux-libre-4.8.5-gnu/tools/perf/util/symbol-elf.c	2016-10-28 03:51:31.000000000 -0400
+++ linux-libre-4.8.6-gnu/tools/perf/util/symbol-elf.c	2016-10-31 07:26:46.000000000 -0400
@@ -1113,9 +1113,8 @@ new_symbol:
 	 * For misannotated, zeroed, ASM function sizes.
 	 */
 	if (nr > 0) {
-		if (!symbol_conf.allow_aliases)
-			symbols__fixup_duplicate(&dso->symbols[map->type]);
 		symbols__fixup_end(&dso->symbols[map->type]);
+		symbols__fixup_duplicate(&dso->symbols[map->type]);
 		if (kmap) {
 			/*
 			 * We need to fixup this here too because we create new
