diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/arm/boot/dts/omap3-pandora-common.dtsi linux-libre-5.3.17-gnu/arch/arm/boot/dts/omap3-pandora-common.dtsi
--- linux-libre-5.3.16-gnu/arch/arm/boot/dts/omap3-pandora-common.dtsi	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/arm/boot/dts/omap3-pandora-common.dtsi	2019-12-17 14:08:41.000000000 -0500
@@ -226,6 +226,17 @@
 		gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>;	/* GPIO_164 */
 	};
 
+	/* wl1251 wifi+bt module */
+	wlan_en: fixed-regulator-wg7210_en {
+		compatible = "regulator-fixed";
+		regulator-name = "vwlan";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us = <50000>;
+		enable-active-high;
+		gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+	};
+
 	/* wg7210 (wifi+bt module) 32k clock buffer */
 	wg7210_32k: fixed-regulator-wg7210_32k {
 		compatible = "regulator-fixed";
@@ -522,9 +533,30 @@
 	/*wp-gpios = <&gpio4 31 GPIO_ACTIVE_HIGH>;*/	/* GPIO_127 */
 };
 
-/* mmc3 is probed using pdata-quirks to pass wl1251 card data */
 &mmc3 {
-	status = "disabled";
+	vmmc-supply = <&wlan_en>;
+
+	bus-width = <4>;
+	non-removable;
+	ti,non-removable;
+	cap-power-off-card;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc3_pins>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	wlan: wifi@1 {
+		compatible = "ti,wl1251";
+
+		reg = <1>;
+
+		interrupt-parent = <&gpio1>;
+		interrupts = <21 IRQ_TYPE_LEVEL_HIGH>;	/* GPIO_21 */
+
+		ti,wl1251-has-eeprom;
+	};
 };
 
 /* bluetooth*/
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/arm/boot/dts/omap3-tao3530.dtsi linux-libre-5.3.17-gnu/arch/arm/boot/dts/omap3-tao3530.dtsi
--- linux-libre-5.3.16-gnu/arch/arm/boot/dts/omap3-tao3530.dtsi	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/arm/boot/dts/omap3-tao3530.dtsi	2019-12-17 14:08:41.000000000 -0500
@@ -222,7 +222,7 @@
 	pinctrl-0 = <&mmc1_pins>;
 	vmmc-supply = <&vmmc1>;
 	vqmmc-supply = <&vsim>;
-	cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_HIGH>;
+	cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_LOW>;
 	bus-width = <8>;
 };
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/arm/mach-omap2/pdata-quirks.c linux-libre-5.3.17-gnu/arch/arm/mach-omap2/pdata-quirks.c
--- linux-libre-5.3.16-gnu/arch/arm/mach-omap2/pdata-quirks.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/arm/mach-omap2/pdata-quirks.c	2019-12-17 14:08:41.000000000 -0500
@@ -7,7 +7,6 @@
 #include <linux/clk.h>
 #include <linux/davinci_emac.h>
 #include <linux/gpio.h>
-#include <linux/gpio/machine.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/of_platform.h>
@@ -304,118 +303,15 @@ static void __init omap3_logicpd_torpedo
 }
 
 /* omap3pandora legacy devices */
-#define PANDORA_WIFI_IRQ_GPIO		21
-#define PANDORA_WIFI_NRESET_GPIO	23
 
 static struct platform_device pandora_backlight = {
 	.name	= "pandora-backlight",
 	.id	= -1,
 };
 
-static struct regulator_consumer_supply pandora_vmmc3_supply[] = {
-	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"),
-};
-
-static struct regulator_init_data pandora_vmmc3 = {
-	.constraints = {
-		.valid_ops_mask		= REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(pandora_vmmc3_supply),
-	.consumer_supplies	= pandora_vmmc3_supply,
-};
-
-static struct fixed_voltage_config pandora_vwlan = {
-	.supply_name		= "vwlan",
-	.microvolts		= 1800000, /* 1.8V */
-	.startup_delay		= 50000, /* 50ms */
-	.init_data		= &pandora_vmmc3,
-};
-
-static struct platform_device pandora_vwlan_device = {
-	.name		= "reg-fixed-voltage",
-	.id		= 1,
-	.dev = {
-		.platform_data = &pandora_vwlan,
-	},
-};
-
-static struct gpiod_lookup_table pandora_vwlan_gpiod_table = {
-	.dev_id = "reg-fixed-voltage.1",
-	.table = {
-		/*
-		 * As this is a low GPIO number it should be at the first
-		 * GPIO bank.
-		 */
-		GPIO_LOOKUP("gpio-0-31", PANDORA_WIFI_NRESET_GPIO,
-			    NULL, GPIO_ACTIVE_HIGH),
-		{ },
-	},
-};
-
-static void pandora_wl1251_init_card(struct mmc_card *card)
-{
-	/*
-	 * We have TI wl1251 attached to MMC3. Pass this information to
-	 * SDIO core because it can't be probed by normal methods.
-	 */
-	if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) {
-		card->quirks |= MMC_QUIRK_NONSTD_SDIO;
-		card->cccr.wide_bus = 1;
-		card->cis.vendor = 0x104c;
-		card->cis.device = 0x9066;
-		card->cis.blksize = 512;
-		card->cis.max_dtr = 24000000;
-		card->ocr = 0x80;
-	}
-}
-
-static struct omap2_hsmmc_info pandora_mmc3[] = {
-	{
-		.mmc		= 3,
-		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
-		.init_card	= pandora_wl1251_init_card,
-	},
-	{}	/* Terminator */
-};
-
-static void __init pandora_wl1251_init(void)
-{
-	struct wl1251_platform_data pandora_wl1251_pdata;
-	int ret;
-
-	memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
-
-	pandora_wl1251_pdata.power_gpio = -1;
-
-	ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq");
-	if (ret < 0)
-		goto fail;
-
-	pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO);
-	if (pandora_wl1251_pdata.irq < 0)
-		goto fail_irq;
-
-	pandora_wl1251_pdata.use_eeprom = true;
-	ret = wl1251_set_platform_data(&pandora_wl1251_pdata);
-	if (ret < 0)
-		goto fail_irq;
-
-	return;
-
-fail_irq:
-	gpio_free(PANDORA_WIFI_IRQ_GPIO);
-fail:
-	pr_err("wl1251 board initialisation failed\n");
-}
-
 static void __init omap3_pandora_legacy_init(void)
 {
 	platform_device_register(&pandora_backlight);
-	gpiod_add_lookup_table(&pandora_vwlan_gpiod_table);
-	platform_device_register(&pandora_vwlan_device);
-	omap_hsmmc_init(pandora_mmc3);
-	omap_hsmmc_late_init(pandora_mmc3);
-	pandora_wl1251_init();
 }
 #endif /* CONFIG_ARCH_OMAP3 */
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi linux-libre-5.3.17-gnu/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
--- linux-libre-5.3.16-gnu/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi	2019-12-17 14:08:41.000000000 -0500
@@ -142,6 +142,15 @@
 		clock-output-names = "ext-osc32k";
 	};
 
+	pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
 	psci {
 		compatible = "arm,psci-0.2";
 		method = "smc";
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/include/asm/vdso_datapage.h linux-libre-5.3.17-gnu/arch/powerpc/include/asm/vdso_datapage.h
--- linux-libre-5.3.16-gnu/arch/powerpc/include/asm/vdso_datapage.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/include/asm/vdso_datapage.h	2019-12-17 14:08:41.000000000 -0500
@@ -82,6 +82,7 @@ struct vdso_data {
 	__s32 wtom_clock_nsec;			/* Wall to monotonic clock nsec */
 	__s64 wtom_clock_sec;			/* Wall to monotonic clock sec */
 	struct timespec stamp_xtime;		/* xtime as at tb_orig_stamp */
+	__u32 hrtimer_res;			/* hrtimer resolution */
    	__u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls  */
    	__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
 };
@@ -103,6 +104,7 @@ struct vdso_data {
 	__s32 wtom_clock_nsec;
 	struct timespec stamp_xtime;	/* xtime as at tb_orig_stamp */
 	__u32 stamp_sec_fraction;	/* fractional seconds of stamp_xtime */
+	__u32 hrtimer_res;		/* hrtimer resolution */
    	__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
 	__u32 dcache_block_size;	/* L1 d-cache block size     */
 	__u32 icache_block_size;	/* L1 i-cache block size     */
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/kernel/asm-offsets.c linux-libre-5.3.17-gnu/arch/powerpc/kernel/asm-offsets.c
--- linux-libre-5.3.16-gnu/arch/powerpc/kernel/asm-offsets.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/kernel/asm-offsets.c	2019-12-17 14:08:41.000000000 -0500
@@ -387,6 +387,7 @@ int main(void)
 	OFFSET(WTOM_CLOCK_NSEC, vdso_data, wtom_clock_nsec);
 	OFFSET(STAMP_XTIME, vdso_data, stamp_xtime);
 	OFFSET(STAMP_SEC_FRAC, vdso_data, stamp_sec_fraction);
+	OFFSET(CLOCK_HRTIMER_RES, vdso_data, hrtimer_res);
 	OFFSET(CFG_ICACHE_BLOCKSZ, vdso_data, icache_block_size);
 	OFFSET(CFG_DCACHE_BLOCKSZ, vdso_data, dcache_block_size);
 	OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_data, icache_log_block_size);
@@ -417,7 +418,6 @@ int main(void)
 	DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
 	DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
 	DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
-	DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
 
 #ifdef CONFIG_BUG
 	DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/kernel/Makefile linux-libre-5.3.17-gnu/arch/powerpc/kernel/Makefile
--- linux-libre-5.3.16-gnu/arch/powerpc/kernel/Makefile	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/kernel/Makefile	2019-12-17 14:08:41.000000000 -0500
@@ -5,8 +5,8 @@
 
 CFLAGS_ptrace.o		+= -DUTS_MACHINE='"$(UTS_MACHINE)"'
 
-# Disable clang warning for using setjmp without setjmp.h header
-CFLAGS_crash.o		+= $(call cc-disable-warning, builtin-requires-header)
+# Avoid clang warnings around longjmp/setjmp declarations
+CFLAGS_crash.o += -ffreestanding
 
 ifdef CONFIG_PPC64
 CFLAGS_prom_init.o	+= $(NO_MINIMAL_TOC)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/kernel/misc_64.S linux-libre-5.3.17-gnu/arch/powerpc/kernel/misc_64.S
--- linux-libre-5.3.16-gnu/arch/powerpc/kernel/misc_64.S	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/kernel/misc_64.S	2019-12-17 14:08:41.000000000 -0500
@@ -82,7 +82,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_I
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5		/* ensure we get enough */
 	lwz	r9,DCACHEL1LOGBLOCKSIZE(r10)	/* Get log-2 of cache block size */
-	srw.	r8,r8,r9		/* compute line count */
+	srd.	r8,r8,r9		/* compute line count */
 	beqlr				/* nothing to do? */
 	mtctr	r8
 1:	dcbst	0,r6
@@ -98,7 +98,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_I
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5
 	lwz	r9,ICACHEL1LOGBLOCKSIZE(r10)	/* Get log-2 of Icache block size */
-	srw.	r8,r8,r9		/* compute line count */
+	srd.	r8,r8,r9		/* compute line count */
 	beqlr				/* nothing to do? */
 	mtctr	r8
 2:	icbi	0,r6
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/kernel/time.c linux-libre-5.3.17-gnu/arch/powerpc/kernel/time.c
--- linux-libre-5.3.16-gnu/arch/powerpc/kernel/time.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/kernel/time.c	2019-12-17 14:08:41.000000000 -0500
@@ -959,6 +959,7 @@ void update_vsyscall(struct timekeeper *
 	vdso_data->wtom_clock_nsec = tk->wall_to_monotonic.tv_nsec;
 	vdso_data->stamp_xtime = xt;
 	vdso_data->stamp_sec_fraction = frac_sec;
+	vdso_data->hrtimer_res = hrtimer_resolution;
 	smp_wmb();
 	++(vdso_data->tb_update_count);
 }
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/kernel/vdso32/gettimeofday.S linux-libre-5.3.17-gnu/arch/powerpc/kernel/vdso32/gettimeofday.S
--- linux-libre-5.3.16-gnu/arch/powerpc/kernel/vdso32/gettimeofday.S	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/kernel/vdso32/gettimeofday.S	2019-12-17 14:08:41.000000000 -0500
@@ -156,12 +156,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
 	cror	cr0*4+eq,cr0*4+eq,cr1*4+eq
 	bne	cr0,99f
 
+	mflr	r12
+  .cfi_register lr,r12
+	bl	__get_datapage@local	/* get data page */
+	lwz	r5, CLOCK_HRTIMER_RES(r3)
+	mtlr	r12
 	li	r3,0
 	cmpli	cr0,r4,0
 	crclr	cr0*4+so
 	beqlr
-	lis	r5,CLOCK_REALTIME_RES@h
-	ori	r5,r5,CLOCK_REALTIME_RES@l
 	stw	r3,TSPC32_TV_SEC(r4)
 	stw	r5,TSPC32_TV_NSEC(r4)
 	blr
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/kernel/vdso64/cacheflush.S linux-libre-5.3.17-gnu/arch/powerpc/kernel/vdso64/cacheflush.S
--- linux-libre-5.3.16-gnu/arch/powerpc/kernel/vdso64/cacheflush.S	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/kernel/vdso64/cacheflush.S	2019-12-17 14:08:41.000000000 -0500
@@ -35,7 +35,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache)
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5		/* ensure we get enough */
 	lwz	r9,CFG_DCACHE_LOGBLOCKSZ(r10)
-	srw.	r8,r8,r9		/* compute line count */
+	srd.	r8,r8,r9		/* compute line count */
 	crclr	cr0*4+so
 	beqlr				/* nothing to do? */
 	mtctr	r8
@@ -52,7 +52,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache)
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5
 	lwz	r9,CFG_ICACHE_LOGBLOCKSZ(r10)
-	srw.	r8,r8,r9		/* compute line count */
+	srd.	r8,r8,r9		/* compute line count */
 	crclr	cr0*4+so
 	beqlr				/* nothing to do? */
 	mtctr	r8
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/kernel/vdso64/gettimeofday.S linux-libre-5.3.17-gnu/arch/powerpc/kernel/vdso64/gettimeofday.S
--- linux-libre-5.3.16-gnu/arch/powerpc/kernel/vdso64/gettimeofday.S	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/kernel/vdso64/gettimeofday.S	2019-12-17 14:08:41.000000000 -0500
@@ -186,12 +186,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
 	cror	cr0*4+eq,cr0*4+eq,cr1*4+eq
 	bne	cr0,99f
 
+	mflr	r12
+  .cfi_register lr,r12
+	bl	V_LOCAL_FUNC(__get_datapage)
+	lwz	r5, CLOCK_HRTIMER_RES(r3)
+	mtlr	r12
 	li	r3,0
 	cmpldi	cr0,r4,0
 	crclr	cr0*4+so
 	beqlr
-	lis	r5,CLOCK_REALTIME_RES@h
-	ori	r5,r5,CLOCK_REALTIME_RES@l
 	std	r3,TSPC64_TV_SEC(r4)
 	std	r5,TSPC64_TV_NSEC(r4)
 	blr
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/platforms/powernv/opal-imc.c linux-libre-5.3.17-gnu/arch/powerpc/platforms/powernv/opal-imc.c
--- linux-libre-5.3.16-gnu/arch/powerpc/platforms/powernv/opal-imc.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/platforms/powernv/opal-imc.c	2019-12-17 14:08:41.000000000 -0500
@@ -285,7 +285,14 @@ static int opal_imc_counters_probe(struc
 			domain = IMC_DOMAIN_THREAD;
 			break;
 		case IMC_TYPE_TRACE:
-			domain = IMC_DOMAIN_TRACE;
+			/*
+			 * FIXME. Using trace_imc events to monitor application
+			 * or KVM thread performance can cause a checkstop
+			 * (system crash).
+			 * Disable it for now.
+			 */
+			pr_info_once("IMC: disabling trace_imc PMU\n");
+			domain = -1;
 			break;
 		default:
 			pr_warn("IMC Unknown Device type \n");
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/sysdev/xive/common.c linux-libre-5.3.17-gnu/arch/powerpc/sysdev/xive/common.c
--- linux-libre-5.3.16-gnu/arch/powerpc/sysdev/xive/common.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/sysdev/xive/common.c	2019-12-17 14:08:41.000000000 -0500
@@ -1000,6 +1000,15 @@ static int xive_irq_alloc_data(unsigned
 	xd->target = XIVE_INVALID_TARGET;
 	irq_set_handler_data(virq, xd);
 
+	/*
+	 * Turn OFF by default the interrupt being mapped. A side
+	 * effect of this check is the mapping the ESB page of the
+	 * interrupt in the Linux address space. This prevents page
+	 * fault issues in the crash handler which masks all
+	 * interrupts.
+	 */
+	xive_esb_read(xd, XIVE_ESB_SET_PQ_01);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/sysdev/xive/spapr.c linux-libre-5.3.17-gnu/arch/powerpc/sysdev/xive/spapr.c
--- linux-libre-5.3.16-gnu/arch/powerpc/sysdev/xive/spapr.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/sysdev/xive/spapr.c	2019-12-17 14:08:41.000000000 -0500
@@ -356,20 +356,28 @@ static int xive_spapr_populate_irq_data(
 	data->esb_shift = esb_shift;
 	data->trig_page = trig_page;
 
+	data->hw_irq = hw_irq;
+
 	/*
 	 * No chip-id for the sPAPR backend. This has an impact how we
 	 * pick a target. See xive_pick_irq_target().
 	 */
 	data->src_chip = XIVE_INVALID_CHIP_ID;
 
+	/*
+	 * When the H_INT_ESB flag is set, the H_INT_ESB hcall should
+	 * be used for interrupt management. Skip the remapping of the
+	 * ESB pages which are not available.
+	 */
+	if (data->flags & XIVE_IRQ_FLAG_H_INT_ESB)
+		return 0;
+
 	data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift);
 	if (!data->eoi_mmio) {
 		pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq);
 		return -ENOMEM;
 	}
 
-	data->hw_irq = hw_irq;
-
 	/* Full function page supports trigger */
 	if (flags & XIVE_SRC_TRIGGER) {
 		data->trig_mmio = data->eoi_mmio;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/powerpc/xmon/Makefile linux-libre-5.3.17-gnu/arch/powerpc/xmon/Makefile
--- linux-libre-5.3.16-gnu/arch/powerpc/xmon/Makefile	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/powerpc/xmon/Makefile	2019-12-17 14:08:41.000000000 -0500
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for xmon
 
-# Disable clang warning for using setjmp without setjmp.h header
-subdir-ccflags-y := $(call cc-disable-warning, builtin-requires-header)
+# Avoid clang warnings around longjmp/setjmp declarations
+subdir-ccflags-y := -ffreestanding
 
 GCOV_PROFILE := n
 KCOV_INSTRUMENT := n
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/s390/boot/startup.c linux-libre-5.3.17-gnu/arch/s390/boot/startup.c
--- linux-libre-5.3.16-gnu/arch/s390/boot/startup.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/s390/boot/startup.c	2019-12-17 14:08:41.000000000 -0500
@@ -164,6 +164,11 @@ void startup_kernel(void)
 		handle_relocs(__kaslr_offset);
 
 	if (__kaslr_offset) {
+		/*
+		 * Save KASLR offset for early dumps, before vmcore_info is set.
+		 * Mark as uneven to distinguish from real vmcore_info pointer.
+		 */
+		S390_lowcore.vmcore_info = __kaslr_offset | 0x1UL;
 		/* Clear non-relocated kernel */
 		if (IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED))
 			memset(img, 0, vmlinux.image_size);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/s390/include/asm/pgtable.h linux-libre-5.3.17-gnu/arch/s390/include/asm/pgtable.h
--- linux-libre-5.3.16-gnu/arch/s390/include/asm/pgtable.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/s390/include/asm/pgtable.h	2019-12-17 14:08:41.000000000 -0500
@@ -1172,8 +1172,6 @@ void gmap_pmdp_idte_global(struct mm_str
 static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 			      pte_t *ptep, pte_t entry)
 {
-	if (!MACHINE_HAS_NX)
-		pte_val(entry) &= ~_PAGE_NOEXEC;
 	if (pte_present(entry))
 		pte_val(entry) &= ~_PAGE_UNUSED;
 	if (mm_has_pgste(mm))
@@ -1190,6 +1188,8 @@ static inline pte_t mk_pte_phys(unsigned
 {
 	pte_t __pte;
 	pte_val(__pte) = physpage + pgprot_val(pgprot);
+	if (!MACHINE_HAS_NX)
+		pte_val(__pte) &= ~_PAGE_NOEXEC;
 	return pte_mkyoung(__pte);
 }
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/s390/kernel/machine_kexec.c linux-libre-5.3.17-gnu/arch/s390/kernel/machine_kexec.c
--- linux-libre-5.3.16-gnu/arch/s390/kernel/machine_kexec.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/s390/kernel/machine_kexec.c	2019-12-17 14:08:41.000000000 -0500
@@ -254,10 +254,10 @@ void arch_crash_save_vmcoreinfo(void)
 	VMCOREINFO_SYMBOL(lowcore_ptr);
 	VMCOREINFO_SYMBOL(high_memory);
 	VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS);
-	mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note());
 	vmcoreinfo_append_str("SDMA=%lx\n", __sdma);
 	vmcoreinfo_append_str("EDMA=%lx\n", __edma);
 	vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
+	mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note());
 }
 
 void machine_shutdown(void)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/arch/s390/kernel/smp.c linux-libre-5.3.17-gnu/arch/s390/kernel/smp.c
--- linux-libre-5.3.16-gnu/arch/s390/kernel/smp.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/arch/s390/kernel/smp.c	2019-12-17 14:08:41.000000000 -0500
@@ -262,10 +262,13 @@ static void pcpu_prepare_secondary(struc
 	lc->spinlock_index = 0;
 	lc->percpu_offset = __per_cpu_offset[cpu];
 	lc->kernel_asce = S390_lowcore.kernel_asce;
+	lc->user_asce = S390_lowcore.kernel_asce;
 	lc->machine_flags = S390_lowcore.machine_flags;
 	lc->user_timer = lc->system_timer =
 		lc->steal_timer = lc->avg_steal_timer = 0;
 	__ctl_store(lc->cregs_save_area, 0, 15);
+	lc->cregs_save_area[1] = lc->kernel_asce;
+	lc->cregs_save_area[7] = lc->vdso_asce;
 	save_access_regs((unsigned int *) lc->access_regs_save_area);
 	memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
 	       sizeof(lc->stfle_fac_list));
@@ -816,6 +819,8 @@ static void smp_init_secondary(void)
 
 	S390_lowcore.last_update_clock = get_tod_clock();
 	restore_access_regs(S390_lowcore.access_regs_save_area);
+	set_cpu_flag(CIF_ASCE_PRIMARY);
+	set_cpu_flag(CIF_ASCE_SECONDARY);
 	cpu_init();
 	preempt_disable();
 	init_cpu_timer();
diff -druNp --no-dereference linux-libre-5.3.16-gnu/block/bio.c linux-libre-5.3.17-gnu/block/bio.c
--- linux-libre-5.3.16-gnu/block/bio.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/block/bio.c	2019-12-17 14:08:41.000000000 -0500
@@ -769,10 +769,12 @@ bool __bio_try_merge_page(struct bio *bi
 	if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
 		return false;
 
-	if (bio->bi_vcnt > 0 && !bio_full(bio, len)) {
+	if (bio->bi_vcnt > 0) {
 		struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
 
 		if (page_is_mergeable(bv, page, len, off, same_page)) {
+			if (bio->bi_iter.bi_size > UINT_MAX - len)
+				return false;
 			bv->bv_len += len;
 			bio->bi_iter.bi_size += len;
 			return true;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/block/blk-mq-sysfs.c linux-libre-5.3.17-gnu/block/blk-mq-sysfs.c
--- linux-libre-5.3.16-gnu/block/blk-mq-sysfs.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/block/blk-mq-sysfs.c	2019-12-17 14:08:41.000000000 -0500
@@ -166,20 +166,25 @@ static ssize_t blk_mq_hw_sysfs_nr_reserv
 
 static ssize_t blk_mq_hw_sysfs_cpus_show(struct blk_mq_hw_ctx *hctx, char *page)
 {
+	const size_t size = PAGE_SIZE - 1;
 	unsigned int i, first = 1;
-	ssize_t ret = 0;
+	int ret = 0, pos = 0;
 
 	for_each_cpu(i, hctx->cpumask) {
 		if (first)
-			ret += sprintf(ret + page, "%u", i);
+			ret = snprintf(pos + page, size - pos, "%u", i);
 		else
-			ret += sprintf(ret + page, ", %u", i);
+			ret = snprintf(pos + page, size - pos, ", %u", i);
+
+		if (ret >= size - pos)
+			break;
 
 		first = 0;
+		pos += ret;
 	}
 
-	ret += sprintf(ret + page, "\n");
-	return ret;
+	ret = snprintf(pos + page, size + 1 - pos, "\n");
+	return pos + ret;
 }
 
 static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_nr_tags = {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/Documentation/admin-guide/kernel-parameters.txt linux-libre-5.3.17-gnu/Documentation/admin-guide/kernel-parameters.txt
--- linux-libre-5.3.16-gnu/Documentation/admin-guide/kernel-parameters.txt	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/Documentation/admin-guide/kernel-parameters.txt	2019-12-17 14:08:41.000000000 -0500
@@ -5066,13 +5066,13 @@
 			Flags is a set of characters, each corresponding
 			to a common usb-storage quirk flag as follows:
 				a = SANE_SENSE (collect more than 18 bytes
-					of sense data);
+					of sense data, not on uas);
 				b = BAD_SENSE (don't collect more than 18
-					bytes of sense data);
+					bytes of sense data, not on uas);
 				c = FIX_CAPACITY (decrease the reported
 					device capacity by one sector);
 				d = NO_READ_DISC_INFO (don't use
-					READ_DISC_INFO command);
+					READ_DISC_INFO command, not on uas);
 				e = NO_READ_CAPACITY_16 (don't use
 					READ_CAPACITY_16 command);
 				f = NO_REPORT_OPCODES (don't use report opcodes
@@ -5087,17 +5087,18 @@
 				j = NO_REPORT_LUNS (don't use report luns
 					command, uas only);
 				l = NOT_LOCKABLE (don't try to lock and
-					unlock ejectable media);
+					unlock ejectable media, not on uas);
 				m = MAX_SECTORS_64 (don't transfer more
-					than 64 sectors = 32 KB at a time);
+					than 64 sectors = 32 KB at a time,
+					not on uas);
 				n = INITIAL_READ10 (force a retry of the
-					initial READ(10) command);
+					initial READ(10) command, not on uas);
 				o = CAPACITY_OK (accept the capacity
-					reported by the device);
+					reported by the device, not on uas);
 				p = WRITE_CACHE (the device cache is ON
-					by default);
+					by default, not on uas);
 				r = IGNORE_RESIDUE (the device reports
-					bogus residue values);
+					bogus residue values, not on uas);
 				s = SINGLE_LUN (the device has only one
 					Logical Unit);
 				t = NO_ATA_1X (don't allow ATA(12) and ATA(16)
@@ -5106,7 +5107,8 @@
 				w = NO_WP_DETECT (don't test whether the
 					medium is write-protected).
 				y = ALWAYS_SYNC (issue a SYNCHRONIZE_CACHE
-					even if the device claims no cache)
+					even if the device claims no cache,
+					not on uas)
 			Example: quirks=0419:aaf5:rl,0421:0433:rc
 
 	user_debug=	[KNL,ARM]
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/acpi/acpi_lpss.c linux-libre-5.3.17-gnu/drivers/acpi/acpi_lpss.c
--- linux-libre-5.3.16-gnu/drivers/acpi/acpi_lpss.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/acpi/acpi_lpss.c	2019-12-17 14:08:41.000000000 -0500
@@ -10,6 +10,7 @@
 #include <linux/acpi.h>
 #include <linux/clkdev.h>
 #include <linux/clk-provider.h>
+#include <linux/dmi.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/mutex.h>
@@ -463,6 +464,18 @@ struct lpss_device_links {
 	const char *consumer_hid;
 	const char *consumer_uid;
 	u32 flags;
+	const struct dmi_system_id *dep_missing_ids;
+};
+
+/* Please keep this list sorted alphabetically by vendor and model */
+static const struct dmi_system_id i2c1_dep_missing_dmi_ids[] = {
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "T200TA"),
+		},
+	},
+	{}
 };
 
 /*
@@ -473,9 +486,17 @@ struct lpss_device_links {
  * the supplier is not enumerated until after the consumer is probed.
  */
 static const struct lpss_device_links lpss_device_links[] = {
+	/* CHT External sdcard slot controller depends on PMIC I2C ctrl */
 	{"808622C1", "7", "80860F14", "3", DL_FLAG_PM_RUNTIME},
+	/* CHT iGPU depends on PMIC I2C controller */
 	{"808622C1", "7", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME},
+	/* BYT iGPU depends on the Embedded Controller I2C controller (UID 1) */
+	{"80860F41", "1", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME,
+	 i2c1_dep_missing_dmi_ids},
+	/* BYT CR iGPU depends on PMIC I2C controller (UID 5 on CR) */
 	{"80860F41", "5", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME},
+	/* BYT iGPU depends on PMIC I2C controller (UID 7 on non CR) */
+	{"80860F41", "7", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME},
 };
 
 static bool hid_uid_match(struct acpi_device *adev,
@@ -570,7 +591,8 @@ static void acpi_lpss_link_consumer(stru
 	if (!dev2)
 		return;
 
-	if (acpi_lpss_dep(ACPI_COMPANION(dev2), ACPI_HANDLE(dev1)))
+	if ((link->dep_missing_ids && dmi_check_system(link->dep_missing_ids))
+	    || acpi_lpss_dep(ACPI_COMPANION(dev2), ACPI_HANDLE(dev1)))
 		device_link_add(dev2, dev1, link->flags);
 
 	put_device(dev2);
@@ -585,7 +607,8 @@ static void acpi_lpss_link_supplier(stru
 	if (!dev2)
 		return;
 
-	if (acpi_lpss_dep(ACPI_COMPANION(dev1), ACPI_HANDLE(dev2)))
+	if ((link->dep_missing_ids && dmi_check_system(link->dep_missing_ids))
+	    || acpi_lpss_dep(ACPI_COMPANION(dev1), ACPI_HANDLE(dev2)))
 		device_link_add(dev1, dev2, link->flags);
 
 	put_device(dev2);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/acpi/bus.c linux-libre-5.3.17-gnu/drivers/acpi/bus.c
--- linux-libre-5.3.16-gnu/drivers/acpi/bus.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/acpi/bus.c	2019-12-17 14:08:41.000000000 -0500
@@ -153,7 +153,7 @@ int acpi_bus_get_private_data(acpi_handl
 {
 	acpi_status status;
 
-	if (!*data)
+	if (!data)
 		return -EINVAL;
 
 	status = acpi_get_data(handle, acpi_bus_private_data_handler, data);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/acpi/device_pm.c linux-libre-5.3.17-gnu/drivers/acpi/device_pm.c
--- linux-libre-5.3.16-gnu/drivers/acpi/device_pm.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/acpi/device_pm.c	2019-12-17 14:08:41.000000000 -0500
@@ -1309,9 +1309,19 @@ static void acpi_dev_pm_detach(struct de
  */
 int acpi_dev_pm_attach(struct device *dev, bool power_on)
 {
+	/*
+	 * Skip devices whose ACPI companions match the device IDs below,
+	 * because they require special power management handling incompatible
+	 * with the generic ACPI PM domain.
+	 */
+	static const struct acpi_device_id special_pm_ids[] = {
+		{"PNP0C0B", }, /* Generic ACPI fan */
+		{"INT3404", }, /* Fan */
+		{}
+	};
 	struct acpi_device *adev = ACPI_COMPANION(dev);
 
-	if (!adev)
+	if (!adev || !acpi_match_device_ids(adev, special_pm_ids))
 		return 0;
 
 	/*
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/acpi/osl.c linux-libre-5.3.17-gnu/drivers/acpi/osl.c
--- linux-libre-5.3.16-gnu/drivers/acpi/osl.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/acpi/osl.c	2019-12-17 14:08:41.000000000 -0500
@@ -360,19 +360,21 @@ void *__ref acpi_os_map_memory(acpi_phys
 }
 EXPORT_SYMBOL_GPL(acpi_os_map_memory);
 
-static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
+/* Must be called with mutex_lock(&acpi_ioremap_lock) */
+static unsigned long acpi_os_drop_map_ref(struct acpi_ioremap *map)
 {
-	if (!--map->refcount)
+	unsigned long refcount = --map->refcount;
+
+	if (!refcount)
 		list_del_rcu(&map->list);
+	return refcount;
 }
 
 static void acpi_os_map_cleanup(struct acpi_ioremap *map)
 {
-	if (!map->refcount) {
-		synchronize_rcu_expedited();
-		acpi_unmap(map->phys, map->virt);
-		kfree(map);
-	}
+	synchronize_rcu_expedited();
+	acpi_unmap(map->phys, map->virt);
+	kfree(map);
 }
 
 /**
@@ -392,6 +394,7 @@ static void acpi_os_map_cleanup(struct a
 void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)
 {
 	struct acpi_ioremap *map;
+	unsigned long refcount;
 
 	if (!acpi_permanent_mmap) {
 		__acpi_unmap_table(virt, size);
@@ -405,10 +408,11 @@ void __ref acpi_os_unmap_iomem(void __io
 		WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
 		return;
 	}
-	acpi_os_drop_map_ref(map);
+	refcount = acpi_os_drop_map_ref(map);
 	mutex_unlock(&acpi_ioremap_lock);
 
-	acpi_os_map_cleanup(map);
+	if (!refcount)
+		acpi_os_map_cleanup(map);
 }
 EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem);
 
@@ -443,6 +447,7 @@ void acpi_os_unmap_generic_address(struc
 {
 	u64 addr;
 	struct acpi_ioremap *map;
+	unsigned long refcount;
 
 	if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
 		return;
@@ -458,10 +463,11 @@ void acpi_os_unmap_generic_address(struc
 		mutex_unlock(&acpi_ioremap_lock);
 		return;
 	}
-	acpi_os_drop_map_ref(map);
+	refcount = acpi_os_drop_map_ref(map);
 	mutex_unlock(&acpi_ioremap_lock);
 
-	acpi_os_map_cleanup(map);
+	if (!refcount)
+		acpi_os_map_cleanup(map);
 }
 EXPORT_SYMBOL(acpi_os_unmap_generic_address);
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/android/binder.c linux-libre-5.3.17-gnu/drivers/android/binder.c
--- linux-libre-5.3.16-gnu/drivers/android/binder.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/android/binder.c	2019-12-17 14:08:41.000000000 -0500
@@ -3332,7 +3332,7 @@ static void binder_transaction(struct bi
 			binder_size_t parent_offset;
 			struct binder_fd_array_object *fda =
 				to_binder_fd_array_object(hdr);
-			size_t num_valid = (buffer_offset - off_start_offset) *
+			size_t num_valid = (buffer_offset - off_start_offset) /
 						sizeof(binder_size_t);
 			struct binder_buffer_object *parent =
 				binder_validate_ptr(target_proc, t->buffer,
@@ -3406,7 +3406,7 @@ static void binder_transaction(struct bi
 				t->buffer->user_data + sg_buf_offset;
 			sg_buf_offset += ALIGN(bp->length, sizeof(u64));
 
-			num_valid = (buffer_offset - off_start_offset) *
+			num_valid = (buffer_offset - off_start_offset) /
 					sizeof(binder_size_t);
 			ret = binder_fixup_parent(t, thread, bp,
 						  off_start_offset,
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/char/hw_random/omap-rng.c linux-libre-5.3.17-gnu/drivers/char/hw_random/omap-rng.c
--- linux-libre-5.3.16-gnu/drivers/char/hw_random/omap-rng.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/char/hw_random/omap-rng.c	2019-12-17 14:08:41.000000000 -0500
@@ -66,6 +66,13 @@
 #define OMAP4_RNG_OUTPUT_SIZE			0x8
 #define EIP76_RNG_OUTPUT_SIZE			0x10
 
+/*
+ * EIP76 RNG takes approx. 700us to produce 16 bytes of output data
+ * as per testing results. And to account for the lack of udelay()'s
+ * reliability, we keep the timeout as 1000us.
+ */
+#define RNG_DATA_FILL_TIMEOUT			100
+
 enum {
 	RNG_OUTPUT_0_REG = 0,
 	RNG_OUTPUT_1_REG,
@@ -176,7 +183,7 @@ static int omap_rng_do_read(struct hwrng
 	if (max < priv->pdata->data_size)
 		return 0;
 
-	for (i = 0; i < 20; i++) {
+	for (i = 0; i < RNG_DATA_FILL_TIMEOUT; i++) {
 		present = priv->pdata->data_present(priv);
 		if (present || !wait)
 			break;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/char/ppdev.c linux-libre-5.3.17-gnu/drivers/char/ppdev.c
--- linux-libre-5.3.16-gnu/drivers/char/ppdev.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/char/ppdev.c	2019-12-17 14:08:41.000000000 -0500
@@ -619,20 +619,27 @@ static int pp_do_ioctl(struct file *file
 		if (copy_from_user(time32, argp, sizeof(time32)))
 			return -EFAULT;
 
+		if ((time32[0] < 0) || (time32[1] < 0))
+			return -EINVAL;
+
 		return pp_set_timeout(pp->pdev, time32[0], time32[1]);
 
 	case PPSETTIME64:
 		if (copy_from_user(time64, argp, sizeof(time64)))
 			return -EFAULT;
 
+		if ((time64[0] < 0) || (time64[1] < 0))
+			return -EINVAL;
+
+		if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall())
+			time64[1] >>= 32;
+
 		return pp_set_timeout(pp->pdev, time64[0], time64[1]);
 
 	case PPGETTIME32:
 		jiffies_to_timespec64(pp->pdev->timeout, &ts);
 		time32[0] = ts.tv_sec;
 		time32[1] = ts.tv_nsec / NSEC_PER_USEC;
-		if ((time32[0] < 0) || (time32[1] < 0))
-			return -EINVAL;
 
 		if (copy_to_user(argp, time32, sizeof(time32)))
 			return -EFAULT;
@@ -643,8 +650,9 @@ static int pp_do_ioctl(struct file *file
 		jiffies_to_timespec64(pp->pdev->timeout, &ts);
 		time64[0] = ts.tv_sec;
 		time64[1] = ts.tv_nsec / NSEC_PER_USEC;
-		if ((time64[0] < 0) || (time64[1] < 0))
-			return -EINVAL;
+
+		if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall())
+			time64[1] <<= 32;
 
 		if (copy_to_user(argp, time64, sizeof(time64)))
 			return -EFAULT;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/char/tpm/tpm2-cmd.c linux-libre-5.3.17-gnu/drivers/char/tpm/tpm2-cmd.c
--- linux-libre-5.3.16-gnu/drivers/char/tpm/tpm2-cmd.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/char/tpm/tpm2-cmd.c	2019-12-17 14:08:41.000000000 -0500
@@ -939,6 +939,10 @@ static int tpm2_get_cc_attrs_tbl(struct
 
 	chip->cc_attrs_tbl = devm_kcalloc(&chip->dev, 4, nr_commands,
 					  GFP_KERNEL);
+	if (!chip->cc_attrs_tbl) {
+		rc = -ENOMEM;
+		goto out;
+	}
 
 	rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
 	if (rc)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/cpufreq/powernv-cpufreq.c linux-libre-5.3.17-gnu/drivers/cpufreq/powernv-cpufreq.c
--- linux-libre-5.3.16-gnu/drivers/cpufreq/powernv-cpufreq.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/cpufreq/powernv-cpufreq.c	2019-12-17 14:08:41.000000000 -0500
@@ -1041,9 +1041,14 @@ static struct cpufreq_driver powernv_cpu
 
 static int init_chip_info(void)
 {
-	unsigned int chip[256];
+	unsigned int *chip;
 	unsigned int cpu, i;
 	unsigned int prev_chip_id = UINT_MAX;
+	int ret = 0;
+
+	chip = kcalloc(num_possible_cpus(), sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
 
 	for_each_possible_cpu(cpu) {
 		unsigned int id = cpu_to_chip_id(cpu);
@@ -1055,8 +1060,10 @@ static int init_chip_info(void)
 	}
 
 	chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL);
-	if (!chips)
-		return -ENOMEM;
+	if (!chips) {
+		ret = -ENOMEM;
+		goto free_and_return;
+	}
 
 	for (i = 0; i < nr_chips; i++) {
 		chips[i].id = chip[i];
@@ -1066,7 +1073,9 @@ static int init_chip_info(void)
 			per_cpu(chip_info, cpu) =  &chips[i];
 	}
 
-	return 0;
+free_and_return:
+	kfree(chip);
+	return ret;
 }
 
 static inline void clean_chip_info(void)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/cpuidle/driver.c linux-libre-5.3.17-gnu/drivers/cpuidle/driver.c
--- linux-libre-5.3.16-gnu/drivers/cpuidle/driver.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/cpuidle/driver.c	2019-12-17 14:08:41.000000000 -0500
@@ -62,24 +62,23 @@ static inline void __cpuidle_unset_drive
  * __cpuidle_set_driver - set per CPU driver variables for the given driver.
  * @drv: a valid pointer to a struct cpuidle_driver
  *
- * For each CPU in the driver's cpumask, unset the registered driver per CPU
- * to @drv.
- *
- * Returns 0 on success, -EBUSY if the CPUs have driver(s) already.
+ * Returns 0 on success, -EBUSY if any CPU in the cpumask have a driver
+ * different from drv already.
  */
 static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
 {
 	int cpu;
 
 	for_each_cpu(cpu, drv->cpumask) {
+		struct cpuidle_driver *old_drv;
 
-		if (__cpuidle_get_cpu_driver(cpu)) {
-			__cpuidle_unset_driver(drv);
+		old_drv = __cpuidle_get_cpu_driver(cpu);
+		if (old_drv && old_drv != drv)
 			return -EBUSY;
-		}
+	}
 
+	for_each_cpu(cpu, drv->cpumask)
 		per_cpu(cpuidle_drivers, cpu) = drv;
-	}
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/cpuidle/governors/teo.c linux-libre-5.3.17-gnu/drivers/cpuidle/governors/teo.c
--- linux-libre-5.3.16-gnu/drivers/cpuidle/governors/teo.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/cpuidle/governors/teo.c	2019-12-17 14:08:41.000000000 -0500
@@ -241,7 +241,7 @@ static int teo_select(struct cpuidle_dri
 {
 	struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
 	int latency_req = cpuidle_governor_latency_req(dev->cpu);
-	unsigned int duration_us, count;
+	unsigned int duration_us, hits, misses, early_hits;
 	int max_early_idx, constraint_idx, idx, i;
 	ktime_t delta_tick;
 
@@ -255,7 +255,9 @@ static int teo_select(struct cpuidle_dri
 	cpu_data->sleep_length_ns = tick_nohz_get_sleep_length(&delta_tick);
 	duration_us = ktime_to_us(cpu_data->sleep_length_ns);
 
-	count = 0;
+	hits = 0;
+	misses = 0;
+	early_hits = 0;
 	max_early_idx = -1;
 	constraint_idx = drv->state_count;
 	idx = -1;
@@ -266,23 +268,61 @@ static int teo_select(struct cpuidle_dri
 
 		if (s->disabled || su->disable) {
 			/*
-			 * If the "early hits" metric of a disabled state is
-			 * greater than the current maximum, it should be taken
-			 * into account, because it would be a mistake to select
-			 * a deeper state with lower "early hits" metric.  The
-			 * index cannot be changed to point to it, however, so
-			 * just increase the max count alone and let the index
-			 * still point to a shallower idle state.
+			 * Ignore disabled states with target residencies beyond
+			 * the anticipated idle duration.
 			 */
-			if (max_early_idx >= 0 &&
-			    count < cpu_data->states[i].early_hits)
-				count = cpu_data->states[i].early_hits;
+			if (s->target_residency > duration_us)
+				continue;
+
+			/*
+			 * This state is disabled, so the range of idle duration
+			 * values corresponding to it is covered by the current
+			 * candidate state, but still the "hits" and "misses"
+			 * metrics of the disabled state need to be used to
+			 * decide whether or not the state covering the range in
+			 * question is good enough.
+			 */
+			hits = cpu_data->states[i].hits;
+			misses = cpu_data->states[i].misses;
+
+			if (early_hits >= cpu_data->states[i].early_hits ||
+			    idx < 0)
+				continue;
+
+			/*
+			 * If the current candidate state has been the one with
+			 * the maximum "early hits" metric so far, the "early
+			 * hits" metric of the disabled state replaces the
+			 * current "early hits" count to avoid selecting a
+			 * deeper state with lower "early hits" metric.
+			 */
+			if (max_early_idx == idx) {
+				early_hits = cpu_data->states[i].early_hits;
+				continue;
+			}
+
+			/*
+			 * The current candidate state is closer to the disabled
+			 * one than the current maximum "early hits" state, so
+			 * replace the latter with it, but in case the maximum
+			 * "early hits" state index has not been set so far,
+			 * check if the current candidate state is not too
+			 * shallow for that role.
+			 */
+			if (!(tick_nohz_tick_stopped() &&
+			      drv->states[idx].target_residency < TICK_USEC)) {
+				early_hits = cpu_data->states[i].early_hits;
+				max_early_idx = idx;
+			}
 
 			continue;
 		}
 
-		if (idx < 0)
+		if (idx < 0) {
 			idx = i; /* first enabled state */
+			hits = cpu_data->states[i].hits;
+			misses = cpu_data->states[i].misses;
+		}
 
 		if (s->target_residency > duration_us)
 			break;
@@ -291,11 +331,13 @@ static int teo_select(struct cpuidle_dri
 			constraint_idx = i;
 
 		idx = i;
+		hits = cpu_data->states[i].hits;
+		misses = cpu_data->states[i].misses;
 
-		if (count < cpu_data->states[i].early_hits &&
+		if (early_hits < cpu_data->states[i].early_hits &&
 		    !(tick_nohz_tick_stopped() &&
 		      drv->states[i].target_residency < TICK_USEC)) {
-			count = cpu_data->states[i].early_hits;
+			early_hits = cpu_data->states[i].early_hits;
 			max_early_idx = i;
 		}
 	}
@@ -308,8 +350,7 @@ static int teo_select(struct cpuidle_dri
 	 * "early hits" metric, but if that cannot be determined, just use the
 	 * state selected so far.
 	 */
-	if (cpu_data->states[idx].hits <= cpu_data->states[idx].misses &&
-	    max_early_idx >= 0) {
+	if (hits <= misses && max_early_idx >= 0) {
 		idx = max_early_idx;
 		duration_us = drv->states[idx].target_residency;
 	}
@@ -324,10 +365,9 @@ static int teo_select(struct cpuidle_dri
 	if (idx < 0) {
 		idx = 0; /* No states enabled. Must use 0. */
 	} else if (idx > 0) {
+		unsigned int count = 0;
 		u64 sum = 0;
 
-		count = 0;
-
 		/*
 		 * Count and sum the most recent idle duration values less than
 		 * the current expected idle duration value.
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/devfreq/devfreq.c linux-libre-5.3.17-gnu/drivers/devfreq/devfreq.c
--- linux-libre-5.3.16-gnu/drivers/devfreq/devfreq.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/devfreq/devfreq.c	2019-12-17 14:08:41.000000000 -0500
@@ -160,6 +160,7 @@ int devfreq_update_status(struct devfreq
 	int lev, prev_lev, ret = 0;
 	unsigned long cur_time;
 
+	lockdep_assert_held(&devfreq->lock);
 	cur_time = jiffies;
 
 	/* Immediately exit if previous_freq is not initialized yet. */
@@ -1397,12 +1398,17 @@ static ssize_t trans_stat_show(struct de
 	int i, j;
 	unsigned int max_state = devfreq->profile->max_state;
 
-	if (!devfreq->stop_polling &&
-			devfreq_update_status(devfreq, devfreq->previous_freq))
-		return 0;
 	if (max_state == 0)
 		return sprintf(buf, "Not Supported.\n");
 
+	mutex_lock(&devfreq->lock);
+	if (!devfreq->stop_polling &&
+			devfreq_update_status(devfreq, devfreq->previous_freq)) {
+		mutex_unlock(&devfreq->lock);
+		return 0;
+	}
+	mutex_unlock(&devfreq->lock);
+
 	len = sprintf(buf, "     From  :   To\n");
 	len += sprintf(buf + len, "           :");
 	for (i = 0; i < max_state; i++)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/edac/altera_edac.c linux-libre-5.3.17-gnu/drivers/edac/altera_edac.c
--- linux-libre-5.3.16-gnu/drivers/edac/altera_edac.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/edac/altera_edac.c	2019-12-17 14:08:41.000000000 -0500
@@ -561,6 +561,7 @@ static const struct regmap_config s10_sd
 	.reg_write = s10_protected_reg_write,
 	.use_single_read = true,
 	.use_single_write = true,
+	.fast_io = true,
 };
 
 /************** </Stratix10 EDAC Memory Controller Functions> ***********/
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/edac/ghes_edac.c linux-libre-5.3.17-gnu/drivers/edac/ghes_edac.c
--- linux-libre-5.3.16-gnu/drivers/edac/ghes_edac.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/edac/ghes_edac.c	2019-12-17 14:08:41.000000000 -0500
@@ -566,8 +566,8 @@ int ghes_edac_register(struct ghes *ghes
 	ghes_pvt = pvt;
 	spin_unlock_irqrestore(&ghes_lock, flags);
 
-	/* only increment on success */
-	refcount_inc(&ghes_refcount);
+	/* only set on success */
+	refcount_set(&ghes_refcount, 1);
 
 unlock:
 	mutex_unlock(&ghes_reg_mutex);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/firmware/qcom_scm-64.c linux-libre-5.3.17-gnu/drivers/firmware/qcom_scm-64.c
--- linux-libre-5.3.16-gnu/drivers/firmware/qcom_scm-64.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/firmware/qcom_scm-64.c	2019-12-17 14:08:41.000000000 -0500
@@ -150,7 +150,7 @@ static int qcom_scm_call(struct device *
 		kfree(args_virt);
 	}
 
-	if (res->a0 < 0)
+	if ((long)res->a0 < 0)
 		return qcom_scm_remap_error(res->a0);
 
 	return 0;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/hwtracing/coresight/coresight.c linux-libre-5.3.17-gnu/drivers/hwtracing/coresight/coresight.c
--- linux-libre-5.3.16-gnu/drivers/hwtracing/coresight/coresight.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/hwtracing/coresight/coresight.c	2019-12-17 14:08:41.000000000 -0500
@@ -253,9 +253,9 @@ static int coresight_enable_link(struct
 				 struct coresight_device *parent,
 				 struct coresight_device *child)
 {
-	int ret;
+	int ret = 0;
 	int link_subtype;
-	int refport, inport, outport;
+	int inport, outport;
 
 	if (!parent || !child)
 		return -EINVAL;
@@ -264,29 +264,17 @@ static int coresight_enable_link(struct
 	outport = coresight_find_link_outport(csdev, child);
 	link_subtype = csdev->subtype.link_subtype;
 
-	if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG)
-		refport = inport;
-	else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT)
-		refport = outport;
-	else
-		refport = 0;
-
-	if (refport < 0)
-		return refport;
-
-	if (atomic_inc_return(&csdev->refcnt[refport]) == 1) {
-		if (link_ops(csdev)->enable) {
-			ret = link_ops(csdev)->enable(csdev, inport, outport);
-			if (ret) {
-				atomic_dec(&csdev->refcnt[refport]);
-				return ret;
-			}
-		}
-	}
+	if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && inport < 0)
+		return inport;
+	if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT && outport < 0)
+		return outport;
 
-	csdev->enable = true;
+	if (link_ops(csdev)->enable)
+		ret = link_ops(csdev)->enable(csdev, inport, outport);
+	if (!ret)
+		csdev->enable = true;
 
-	return 0;
+	return ret;
 }
 
 static void coresight_disable_link(struct coresight_device *csdev,
@@ -295,7 +283,7 @@ static void coresight_disable_link(struc
 {
 	int i, nr_conns;
 	int link_subtype;
-	int refport, inport, outport;
+	int inport, outport;
 
 	if (!parent || !child)
 		return;
@@ -305,20 +293,15 @@ static void coresight_disable_link(struc
 	link_subtype = csdev->subtype.link_subtype;
 
 	if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) {
-		refport = inport;
 		nr_conns = csdev->pdata->nr_inport;
 	} else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) {
-		refport = outport;
 		nr_conns = csdev->pdata->nr_outport;
 	} else {
-		refport = 0;
 		nr_conns = 1;
 	}
 
-	if (atomic_dec_return(&csdev->refcnt[refport]) == 0) {
-		if (link_ops(csdev)->disable)
-			link_ops(csdev)->disable(csdev, inport, outport);
-	}
+	if (link_ops(csdev)->disable)
+		link_ops(csdev)->disable(csdev, inport, outport);
 
 	for (i = 0; i < nr_conns; i++)
 		if (atomic_read(&csdev->refcnt[i]) != 0)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/hwtracing/coresight/coresight-funnel.c linux-libre-5.3.17-gnu/drivers/hwtracing/coresight/coresight-funnel.c
--- linux-libre-5.3.16-gnu/drivers/hwtracing/coresight/coresight-funnel.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/hwtracing/coresight/coresight-funnel.c	2019-12-17 14:08:41.000000000 -0500
@@ -37,12 +37,14 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "f
  * @atclk:	optional clock for the core parts of the funnel.
  * @csdev:	component vitals needed by the framework.
  * @priority:	port selection order.
+ * @spinlock:	serialize enable/disable operations.
  */
 struct funnel_drvdata {
 	void __iomem		*base;
 	struct clk		*atclk;
 	struct coresight_device	*csdev;
 	unsigned long		priority;
+	spinlock_t		spinlock;
 };
 
 static int dynamic_funnel_enable_hw(struct funnel_drvdata *drvdata, int port)
@@ -75,11 +77,21 @@ static int funnel_enable(struct coresigh
 {
 	int rc = 0;
 	struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	unsigned long flags;
+	bool first_enable = false;
 
-	if (drvdata->base)
-		rc = dynamic_funnel_enable_hw(drvdata, inport);
-
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	if (atomic_read(&csdev->refcnt[inport]) == 0) {
+		if (drvdata->base)
+			rc = dynamic_funnel_enable_hw(drvdata, inport);
+		if (!rc)
+			first_enable = true;
+	}
 	if (!rc)
+		atomic_inc(&csdev->refcnt[inport]);
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	if (first_enable)
 		dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n", inport);
 	return rc;
 }
@@ -106,11 +118,19 @@ static void funnel_disable(struct coresi
 			   int outport)
 {
 	struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	unsigned long flags;
+	bool last_disable = false;
 
-	if (drvdata->base)
-		dynamic_funnel_disable_hw(drvdata, inport);
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	if (atomic_dec_return(&csdev->refcnt[inport]) == 0) {
+		if (drvdata->base)
+			dynamic_funnel_disable_hw(drvdata, inport);
+		last_disable = true;
+	}
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-	dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", inport);
+	if (last_disable)
+		dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", inport);
 }
 
 static const struct coresight_ops_link funnel_link_ops = {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/hwtracing/coresight/coresight-replicator.c linux-libre-5.3.17-gnu/drivers/hwtracing/coresight/coresight-replicator.c
--- linux-libre-5.3.16-gnu/drivers/hwtracing/coresight/coresight-replicator.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/hwtracing/coresight/coresight-replicator.c	2019-12-17 14:08:41.000000000 -0500
@@ -31,11 +31,13 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs
  *		whether this one is programmable or not.
  * @atclk:	optional clock for the core parts of the replicator.
  * @csdev:	component vitals needed by the framework
+ * @spinlock:	serialize enable/disable operations.
  */
 struct replicator_drvdata {
 	void __iomem		*base;
 	struct clk		*atclk;
 	struct coresight_device	*csdev;
+	spinlock_t		spinlock;
 };
 
 static void dynamic_replicator_reset(struct replicator_drvdata *drvdata)
@@ -97,10 +99,22 @@ static int replicator_enable(struct core
 {
 	int rc = 0;
 	struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	unsigned long flags;
+	bool first_enable = false;
 
-	if (drvdata->base)
-		rc = dynamic_replicator_enable(drvdata, inport, outport);
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	if (atomic_read(&csdev->refcnt[outport]) == 0) {
+		if (drvdata->base)
+			rc = dynamic_replicator_enable(drvdata, inport,
+						       outport);
+		if (!rc)
+			first_enable = true;
+	}
 	if (!rc)
+		atomic_inc(&csdev->refcnt[outport]);
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	if (first_enable)
 		dev_dbg(&csdev->dev, "REPLICATOR enabled\n");
 	return rc;
 }
@@ -137,10 +151,19 @@ static void replicator_disable(struct co
 			       int outport)
 {
 	struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	unsigned long flags;
+	bool last_disable = false;
 
-	if (drvdata->base)
-		dynamic_replicator_disable(drvdata, inport, outport);
-	dev_dbg(&csdev->dev, "REPLICATOR disabled\n");
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	if (atomic_dec_return(&csdev->refcnt[outport]) == 0) {
+		if (drvdata->base)
+			dynamic_replicator_disable(drvdata, inport, outport);
+		last_disable = true;
+	}
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	if (last_disable)
+		dev_dbg(&csdev->dev, "REPLICATOR disabled\n");
 }
 
 static const struct coresight_ops_link replicator_link_ops = {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/hwtracing/coresight/coresight-tmc-etf.c linux-libre-5.3.17-gnu/drivers/hwtracing/coresight/coresight-tmc-etf.c
--- linux-libre-5.3.16-gnu/drivers/hwtracing/coresight/coresight-tmc-etf.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/hwtracing/coresight/coresight-tmc-etf.c	2019-12-17 14:08:41.000000000 -0500
@@ -334,9 +334,10 @@ static int tmc_disable_etf_sink(struct c
 static int tmc_enable_etf_link(struct coresight_device *csdev,
 			       int inport, int outport)
 {
-	int ret;
+	int ret = 0;
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	bool first_enable = false;
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
@@ -344,12 +345,18 @@ static int tmc_enable_etf_link(struct co
 		return -EBUSY;
 	}
 
-	ret = tmc_etf_enable_hw(drvdata);
+	if (atomic_read(&csdev->refcnt[0]) == 0) {
+		ret = tmc_etf_enable_hw(drvdata);
+		if (!ret) {
+			drvdata->mode = CS_MODE_SYSFS;
+			first_enable = true;
+		}
+	}
 	if (!ret)
-		drvdata->mode = CS_MODE_SYSFS;
+		atomic_inc(&csdev->refcnt[0]);
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-	if (!ret)
+	if (first_enable)
 		dev_dbg(&csdev->dev, "TMC-ETF enabled\n");
 	return ret;
 }
@@ -359,6 +366,7 @@ static void tmc_disable_etf_link(struct
 {
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	bool last_disable = false;
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
@@ -366,11 +374,15 @@ static void tmc_disable_etf_link(struct
 		return;
 	}
 
-	tmc_etf_disable_hw(drvdata);
-	drvdata->mode = CS_MODE_DISABLED;
+	if (atomic_dec_return(&csdev->refcnt[0]) == 0) {
+		tmc_etf_disable_hw(drvdata);
+		drvdata->mode = CS_MODE_DISABLED;
+		last_disable = true;
+	}
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-	dev_dbg(&csdev->dev, "TMC-ETF disabled\n");
+	if (last_disable)
+		dev_dbg(&csdev->dev, "TMC-ETF disabled\n");
 }
 
 static void *tmc_alloc_etf_buffer(struct coresight_device *csdev,
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/hwtracing/intel_th/core.c linux-libre-5.3.17-gnu/drivers/hwtracing/intel_th/core.c
--- linux-libre-5.3.16-gnu/drivers/hwtracing/intel_th/core.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/hwtracing/intel_th/core.c	2019-12-17 14:08:41.000000000 -0500
@@ -649,10 +649,8 @@ intel_th_subdevice_alloc(struct intel_th
 	}
 
 	err = intel_th_device_add_resources(thdev, res, subdev->nres);
-	if (err) {
-		put_device(&thdev->dev);
+	if (err)
 		goto fail_put_device;
-	}
 
 	if (subdev->type == INTEL_TH_OUTPUT) {
 		if (subdev->mknode)
@@ -667,10 +665,8 @@ intel_th_subdevice_alloc(struct intel_th
 	}
 
 	err = device_add(&thdev->dev);
-	if (err) {
-		put_device(&thdev->dev);
+	if (err)
 		goto fail_free_res;
-	}
 
 	/* need switch driver to be loaded to enumerate the rest */
 	if (subdev->type == INTEL_TH_SWITCH && !req) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/hwtracing/intel_th/pci.c linux-libre-5.3.17-gnu/drivers/hwtracing/intel_th/pci.c
--- linux-libre-5.3.16-gnu/drivers/hwtracing/intel_th/pci.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/hwtracing/intel_th/pci.c	2019-12-17 14:08:41.000000000 -0500
@@ -210,6 +210,16 @@ static const struct pci_device_id intel_
 		.driver_data = (kernel_ulong_t)&intel_th_2x,
 	},
 	{
+		/* Ice Lake CPU */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29),
+		.driver_data = (kernel_ulong_t)&intel_th_2x,
+	},
+	{
+		/* Tiger Lake CPU */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33),
+		.driver_data = (kernel_ulong_t)&intel_th_2x,
+	},
+	{
 		/* Tiger Lake PCH */
 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6),
 		.driver_data = (kernel_ulong_t)&intel_th_2x,
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/hwtracing/stm/policy.c linux-libre-5.3.17-gnu/drivers/hwtracing/stm/policy.c
--- linux-libre-5.3.16-gnu/drivers/hwtracing/stm/policy.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/hwtracing/stm/policy.c	2019-12-17 14:08:41.000000000 -0500
@@ -345,7 +345,11 @@ void stp_policy_unbind(struct stp_policy
 	stm->policy = NULL;
 	policy->stm = NULL;
 
+	/*
+	 * Drop the reference on the protocol driver and lose the link.
+	 */
 	stm_put_protocol(stm->pdrv);
+	stm->pdrv = NULL;
 	stm_put_device(stm);
 }
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/iio/adc/ad7124.c linux-libre-5.3.17-gnu/drivers/iio/adc/ad7124.c
--- linux-libre-5.3.16-gnu/drivers/iio/adc/ad7124.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/iio/adc/ad7124.c	2019-12-17 14:08:41.000000000 -0500
@@ -39,6 +39,8 @@
 #define AD7124_STATUS_POR_FLAG_MSK	BIT(4)
 
 /* AD7124_ADC_CONTROL */
+#define AD7124_ADC_CTRL_REF_EN_MSK	BIT(8)
+#define AD7124_ADC_CTRL_REF_EN(x)	FIELD_PREP(AD7124_ADC_CTRL_REF_EN_MSK, x)
 #define AD7124_ADC_CTRL_PWR_MSK	GENMASK(7, 6)
 #define AD7124_ADC_CTRL_PWR(x)		FIELD_PREP(AD7124_ADC_CTRL_PWR_MSK, x)
 #define AD7124_ADC_CTRL_MODE_MSK	GENMASK(5, 2)
@@ -424,7 +426,10 @@ static int ad7124_init_channel_vref(stru
 		break;
 	case AD7124_INT_REF:
 		st->channel_config[channel_number].vref_mv = 2500;
-		break;
+		st->adc_control &= ~AD7124_ADC_CTRL_REF_EN_MSK;
+		st->adc_control |= AD7124_ADC_CTRL_REF_EN(1);
+		return ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL,
+				      2, st->adc_control);
 	default:
 		dev_err(&st->sd.spi->dev, "Invalid reference %d\n", refsel);
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/iio/adc/ad7606.c linux-libre-5.3.17-gnu/drivers/iio/adc/ad7606.c
--- linux-libre-5.3.16-gnu/drivers/iio/adc/ad7606.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/iio/adc/ad7606.c	2019-12-17 14:08:41.000000000 -0500
@@ -57,7 +57,7 @@ static int ad7606_reset(struct ad7606_st
 
 static int ad7606_read_samples(struct ad7606_state *st)
 {
-	unsigned int num = st->chip_info->num_channels;
+	unsigned int num = st->chip_info->num_channels - 1;
 	u16 *data = st->data;
 	int ret;
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/iio/adc/ad7949.c linux-libre-5.3.17-gnu/drivers/iio/adc/ad7949.c
--- linux-libre-5.3.16-gnu/drivers/iio/adc/ad7949.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/iio/adc/ad7949.c	2019-12-17 14:08:41.000000000 -0500
@@ -57,29 +57,11 @@ struct ad7949_adc_chip {
 	u32 buffer ____cacheline_aligned;
 };
 
-static bool ad7949_spi_cfg_is_read_back(struct ad7949_adc_chip *ad7949_adc)
-{
-	if (!(ad7949_adc->cfg & AD7949_CFG_READ_BACK))
-		return true;
-
-	return false;
-}
-
-static int ad7949_spi_bits_per_word(struct ad7949_adc_chip *ad7949_adc)
-{
-	int ret = ad7949_adc->resolution;
-
-	if (ad7949_spi_cfg_is_read_back(ad7949_adc))
-		ret += AD7949_CFG_REG_SIZE_BITS;
-
-	return ret;
-}
-
 static int ad7949_spi_write_cfg(struct ad7949_adc_chip *ad7949_adc, u16 val,
 				u16 mask)
 {
 	int ret;
-	int bits_per_word = ad7949_spi_bits_per_word(ad7949_adc);
+	int bits_per_word = ad7949_adc->resolution;
 	int shift = bits_per_word - AD7949_CFG_REG_SIZE_BITS;
 	struct spi_message msg;
 	struct spi_transfer tx[] = {
@@ -107,7 +89,8 @@ static int ad7949_spi_read_channel(struc
 				   unsigned int channel)
 {
 	int ret;
-	int bits_per_word = ad7949_spi_bits_per_word(ad7949_adc);
+	int i;
+	int bits_per_word = ad7949_adc->resolution;
 	int mask = GENMASK(ad7949_adc->resolution, 0);
 	struct spi_message msg;
 	struct spi_transfer tx[] = {
@@ -118,12 +101,23 @@ static int ad7949_spi_read_channel(struc
 		},
 	};
 
-	ret = ad7949_spi_write_cfg(ad7949_adc,
-				   channel << AD7949_OFFSET_CHANNEL_SEL,
-				   AD7949_MASK_CHANNEL_SEL);
-	if (ret)
-		return ret;
+	/*
+	 * 1: write CFG for sample N and read old data (sample N-2)
+	 * 2: if CFG was not changed since sample N-1 then we'll get good data
+	 *    at the next xfer, so we bail out now, otherwise we write something
+	 *    and we read garbage (sample N-1 configuration).
+	 */
+	for (i = 0; i < 2; i++) {
+		ret = ad7949_spi_write_cfg(ad7949_adc,
+					   channel << AD7949_OFFSET_CHANNEL_SEL,
+					   AD7949_MASK_CHANNEL_SEL);
+		if (ret)
+			return ret;
+		if (channel == ad7949_adc->current_channel)
+			break;
+	}
 
+	/* 3: write something and read actual data */
 	ad7949_adc->buffer = 0;
 	spi_message_init_with_transfers(&msg, tx, 1);
 	ret = spi_sync(ad7949_adc->spi, &msg);
@@ -138,10 +132,7 @@ static int ad7949_spi_read_channel(struc
 
 	ad7949_adc->current_channel = channel;
 
-	if (ad7949_spi_cfg_is_read_back(ad7949_adc))
-		*val = (ad7949_adc->buffer >> AD7949_CFG_REG_SIZE_BITS) & mask;
-	else
-		*val = ad7949_adc->buffer & mask;
+	*val = ad7949_adc->buffer & mask;
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/iio/humidity/hdc100x.c linux-libre-5.3.17-gnu/drivers/iio/humidity/hdc100x.c
--- linux-libre-5.3.16-gnu/drivers/iio/humidity/hdc100x.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/iio/humidity/hdc100x.c	2019-12-17 14:08:41.000000000 -0500
@@ -229,7 +229,7 @@ static int hdc100x_read_raw(struct iio_d
 			*val2 = 65536;
 			return IIO_VAL_FRACTIONAL;
 		} else {
-			*val = 100;
+			*val = 100000;
 			*val2 = 65536;
 			return IIO_VAL_FRACTIONAL;
 		}
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/iio/imu/adis16480.c linux-libre-5.3.17-gnu/drivers/iio/imu/adis16480.c
--- linux-libre-5.3.16-gnu/drivers/iio/imu/adis16480.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/iio/imu/adis16480.c	2019-12-17 14:08:41.000000000 -0500
@@ -623,9 +623,13 @@ static int adis16480_read_raw(struct iio
 			*val2 = (st->chip_info->temp_scale % 1000) * 1000;
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_PRESSURE:
-			*val = 0;
-			*val2 = 4000; /* 40ubar = 0.004 kPa */
-			return IIO_VAL_INT_PLUS_MICRO;
+			/*
+			 * max scale is 1310 mbar
+			 * max raw value is 32767 shifted for 32bits
+			 */
+			*val = 131; /* 1310mbar = 131 kPa */
+			*val2 = 32767 << 16;
+			return IIO_VAL_FRACTIONAL;
 		default:
 			return -EINVAL;
 		}
@@ -786,13 +790,14 @@ static const struct adis16480_chip_info
 		.channels = adis16485_channels,
 		.num_channels = ARRAY_SIZE(adis16485_channels),
 		/*
-		 * storing the value in rad/degree and the scale in degree
-		 * gives us the result in rad and better precession than
-		 * storing the scale directly in rad.
+		 * Typically we do IIO_RAD_TO_DEGREE in the denominator, which
+		 * is exactly the same as IIO_DEGREE_TO_RAD in numerator, since
+		 * it gives better approximation. However, in this case we
+		 * cannot do it since it would not fit in a 32bit variable.
 		 */
-		.gyro_max_val = IIO_RAD_TO_DEGREE(22887),
-		.gyro_max_scale = 300,
-		.accel_max_val = IIO_M_S_2_TO_G(21973),
+		.gyro_max_val = 22887 << 16,
+		.gyro_max_scale = IIO_DEGREE_TO_RAD(300),
+		.accel_max_val = IIO_M_S_2_TO_G(21973 << 16),
 		.accel_max_scale = 18,
 		.temp_scale = 5650, /* 5.65 milli degree Celsius */
 		.int_clk = 2460000,
@@ -802,9 +807,9 @@ static const struct adis16480_chip_info
 	[ADIS16480] = {
 		.channels = adis16480_channels,
 		.num_channels = ARRAY_SIZE(adis16480_channels),
-		.gyro_max_val = IIO_RAD_TO_DEGREE(22500),
-		.gyro_max_scale = 450,
-		.accel_max_val = IIO_M_S_2_TO_G(12500),
+		.gyro_max_val = 22500 << 16,
+		.gyro_max_scale = IIO_DEGREE_TO_RAD(450),
+		.accel_max_val = IIO_M_S_2_TO_G(12500 << 16),
 		.accel_max_scale = 10,
 		.temp_scale = 5650, /* 5.65 milli degree Celsius */
 		.int_clk = 2460000,
@@ -814,9 +819,9 @@ static const struct adis16480_chip_info
 	[ADIS16485] = {
 		.channels = adis16485_channels,
 		.num_channels = ARRAY_SIZE(adis16485_channels),
-		.gyro_max_val = IIO_RAD_TO_DEGREE(22500),
-		.gyro_max_scale = 450,
-		.accel_max_val = IIO_M_S_2_TO_G(20000),
+		.gyro_max_val = 22500 << 16,
+		.gyro_max_scale = IIO_DEGREE_TO_RAD(450),
+		.accel_max_val = IIO_M_S_2_TO_G(20000 << 16),
 		.accel_max_scale = 5,
 		.temp_scale = 5650, /* 5.65 milli degree Celsius */
 		.int_clk = 2460000,
@@ -826,9 +831,9 @@ static const struct adis16480_chip_info
 	[ADIS16488] = {
 		.channels = adis16480_channels,
 		.num_channels = ARRAY_SIZE(adis16480_channels),
-		.gyro_max_val = IIO_RAD_TO_DEGREE(22500),
-		.gyro_max_scale = 450,
-		.accel_max_val = IIO_M_S_2_TO_G(22500),
+		.gyro_max_val = 22500 << 16,
+		.gyro_max_scale = IIO_DEGREE_TO_RAD(450),
+		.accel_max_val = IIO_M_S_2_TO_G(22500 << 16),
 		.accel_max_scale = 18,
 		.temp_scale = 5650, /* 5.65 milli degree Celsius */
 		.int_clk = 2460000,
@@ -838,9 +843,9 @@ static const struct adis16480_chip_info
 	[ADIS16495_1] = {
 		.channels = adis16485_channels,
 		.num_channels = ARRAY_SIZE(adis16485_channels),
-		.gyro_max_val = IIO_RAD_TO_DEGREE(20000),
-		.gyro_max_scale = 125,
-		.accel_max_val = IIO_M_S_2_TO_G(32000),
+		.gyro_max_val = 20000 << 16,
+		.gyro_max_scale = IIO_DEGREE_TO_RAD(125),
+		.accel_max_val = IIO_M_S_2_TO_G(32000 << 16),
 		.accel_max_scale = 8,
 		.temp_scale = 12500, /* 12.5 milli degree Celsius */
 		.int_clk = 4250000,
@@ -851,9 +856,9 @@ static const struct adis16480_chip_info
 	[ADIS16495_2] = {
 		.channels = adis16485_channels,
 		.num_channels = ARRAY_SIZE(adis16485_channels),
-		.gyro_max_val = IIO_RAD_TO_DEGREE(18000),
-		.gyro_max_scale = 450,
-		.accel_max_val = IIO_M_S_2_TO_G(32000),
+		.gyro_max_val = 18000 << 16,
+		.gyro_max_scale = IIO_DEGREE_TO_RAD(450),
+		.accel_max_val = IIO_M_S_2_TO_G(32000 << 16),
 		.accel_max_scale = 8,
 		.temp_scale = 12500, /* 12.5 milli degree Celsius */
 		.int_clk = 4250000,
@@ -864,9 +869,9 @@ static const struct adis16480_chip_info
 	[ADIS16495_3] = {
 		.channels = adis16485_channels,
 		.num_channels = ARRAY_SIZE(adis16485_channels),
-		.gyro_max_val = IIO_RAD_TO_DEGREE(20000),
-		.gyro_max_scale = 2000,
-		.accel_max_val = IIO_M_S_2_TO_G(32000),
+		.gyro_max_val = 20000 << 16,
+		.gyro_max_scale = IIO_DEGREE_TO_RAD(2000),
+		.accel_max_val = IIO_M_S_2_TO_G(32000 << 16),
 		.accel_max_scale = 8,
 		.temp_scale = 12500, /* 12.5 milli degree Celsius */
 		.int_clk = 4250000,
@@ -877,9 +882,9 @@ static const struct adis16480_chip_info
 	[ADIS16497_1] = {
 		.channels = adis16485_channels,
 		.num_channels = ARRAY_SIZE(adis16485_channels),
-		.gyro_max_val = IIO_RAD_TO_DEGREE(20000),
-		.gyro_max_scale = 125,
-		.accel_max_val = IIO_M_S_2_TO_G(32000),
+		.gyro_max_val = 20000 << 16,
+		.gyro_max_scale = IIO_DEGREE_TO_RAD(125),
+		.accel_max_val = IIO_M_S_2_TO_G(32000 << 16),
 		.accel_max_scale = 40,
 		.temp_scale = 12500, /* 12.5 milli degree Celsius */
 		.int_clk = 4250000,
@@ -890,9 +895,9 @@ static const struct adis16480_chip_info
 	[ADIS16497_2] = {
 		.channels = adis16485_channels,
 		.num_channels = ARRAY_SIZE(adis16485_channels),
-		.gyro_max_val = IIO_RAD_TO_DEGREE(18000),
-		.gyro_max_scale = 450,
-		.accel_max_val = IIO_M_S_2_TO_G(32000),
+		.gyro_max_val = 18000 << 16,
+		.gyro_max_scale = IIO_DEGREE_TO_RAD(450),
+		.accel_max_val = IIO_M_S_2_TO_G(32000 << 16),
 		.accel_max_scale = 40,
 		.temp_scale = 12500, /* 12.5 milli degree Celsius */
 		.int_clk = 4250000,
@@ -903,9 +908,9 @@ static const struct adis16480_chip_info
 	[ADIS16497_3] = {
 		.channels = adis16485_channels,
 		.num_channels = ARRAY_SIZE(adis16485_channels),
-		.gyro_max_val = IIO_RAD_TO_DEGREE(20000),
-		.gyro_max_scale = 2000,
-		.accel_max_val = IIO_M_S_2_TO_G(32000),
+		.gyro_max_val = 20000 << 16,
+		.gyro_max_scale = IIO_DEGREE_TO_RAD(2000),
+		.accel_max_val = IIO_M_S_2_TO_G(32000 << 16),
 		.accel_max_scale = 40,
 		.temp_scale = 12500, /* 12.5 milli degree Celsius */
 		.int_clk = 4250000,
@@ -919,6 +924,7 @@ static const struct iio_info adis16480_i
 	.read_raw = &adis16480_read_raw,
 	.write_raw = &adis16480_write_raw,
 	.update_scan_mode = adis_update_scan_mode,
+	.debugfs_reg_access = adis_debugfs_reg_access,
 };
 
 static int adis16480_stop_device(struct iio_dev *indio_dev)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c linux-libre-5.3.17-gnu/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
--- linux-libre-5.3.16-gnu/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c	2019-12-17 14:08:41.000000000 -0500
@@ -115,6 +115,7 @@ static const struct inv_mpu6050_hw hw_in
 		.reg = &reg_set_6050,
 		.config = &chip_config_6050,
 		.fifo_size = 1024,
+		.temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
 	},
 	{
 		.whoami = INV_MPU6500_WHOAMI_VALUE,
@@ -122,6 +123,7 @@ static const struct inv_mpu6050_hw hw_in
 		.reg = &reg_set_6500,
 		.config = &chip_config_6050,
 		.fifo_size = 512,
+		.temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
 	},
 	{
 		.whoami = INV_MPU6515_WHOAMI_VALUE,
@@ -129,6 +131,7 @@ static const struct inv_mpu6050_hw hw_in
 		.reg = &reg_set_6500,
 		.config = &chip_config_6050,
 		.fifo_size = 512,
+		.temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
 	},
 	{
 		.whoami = INV_MPU6000_WHOAMI_VALUE,
@@ -136,6 +139,7 @@ static const struct inv_mpu6050_hw hw_in
 		.reg = &reg_set_6050,
 		.config = &chip_config_6050,
 		.fifo_size = 1024,
+		.temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
 	},
 	{
 		.whoami = INV_MPU9150_WHOAMI_VALUE,
@@ -143,6 +147,7 @@ static const struct inv_mpu6050_hw hw_in
 		.reg = &reg_set_6050,
 		.config = &chip_config_6050,
 		.fifo_size = 1024,
+		.temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
 	},
 	{
 		.whoami = INV_MPU9250_WHOAMI_VALUE,
@@ -150,6 +155,7 @@ static const struct inv_mpu6050_hw hw_in
 		.reg = &reg_set_6500,
 		.config = &chip_config_6050,
 		.fifo_size = 512,
+		.temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
 	},
 	{
 		.whoami = INV_MPU9255_WHOAMI_VALUE,
@@ -157,6 +163,7 @@ static const struct inv_mpu6050_hw hw_in
 		.reg = &reg_set_6500,
 		.config = &chip_config_6050,
 		.fifo_size = 512,
+		.temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
 	},
 	{
 		.whoami = INV_ICM20608_WHOAMI_VALUE,
@@ -164,6 +171,7 @@ static const struct inv_mpu6050_hw hw_in
 		.reg = &reg_set_6500,
 		.config = &chip_config_6050,
 		.fifo_size = 512,
+		.temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
 	},
 	{
 		.whoami = INV_ICM20602_WHOAMI_VALUE,
@@ -171,6 +179,7 @@ static const struct inv_mpu6050_hw hw_in
 		.reg = &reg_set_icm20602,
 		.config = &chip_config_6050,
 		.fifo_size = 1008,
+		.temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
 	},
 };
 
@@ -471,12 +480,8 @@ inv_mpu6050_read_raw(struct iio_dev *ind
 
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_TEMP:
-			*val = 0;
-			if (st->chip_type == INV_ICM20602)
-				*val2 = INV_ICM20602_TEMP_SCALE;
-			else
-				*val2 = INV_MPU6050_TEMP_SCALE;
-
+			*val = st->hw->temp.scale / 1000000;
+			*val2 = st->hw->temp.scale % 1000000;
 			return IIO_VAL_INT_PLUS_MICRO;
 		default:
 			return -EINVAL;
@@ -484,11 +489,7 @@ inv_mpu6050_read_raw(struct iio_dev *ind
 	case IIO_CHAN_INFO_OFFSET:
 		switch (chan->type) {
 		case IIO_TEMP:
-			if (st->chip_type == INV_ICM20602)
-				*val = INV_ICM20602_TEMP_OFFSET;
-			else
-				*val = INV_MPU6050_TEMP_OFFSET;
-
+			*val = st->hw->temp.offset;
 			return IIO_VAL_INT;
 		default:
 			return -EINVAL;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h linux-libre-5.3.17-gnu/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
--- linux-libre-5.3.16-gnu/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h	2019-12-17 14:08:41.000000000 -0500
@@ -101,6 +101,7 @@ struct inv_mpu6050_chip_config {
  *  @reg:   register map of the chip.
  *  @config:    configuration of the chip.
  *  @fifo_size:	size of the FIFO in bytes.
+ *  @temp:	offset and scale to apply to raw temperature.
  */
 struct inv_mpu6050_hw {
 	u8 whoami;
@@ -108,6 +109,10 @@ struct inv_mpu6050_hw {
 	const struct inv_mpu6050_reg_map *reg;
 	const struct inv_mpu6050_chip_config *config;
 	size_t fifo_size;
+	struct {
+		int offset;
+		int scale;
+	} temp;
 };
 
 /*
@@ -218,16 +223,19 @@ struct inv_mpu6050_state {
 #define INV_MPU6050_REG_UP_TIME_MIN          5000
 #define INV_MPU6050_REG_UP_TIME_MAX          10000
 
-#define INV_MPU6050_TEMP_OFFSET	             12421
-#define INV_MPU6050_TEMP_SCALE               2941
+#define INV_MPU6050_TEMP_OFFSET	             12420
+#define INV_MPU6050_TEMP_SCALE               2941176
 #define INV_MPU6050_MAX_GYRO_FS_PARAM        3
 #define INV_MPU6050_MAX_ACCL_FS_PARAM        3
 #define INV_MPU6050_THREE_AXIS               3
 #define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT    3
 #define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT    3
 
-#define INV_ICM20602_TEMP_OFFSET	     8170
-#define INV_ICM20602_TEMP_SCALE		     3060
+#define INV_MPU6500_TEMP_OFFSET              7011
+#define INV_MPU6500_TEMP_SCALE               2995178
+
+#define INV_ICM20608_TEMP_OFFSET	     8170
+#define INV_ICM20608_TEMP_SCALE		     3059976
 
 /* 6 + 6 round up and plus 8 */
 #define INV_MPU6050_OUTPUT_DATA_SIZE         24
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c linux-libre-5.3.17-gnu/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
--- linux-libre-5.3.16-gnu/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c	2019-12-17 14:08:41.000000000 -0500
@@ -69,33 +69,6 @@
 #define ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR	0x24
 #define ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR	0x26
 
-static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = {
-	[ST_LSM6DSX_ID_ACC] = {
-		.reg = {
-			.addr = 0x10,
-			.mask = GENMASK(7, 4),
-		},
-		.odr_avl[0] = {  13, 0x01 },
-		.odr_avl[1] = {  26, 0x02 },
-		.odr_avl[2] = {  52, 0x03 },
-		.odr_avl[3] = { 104, 0x04 },
-		.odr_avl[4] = { 208, 0x05 },
-		.odr_avl[5] = { 416, 0x06 },
-	},
-	[ST_LSM6DSX_ID_GYRO] = {
-		.reg = {
-			.addr = 0x11,
-			.mask = GENMASK(7, 4),
-		},
-		.odr_avl[0] = {  13, 0x01 },
-		.odr_avl[1] = {  26, 0x02 },
-		.odr_avl[2] = {  52, 0x03 },
-		.odr_avl[3] = { 104, 0x04 },
-		.odr_avl[4] = { 208, 0x05 },
-		.odr_avl[5] = { 416, 0x06 },
-	}
-};
-
 static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = {
 	[ST_LSM6DSX_ID_ACC] = {
 		.reg = {
@@ -129,6 +102,32 @@ static const struct st_lsm6dsx_settings
 				.name = ST_LSM6DS3_DEV_NAME,
 			},
 		},
+		.odr_table = {
+			[ST_LSM6DSX_ID_ACC] = {
+				.reg = {
+					.addr = 0x10,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+			[ST_LSM6DSX_ID_GYRO] = {
+				.reg = {
+					.addr = 0x11,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+		},
 		.decimator = {
 			[ST_LSM6DSX_ID_ACC] = {
 				.addr = 0x08,
@@ -179,6 +178,32 @@ static const struct st_lsm6dsx_settings
 				.name = ST_LSM6DS3H_DEV_NAME,
 			},
 		},
+		.odr_table = {
+			[ST_LSM6DSX_ID_ACC] = {
+				.reg = {
+					.addr = 0x10,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+			[ST_LSM6DSX_ID_GYRO] = {
+				.reg = {
+					.addr = 0x11,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+		},
 		.decimator = {
 			[ST_LSM6DSX_ID_ACC] = {
 				.addr = 0x08,
@@ -235,6 +260,32 @@ static const struct st_lsm6dsx_settings
 				.name = ST_ISM330DLC_DEV_NAME,
 			},
 		},
+		.odr_table = {
+			[ST_LSM6DSX_ID_ACC] = {
+				.reg = {
+					.addr = 0x10,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+			[ST_LSM6DSX_ID_GYRO] = {
+				.reg = {
+					.addr = 0x11,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+		},
 		.decimator = {
 			[ST_LSM6DSX_ID_ACC] = {
 				.addr = 0x08,
@@ -288,6 +339,32 @@ static const struct st_lsm6dsx_settings
 				.name = ST_LSM6DSOX_DEV_NAME,
 			},
 		},
+		.odr_table = {
+			[ST_LSM6DSX_ID_ACC] = {
+				.reg = {
+					.addr = 0x10,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+			[ST_LSM6DSX_ID_GYRO] = {
+				.reg = {
+					.addr = 0x11,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+		},
 		.batch = {
 			[ST_LSM6DSX_ID_ACC] = {
 				.addr = 0x09,
@@ -356,6 +433,32 @@ static const struct st_lsm6dsx_settings
 				.name = ST_ASM330LHH_DEV_NAME,
 			},
 		},
+		.odr_table = {
+			[ST_LSM6DSX_ID_ACC] = {
+				.reg = {
+					.addr = 0x10,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+			[ST_LSM6DSX_ID_GYRO] = {
+				.reg = {
+					.addr = 0x11,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+		},
 		.batch = {
 			[ST_LSM6DSX_ID_ACC] = {
 				.addr = 0x09,
@@ -398,6 +501,32 @@ static const struct st_lsm6dsx_settings
 				.name = ST_LSM6DSR_DEV_NAME,
 			},
 		},
+		.odr_table = {
+			[ST_LSM6DSX_ID_ACC] = {
+				.reg = {
+					.addr = 0x10,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+			[ST_LSM6DSX_ID_GYRO] = {
+				.reg = {
+					.addr = 0x11,
+					.mask = GENMASK(7, 4),
+				},
+				.odr_avl[0] = {  13, 0x01 },
+				.odr_avl[1] = {  26, 0x02 },
+				.odr_avl[2] = {  52, 0x03 },
+				.odr_avl[3] = { 104, 0x04 },
+				.odr_avl[4] = { 208, 0x05 },
+				.odr_avl[5] = { 416, 0x06 },
+			},
+		},
 		.batch = {
 			[ST_LSM6DSX_ID_ACC] = {
 				.addr = 0x09,
@@ -560,22 +689,23 @@ static int st_lsm6dsx_set_full_scale(str
 
 int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val)
 {
+	const struct st_lsm6dsx_odr_table_entry *odr_table;
 	int i;
 
+	odr_table = &sensor->hw->settings->odr_table[sensor->id];
 	for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
 		/*
 		 * ext devices can run at different odr respect to
 		 * accel sensor
 		 */
-		if (st_lsm6dsx_odr_table[sensor->id].odr_avl[i].hz >= odr)
+		if (odr_table->odr_avl[i].hz >= odr)
 			break;
 
 	if (i == ST_LSM6DSX_ODR_LIST_SIZE)
 		return -EINVAL;
 
-	*val = st_lsm6dsx_odr_table[sensor->id].odr_avl[i].val;
-
-	return 0;
+	*val = odr_table->odr_avl[i].val;
+	return odr_table->odr_avl[i].hz;
 }
 
 static u16 st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u16 odr,
@@ -638,7 +768,7 @@ static int st_lsm6dsx_set_odr(struct st_
 			return err;
 	}
 
-	reg = &st_lsm6dsx_odr_table[ref_sensor->id].reg;
+	reg = &hw->settings->odr_table[ref_sensor->id].reg;
 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
 	return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
 }
@@ -738,8 +868,10 @@ static int st_lsm6dsx_write_raw(struct i
 	case IIO_CHAN_INFO_SAMP_FREQ: {
 		u8 data;
 
-		err = st_lsm6dsx_check_odr(sensor, val, &data);
-		if (!err)
+		val = st_lsm6dsx_check_odr(sensor, val, &data);
+		if (val < 0)
+			err = val;
+		else
 			sensor->odr = val;
 		break;
 	}
@@ -783,11 +915,12 @@ st_lsm6dsx_sysfs_sampling_frequency_avai
 {
 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
 	enum st_lsm6dsx_sensor_id id = sensor->id;
+	struct st_lsm6dsx_hw *hw = sensor->hw;
 	int i, len = 0;
 
 	for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
-				 st_lsm6dsx_odr_table[id].odr_avl[i].hz);
+				 hw->settings->odr_table[id].odr_avl[i].hz);
 	buf[len - 1] = '\n';
 
 	return len;
@@ -1037,7 +1170,7 @@ static struct iio_dev *st_lsm6dsx_alloc_
 	sensor = iio_priv(iio_dev);
 	sensor->id = id;
 	sensor->hw = hw;
-	sensor->odr = st_lsm6dsx_odr_table[id].odr_avl[0].hz;
+	sensor->odr = hw->settings->odr_table[id].odr_avl[0].hz;
 	sensor->gain = st_lsm6dsx_fs_table[id].fs_avl[0].gain;
 	sensor->watermark = 1;
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h linux-libre-5.3.17-gnu/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
--- linux-libre-5.3.16-gnu/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h	2019-12-17 14:08:41.000000000 -0500
@@ -198,6 +198,7 @@ struct st_lsm6dsx_ext_dev_settings {
  * @wai: Sensor WhoAmI default value.
  * @max_fifo_size: Sensor max fifo length in FIFO words.
  * @id: List of hw id/device name supported by the driver configuration.
+ * @odr_table: Hw sensors odr table (Hz + val).
  * @decimator: List of decimator register info (addr + mask).
  * @batch: List of FIFO batching register info (addr + mask).
  * @fifo_ops: Sensor hw FIFO parameters.
@@ -211,6 +212,7 @@ struct st_lsm6dsx_settings {
 		enum st_lsm6dsx_hw_id hw_id;
 		const char *name;
 	} id[ST_LSM6DSX_MAX_ID];
+	struct st_lsm6dsx_odr_table_entry odr_table[2];
 	struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID];
 	struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID];
 	struct st_lsm6dsx_fifo_ops fifo_ops;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/interconnect/qcom/sdm845.c linux-libre-5.3.17-gnu/drivers/interconnect/qcom/sdm845.c
--- linux-libre-5.3.16-gnu/drivers/interconnect/qcom/sdm845.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/interconnect/qcom/sdm845.c	2019-12-17 14:08:41.000000000 -0500
@@ -807,9 +807,9 @@ static int qnoc_remove(struct platform_d
 {
 	struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
 	struct icc_provider *provider = &qp->provider;
-	struct icc_node *n;
+	struct icc_node *n, *tmp;
 
-	list_for_each_entry(n, &provider->nodes, node_list) {
+	list_for_each_entry_safe(n, tmp, &provider->nodes, node_list) {
 		icc_node_del(n);
 		icc_node_destroy(n->id);
 	}
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/dm-writecache.c linux-libre-5.3.17-gnu/drivers/md/dm-writecache.c
--- linux-libre-5.3.16-gnu/drivers/md/dm-writecache.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/dm-writecache.c	2019-12-17 14:08:41.000000000 -0500
@@ -1218,7 +1218,8 @@ bio_copy:
 			}
 		} while (bio->bi_iter.bi_size);
 
-		if (unlikely(wc->uncommitted_blocks >= wc->autocommit_blocks))
+		if (unlikely(bio->bi_opf & REQ_FUA ||
+			     wc->uncommitted_blocks >= wc->autocommit_blocks))
 			writecache_flush(wc);
 		else
 			writecache_schedule_autocommit(wc);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/dm-zoned.h linux-libre-5.3.17-gnu/drivers/md/dm-zoned.h
--- linux-libre-5.3.16-gnu/drivers/md/dm-zoned.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/dm-zoned.h	2019-12-17 14:08:41.000000000 -0500
@@ -72,6 +72,7 @@ struct dmz_dev {
 
 /* Device flags. */
 #define DMZ_BDEV_DYING		(1 << 0)
+#define DMZ_CHECK_BDEV		(2 << 0)
 
 /*
  * Zone descriptor.
@@ -255,5 +256,6 @@ void dmz_schedule_reclaim(struct dmz_rec
  * Functions defined in dm-zoned-target.c
  */
 bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev);
+bool dmz_check_bdev(struct dmz_dev *dmz_dev);
 
 #endif /* DM_ZONED_H */
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/dm-zoned-metadata.c linux-libre-5.3.17-gnu/drivers/md/dm-zoned-metadata.c
--- linux-libre-5.3.16-gnu/drivers/md/dm-zoned-metadata.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/dm-zoned-metadata.c	2019-12-17 14:08:41.000000000 -0500
@@ -554,6 +554,7 @@ static struct dmz_mblock *dmz_get_mblock
 		       TASK_UNINTERRUPTIBLE);
 	if (test_bit(DMZ_META_ERROR, &mblk->state)) {
 		dmz_release_mblock(zmd, mblk);
+		dmz_check_bdev(zmd->dev);
 		return ERR_PTR(-EIO);
 	}
 
@@ -625,6 +626,8 @@ static int dmz_rdwr_block(struct dmz_met
 	ret = submit_bio_wait(bio);
 	bio_put(bio);
 
+	if (ret)
+		dmz_check_bdev(zmd->dev);
 	return ret;
 }
 
@@ -691,6 +694,7 @@ static int dmz_write_dirty_mblocks(struc
 			       TASK_UNINTERRUPTIBLE);
 		if (test_bit(DMZ_META_ERROR, &mblk->state)) {
 			clear_bit(DMZ_META_ERROR, &mblk->state);
+			dmz_check_bdev(zmd->dev);
 			ret = -EIO;
 		}
 		nr_mblks_submitted--;
@@ -768,7 +772,7 @@ int dmz_flush_metadata(struct dmz_metada
 	/* If there are no dirty metadata blocks, just flush the device cache */
 	if (list_empty(&write_list)) {
 		ret = blkdev_issue_flush(zmd->dev->bdev, GFP_NOIO, NULL);
-		goto out;
+		goto err;
 	}
 
 	/*
@@ -778,7 +782,7 @@ int dmz_flush_metadata(struct dmz_metada
 	 */
 	ret = dmz_log_dirty_mblocks(zmd, &write_list);
 	if (ret)
-		goto out;
+		goto err;
 
 	/*
 	 * The log is on disk. It is now safe to update in place
@@ -786,11 +790,11 @@ int dmz_flush_metadata(struct dmz_metada
 	 */
 	ret = dmz_write_dirty_mblocks(zmd, &write_list, zmd->mblk_primary);
 	if (ret)
-		goto out;
+		goto err;
 
 	ret = dmz_write_sb(zmd, zmd->mblk_primary);
 	if (ret)
-		goto out;
+		goto err;
 
 	while (!list_empty(&write_list)) {
 		mblk = list_first_entry(&write_list, struct dmz_mblock, link);
@@ -805,16 +809,20 @@ int dmz_flush_metadata(struct dmz_metada
 
 	zmd->sb_gen++;
 out:
-	if (ret && !list_empty(&write_list)) {
-		spin_lock(&zmd->mblk_lock);
-		list_splice(&write_list, &zmd->mblk_dirty_list);
-		spin_unlock(&zmd->mblk_lock);
-	}
-
 	dmz_unlock_flush(zmd);
 	up_write(&zmd->mblk_sem);
 
 	return ret;
+
+err:
+	if (!list_empty(&write_list)) {
+		spin_lock(&zmd->mblk_lock);
+		list_splice(&write_list, &zmd->mblk_dirty_list);
+		spin_unlock(&zmd->mblk_lock);
+	}
+	if (!dmz_check_bdev(zmd->dev))
+		ret = -EIO;
+	goto out;
 }
 
 /*
@@ -1244,6 +1252,7 @@ static int dmz_update_zone(struct dmz_me
 	if (ret) {
 		dmz_dev_err(zmd->dev, "Get zone %u report failed",
 			    dmz_id(zmd, zone));
+		dmz_check_bdev(zmd->dev);
 		return ret;
 	}
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/dm-zoned-reclaim.c linux-libre-5.3.17-gnu/drivers/md/dm-zoned-reclaim.c
--- linux-libre-5.3.16-gnu/drivers/md/dm-zoned-reclaim.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/dm-zoned-reclaim.c	2019-12-17 14:08:41.000000000 -0500
@@ -82,6 +82,7 @@ static int dmz_reclaim_align_wp(struct d
 			    "Align zone %u wp %llu to %llu (wp+%u) blocks failed %d",
 			    dmz_id(zmd, zone), (unsigned long long)wp_block,
 			    (unsigned long long)block, nr_blocks, ret);
+		dmz_check_bdev(zrc->dev);
 		return ret;
 	}
 
@@ -489,12 +490,7 @@ static void dmz_reclaim_work(struct work
 	ret = dmz_do_reclaim(zrc);
 	if (ret) {
 		dmz_dev_debug(zrc->dev, "Reclaim error %d\n", ret);
-		if (ret == -EIO)
-			/*
-			 * LLD might be performing some error handling sequence
-			 * at the underlying device. To not interfere, do not
-			 * attempt to schedule the next reclaim run immediately.
-			 */
+		if (!dmz_check_bdev(zrc->dev))
 			return;
 	}
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/dm-zoned-target.c linux-libre-5.3.17-gnu/drivers/md/dm-zoned-target.c
--- linux-libre-5.3.16-gnu/drivers/md/dm-zoned-target.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/dm-zoned-target.c	2019-12-17 14:08:41.000000000 -0500
@@ -80,6 +80,8 @@ static inline void dmz_bio_endio(struct
 
 	if (status != BLK_STS_OK && bio->bi_status == BLK_STS_OK)
 		bio->bi_status = status;
+	if (bio->bi_status != BLK_STS_OK)
+		bioctx->target->dev->flags |= DMZ_CHECK_BDEV;
 
 	if (refcount_dec_and_test(&bioctx->ref)) {
 		struct dm_zone *zone = bioctx->zone;
@@ -565,32 +567,52 @@ out:
 }
 
 /*
- * Check the backing device availability. If it's on the way out,
+ * Check if the backing device is being removed. If it's on the way out,
  * start failing I/O. Reclaim and metadata components also call this
  * function to cleanly abort operation in the event of such failure.
  */
 bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev)
 {
-	struct gendisk *disk;
+	if (dmz_dev->flags & DMZ_BDEV_DYING)
+		return true;
 
-	if (!(dmz_dev->flags & DMZ_BDEV_DYING)) {
-		disk = dmz_dev->bdev->bd_disk;
-		if (blk_queue_dying(bdev_get_queue(dmz_dev->bdev))) {
-			dmz_dev_warn(dmz_dev, "Backing device queue dying");
-			dmz_dev->flags |= DMZ_BDEV_DYING;
-		} else if (disk->fops->check_events) {
-			if (disk->fops->check_events(disk, 0) &
-					DISK_EVENT_MEDIA_CHANGE) {
-				dmz_dev_warn(dmz_dev, "Backing device offline");
-				dmz_dev->flags |= DMZ_BDEV_DYING;
-			}
-		}
+	if (dmz_dev->flags & DMZ_CHECK_BDEV)
+		return !dmz_check_bdev(dmz_dev);
+
+	if (blk_queue_dying(bdev_get_queue(dmz_dev->bdev))) {
+		dmz_dev_warn(dmz_dev, "Backing device queue dying");
+		dmz_dev->flags |= DMZ_BDEV_DYING;
 	}
 
 	return dmz_dev->flags & DMZ_BDEV_DYING;
 }
 
 /*
+ * Check the backing device availability. This detects such events as
+ * backing device going offline due to errors, media removals, etc.
+ * This check is less efficient than dmz_bdev_is_dying() and should
+ * only be performed as a part of error handling.
+ */
+bool dmz_check_bdev(struct dmz_dev *dmz_dev)
+{
+	struct gendisk *disk;
+
+	dmz_dev->flags &= ~DMZ_CHECK_BDEV;
+
+	if (dmz_bdev_is_dying(dmz_dev))
+		return false;
+
+	disk = dmz_dev->bdev->bd_disk;
+	if (disk->fops->check_events &&
+	    disk->fops->check_events(disk, 0) & DISK_EVENT_MEDIA_CHANGE) {
+		dmz_dev_warn(dmz_dev, "Backing device offline");
+		dmz_dev->flags |= DMZ_BDEV_DYING;
+	}
+
+	return !(dmz_dev->flags & DMZ_BDEV_DYING);
+}
+
+/*
  * Process a new BIO.
  */
 static int dmz_map(struct dm_target *ti, struct bio *bio)
@@ -902,8 +924,8 @@ static int dmz_prepare_ioctl(struct dm_t
 {
 	struct dmz_target *dmz = ti->private;
 
-	if (dmz_bdev_is_dying(dmz->dev))
-		return -ENODEV;
+	if (!dmz_check_bdev(dmz->dev))
+		return -EIO;
 
 	*bdev = dmz->dev->bdev;
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/md.c linux-libre-5.3.17-gnu/drivers/md/md.c
--- linux-libre-5.3.16-gnu/drivers/md/md.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/md.c	2019-12-17 14:08:41.000000000 -0500
@@ -545,7 +545,13 @@ static void md_submit_flush_data(struct
 	}
 }
 
-void md_flush_request(struct mddev *mddev, struct bio *bio)
+/*
+ * Manages consolidation of flushes and submitting any flushes needed for
+ * a bio with REQ_PREFLUSH.  Returns true if the bio is finished or is
+ * being finished in another context.  Returns false if the flushing is
+ * complete but still needs the I/O portion of the bio to be processed.
+ */
+bool md_flush_request(struct mddev *mddev, struct bio *bio)
 {
 	ktime_t start = ktime_get_boottime();
 	spin_lock_irq(&mddev->lock);
@@ -570,9 +576,10 @@ void md_flush_request(struct mddev *mdde
 			bio_endio(bio);
 		else {
 			bio->bi_opf &= ~REQ_PREFLUSH;
-			mddev->pers->make_request(mddev, bio);
+			return false;
 		}
 	}
+	return true;
 }
 EXPORT_SYMBOL(md_flush_request);
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/md.h linux-libre-5.3.17-gnu/drivers/md/md.h
--- linux-libre-5.3.16-gnu/drivers/md/md.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/md.h	2019-12-17 14:08:41.000000000 -0500
@@ -546,7 +546,7 @@ struct md_personality
 	int level;
 	struct list_head list;
 	struct module *owner;
-	bool (*make_request)(struct mddev *mddev, struct bio *bio);
+	bool __must_check (*make_request)(struct mddev *mddev, struct bio *bio);
 	/*
 	 * start up works that do NOT require md_thread. tasks that
 	 * requires md_thread should go into start()
@@ -699,7 +699,7 @@ extern void md_error(struct mddev *mddev
 extern void md_finish_reshape(struct mddev *mddev);
 
 extern int mddev_congested(struct mddev *mddev, int bits);
-extern void md_flush_request(struct mddev *mddev, struct bio *bio);
+extern bool __must_check md_flush_request(struct mddev *mddev, struct bio *bio);
 extern void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
 			   sector_t sector, int size, struct page *page);
 extern int md_super_wait(struct mddev *mddev);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/md-linear.c linux-libre-5.3.17-gnu/drivers/md/md-linear.c
--- linux-libre-5.3.16-gnu/drivers/md/md-linear.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/md-linear.c	2019-12-17 14:08:41.000000000 -0500
@@ -244,10 +244,9 @@ static bool linear_make_request(struct m
 	sector_t start_sector, end_sector, data_offset;
 	sector_t bio_sector = bio->bi_iter.bi_sector;
 
-	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
-		md_flush_request(mddev, bio);
+	if (unlikely(bio->bi_opf & REQ_PREFLUSH)
+	    && md_flush_request(mddev, bio))
 		return true;
-	}
 
 	tmp_dev = which_dev(mddev, bio_sector);
 	start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/md-multipath.c linux-libre-5.3.17-gnu/drivers/md/md-multipath.c
--- linux-libre-5.3.16-gnu/drivers/md/md-multipath.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/md-multipath.c	2019-12-17 14:08:41.000000000 -0500
@@ -104,10 +104,9 @@ static bool multipath_make_request(struc
 	struct multipath_bh * mp_bh;
 	struct multipath_info *multipath;
 
-	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
-		md_flush_request(mddev, bio);
+	if (unlikely(bio->bi_opf & REQ_PREFLUSH)
+	    && md_flush_request(mddev, bio))
 		return true;
-	}
 
 	mp_bh = mempool_alloc(&conf->pool, GFP_NOIO);
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/raid0.c linux-libre-5.3.17-gnu/drivers/md/raid0.c
--- linux-libre-5.3.16-gnu/drivers/md/raid0.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/raid0.c	2019-12-17 14:08:41.000000000 -0500
@@ -572,10 +572,9 @@ static bool raid0_make_request(struct md
 	unsigned chunk_sects;
 	unsigned sectors;
 
-	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
-		md_flush_request(mddev, bio);
+	if (unlikely(bio->bi_opf & REQ_PREFLUSH)
+	    && md_flush_request(mddev, bio))
 		return true;
-	}
 
 	if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) {
 		raid0_handle_discard(mddev, bio);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/raid10.c linux-libre-5.3.17-gnu/drivers/md/raid10.c
--- linux-libre-5.3.16-gnu/drivers/md/raid10.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/raid10.c	2019-12-17 14:08:41.000000000 -0500
@@ -1523,10 +1523,9 @@ static bool raid10_make_request(struct m
 	int chunk_sects = chunk_mask + 1;
 	int sectors = bio_sectors(bio);
 
-	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
-		md_flush_request(mddev, bio);
+	if (unlikely(bio->bi_opf & REQ_PREFLUSH)
+	    && md_flush_request(mddev, bio))
 		return true;
-	}
 
 	if (!md_write_start(mddev, bio))
 		return false;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/raid1.c linux-libre-5.3.17-gnu/drivers/md/raid1.c
--- linux-libre-5.3.16-gnu/drivers/md/raid1.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/raid1.c	2019-12-17 14:08:41.000000000 -0500
@@ -1564,10 +1564,9 @@ static bool raid1_make_request(struct md
 {
 	sector_t sectors;
 
-	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
-		md_flush_request(mddev, bio);
+	if (unlikely(bio->bi_opf & REQ_PREFLUSH)
+	    && md_flush_request(mddev, bio))
 		return true;
-	}
 
 	/*
 	 * There is a limit to the maximum size, but
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/md/raid5.c linux-libre-5.3.17-gnu/drivers/md/raid5.c
--- linux-libre-5.3.16-gnu/drivers/md/raid5.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/md/raid5.c	2019-12-17 14:08:41.000000000 -0500
@@ -5587,8 +5587,8 @@ static bool raid5_make_request(struct md
 		if (ret == 0)
 			return true;
 		if (ret == -ENODEV) {
-			md_flush_request(mddev, bi);
-			return true;
+			if (md_flush_request(mddev, bi))
+				return true;
 		}
 		/* ret == -EAGAIN, fallback */
 		/*
@@ -5721,7 +5721,7 @@ static bool raid5_make_request(struct md
 				do_flush = false;
 			}
 
-			if (!sh->batch_head)
+			if (!sh->batch_head || sh == sh->batch_head)
 				set_bit(STRIPE_HANDLE, &sh->state);
 			clear_bit(STRIPE_DELAYED, &sh->state);
 			if ((!sh->batch_head || sh == sh->batch_head) &&
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/media/platform/qcom/venus/vdec.c linux-libre-5.3.17-gnu/drivers/media/platform/qcom/venus/vdec.c
--- linux-libre-5.3.16-gnu/drivers/media/platform/qcom/venus/vdec.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/media/platform/qcom/venus/vdec.c	2019-12-17 14:08:41.000000000 -0500
@@ -1104,9 +1104,6 @@ static const struct v4l2_file_operations
 	.unlocked_ioctl = video_ioctl2,
 	.poll = v4l2_m2m_fop_poll,
 	.mmap = v4l2_m2m_fop_mmap,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl32 = v4l2_compat_ioctl32,
-#endif
 };
 
 static int vdec_probe(struct platform_device *pdev)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/media/platform/qcom/venus/venc.c linux-libre-5.3.17-gnu/drivers/media/platform/qcom/venus/venc.c
--- linux-libre-5.3.16-gnu/drivers/media/platform/qcom/venus/venc.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/media/platform/qcom/venus/venc.c	2019-12-17 14:08:41.000000000 -0500
@@ -1230,9 +1230,6 @@ static const struct v4l2_file_operations
 	.unlocked_ioctl = video_ioctl2,
 	.poll = v4l2_m2m_fop_poll,
 	.mmap = v4l2_m2m_fop_mmap,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl32 = v4l2_compat_ioctl32,
-#endif
 };
 
 static int venc_probe(struct platform_device *pdev)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/media/platform/sti/bdisp/bdisp-v4l2.c linux-libre-5.3.17-gnu/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
--- linux-libre-5.3.16-gnu/drivers/media/platform/sti/bdisp/bdisp-v4l2.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/media/platform/sti/bdisp/bdisp-v4l2.c	2019-12-17 14:08:41.000000000 -0500
@@ -651,8 +651,7 @@ static int bdisp_release(struct file *fi
 
 	dev_dbg(bdisp->dev, "%s\n", __func__);
 
-	if (mutex_lock_interruptible(&bdisp->lock))
-		return -ERESTARTSYS;
+	mutex_lock(&bdisp->lock);
 
 	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/media/radio/radio-wl1273.c linux-libre-5.3.17-gnu/drivers/media/radio/radio-wl1273.c
--- linux-libre-5.3.16-gnu/drivers/media/radio/radio-wl1273.c	2019-12-13 10:55:46.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/media/radio/radio-wl1273.c	2019-12-17 15:58:10.000000000 -0500
@@ -1148,8 +1148,7 @@ static int wl1273_fm_fops_release(struct
 	if (radio->rds_users > 0) {
 		radio->rds_users--;
 		if (radio->rds_users == 0) {
-			if (mutex_lock_interruptible(&core->lock))
-				return -EINTR;
+			mutex_lock(&core->lock);
 
 			radio->irq_flags &= ~WL1273_RDS_EVENT;
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/mmc/host/omap_hsmmc.c linux-libre-5.3.17-gnu/drivers/mmc/host/omap_hsmmc.c
--- linux-libre-5.3.16-gnu/drivers/mmc/host/omap_hsmmc.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/mmc/host/omap_hsmmc.c	2019-12-17 14:08:41.000000000 -0500
@@ -1512,6 +1512,36 @@ static void omap_hsmmc_init_card(struct
 
 	if (mmc_pdata(host)->init_card)
 		mmc_pdata(host)->init_card(card);
+	else if (card->type == MMC_TYPE_SDIO ||
+		 card->type == MMC_TYPE_SD_COMBO) {
+		struct device_node *np = mmc_dev(mmc)->of_node;
+
+		/*
+		 * REVISIT: should be moved to sdio core and made more
+		 * general e.g. by expanding the DT bindings of child nodes
+		 * to provide a mechanism to provide this information:
+		 * Documentation/devicetree/bindings/mmc/mmc-card.txt
+		 */
+
+		np = of_get_compatible_child(np, "ti,wl1251");
+		if (np) {
+			/*
+			 * We have TI wl1251 attached to MMC3. Pass this
+			 * information to the SDIO core because it can't be
+			 * probed by normal methods.
+			 */
+
+			dev_info(host->dev, "found wl1251\n");
+			card->quirks |= MMC_QUIRK_NONSTD_SDIO;
+			card->cccr.wide_bus = 1;
+			card->cis.vendor = 0x104c;
+			card->cis.device = 0x9066;
+			card->cis.blksize = 512;
+			card->cis.max_dtr = 24000000;
+			card->ocr = 0x80;
+			of_node_put(np);
+		}
+	}
 }
 
 static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/mtd/devices/spear_smi.c linux-libre-5.3.17-gnu/drivers/mtd/devices/spear_smi.c
--- linux-libre-5.3.16-gnu/drivers/mtd/devices/spear_smi.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/mtd/devices/spear_smi.c	2019-12-17 14:08:41.000000000 -0500
@@ -592,6 +592,26 @@ static int spear_mtd_read(struct mtd_inf
 	return 0;
 }
 
+/*
+ * The purpose of this function is to ensure a memcpy_toio() with byte writes
+ * only. Its structure is inspired from the ARM implementation of _memcpy_toio()
+ * which also does single byte writes but cannot be used here as this is just an
+ * implementation detail and not part of the API. Not mentioning the comment
+ * stating that _memcpy_toio() should be optimized.
+ */
+static void spear_smi_memcpy_toio_b(volatile void __iomem *dest,
+				    const void *src, size_t len)
+{
+	const unsigned char *from = src;
+
+	while (len) {
+		len--;
+		writeb(*from, dest);
+		from++;
+		dest++;
+	}
+}
+
 static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank,
 		void __iomem *dest, const void *src, size_t len)
 {
@@ -614,7 +634,23 @@ static inline int spear_smi_cpy_toio(str
 	ctrlreg1 = readl(dev->io_base + SMI_CR1);
 	writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1);
 
-	memcpy_toio(dest, src, len);
+	/*
+	 * In Write Burst mode (WB_MODE), the specs states that writes must be:
+	 * - incremental
+	 * - of the same size
+	 * The ARM implementation of memcpy_toio() will optimize the number of
+	 * I/O by using as much 4-byte writes as possible, surrounded by
+	 * 2-byte/1-byte access if:
+	 * - the destination is not 4-byte aligned
+	 * - the length is not a multiple of 4-byte.
+	 * Avoid this alternance of write access size by using our own 'byte
+	 * access' helper if at least one of the two conditions above is true.
+	 */
+	if (IS_ALIGNED(len, sizeof(u32)) &&
+	    IS_ALIGNED((uintptr_t)dest, sizeof(u32)))
+		memcpy_toio(dest, src, len);
+	else
+		spear_smi_memcpy_toio_b(dest, src, len);
 
 	writel(ctrlreg1, dev->io_base + SMI_CR1);
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/mtd/nand/raw/nand_base.c linux-libre-5.3.17-gnu/drivers/mtd/nand/raw/nand_base.c
--- linux-libre-5.3.16-gnu/drivers/mtd/nand/raw/nand_base.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/mtd/nand/raw/nand_base.c	2019-12-17 14:08:41.000000000 -0500
@@ -292,12 +292,16 @@ int nand_bbm_get_next_page(struct nand_c
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	int last_page = ((mtd->erasesize - mtd->writesize) >>
 			 chip->page_shift) & chip->pagemask;
+	unsigned int bbm_flags = NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE
+		| NAND_BBM_LASTPAGE;
 
+	if (page == 0 && !(chip->options & bbm_flags))
+		return 0;
 	if (page == 0 && chip->options & NAND_BBM_FIRSTPAGE)
 		return 0;
-	else if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE)
+	if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE)
 		return 1;
-	else if (page <= last_page && chip->options & NAND_BBM_LASTPAGE)
+	if (page <= last_page && chip->options & NAND_BBM_LASTPAGE)
 		return last_page;
 
 	return -EINVAL;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/mtd/nand/raw/nand_micron.c linux-libre-5.3.17-gnu/drivers/mtd/nand/raw/nand_micron.c
--- linux-libre-5.3.16-gnu/drivers/mtd/nand/raw/nand_micron.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/mtd/nand/raw/nand_micron.c	2019-12-17 14:08:41.000000000 -0500
@@ -446,8 +446,10 @@ static int micron_nand_init(struct nand_
 	if (ret)
 		goto err_free_manuf_data;
 
+	chip->options |= NAND_BBM_FIRSTPAGE;
+
 	if (mtd->writesize == 2048)
-		chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE;
+		chip->options |= NAND_BBM_SECONDPAGE;
 
 	ondie = micron_supports_on_die_ecc(chip);
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/net/wireless/ath/ar5523/ar5523.c linux-libre-5.3.17-gnu/drivers/net/wireless/ath/ar5523/ar5523.c
--- linux-libre-5.3.16-gnu/drivers/net/wireless/ath/ar5523/ar5523.c	2019-12-13 11:06:48.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/net/wireless/ath/ar5523/ar5523.c	2019-12-17 16:07:26.000000000 -0500
@@ -255,7 +255,8 @@ static int ar5523_cmd(struct ar5523 *ar,
 
 	if (flags & AR5523_CMD_FLAG_MAGIC)
 		hdr->magic = cpu_to_be32(1 << 24);
-	memcpy(hdr + 1, idata, ilen);
+	if (ilen)
+		memcpy(hdr + 1, idata, ilen);
 
 	cmd->odata = odata;
 	cmd->olen = olen;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/net/wireless/ath/wil6210/wmi.c linux-libre-5.3.17-gnu/drivers/net/wireless/ath/wil6210/wmi.c
--- linux-libre-5.3.16-gnu/drivers/net/wireless/ath/wil6210/wmi.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/net/wireless/ath/wil6210/wmi.c	2019-12-17 14:08:41.000000000 -0500
@@ -2478,7 +2478,8 @@ int wmi_set_ie(struct wil6210_vif *vif,
 	cmd->mgmt_frm_type = type;
 	/* BUG: FW API define ieLen as u8. Will fix FW */
 	cmd->ie_len = cpu_to_le16(ie_len);
-	memcpy(cmd->ie_info, ie, ie_len);
+	if (ie_len)
+		memcpy(cmd->ie_info, ie, ie_len);
 	rc = wmi_send(wil, WMI_SET_APPIE_CMDID, vif->mid, cmd, len);
 	kfree(cmd);
 out:
@@ -2514,7 +2515,8 @@ int wmi_update_ft_ies(struct wil6210_vif
 	}
 
 	cmd->ie_len = cpu_to_le16(ie_len);
-	memcpy(cmd->ie_info, ie, ie_len);
+	if (ie_len)
+		memcpy(cmd->ie_info, ie, ie_len);
 	rc = wmi_send(wil, WMI_UPDATE_FT_IES_CMDID, vif->mid, cmd, len);
 	kfree(cmd);
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c linux-libre-5.3.17-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
--- linux-libre-5.3.16-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c	2019-12-13 11:02:35.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c	2019-12-17 16:04:34.000000000 -0500
@@ -1426,6 +1426,8 @@ static int brcmf_pcie_reset(struct devic
 	struct brcmf_fw_request *fwreq;
 	int err;
 
+	brcmf_pcie_intr_disable(devinfo);
+
 	brcmf_pcie_bus_console_read(devinfo, true);
 
 	brcmf_detach(dev);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c linux-libre-5.3.17-gnu/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
--- linux-libre-5.3.16-gnu/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c	2019-12-17 14:08:41.000000000 -0500
@@ -469,6 +469,7 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(stru
 	dma_addr_t tb_phys;
 	int len, tb1_len, tb2_len;
 	void *tb1_addr;
+	struct sk_buff *frag;
 
 	tb_phys = iwl_pcie_get_first_tb_dma(txq, idx);
 
@@ -517,6 +518,19 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(stru
 	if (iwl_pcie_gen2_tx_add_frags(trans, skb, tfd, out_meta))
 		goto out_err;
 
+	skb_walk_frags(skb, frag) {
+		tb_phys = dma_map_single(trans->dev, frag->data,
+					 skb_headlen(frag), DMA_TO_DEVICE);
+		if (unlikely(dma_mapping_error(trans->dev, tb_phys)))
+			goto out_err;
+		iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, skb_headlen(frag));
+		trace_iwlwifi_dev_tx_tb(trans->dev, skb,
+					frag->data,
+					skb_headlen(frag));
+		if (iwl_pcie_gen2_tx_add_frags(trans, frag, tfd, out_meta))
+			goto out_err;
+	}
+
 	return tfd;
 
 out_err:
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c linux-libre-5.3.17-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c
--- linux-libre-5.3.16-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c	2019-12-17 14:08:41.000000000 -0500
@@ -1176,6 +1176,7 @@ void rtl92de_enable_interrupt(struct iee
 
 	rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
 	rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
+	rtlpci->irq_enabled = true;
 }
 
 void rtl92de_disable_interrupt(struct ieee80211_hw *hw)
@@ -1185,7 +1186,7 @@ void rtl92de_disable_interrupt(struct ie
 
 	rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
 	rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
-	synchronize_irq(rtlpci->pdev->irq);
+	rtlpci->irq_enabled = false;
 }
 
 static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw)
@@ -1351,7 +1352,7 @@ void rtl92de_set_beacon_related_register
 
 	bcn_interval = mac->beacon_interval;
 	atim_window = 2;
-	/*rtl92de_disable_interrupt(hw);  */
+	rtl92de_disable_interrupt(hw);
 	rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
 	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
 	rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
@@ -1371,9 +1372,9 @@ void rtl92de_set_beacon_interval(struct
 
 	RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
 		 "beacon_interval:%d\n", bcn_interval);
-	/* rtl92de_disable_interrupt(hw); */
+	rtl92de_disable_interrupt(hw);
 	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
-	/* rtl92de_enable_interrupt(hw); */
+	rtl92de_enable_interrupt(hw);
 }
 
 void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw,
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c linux-libre-5.3.17-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c
--- linux-libre-5.3.16-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c	2019-12-13 11:09:30.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c	2019-12-17 16:09:53.000000000 -0500
@@ -216,6 +216,7 @@ static struct rtl_hal_ops rtl8192de_hal_
 	.led_control = rtl92de_led_control,
 	.set_desc = rtl92de_set_desc,
 	.get_desc = rtl92de_get_desc,
+	.is_tx_desc_closed = rtl92de_is_tx_desc_closed,
 	.tx_polling = rtl92de_tx_polling,
 	.enable_hw_sec = rtl92de_enable_hw_security_config,
 	.set_key = rtl92de_set_key,
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c linux-libre-5.3.17-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
--- linux-libre-5.3.16-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c	2019-12-17 14:08:41.000000000 -0500
@@ -818,13 +818,15 @@ u64 rtl92de_get_desc(struct ieee80211_hw
 			break;
 		}
 	} else {
-		struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
 		switch (desc_name) {
 		case HW_DESC_OWN:
-			ret = GET_RX_DESC_OWN(pdesc);
+			ret = GET_RX_DESC_OWN(p_desc);
 			break;
 		case HW_DESC_RXPKT_LEN:
-			ret = GET_RX_DESC_PKT_LEN(pdesc);
+			ret = GET_RX_DESC_PKT_LEN(p_desc);
+			break;
+		case HW_DESC_RXBUFF_ADDR:
+			ret = GET_RX_DESC_BUFF_ADDR(p_desc);
 			break;
 		default:
 			WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n",
@@ -835,6 +837,23 @@ u64 rtl92de_get_desc(struct ieee80211_hw
 	return ret;
 }
 
+bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw,
+			       u8 hw_queue, u16 index)
+{
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
+	u8 *entry = (u8 *)(&ring->desc[ring->idx]);
+	u8 own = (u8)rtl92de_get_desc(hw, entry, true, HW_DESC_OWN);
+
+	/* a beacon packet will only use the first
+	 * descriptor by defaut, and the own bit may not
+	 * be cleared by the hardware
+	 */
+	if (own)
+		return false;
+	return true;
+}
+
 void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h linux-libre-5.3.17-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h
--- linux-libre-5.3.16-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h	2019-12-17 14:08:41.000000000 -0500
@@ -715,6 +715,8 @@ void rtl92de_set_desc(struct ieee80211_h
 		      u8 desc_name, u8 *val);
 u64 rtl92de_get_desc(struct ieee80211_hw *hw,
 		     u8 *p_desc, bool istx, u8 desc_name);
+bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw,
+			       u8 hw_queue, u16 index);
 void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
 void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
 			     bool b_firstseg, bool b_lastseg,
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/net/wireless/virt_wifi.c linux-libre-5.3.17-gnu/drivers/net/wireless/virt_wifi.c
--- linux-libre-5.3.16-gnu/drivers/net/wireless/virt_wifi.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/net/wireless/virt_wifi.c	2019-12-17 14:08:41.000000000 -0500
@@ -450,7 +450,6 @@ static void virt_wifi_net_device_destruc
 	 */
 	kfree(dev->ieee80211_ptr);
 	dev->ieee80211_ptr = NULL;
-	free_netdev(dev);
 }
 
 /* No lock interaction. */
@@ -458,7 +457,7 @@ static void virt_wifi_setup(struct net_d
 {
 	ether_setup(dev);
 	dev->netdev_ops = &virt_wifi_ops;
-	dev->priv_destructor = virt_wifi_net_device_destructor;
+	dev->needs_free_netdev  = true;
 }
 
 /* Called in a RCU read critical section from netif_receive_skb */
@@ -544,6 +543,7 @@ static int virt_wifi_newlink(struct net
 		goto unregister_netdev;
 	}
 
+	dev->priv_destructor = virt_wifi_net_device_destructor;
 	priv->being_deleted = false;
 	priv->is_connected = false;
 	priv->is_up = false;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/nvme/host/core.c linux-libre-5.3.17-gnu/drivers/nvme/host/core.c
--- linux-libre-5.3.16-gnu/drivers/nvme/host/core.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/nvme/host/core.c	2019-12-17 14:08:41.000000000 -0500
@@ -2270,16 +2270,6 @@ static const struct nvme_core_quirk_entr
 		.vid = 0x14a4,
 		.fr = "22301111",
 		.quirks = NVME_QUIRK_SIMPLE_SUSPEND,
-	},
-	{
-		/*
-		 * This Kingston E8FK11.T firmware version has no interrupt
-		 * after resume with actions related to suspend to idle
-		 * https://bugzilla.kernel.org/show_bug.cgi?id=204887
-		 */
-		.vid = 0x2646,
-		.fr = "E8FK11.T",
-		.quirks = NVME_QUIRK_SIMPLE_SUSPEND,
 	}
 };
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/pci/hotplug/acpiphp_glue.c linux-libre-5.3.17-gnu/drivers/pci/hotplug/acpiphp_glue.c
--- linux-libre-5.3.16-gnu/drivers/pci/hotplug/acpiphp_glue.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/pci/hotplug/acpiphp_glue.c	2019-12-17 14:08:41.000000000 -0500
@@ -449,8 +449,15 @@ static void acpiphp_native_scan_bridge(s
 
 	/* Scan non-hotplug bridges that need to be reconfigured */
 	for_each_pci_bridge(dev, bus) {
-		if (!hotplug_is_native(dev))
-			max = pci_scan_bridge(bus, dev, max, 1);
+		if (hotplug_is_native(dev))
+			continue;
+
+		max = pci_scan_bridge(bus, dev, max, 1);
+		if (dev->subordinate) {
+			pcibios_resource_survey_bus(dev->subordinate);
+			pci_bus_size_bridges(dev->subordinate);
+			pci_bus_assign_resources(dev->subordinate);
+		}
 	}
 }
 
@@ -480,7 +487,6 @@ static void enable_slot(struct acpiphp_s
 			if (PCI_SLOT(dev->devfn) == slot->device)
 				acpiphp_native_scan_bridge(dev);
 		}
-		pci_assign_unassigned_bridge_resources(bus->self);
 	} else {
 		LIST_HEAD(add_list);
 		int max, pass;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/phy/renesas/phy-rcar-gen3-usb2.c linux-libre-5.3.17-gnu/drivers/phy/renesas/phy-rcar-gen3-usb2.c
--- linux-libre-5.3.16-gnu/drivers/phy/renesas/phy-rcar-gen3-usb2.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/phy/renesas/phy-rcar-gen3-usb2.c	2019-12-17 14:08:41.000000000 -0500
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/string.h>
 #include <linux/usb/of.h>
 #include <linux/workqueue.h>
 
@@ -320,9 +321,9 @@ static ssize_t role_store(struct device
 	if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch))
 		return -EIO;
 
-	if (!strncmp(buf, "host", strlen("host")))
+	if (sysfs_streq(buf, "host"))
 		new_mode = PHY_MODE_USB_HOST;
-	else if (!strncmp(buf, "peripheral", strlen("peripheral")))
+	else if (sysfs_streq(buf, "peripheral"))
 		new_mode = PHY_MODE_USB_DEVICE;
 	else
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c linux-libre-5.3.17-gnu/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
--- linux-libre-5.3.16-gnu/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c	2019-12-17 14:08:41.000000000 -0500
@@ -595,10 +595,10 @@ static int armada_37xx_irq_set_type(stru
 		regmap_read(info->regmap, in_reg, &in_val);
 
 		/* Set initial polarity based on current input level. */
-		if (in_val & d->mask)
-			val |= d->mask;		/* falling */
+		if (in_val & BIT(d->hwirq % GPIO_PER_REG))
+			val |= BIT(d->hwirq % GPIO_PER_REG);	/* falling */
 		else
-			val &= ~d->mask;	/* rising */
+			val &= ~(BIT(d->hwirq % GPIO_PER_REG));	/* rising */
 		break;
 	}
 	default:
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/pinctrl/pinctrl-rza2.c linux-libre-5.3.17-gnu/drivers/pinctrl/pinctrl-rza2.c
--- linux-libre-5.3.16-gnu/drivers/pinctrl/pinctrl-rza2.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/pinctrl/pinctrl-rza2.c	2019-12-17 14:08:41.000000000 -0500
@@ -212,8 +212,8 @@ static const char * const rza2_gpio_name
 	"PC_0", "PC_1", "PC_2", "PC_3", "PC_4", "PC_5", "PC_6", "PC_7",
 	"PD_0", "PD_1", "PD_2", "PD_3", "PD_4", "PD_5", "PD_6", "PD_7",
 	"PE_0", "PE_1", "PE_2", "PE_3", "PE_4", "PE_5", "PE_6", "PE_7",
-	"PF_0", "PF_1", "PF_2", "PF_3", "P0_4", "PF_5", "PF_6", "PF_7",
-	"PG_0", "PG_1", "PG_2", "P0_3", "PG_4", "PG_5", "PG_6", "PG_7",
+	"PF_0", "PF_1", "PF_2", "PF_3", "PF_4", "PF_5", "PF_6", "PF_7",
+	"PG_0", "PG_1", "PG_2", "PG_3", "PG_4", "PG_5", "PG_6", "PG_7",
 	"PH_0", "PH_1", "PH_2", "PH_3", "PH_4", "PH_5", "PH_6", "PH_7",
 	/* port I does not exist */
 	"PJ_0", "PJ_1", "PJ_2", "PJ_3", "PJ_4", "PJ_5", "PJ_6", "PJ_7",
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/pinctrl/samsung/pinctrl-exynos.c linux-libre-5.3.17-gnu/drivers/pinctrl/samsung/pinctrl-exynos.c
--- linux-libre-5.3.16-gnu/drivers/pinctrl/samsung/pinctrl-exynos.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/pinctrl/samsung/pinctrl-exynos.c	2019-12-17 14:08:41.000000000 -0500
@@ -486,8 +486,10 @@ int exynos_eint_wkup_init(struct samsung
 		if (match) {
 			irq_chip = kmemdup(match->data,
 				sizeof(*irq_chip), GFP_KERNEL);
-			if (!irq_chip)
+			if (!irq_chip) {
+				of_node_put(np);
 				return -ENOMEM;
+			}
 			wkup_np = np;
 			break;
 		}
@@ -504,6 +506,7 @@ int exynos_eint_wkup_init(struct samsung
 				bank->nr_pins, &exynos_eint_irqd_ops, bank);
 		if (!bank->irq_domain) {
 			dev_err(dev, "wkup irq domain add failed\n");
+			of_node_put(wkup_np);
 			return -ENXIO;
 		}
 
@@ -518,8 +521,10 @@ int exynos_eint_wkup_init(struct samsung
 		weint_data = devm_kcalloc(dev,
 					  bank->nr_pins, sizeof(*weint_data),
 					  GFP_KERNEL);
-		if (!weint_data)
+		if (!weint_data) {
+			of_node_put(wkup_np);
 			return -ENOMEM;
+		}
 
 		for (idx = 0; idx < bank->nr_pins; ++idx) {
 			irq = irq_of_parse_and_map(bank->of_node, idx);
@@ -536,10 +541,13 @@ int exynos_eint_wkup_init(struct samsung
 		}
 	}
 
-	if (!muxed_banks)
+	if (!muxed_banks) {
+		of_node_put(wkup_np);
 		return 0;
+	}
 
 	irq = irq_of_parse_and_map(wkup_np, 0);
+	of_node_put(wkup_np);
 	if (!irq) {
 		dev_err(dev, "irq number for muxed EINTs not found\n");
 		return 0;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/pinctrl/samsung/pinctrl-s3c24xx.c linux-libre-5.3.17-gnu/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
--- linux-libre-5.3.16-gnu/drivers/pinctrl/samsung/pinctrl-s3c24xx.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/pinctrl/samsung/pinctrl-s3c24xx.c	2019-12-17 14:08:41.000000000 -0500
@@ -490,8 +490,10 @@ static int s3c24xx_eint_init(struct sams
 		return -ENODEV;
 
 	eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL);
-	if (!eint_data)
+	if (!eint_data) {
+		of_node_put(eint_np);
 		return -ENOMEM;
+	}
 
 	eint_data->drvdata = d;
 
@@ -503,12 +505,14 @@ static int s3c24xx_eint_init(struct sams
 		irq = irq_of_parse_and_map(eint_np, i);
 		if (!irq) {
 			dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
+			of_node_put(eint_np);
 			return -ENXIO;
 		}
 
 		eint_data->parents[i] = irq;
 		irq_set_chained_handler_and_data(irq, handlers[i], eint_data);
 	}
+	of_node_put(eint_np);
 
 	bank = d->pin_banks;
 	for (i = 0; i < d->nr_banks; ++i, ++bank) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/pinctrl/samsung/pinctrl-s3c64xx.c linux-libre-5.3.17-gnu/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
--- linux-libre-5.3.16-gnu/drivers/pinctrl/samsung/pinctrl-s3c64xx.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/pinctrl/samsung/pinctrl-s3c64xx.c	2019-12-17 14:08:41.000000000 -0500
@@ -704,8 +704,10 @@ static int s3c64xx_eint_eint0_init(struc
 		return -ENODEV;
 
 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
-	if (!data)
+	if (!data) {
+		of_node_put(eint0_np);
 		return -ENOMEM;
+	}
 	data->drvdata = d;
 
 	for (i = 0; i < NUM_EINT0_IRQ; ++i) {
@@ -714,6 +716,7 @@ static int s3c64xx_eint_eint0_init(struc
 		irq = irq_of_parse_and_map(eint0_np, i);
 		if (!irq) {
 			dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
+			of_node_put(eint0_np);
 			return -ENXIO;
 		}
 
@@ -721,6 +724,7 @@ static int s3c64xx_eint_eint0_init(struc
 						 s3c64xx_eint0_handlers[i],
 						 data);
 	}
+	of_node_put(eint0_np);
 
 	bank = d->pin_banks;
 	for (i = 0; i < d->nr_banks; ++i, ++bank) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/pinctrl/samsung/pinctrl-samsung.c linux-libre-5.3.17-gnu/drivers/pinctrl/samsung/pinctrl-samsung.c
--- linux-libre-5.3.16-gnu/drivers/pinctrl/samsung/pinctrl-samsung.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/pinctrl/samsung/pinctrl-samsung.c	2019-12-17 14:08:41.000000000 -0500
@@ -272,6 +272,7 @@ static int samsung_dt_node_to_map(struct
 						&reserved_maps, num_maps);
 		if (ret < 0) {
 			samsung_dt_free_map(pctldev, *map, *num_maps);
+			of_node_put(np);
 			return ret;
 		}
 	}
@@ -785,8 +786,10 @@ static struct samsung_pmx_func *samsung_
 		if (!of_get_child_count(cfg_np)) {
 			ret = samsung_pinctrl_create_function(dev, drvdata,
 							cfg_np, func);
-			if (ret < 0)
+			if (ret < 0) {
+				of_node_put(cfg_np);
 				return ERR_PTR(ret);
+			}
 			if (ret > 0) {
 				++func;
 				++func_cnt;
@@ -797,8 +800,11 @@ static struct samsung_pmx_func *samsung_
 		for_each_child_of_node(cfg_np, func_np) {
 			ret = samsung_pinctrl_create_function(dev, drvdata,
 						func_np, func);
-			if (ret < 0)
+			if (ret < 0) {
+				of_node_put(func_np);
+				of_node_put(cfg_np);
 				return ERR_PTR(ret);
+			}
 			if (ret > 0) {
 				++func;
 				++func_cnt;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/rtc/interface.c linux-libre-5.3.17-gnu/drivers/rtc/interface.c
--- linux-libre-5.3.16-gnu/drivers/rtc/interface.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/rtc/interface.c	2019-12-17 14:08:41.000000000 -0500
@@ -125,7 +125,7 @@ EXPORT_SYMBOL_GPL(rtc_read_time);
 
 int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
 {
-	int err;
+	int err, uie;
 
 	err = rtc_valid_tm(tm);
 	if (err != 0)
@@ -137,6 +137,17 @@ int rtc_set_time(struct rtc_device *rtc,
 
 	rtc_subtract_offset(rtc, tm);
 
+#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
+	uie = rtc->uie_rtctimer.enabled || rtc->uie_irq_active;
+#else
+	uie = rtc->uie_rtctimer.enabled;
+#endif
+	if (uie) {
+		err = rtc_update_irq_enable(rtc, 0);
+		if (err)
+			return err;
+	}
+
 	err = mutex_lock_interruptible(&rtc->ops_lock);
 	if (err)
 		return err;
@@ -153,6 +164,12 @@ int rtc_set_time(struct rtc_device *rtc,
 	/* A timer might have just expired */
 	schedule_work(&rtc->irqwork);
 
+	if (uie) {
+		err = rtc_update_irq_enable(rtc, 1);
+		if (err)
+			return err;
+	}
+
 	trace_rtc_set_time(rtc_tm_to_time64(tm), err);
 	return err;
 }
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/s390/scsi/zfcp_dbf.c linux-libre-5.3.17-gnu/drivers/s390/scsi/zfcp_dbf.c
--- linux-libre-5.3.16-gnu/drivers/s390/scsi/zfcp_dbf.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/s390/scsi/zfcp_dbf.c	2019-12-17 14:08:41.000000000 -0500
@@ -95,11 +95,9 @@ void zfcp_dbf_hba_fsf_res(char *tag, int
 	memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual,
 	       FSF_STATUS_QUALIFIER_SIZE);
 
-	if (q_head->fsf_command != FSF_QTCB_FCP_CMND) {
-		rec->pl_len = q_head->log_length;
-		zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start,
-				  rec->pl_len, "fsf_res", req->req_id);
-	}
+	rec->pl_len = q_head->log_length;
+	zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start,
+			  rec->pl_len, "fsf_res", req->req_id);
 
 	debug_event(dbf->hba, level, rec, sizeof(*rec));
 	spin_unlock_irqrestore(&dbf->hba_lock, flags);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/lpfc/lpfc_scsi.c linux-libre-5.3.17-gnu/drivers/scsi/lpfc/lpfc_scsi.c
--- linux-libre-5.3.16-gnu/drivers/scsi/lpfc/lpfc_scsi.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/lpfc/lpfc_scsi.c	2019-12-17 14:08:41.000000000 -0500
@@ -583,7 +583,7 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hb
 		if (psb->cur_iocbq.sli4_xritag == xri) {
 			list_del(&psb->list);
 			qp->abts_scsi_io_bufs--;
-			psb->exch_busy = 0;
+			psb->flags &= ~LPFC_SBUF_XBUSY;
 			psb->status = IOSTAT_SUCCESS;
 			spin_unlock(
 				&qp->abts_scsi_buf_list_lock);
@@ -615,7 +615,7 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hb
 		if (iocbq->sli4_xritag != xri)
 			continue;
 		psb = container_of(iocbq, struct lpfc_io_buf, cur_iocbq);
-		psb->exch_busy = 0;
+		psb->flags &= ~LPFC_SBUF_XBUSY;
 		spin_unlock_irqrestore(&phba->hbalock, iflag);
 		if (!list_empty(&pring->txq))
 			lpfc_worker_wake_up(phba);
@@ -834,7 +834,7 @@ lpfc_release_scsi_buf_s4(struct lpfc_hba
 	psb->prot_seg_cnt = 0;
 
 	qp = psb->hdwq;
-	if (psb->exch_busy) {
+	if (psb->flags & LPFC_SBUF_XBUSY) {
 		spin_lock_irqsave(&qp->abts_scsi_buf_list_lock, iflag);
 		psb->pCmd = NULL;
 		list_add_tail(&psb->list, &qp->lpfc_abts_scsi_buf_list);
@@ -3679,7 +3679,10 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba
 	lpfc_cmd->result = (pIocbOut->iocb.un.ulpWord[4] & IOERR_PARAM_MASK);
 	lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
 	/* pick up SLI4 exhange busy status from HBA */
-	lpfc_cmd->exch_busy = pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY;
+	if (pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY)
+		lpfc_cmd->flags |= LPFC_SBUF_XBUSY;
+	else
+		lpfc_cmd->flags &= ~LPFC_SBUF_XBUSY;
 
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 	if (lpfc_cmd->prot_data_type) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/lpfc/lpfc_sli.c linux-libre-5.3.17-gnu/drivers/scsi/lpfc/lpfc_sli.c
--- linux-libre-5.3.16-gnu/drivers/scsi/lpfc/lpfc_sli.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/lpfc/lpfc_sli.c	2019-12-17 14:08:41.000000000 -0500
@@ -11768,7 +11768,10 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba
 		!(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) {
 		lpfc_cmd = container_of(cmdiocbq, struct lpfc_io_buf,
 			cur_iocbq);
-		lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY;
+		if (rspiocbq && (rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY))
+			lpfc_cmd->flags |= LPFC_SBUF_XBUSY;
+		else
+			lpfc_cmd->flags &= ~LPFC_SBUF_XBUSY;
 	}
 
 	pdone_q = cmdiocbq->context_un.wait_queue;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/lpfc/lpfc_sli.h linux-libre-5.3.17-gnu/drivers/scsi/lpfc/lpfc_sli.h
--- linux-libre-5.3.16-gnu/drivers/scsi/lpfc/lpfc_sli.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/lpfc/lpfc_sli.h	2019-12-17 14:08:41.000000000 -0500
@@ -375,14 +375,13 @@ struct lpfc_io_buf {
 
 	struct lpfc_nodelist *ndlp;
 	uint32_t timeout;
-	uint16_t flags;  /* TBD convert exch_busy to flags */
+	uint16_t flags;
 #define LPFC_SBUF_XBUSY		0x1	/* SLI4 hba reported XB on WCQE cmpl */
 #define LPFC_SBUF_BUMP_QDEPTH	0x2	/* bumped queue depth counter */
 					/* External DIF device IO conversions */
 #define LPFC_SBUF_NORMAL_DIF	0x4	/* normal mode to insert/strip */
 #define LPFC_SBUF_PASS_DIF	0x8	/* insert/strip mode to passthru */
 #define LPFC_SBUF_NOT_POSTED    0x10    /* SGL failed post to FW. */
-	uint16_t exch_busy;     /* SLI4 hba reported XB on complete WCQE */
 	uint16_t status;	/* From IOCB Word 7- ulpStatus */
 	uint32_t result;	/* From IOCB Word 4. */
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_attr.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_attr.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_attr.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_attr.c	2019-12-17 14:08:41.000000000 -0500
@@ -725,7 +725,8 @@ qla2x00_sysfs_write_reset(struct file *f
 			break;
 		} else {
 			/* Make sure FC side is not in reset */
-			qla2x00_wait_for_hba_online(vha);
+			WARN_ON_ONCE(qla2x00_wait_for_hba_online(vha) !=
+				     QLA_SUCCESS);
 
 			/* Issue MPI reset */
 			scsi_block_requests(vha->host);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_bsg.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_bsg.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_bsg.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_bsg.c	2019-12-17 14:08:41.000000000 -0500
@@ -341,6 +341,8 @@ qla2x00_process_els(struct bsg_job *bsg_
 		dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
 	if (!req_sg_cnt) {
+		dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
+		    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
 		rval = -ENOMEM;
 		goto done_free_fcport;
 	}
@@ -348,6 +350,8 @@ qla2x00_process_els(struct bsg_job *bsg_
 	rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
 		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
         if (!rsp_sg_cnt) {
+		dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
+		    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
 		rval = -ENOMEM;
 		goto done_free_fcport;
 	}
@@ -1778,8 +1782,8 @@ qla24xx_process_bidir_cmd(struct bsg_job
 	uint16_t nextlid = 0;
 	uint32_t tot_dsds;
 	srb_t *sp = NULL;
-	uint32_t req_data_len = 0;
-	uint32_t rsp_data_len = 0;
+	uint32_t req_data_len;
+	uint32_t rsp_data_len;
 
 	/* Check the type of the adapter */
 	if (!IS_BIDI_CAPABLE(ha)) {
@@ -1884,6 +1888,9 @@ qla24xx_process_bidir_cmd(struct bsg_job
 		goto done_unmap_sg;
 	}
 
+	req_data_len = bsg_job->request_payload.payload_len;
+	rsp_data_len = bsg_job->reply_payload.payload_len;
+
 	if (req_data_len != rsp_data_len) {
 		rval = EXT_STATUS_BUSY;
 		ql_log(ql_log_warn, vha, 0x70aa,
@@ -1891,10 +1898,6 @@ qla24xx_process_bidir_cmd(struct bsg_job
 		goto done_unmap_sg;
 	}
 
-	req_data_len = bsg_job->request_payload.payload_len;
-	rsp_data_len = bsg_job->reply_payload.payload_len;
-
-
 	/* Alloc SRB structure */
 	sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL);
 	if (!sp) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_def.h linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_def.h
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_def.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_def.h	2019-12-17 14:08:41.000000000 -0500
@@ -531,18 +531,23 @@ typedef struct srb {
 	 */
 	uint8_t cmd_type;
 	uint8_t pad[3];
-	atomic_t ref_count;
 	struct kref cmd_kref;	/* need to migrate ref_count over to this */
 	void *priv;
 	wait_queue_head_t nvme_ls_waitq;
 	struct fc_port *fcport;
 	struct scsi_qla_host *vha;
+	unsigned int start_timer:1;
+	unsigned int abort:1;
+	unsigned int aborted:1;
+	unsigned int completed:1;
+
 	uint32_t handle;
 	uint16_t flags;
 	uint16_t type;
 	const char *name;
 	int iocbs;
 	struct qla_qpair *qpair;
+	struct srb *cmd_sp;
 	struct list_head elem;
 	u32 gen1;	/* scratch */
 	u32 gen2;	/* scratch */
@@ -560,7 +565,6 @@ typedef struct srb {
 } srb_t;
 
 #define GET_CMD_SP(sp) (sp->u.scmd.cmd)
-#define SET_CMD_SP(sp, cmd) (sp->u.scmd.cmd = cmd)
 #define GET_CMD_CTX_SP(sp) (sp->u.scmd.ctx)
 
 #define GET_CMD_SENSE_LEN(sp) \
@@ -4629,6 +4633,7 @@ struct secure_flash_update_block_pk {
 #define QLA_SUSPENDED			0x106
 #define QLA_BUSY			0x107
 #define QLA_ALREADY_REGISTERED		0x109
+#define QLA_OS_TIMER_EXPIRED		0x10a
 
 #define NVRAM_DELAY()		udelay(10)
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_gs.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_gs.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_gs.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_gs.c	2019-12-17 14:08:41.000000000 -0500
@@ -3029,7 +3029,7 @@ static void qla24xx_async_gpsc_sp_done(v
 	fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
 
 	if (res == QLA_FUNCTION_TIMEOUT)
-		return;
+		goto done;
 
 	if (res == (DID_ERROR << 16)) {
 		/* entry status error */
@@ -3674,7 +3674,6 @@ void qla24xx_async_gnnft_done(scsi_qla_h
 		list_for_each_entry(fcport, &vha->vp_fcports, list) {
 			if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE))
 				continue;
-			fcport->scan_needed = 0;
 			fcport->scan_state = QLA_FCPORT_FOUND;
 			found = true;
 			/*
@@ -3683,10 +3682,12 @@ void qla24xx_async_gnnft_done(scsi_qla_h
 			if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
 				qla2x00_clear_loop_id(fcport);
 				fcport->flags |= FCF_FABRIC_DEVICE;
-			} else if (fcport->d_id.b24 != rp->id.b24) {
+			} else if (fcport->d_id.b24 != rp->id.b24 ||
+				fcport->scan_needed) {
 				qlt_schedule_sess_for_deletion(fcport);
 			}
 			fcport->d_id.b24 = rp->id.b24;
+			fcport->scan_needed = 0;
 			break;
 		}
 
@@ -4152,7 +4153,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t
 								rspsz,
 								&sp->u.iocb_cmd.u.ctarg.rsp_dma,
 								GFP_KERNEL);
-		sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
+		sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz;
 		if (!sp->u.iocb_cmd.u.ctarg.rsp) {
 			ql_log(ql_log_warn, vha, 0xffff,
 			    "Failed to allocate ct_sns request.\n");
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_init.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_init.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_init.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_init.c	2019-12-17 14:08:41.000000000 -0500
@@ -99,9 +99,39 @@ static void qla24xx_abort_iocb_timeout(v
 {
 	srb_t *sp = data;
 	struct srb_iocb *abt = &sp->u.iocb_cmd;
+	struct qla_qpair *qpair = sp->qpair;
+	u32 handle;
+	unsigned long flags;
+
+	if (sp->cmd_sp)
+		ql_dbg(ql_dbg_async, sp->vha, 0x507c,
+		    "Abort timeout - cmd hdl=%x, cmd type=%x hdl=%x, type=%x\n",
+		    sp->cmd_sp->handle, sp->cmd_sp->type,
+		    sp->handle, sp->type);
+	else
+		ql_dbg(ql_dbg_async, sp->vha, 0x507c,
+		    "Abort timeout 2 - hdl=%x, type=%x\n",
+		    sp->handle, sp->type);
+
+	spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+	for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
+		if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] ==
+		    sp->cmd_sp))
+			qpair->req->outstanding_cmds[handle] = NULL;
+
+		/* removing the abort */
+		if (qpair->req->outstanding_cmds[handle] == sp) {
+			qpair->req->outstanding_cmds[handle] = NULL;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+
+	if (sp->cmd_sp)
+		sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
 
 	abt->u.abt.comp_status = CS_TIMEOUT;
-	sp->done(sp, QLA_FUNCTION_TIMEOUT);
+	sp->done(sp, QLA_OS_TIMER_EXPIRED);
 }
 
 static void qla24xx_abort_sp_done(void *ptr, int res)
@@ -109,7 +139,8 @@ static void qla24xx_abort_sp_done(void *
 	srb_t *sp = ptr;
 	struct srb_iocb *abt = &sp->u.iocb_cmd;
 
-	if (del_timer(&sp->u.iocb_cmd.timer)) {
+	if ((res == QLA_OS_TIMER_EXPIRED) ||
+	    del_timer(&sp->u.iocb_cmd.timer)) {
 		if (sp->flags & SRB_WAKEUP_ON_COMP)
 			complete(&abt->u.abt.comp);
 		else
@@ -133,6 +164,7 @@ static int qla24xx_async_abort_cmd(srb_t
 	sp->type = SRB_ABT_CMD;
 	sp->name = "abort";
 	sp->qpair = cmd_sp->qpair;
+	sp->cmd_sp = cmd_sp;
 	if (wait)
 		sp->flags = SRB_WAKEUP_ON_COMP;
 
@@ -364,9 +396,6 @@ qla2x00_async_logout(struct scsi_qla_hos
 	struct srb_iocb *lio;
 	int rval = QLA_FUNCTION_FAILED;
 
-	if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
-		return rval;
-
 	fcport->flags |= FCF_ASYNC_SENT;
 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
 	if (!sp)
@@ -513,6 +542,7 @@ static int qla_post_els_plogi_work(struc
 
 	e->u.fcport.fcport = fcport;
 	fcport->flags |= FCF_ASYNC_ACTIVE;
+	fcport->disc_state = DSC_LOGIN_PEND;
 	return qla2x00_post_work(vha, e);
 }
 
@@ -813,6 +843,15 @@ static void qla24xx_handle_gnl_done_even
 			fcport->fw_login_state = current_login_state;
 			fcport->d_id = id;
 			switch (current_login_state) {
+			case DSC_LS_PRLI_PEND:
+				/*
+				 * In the middle of PRLI. Let it finish.
+				 * Allow relogin code to recheck state again
+				 * with GNL. Push disc_state back to DELETED
+				 * so GNL can go out again
+				 */
+				fcport->disc_state = DSC_DELETED;
+				break;
 			case DSC_LS_PRLI_COMP:
 				if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
 					fcport->port_type = FCT_INITIATOR;
@@ -1131,13 +1170,11 @@ void qla24xx_async_gpdb_sp_done(void *s,
 	    "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n",
 	    sp->name, res, fcport->port_name, mb[1], mb[2]);
 
-	if (res == QLA_FUNCTION_TIMEOUT) {
-		dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
-			sp->u.iocb_cmd.u.mbx.in_dma);
-		return;
-	}
-
 	fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
+
+	if (res == QLA_FUNCTION_TIMEOUT)
+		goto done;
+
 	memset(&ea, 0, sizeof(ea));
 	ea.event = FCME_GPDB_DONE;
 	ea.fcport = fcport;
@@ -1145,6 +1182,7 @@ void qla24xx_async_gpdb_sp_done(void *s,
 
 	qla2x00_fcport_event_handler(vha, &ea);
 
+done:
 	dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
 		sp->u.iocb_cmd.u.mbx.in_dma);
 
@@ -1488,7 +1526,7 @@ int qla24xx_fcport_handle_login(struct s
 	u64 wwn;
 	u16 sec;
 
-	ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x20d8,
+	ql_dbg(ql_dbg_disc, vha, 0x20d8,
 	    "%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d lid %d scan %d\n",
 	    __func__, fcport->port_name, fcport->disc_state,
 	    fcport->fw_login_state, fcport->login_pause, fcport->flags,
@@ -1499,6 +1537,7 @@ int qla24xx_fcport_handle_login(struct s
 		return 0;
 
 	if ((fcport->loop_id != FC_NO_LOOP_ID) &&
+	    qla_dual_mode_enabled(vha) &&
 	    ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
 	     (fcport->fw_login_state == DSC_LS_PRLI_PEND)))
 		return 0;
@@ -1668,21 +1707,10 @@ void qla24xx_handle_relogin_event(scsi_q
 	    fcport->last_login_gen, fcport->login_gen,
 	    fcport->flags);
 
-	if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
-	    (fcport->fw_login_state == DSC_LS_PRLI_PEND))
-		return;
-
-	if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
-		if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) {
-			set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
-			return;
-		}
-	}
-
 	if (fcport->last_rscn_gen != fcport->rscn_gen) {
-		ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gidpn\n",
+		ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gnl\n",
 		    __func__, __LINE__, fcport->port_name);
-
+		qla24xx_post_gnl_work(vha, fcport);
 		return;
 	}
 
@@ -3288,6 +3316,8 @@ try_eft:
 		ql_dbg(ql_dbg_init, vha, 0x00c3,
 		    "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024);
 		eft_size = EFT_SIZE;
+		ha->eft_dma = tc_dma;
+		ha->eft = tc;
 	}
 
 	if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
@@ -7595,8 +7625,12 @@ qla27xx_get_active_image(struct scsi_qla
 		goto check_sec_image;
 	}
 
-	qla24xx_read_flash_data(vha, (void *)(&pri_image_status),
-	    ha->flt_region_img_status_pri, sizeof(pri_image_status) >> 2);
+	if (qla24xx_read_flash_data(vha, (void *)(&pri_image_status),
+	    ha->flt_region_img_status_pri, sizeof(pri_image_status) >> 2) !=
+	    QLA_SUCCESS) {
+		WARN_ON_ONCE(true);
+		goto check_sec_image;
+	}
 	qla27xx_print_image(vha, "Primary image", &pri_image_status);
 
 	if (qla27xx_check_image_status_signature(&pri_image_status)) {
@@ -8350,7 +8384,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vh
 		    active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
 		    "primary" : "secondary");
 	}
-	qla24xx_read_flash_data(vha, ha->vpd, faddr, ha->vpd_size >> 2);
+	ha->isp_ops->read_optrom(vha, ha->vpd, faddr << 2, ha->vpd_size);
 
 	/* Get NVRAM data into cache and calculate checksum. */
 	faddr = ha->flt_region_nvram;
@@ -8362,7 +8396,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vh
 	    "Loading %s nvram image.\n",
 	    active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
 	    "primary" : "secondary");
-	qla24xx_read_flash_data(vha, ha->nvram, faddr, ha->nvram_size >> 2);
+	ha->isp_ops->read_optrom(vha, ha->nvram, faddr << 2, ha->nvram_size);
 
 	dptr = (uint32_t *)nv;
 	for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++)
@@ -9092,8 +9126,6 @@ int qla2xxx_delete_qpair(struct scsi_qla
 	struct qla_hw_data *ha = qpair->hw;
 
 	qpair->delete_in_progress = 1;
-	while (atomic_read(&qpair->ref_count))
-		msleep(500);
 
 	ret = qla25xx_delete_req_que(vha, qpair->req);
 	if (ret != QLA_SUCCESS)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_inline.h linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_inline.h
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_inline.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_inline.h	2019-12-17 14:08:41.000000000 -0500
@@ -152,6 +152,18 @@ qla2x00_chip_is_down(scsi_qla_host_t *vh
 	return (qla2x00_reset_active(vha) || !vha->hw->flags.fw_started);
 }
 
+static void qla2xxx_init_sp(srb_t *sp, scsi_qla_host_t *vha,
+			    struct qla_qpair *qpair, fc_port_t *fcport)
+{
+	memset(sp, 0, sizeof(*sp));
+	sp->fcport = fcport;
+	sp->iocbs = 1;
+	sp->vha = vha;
+	sp->qpair = qpair;
+	sp->cmd_type = TYPE_SRB;
+	INIT_LIST_HEAD(&sp->elem);
+}
+
 static inline srb_t *
 qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair,
     fc_port_t *fcport, gfp_t flag)
@@ -164,19 +176,9 @@ qla2xxx_get_qpair_sp(scsi_qla_host_t *vh
 		return NULL;
 
 	sp = mempool_alloc(qpair->srb_mempool, flag);
-	if (!sp)
-		goto done;
-
-	memset(sp, 0, sizeof(*sp));
-	sp->fcport = fcport;
-	sp->iocbs = 1;
-	sp->vha = vha;
-	sp->qpair = qpair;
-	sp->cmd_type = TYPE_SRB;
-	INIT_LIST_HEAD(&sp->elem);
-
-done:
-	if (!sp)
+	if (sp)
+		qla2xxx_init_sp(sp, vha, qpair, fcport);
+	else
 		QLA_QPAIR_MARK_NOT_BUSY(qpair);
 	return sp;
 }
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_iocb.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_iocb.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_iocb.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_iocb.c	2019-12-17 14:08:41.000000000 -0500
@@ -2540,7 +2540,7 @@ void qla2x00_init_timer(srb_t *sp, unsig
 	sp->free = qla2x00_sp_free;
 	if (IS_QLAFX00(sp->vha->hw) && sp->type == SRB_FXIOCB_DCMD)
 		init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
-	add_timer(&sp->u.iocb_cmd.timer);
+	sp->start_timer = 1;
 }
 
 static void
@@ -3668,6 +3668,9 @@ qla2x00_start_sp(srb_t *sp)
 		break;
 	}
 
+	if (sp->start_timer)
+		add_timer(&sp->u.iocb_cmd.timer);
+
 	wmb();
 	qla2x00_start_iocbs(vha, qp->req);
 done:
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_isr.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_isr.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_isr.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_isr.c	2019-12-17 14:08:41.000000000 -0500
@@ -2473,6 +2473,11 @@ qla2x00_status_entry(scsi_qla_host_t *vh
 		return;
 	}
 
+	if (sp->abort)
+		sp->aborted = 1;
+	else
+		sp->completed = 1;
+
 	if (sp->cmd_type != TYPE_SRB) {
 		req->outstanding_cmds[handle] = NULL;
 		ql_dbg(ql_dbg_io, vha, 0x3015,
@@ -3471,10 +3476,8 @@ qla24xx_enable_msix(struct qla_hw_data *
 		    ha->msix_count, ret);
 		goto msix_out;
 	} else if (ret < ha->msix_count) {
-		ql_log(ql_log_warn, vha, 0x00c6,
-		    "MSI-X: Failed to enable support "
-		     "with %d vectors, using %d vectors.\n",
-		    ha->msix_count, ret);
+		ql_log(ql_log_info, vha, 0x00c6,
+		    "MSI-X: Using %d vectors\n", ret);
 		ha->msix_count = ret;
 		/* Recalculate queue values */
 		if (ha->mqiobase && (ql2xmqsupport || ql2xnvmeenable)) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_mbx.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_mbx.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_mbx.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_mbx.c	2019-12-17 14:08:41.000000000 -0500
@@ -253,21 +253,9 @@ qla2x00_mailbox_command(scsi_qla_host_t
 	if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
 		set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
 
-		if (IS_P3P_TYPE(ha)) {
-			if (RD_REG_DWORD(&reg->isp82.hint) &
-				HINT_MBX_INT_PENDING) {
-				ha->flags.mbox_busy = 0;
-				spin_unlock_irqrestore(&ha->hardware_lock,
-					flags);
-
-				atomic_dec(&ha->num_pend_mbx_stage2);
-				ql_dbg(ql_dbg_mbx, vha, 0x1010,
-				    "Pending mailbox timeout, exiting.\n");
-				rval = QLA_FUNCTION_TIMEOUT;
-				goto premature_exit;
-			}
+		if (IS_P3P_TYPE(ha))
 			WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
-		} else if (IS_FWI2_CAPABLE(ha))
+		else if (IS_FWI2_CAPABLE(ha))
 			WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
 		else
 			WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
@@ -6297,17 +6285,13 @@ int qla24xx_send_mb_cmd(struct scsi_qla_
 	case  QLA_SUCCESS:
 		ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n",
 		    __func__, sp->name);
-		sp->free(sp);
 		break;
 	default:
 		ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n",
 		    __func__, sp->name, rval);
-		sp->free(sp);
 		break;
 	}
 
-	return rval;
-
 done_free_sp:
 	sp->free(sp);
 done:
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_mid.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_mid.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_mid.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_mid.c	2019-12-17 14:08:41.000000000 -0500
@@ -934,7 +934,7 @@ int qla24xx_control_vp(scsi_qla_host_t *
 
 	sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL);
 	if (!sp)
-		goto done;
+		return rval;
 
 	sp->type = SRB_CTRL_VP;
 	sp->name = "ctrl_vp";
@@ -950,7 +950,7 @@ int qla24xx_control_vp(scsi_qla_host_t *
 		ql_dbg(ql_dbg_async, vha, 0xffff,
 		    "%s: %s Failed submission. %x.\n",
 		    __func__, sp->name, rval);
-		goto done_free_sp;
+		goto done;
 	}
 
 	ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n",
@@ -968,16 +968,13 @@ int qla24xx_control_vp(scsi_qla_host_t *
 	case QLA_SUCCESS:
 		ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s done.\n",
 		    __func__, sp->name);
-		goto done_free_sp;
+		break;
 	default:
 		ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s Failed. %x.\n",
 		    __func__, sp->name, rval);
-		goto done_free_sp;
+		break;
 	}
 done:
-	return rval;
-
-done_free_sp:
 	sp->free(sp);
 	return rval;
 }
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_nvme.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_nvme.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_nvme.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_nvme.c	2019-12-17 14:08:41.000000000 -0500
@@ -227,8 +227,8 @@ static void qla_nvme_abort_work(struct w
 
 	if (ha->flags.host_shutting_down) {
 		ql_log(ql_log_info, sp->fcport->vha, 0xffff,
-		    "%s Calling done on sp: %p, type: 0x%x, sp->ref_count: 0x%x\n",
-		    __func__, sp, sp->type, atomic_read(&sp->ref_count));
+		    "%s Calling done on sp: %p, type: 0x%x\n",
+		    __func__, sp, sp->type);
 		sp->done(sp, 0);
 		goto out;
 	}
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_nx.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_nx.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_nx.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_nx.c	2019-12-17 14:08:41.000000000 -0500
@@ -2287,7 +2287,9 @@ qla82xx_disable_intrs(struct qla_hw_data
 {
 	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
 
-	qla82xx_mbx_intr_disable(vha);
+	if (ha->interrupts_on)
+		qla82xx_mbx_intr_disable(vha);
+
 	spin_lock_irq(&ha->hardware_lock);
 	if (IS_QLA8044(ha))
 		qla8044_wr_reg(ha, LEG_INTR_MASK_OFFSET, 1);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_os.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_os.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_os.c	2019-12-13 11:14:45.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_os.c	2019-12-17 16:15:06.000000000 -0500
@@ -716,18 +716,12 @@ qla2x00_sp_compl(void *ptr, int res)
 	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
 	struct completion *comp = sp->comp;
 
-	if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0))
-		return;
-
-	atomic_dec(&sp->ref_count);
-
 	sp->free(sp);
 	cmd->result = res;
 	CMD_SP(cmd) = NULL;
 	cmd->scsi_done(cmd);
 	if (comp)
 		complete(comp);
-	qla2x00_rel_sp(sp);
 }
 
 void
@@ -821,18 +815,12 @@ qla2xxx_qpair_sp_compl(void *ptr, int re
 	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
 	struct completion *comp = sp->comp;
 
-	if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0))
-		return;
-
-	atomic_dec(&sp->ref_count);
-
 	sp->free(sp);
 	cmd->result = res;
 	CMD_SP(cmd) = NULL;
 	cmd->scsi_done(cmd);
 	if (comp)
 		complete(comp);
-	qla2xxx_rel_qpair_sp(sp->qpair, sp);
 }
 
 static int
@@ -925,13 +913,12 @@ qla2xxx_queuecommand(struct Scsi_Host *h
 	else
 		goto qc24_target_busy;
 
-	sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
-	if (!sp)
-		goto qc24_host_busy;
+	sp = scsi_cmd_priv(cmd);
+	qla2xxx_init_sp(sp, vha, vha->hw->base_qpair, fcport);
 
 	sp->u.scmd.cmd = cmd;
 	sp->type = SRB_SCSI_CMD;
-	atomic_set(&sp->ref_count, 1);
+
 	CMD_SP(cmd) = (void *)sp;
 	sp->free = qla2x00_sp_free_dma;
 	sp->done = qla2x00_sp_compl;
@@ -948,9 +935,6 @@ qla2xxx_queuecommand(struct Scsi_Host *h
 qc24_host_busy_free_sp:
 	sp->free(sp);
 
-qc24_host_busy:
-	return SCSI_MLQUEUE_HOST_BUSY;
-
 qc24_target_busy:
 	return SCSI_MLQUEUE_TARGET_BUSY;
 
@@ -1011,24 +995,21 @@ qla2xxx_mqueuecommand(struct Scsi_Host *
 	else
 		goto qc24_target_busy;
 
-	sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC);
-	if (!sp)
-		goto qc24_host_busy;
+	sp = scsi_cmd_priv(cmd);
+	qla2xxx_init_sp(sp, vha, qpair, fcport);
 
 	sp->u.scmd.cmd = cmd;
 	sp->type = SRB_SCSI_CMD;
-	atomic_set(&sp->ref_count, 1);
 	CMD_SP(cmd) = (void *)sp;
 	sp->free = qla2xxx_qpair_sp_free_dma;
 	sp->done = qla2xxx_qpair_sp_compl;
-	sp->qpair = qpair;
 
 	rval = ha->isp_ops->start_scsi_mq(sp);
 	if (rval != QLA_SUCCESS) {
 		ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078,
 		    "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd);
 		if (rval == QLA_INTERFACE_ERROR)
-			goto qc24_fail_command;
+			goto qc24_free_sp_fail_command;
 		goto qc24_host_busy_free_sp;
 	}
 
@@ -1037,12 +1018,14 @@ qla2xxx_mqueuecommand(struct Scsi_Host *
 qc24_host_busy_free_sp:
 	sp->free(sp);
 
-qc24_host_busy:
-	return SCSI_MLQUEUE_HOST_BUSY;
-
 qc24_target_busy:
 	return SCSI_MLQUEUE_TARGET_BUSY;
 
+qc24_free_sp_fail_command:
+	sp->free(sp);
+	CMD_SP(cmd) = NULL;
+	qla2xxx_rel_qpair_sp(sp->qpair, sp);
+
 qc24_fail_command:
 	cmd->scsi_done(cmd);
 
@@ -1212,16 +1195,6 @@ qla2x00_wait_for_chip_reset(scsi_qla_hos
 	return return_status;
 }
 
-static int
-sp_get(struct srb *sp)
-{
-	if (!refcount_inc_not_zero((refcount_t *)&sp->ref_count))
-		/* kref get fail */
-		return ENXIO;
-	else
-		return 0;
-}
-
 #define ISP_REG_DISCONNECT 0xffffffffU
 /**************************************************************************
 * qla2x00_isp_reg_stat
@@ -1270,14 +1243,16 @@ static int
 qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 {
 	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
+	DECLARE_COMPLETION_ONSTACK(comp);
 	srb_t *sp;
 	int ret;
 	unsigned int id;
 	uint64_t lun;
-	unsigned long flags;
 	int rval;
 	struct qla_hw_data *ha = vha->hw;
+	uint32_t ratov_j;
 	struct qla_qpair *qpair;
+	unsigned long flags;
 
 	if (qla2x00_isp_reg_stat(ha)) {
 		ql_log(ql_log_info, vha, 0x8042,
@@ -1289,29 +1264,28 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 	if (ret != 0)
 		return ret;
 
-	sp = (srb_t *) CMD_SP(cmd);
-	if (!sp)
-		return SUCCESS;
-
+	sp = scsi_cmd_priv(cmd);
 	qpair = sp->qpair;
-	if (!qpair)
+
+	if ((sp->fcport && sp->fcport->deleted) || !qpair)
 		return SUCCESS;
 
 	spin_lock_irqsave(qpair->qp_lock_ptr, flags);
-	if (sp->type != SRB_SCSI_CMD || GET_CMD_SP(sp) != cmd) {
-		/* there's a chance an interrupt could clear
-		   the ptr as part of done & free */
+	if (sp->completed) {
 		spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 		return SUCCESS;
 	}
 
-	if (sp_get(sp)){
-		/* ref_count is already 0 */
+	if (sp->abort || sp->aborted) {
 		spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
-		return SUCCESS;
+		return FAILED;
 	}
+
+	sp->abort = 1;
+	sp->comp = &comp;
 	spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
+
 	id = cmd->device->id;
 	lun = cmd->device->lun;
 
@@ -1319,28 +1293,37 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 	    "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n",
 	    vha->host_no, id, lun, sp, cmd, sp->handle);
 
+	/*
+	 * Abort will release the original Command/sp from FW. Let the
+	 * original command call scsi_done. In return, he will wakeup
+	 * this sleeping thread.
+	 */
 	rval = ha->isp_ops->abort_command(sp);
+
 	ql_dbg(ql_dbg_taskm, vha, 0x8003,
 	       "Abort command mbx cmd=%p, rval=%x.\n", cmd, rval);
 
+	/* Wait for the command completion. */
+	ratov_j = ha->r_a_tov/10 * 4 * 1000;
+	ratov_j = msecs_to_jiffies(ratov_j);
 	switch (rval) {
 	case QLA_SUCCESS:
-		/*
-		 * The command has been aborted. That means that the firmware
-		 * won't report a completion.
-		 */
-		sp->done(sp, DID_ABORT << 16);
-		ret = SUCCESS;
+		if (!wait_for_completion_timeout(&comp, ratov_j)) {
+			ql_dbg(ql_dbg_taskm, vha, 0xffff,
+			    "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n",
+			    __func__, ha->r_a_tov/10);
+			ret = FAILED;
+		} else {
+			ret = SUCCESS;
+		}
 		break;
 	default:
-		/*
-		 * Either abort failed or abort and completion raced. Let
-		 * the SCSI core retry the abort in the former case.
-		 */
 		ret = FAILED;
 		break;
 	}
 
+	sp->comp = NULL;
+
 	ql_log(ql_log_info, vha, 0x801c,
 	    "Abort command issued nexus=%ld:%d:%llu -- %x.\n",
 	    vha->host_no, id, lun, ret);
@@ -1723,29 +1706,52 @@ static void qla2x00_abort_srb(struct qla
 	scsi_qla_host_t *vha = qp->vha;
 	struct qla_hw_data *ha = vha->hw;
 	int rval;
+	bool ret_cmd;
+	uint32_t ratov_j;
 
-	if (sp_get(sp))
+	if (qla2x00_chip_is_down(vha)) {
+		sp->done(sp, res);
 		return;
+	}
 
 	if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS ||
 	    (sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy &&
 	     !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
 	     !qla2x00_isp_reg_stat(ha))) {
+		if (sp->comp) {
+			sp->done(sp, res);
+			return;
+		}
+
 		sp->comp = &comp;
+		sp->abort =  1;
 		spin_unlock_irqrestore(qp->qp_lock_ptr, *flags);
-		rval = ha->isp_ops->abort_command(sp);
 
+		rval = ha->isp_ops->abort_command(sp);
+		/* Wait for command completion. */
+		ret_cmd = false;
+		ratov_j = ha->r_a_tov/10 * 4 * 1000;
+		ratov_j = msecs_to_jiffies(ratov_j);
 		switch (rval) {
 		case QLA_SUCCESS:
-			sp->done(sp, res);
+			if (wait_for_completion_timeout(&comp, ratov_j)) {
+				ql_dbg(ql_dbg_taskm, vha, 0xffff,
+				    "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n",
+				    __func__, ha->r_a_tov/10);
+				ret_cmd = true;
+			}
+			/* else FW return SP to driver */
 			break;
-		case QLA_FUNCTION_PARAMETER_ERROR:
-			wait_for_completion(&comp);
+		default:
+			ret_cmd = true;
 			break;
 		}
 
 		spin_lock_irqsave(qp->qp_lock_ptr, *flags);
-		sp->comp = NULL;
+		if (ret_cmd && (!sp->completed || !sp->aborted))
+			sp->done(sp, res);
+	} else {
+		sp->done(sp, res);
 	}
 }
 
@@ -1768,7 +1774,6 @@ __qla2x00_abort_all_cmds(struct qla_qpai
 	for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
 		sp = req->outstanding_cmds[cnt];
 		if (sp) {
-			req->outstanding_cmds[cnt] = NULL;
 			switch (sp->cmd_type) {
 			case TYPE_SRB:
 				qla2x00_abort_srb(qp, sp, res, &flags);
@@ -1790,6 +1795,7 @@ __qla2x00_abort_all_cmds(struct qla_qpai
 			default:
 				break;
 			}
+			req->outstanding_cmds[cnt] = NULL;
 		}
 	}
 	spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
@@ -4671,7 +4677,8 @@ qla2x00_mem_free(struct qla_hw_data *ha)
 	ha->sfp_data = NULL;
 
 	if (ha->flt)
-		dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE,
+		dma_free_coherent(&ha->pdev->dev,
+		    sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE,
 		    ha->flt, ha->flt_dma);
 	ha->flt = NULL;
 	ha->flt_dma = 0;
@@ -7168,6 +7175,7 @@ struct scsi_host_template qla2xxx_driver
 
 	.supported_mode		= MODE_INITIATOR,
 	.track_queue_depth	= 1,
+	.cmd_size		= sizeof(srb_t),
 };
 
 static const struct pci_error_handlers qla2xxx_err_handler = {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_sup.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_sup.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_sup.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_sup.c	2019-12-17 14:08:41.000000000 -0500
@@ -680,8 +680,8 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vh
 
 	ha->flt_region_flt = flt_addr;
 	wptr = (uint16_t *)ha->flt;
-	qla24xx_read_flash_data(vha, (void *)flt, flt_addr,
-	    (sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE) >> 2);
+	ha->isp_ops->read_optrom(vha, (void *)flt, flt_addr << 2,
+	    (sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE));
 
 	if (le16_to_cpu(*wptr) == 0xffff)
 		goto no_flash_data;
@@ -948,11 +948,11 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vh
 	struct req_que *req = ha->req_q_map[0];
 	uint16_t cnt, chksum;
 	uint16_t *wptr = (void *)req->ring;
-	struct qla_fdt_layout *fdt = (void *)req->ring;
+	struct qla_fdt_layout *fdt = (struct qla_fdt_layout *)req->ring;
 	uint8_t	man_id, flash_id;
 	uint16_t mid = 0, fid = 0;
 
-	qla24xx_read_flash_data(vha, (void *)fdt, ha->flt_region_fdt,
+	ha->isp_ops->read_optrom(vha, fdt, ha->flt_region_fdt << 2,
 	    OPTROM_BURST_DWORDS);
 	if (le16_to_cpu(*wptr) == 0xffff)
 		goto no_flash_data;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_target.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_target.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/qla_target.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/qla_target.c	2019-12-17 14:08:41.000000000 -0500
@@ -3237,7 +3237,8 @@ int qlt_xmit_response(struct qla_tgt_cmd
 	if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) ||
 	    (cmd->sess && cmd->sess->deleted)) {
 		cmd->state = QLA_TGT_STATE_PROCESSED;
-		return 0;
+		res = 0;
+		goto free;
 	}
 
 	ql_dbg_qp(ql_dbg_tgt, qpair, 0xe018,
@@ -3248,9 +3249,8 @@ int qlt_xmit_response(struct qla_tgt_cmd
 
 	res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status,
 	    &full_req_cnt);
-	if (unlikely(res != 0)) {
-		return res;
-	}
+	if (unlikely(res != 0))
+		goto free;
 
 	spin_lock_irqsave(qpair->qp_lock_ptr, flags);
 
@@ -3270,7 +3270,8 @@ int qlt_xmit_response(struct qla_tgt_cmd
 			vha->flags.online, qla2x00_reset_active(vha),
 			cmd->reset_count, qpair->chip_reset);
 		spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
-		return 0;
+		res = 0;
+		goto free;
 	}
 
 	/* Does F/W have an IOCBs for this request */
@@ -3373,6 +3374,8 @@ out_unmap_unlock:
 	qlt_unmap_sg(vha, cmd);
 	spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
+free:
+	vha->hw->tgt.tgt_ops->free_cmd(cmd);
 	return res;
 }
 EXPORT_SYMBOL(qlt_xmit_response);
@@ -6195,7 +6198,6 @@ static void qlt_abort_work(struct qla_tg
 	struct qla_hw_data *ha = vha->hw;
 	struct fc_port *sess = NULL;
 	unsigned long flags = 0, flags2 = 0;
-	uint32_t be_s_id;
 	uint8_t s_id[3];
 	int rc;
 
@@ -6208,8 +6210,7 @@ static void qlt_abort_work(struct qla_tg
 	s_id[1] = prm->abts.fcp_hdr_le.s_id[1];
 	s_id[2] = prm->abts.fcp_hdr_le.s_id[0];
 
-	sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
-	    (unsigned char *)&be_s_id);
+	sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id);
 	if (!sess) {
 		spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
 
@@ -6683,7 +6684,8 @@ qlt_enable_vha(struct scsi_qla_host *vha
 	} else {
 		set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
 		qla2xxx_wake_dpc(base_vha);
-		qla2x00_wait_for_hba_online(base_vha);
+		WARN_ON_ONCE(qla2x00_wait_for_hba_online(base_vha) !=
+			     QLA_SUCCESS);
 	}
 	mutex_unlock(&ha->optrom_mutex);
 }
@@ -6714,7 +6716,9 @@ static void qlt_disable_vha(struct scsi_
 
 	set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 	qla2xxx_wake_dpc(vha);
-	qla2x00_wait_for_hba_online(vha);
+	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS)
+		ql_dbg(ql_dbg_tgt, vha, 0xe081,
+		       "qla2x00_wait_for_hba_online() failed\n");
 }
 
 /*
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/tcm_qla2xxx.c linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/tcm_qla2xxx.c
--- linux-libre-5.3.16-gnu/drivers/scsi/qla2xxx/tcm_qla2xxx.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/scsi/qla2xxx/tcm_qla2xxx.c	2019-12-17 14:08:41.000000000 -0500
@@ -620,6 +620,7 @@ static int tcm_qla2xxx_queue_data_in(str
 {
 	struct qla_tgt_cmd *cmd = container_of(se_cmd,
 				struct qla_tgt_cmd, se_cmd);
+	struct scsi_qla_host *vha = cmd->vha;
 
 	if (cmd->aborted) {
 		/* Cmd can loop during Q-full.  tcm_qla2xxx_aborted_task
@@ -632,6 +633,7 @@ static int tcm_qla2xxx_queue_data_in(str
 			cmd->se_cmd.transport_state,
 			cmd->se_cmd.t_state,
 			cmd->se_cmd.se_cmd_flags);
+		vha->hw->tgt.tgt_ops->free_cmd(cmd);
 		return 0;
 	}
 
@@ -659,6 +661,7 @@ static int tcm_qla2xxx_queue_status(stru
 {
 	struct qla_tgt_cmd *cmd = container_of(se_cmd,
 				struct qla_tgt_cmd, se_cmd);
+	struct scsi_qla_host *vha = cmd->vha;
 	int xmit_type = QLA_TGT_XMIT_STATUS;
 
 	if (cmd->aborted) {
@@ -672,6 +675,7 @@ static int tcm_qla2xxx_queue_status(stru
 		    cmd, kref_read(&cmd->se_cmd.cmd_kref),
 		    cmd->se_cmd.transport_state, cmd->se_cmd.t_state,
 		    cmd->se_cmd.se_cmd_flags);
+		vha->hw->tgt.tgt_ops->free_cmd(cmd);
 		return 0;
 	}
 	cmd->bufflen = se_cmd->data_length;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/staging/erofs/xattr.c linux-libre-5.3.17-gnu/drivers/staging/erofs/xattr.c
--- linux-libre-5.3.16-gnu/drivers/staging/erofs/xattr.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/staging/erofs/xattr.c	2019-12-17 14:08:41.000000000 -0500
@@ -649,6 +649,8 @@ ssize_t erofs_listxattr(struct dentry *d
 	struct listxattr_iter it;
 
 	ret = init_inode_xattrs(d_inode(dentry));
+	if (ret == -ENOATTR)
+		return 0;
 	if (ret)
 		return ret;
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/staging/isdn/gigaset/usb-gigaset.c linux-libre-5.3.17-gnu/drivers/staging/isdn/gigaset/usb-gigaset.c
--- linux-libre-5.3.16-gnu/drivers/staging/isdn/gigaset/usb-gigaset.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/staging/isdn/gigaset/usb-gigaset.c	2019-12-17 14:08:41.000000000 -0500
@@ -571,8 +571,7 @@ static int gigaset_initcshw(struct cards
 {
 	struct usb_cardstate *ucs;
 
-	cs->hw.usb = ucs =
-		kmalloc(sizeof(struct usb_cardstate), GFP_KERNEL);
+	cs->hw.usb = ucs = kzalloc(sizeof(struct usb_cardstate), GFP_KERNEL);
 	if (!ucs) {
 		pr_err("out of memory\n");
 		return -ENOMEM;
@@ -584,9 +583,6 @@ static int gigaset_initcshw(struct cards
 	ucs->bchars[3] = 0;
 	ucs->bchars[4] = 0x11;
 	ucs->bchars[5] = 0x13;
-	ucs->bulk_out_buffer = NULL;
-	ucs->bulk_out_urb = NULL;
-	ucs->read_urb = NULL;
 	tasklet_init(&cs->write_tasklet,
 		     gigaset_modem_fill, (unsigned long) cs);
 
@@ -685,6 +681,11 @@ static int gigaset_probe(struct usb_inte
 		return -ENODEV;
 	}
 
+	if (hostif->desc.bNumEndpoints < 2) {
+		dev_err(&interface->dev, "missing endpoints\n");
+		return -ENODEV;
+	}
+
 	dev_info(&udev->dev, "%s: Device matched ... !\n", __func__);
 
 	/* allocate memory for our device state and initialize it */
@@ -704,6 +705,12 @@ static int gigaset_probe(struct usb_inte
 
 	endpoint = &hostif->endpoint[0].desc;
 
+	if (!usb_endpoint_is_bulk_out(endpoint)) {
+		dev_err(&interface->dev, "missing bulk-out endpoint\n");
+		retval = -ENODEV;
+		goto error;
+	}
+
 	buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 	ucs->bulk_out_size = buffer_size;
 	ucs->bulk_out_epnum = usb_endpoint_num(endpoint);
@@ -723,6 +730,12 @@ static int gigaset_probe(struct usb_inte
 
 	endpoint = &hostif->endpoint[1].desc;
 
+	if (!usb_endpoint_is_int_in(endpoint)) {
+		dev_err(&interface->dev, "missing int-in endpoint\n");
+		retval = -ENODEV;
+		goto error;
+	}
+
 	ucs->busy = 0;
 
 	ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/staging/media/hantro/hantro_v4l2.c linux-libre-5.3.17-gnu/drivers/staging/media/hantro/hantro_v4l2.c
--- linux-libre-5.3.16-gnu/drivers/staging/media/hantro/hantro_v4l2.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/staging/media/hantro/hantro_v4l2.c	2019-12-17 14:08:41.000000000 -0500
@@ -356,20 +356,27 @@ vidioc_s_fmt_out_mplane(struct file *fil
 {
 	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
 	struct hantro_ctx *ctx = fh_to_ctx(priv);
+	struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
 	const struct hantro_fmt *formats;
 	unsigned int num_fmts;
-	struct vb2_queue *vq;
 	int ret;
 
-	/* Change not allowed if queue is busy. */
-	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
-	if (vb2_is_busy(vq))
-		return -EBUSY;
+	ret = vidioc_try_fmt_out_mplane(file, priv, f);
+	if (ret)
+		return ret;
 
 	if (!hantro_is_encoder_ctx(ctx)) {
 		struct vb2_queue *peer_vq;
 
 		/*
+		 * In order to support dynamic resolution change,
+		 * the decoder admits a resolution change, as long
+		 * as the pixelformat remains. Can't be done if streaming.
+		 */
+		if (vb2_is_streaming(vq) || (vb2_is_busy(vq) &&
+		    pix_mp->pixelformat != ctx->src_fmt.pixelformat))
+			return -EBUSY;
+		/*
 		 * Since format change on the OUTPUT queue will reset
 		 * the CAPTURE queue, we can't allow doing so
 		 * when the CAPTURE queue has buffers allocated.
@@ -378,12 +385,15 @@ vidioc_s_fmt_out_mplane(struct file *fil
 					  V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 		if (vb2_is_busy(peer_vq))
 			return -EBUSY;
+	} else {
+		/*
+		 * The encoder doesn't admit a format change if
+		 * there are OUTPUT buffers allocated.
+		 */
+		if (vb2_is_busy(vq))
+			return -EBUSY;
 	}
 
-	ret = vidioc_try_fmt_out_mplane(file, priv, f);
-	if (ret)
-		return ret;
-
 	formats = hantro_get_formats(ctx, &num_fmts);
 	ctx->vpu_src_fmt = hantro_find_format(formats, num_fmts,
 					      pix_mp->pixelformat);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c linux-libre-5.3.17-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c
--- linux-libre-5.3.16-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c	2019-12-17 14:08:41.000000000 -0500
@@ -70,7 +70,7 @@ static struct dvobj_priv *usb_dvobj_init
 	phost_conf = pusbd->actconfig;
 	pconf_desc = &phost_conf->desc;
 
-	phost_iface = &usb_intf->altsetting[0];
+	phost_iface = usb_intf->cur_altsetting;
 	piface_desc = &phost_iface->desc;
 
 	pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/staging/rtl8712/usb_intf.c linux-libre-5.3.17-gnu/drivers/staging/rtl8712/usb_intf.c
--- linux-libre-5.3.16-gnu/drivers/staging/rtl8712/usb_intf.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/staging/rtl8712/usb_intf.c	2019-12-17 14:08:41.000000000 -0500
@@ -247,7 +247,7 @@ static uint r8712_usb_dvobj_init(struct
 
 	pdvobjpriv->padapter = padapter;
 	padapter->eeprom_address_size = 6;
-	phost_iface = &pintf->altsetting[0];
+	phost_iface = pintf->cur_altsetting;
 	piface_desc = &phost_iface->desc;
 	pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
 	if (pusbd->speed == USB_SPEED_HIGH) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c linux-libre-5.3.17-gnu/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
--- linux-libre-5.3.16-gnu/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c	2019-12-17 14:08:41.000000000 -0500
@@ -3300,7 +3300,7 @@ static int __init vchiq_driver_init(void
 	return 0;
 
 region_unregister:
-	platform_driver_unregister(&vchiq_driver);
+	unregister_chrdev_region(vchiq_devid, 1);
 
 class_destroy:
 	class_destroy(vchiq_class);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/atm/ueagle-atm.c linux-libre-5.3.17-gnu/drivers/usb/atm/ueagle-atm.c
--- linux-libre-5.3.16-gnu/drivers/usb/atm/ueagle-atm.c	2019-12-13 11:15:03.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/atm/ueagle-atm.c	2019-12-17 16:15:24.000000000 -0500
@@ -2124,10 +2124,11 @@ resubmit:
 /*
  * Start the modem : init the data and start kernel thread
  */
-static int uea_boot(struct uea_softc *sc)
+static int uea_boot(struct uea_softc *sc, struct usb_interface *intf)
 {
-	int ret, size;
 	struct intr_pkt *intr;
+	int ret = -ENOMEM;
+	int size;
 
 	uea_enters(INS_TO_USBDEV(sc));
 
@@ -2152,6 +2153,11 @@ static int uea_boot(struct uea_softc *sc
 	if (UEA_CHIP_VERSION(sc) == ADI930)
 		load_XILINX_firmware(sc);
 
+	if (intf->cur_altsetting->desc.bNumEndpoints < 1) {
+		ret = -ENODEV;
+		goto err0;
+	}
+
 	intr = kmalloc(size, GFP_KERNEL);
 	if (!intr)
 		goto err0;
@@ -2163,8 +2169,7 @@ static int uea_boot(struct uea_softc *sc
 	usb_fill_int_urb(sc->urb_int, sc->usb_dev,
 			 usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE),
 			 intr, size, uea_intr, sc,
-			 sc->usb_dev->actconfig->interface[0]->altsetting[0].
-			 endpoint[0].desc.bInterval);
+			 intf->cur_altsetting->endpoint[0].desc.bInterval);
 
 	ret = usb_submit_urb(sc->urb_int, GFP_KERNEL);
 	if (ret < 0) {
@@ -2179,6 +2184,7 @@ static int uea_boot(struct uea_softc *sc
 	sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm");
 	if (IS_ERR(sc->kthread)) {
 		uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
+		ret = PTR_ERR(sc->kthread);
 		goto err2;
 	}
 
@@ -2193,7 +2199,7 @@ err1:
 	kfree(intr);
 err0:
 	uea_leaves(INS_TO_USBDEV(sc));
-	return -ENOMEM;
+	return ret;
 }
 
 /*
@@ -2554,7 +2560,7 @@ static int uea_bind(struct usbatm_data *
 	if (ret < 0)
 		goto error;
 
-	ret = uea_boot(sc);
+	ret = uea_boot(sc, intf);
 	if (ret < 0)
 		goto error_rm_grp;
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/core/hub.c linux-libre-5.3.17-gnu/drivers/usb/core/hub.c
--- linux-libre-5.3.16-gnu/drivers/usb/core/hub.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/core/hub.c	2019-12-17 14:08:41.000000000 -0500
@@ -5814,7 +5814,7 @@ re_enumerate_no_bos:
 
 /**
  * usb_reset_device - warn interface drivers and perform a USB port reset
- * @udev: device to reset (not in SUSPENDED or NOTATTACHED state)
+ * @udev: device to reset (not in NOTATTACHED state)
  *
  * Warns all drivers bound to registered interfaces (using their pre_reset
  * method), performs the port reset, and then lets the drivers know that
@@ -5842,8 +5842,7 @@ int usb_reset_device(struct usb_device *
 	struct usb_host_config *config = udev->actconfig;
 	struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
 
-	if (udev->state == USB_STATE_NOTATTACHED ||
-			udev->state == USB_STATE_SUSPENDED) {
+	if (udev->state == USB_STATE_NOTATTACHED) {
 		dev_dbg(&udev->dev, "device reset not allowed in state %d\n",
 				udev->state);
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/core/urb.c linux-libre-5.3.17-gnu/drivers/usb/core/urb.c
--- linux-libre-5.3.16-gnu/drivers/usb/core/urb.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/core/urb.c	2019-12-17 14:08:41.000000000 -0500
@@ -45,6 +45,7 @@ void usb_init_urb(struct urb *urb)
 	if (urb) {
 		memset(urb, 0, sizeof(*urb));
 		kref_init(&urb->kref);
+		INIT_LIST_HEAD(&urb->urb_list);
 		INIT_LIST_HEAD(&urb->anchor_list);
 	}
 }
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/dwc3/dwc3-pci.c linux-libre-5.3.17-gnu/drivers/usb/dwc3/dwc3-pci.c
--- linux-libre-5.3.16-gnu/drivers/usb/dwc3/dwc3-pci.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/dwc3/dwc3-pci.c	2019-12-17 14:08:41.000000000 -0500
@@ -29,7 +29,8 @@
 #define PCI_DEVICE_ID_INTEL_BXT_M		0x1aaa
 #define PCI_DEVICE_ID_INTEL_APL			0x5aaa
 #define PCI_DEVICE_ID_INTEL_KBP			0xa2b0
-#define PCI_DEVICE_ID_INTEL_CMLH		0x02ee
+#define PCI_DEVICE_ID_INTEL_CMLLP		0x02ee
+#define PCI_DEVICE_ID_INTEL_CMLH		0x06ee
 #define PCI_DEVICE_ID_INTEL_GLK			0x31aa
 #define PCI_DEVICE_ID_INTEL_CNPLP		0x9dee
 #define PCI_DEVICE_ID_INTEL_CNPH		0xa36e
@@ -308,6 +309,9 @@ static const struct pci_device_id dwc3_p
 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD),
 	  (kernel_ulong_t) &dwc3_pci_mrfld_properties, },
 
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLLP),
+	  (kernel_ulong_t) &dwc3_pci_intel_properties, },
+
 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLH),
 	  (kernel_ulong_t) &dwc3_pci_intel_properties, },
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/dwc3/ep0.c linux-libre-5.3.17-gnu/drivers/usb/dwc3/ep0.c
--- linux-libre-5.3.16-gnu/drivers/usb/dwc3/ep0.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/dwc3/ep0.c	2019-12-17 14:08:41.000000000 -0500
@@ -1117,6 +1117,9 @@ static void dwc3_ep0_xfernotready(struct
 void dwc3_ep0_interrupt(struct dwc3 *dwc,
 		const struct dwc3_event_depevt *event)
 {
+	struct dwc3_ep	*dep = dwc->eps[event->endpoint_number];
+	u8		cmd;
+
 	switch (event->endpoint_event) {
 	case DWC3_DEPEVT_XFERCOMPLETE:
 		dwc3_ep0_xfer_complete(dwc, event);
@@ -1129,7 +1132,12 @@ void dwc3_ep0_interrupt(struct dwc3 *dwc
 	case DWC3_DEPEVT_XFERINPROGRESS:
 	case DWC3_DEPEVT_RXTXFIFOEVT:
 	case DWC3_DEPEVT_STREAMEVT:
+		break;
 	case DWC3_DEPEVT_EPCMDCMPLT:
+		cmd = DEPEVT_PARAMETER_CMD(event->parameters);
+
+		if (cmd == DWC3_DEPCMD_ENDTRANSFER)
+			dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
 		break;
 	}
 }
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/dwc3/gadget.c linux-libre-5.3.17-gnu/drivers/usb/dwc3/gadget.c
--- linux-libre-5.3.16-gnu/drivers/usb/dwc3/gadget.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/dwc3/gadget.c	2019-12-17 14:08:41.000000000 -0500
@@ -2471,7 +2471,7 @@ static int dwc3_gadget_ep_cleanup_comple
 
 	req->request.actual = req->request.length - req->remaining;
 
-	if (!dwc3_gadget_ep_request_completed(req) &&
+	if (!dwc3_gadget_ep_request_completed(req) ||
 			req->num_pending_sgs) {
 		__dwc3_gadget_kick_transfer(dep);
 		goto out;
@@ -2699,6 +2699,9 @@ static void dwc3_stop_active_transfer(st
 	WARN_ON_ONCE(ret);
 	dep->resource_index = 0;
 
+	if (!interrupt)
+		dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
+
 	if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A)
 		udelay(100);
 }
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/gadget/configfs.c linux-libre-5.3.17-gnu/drivers/usb/gadget/configfs.c
--- linux-libre-5.3.16-gnu/drivers/usb/gadget/configfs.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/gadget/configfs.c	2019-12-17 14:08:41.000000000 -0500
@@ -1544,6 +1544,7 @@ static struct config_group *gadgets_make
 	gi->composite.resume = NULL;
 	gi->composite.max_speed = USB_SPEED_SUPER;
 
+	spin_lock_init(&gi->spinlock);
 	mutex_init(&gi->lock);
 	INIT_LIST_HEAD(&gi->string_list);
 	INIT_LIST_HEAD(&gi->available_func);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/gadget/udc/pch_udc.c linux-libre-5.3.17-gnu/drivers/usb/gadget/udc/pch_udc.c
--- linux-libre-5.3.16-gnu/drivers/usb/gadget/udc/pch_udc.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/gadget/udc/pch_udc.c	2019-12-17 14:08:41.000000000 -0500
@@ -1519,7 +1519,6 @@ static void pch_udc_free_dma_chain(struc
 		td = phys_to_virt(addr);
 		addr2 = (dma_addr_t)td->next;
 		dma_pool_free(dev->data_requests, td, addr);
-		td->next = 0x00;
 		addr = addr2;
 	}
 	req->chain_len = 1;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/host/xhci.c linux-libre-5.3.17-gnu/drivers/usb/host/xhci.c
--- linux-libre-5.3.16-gnu/drivers/usb/host/xhci.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/host/xhci.c	2019-12-17 14:08:41.000000000 -0500
@@ -770,7 +770,7 @@ static void xhci_stop(struct usb_hcd *hc
  *
  * This will only ever be called with the main usb_hcd (the USB3 roothub).
  */
-static void xhci_shutdown(struct usb_hcd *hcd)
+void xhci_shutdown(struct usb_hcd *hcd)
 {
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
@@ -789,11 +789,8 @@ static void xhci_shutdown(struct usb_hcd
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
 			"xhci_shutdown completed - status = %x",
 			readl(&xhci->op_regs->status));
-
-	/* Yet another workaround for spurious wakeups at shutdown with HSW */
-	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
-		pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot);
 }
+EXPORT_SYMBOL_GPL(xhci_shutdown);
 
 #ifdef CONFIG_PM
 static void xhci_save_registers(struct xhci_hcd *xhci)
@@ -973,7 +970,7 @@ static bool xhci_pending_portevent(struc
 int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
 {
 	int			rc = 0;
-	unsigned int		delay = XHCI_MAX_HALT_USEC;
+	unsigned int		delay = XHCI_MAX_HALT_USEC * 2;
 	struct usb_hcd		*hcd = xhci_to_hcd(xhci);
 	u32			command;
 	u32			res;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/host/xhci.h linux-libre-5.3.17-gnu/drivers/usb/host/xhci.h
--- linux-libre-5.3.16-gnu/drivers/usb/host/xhci.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/host/xhci.h	2019-12-17 14:08:41.000000000 -0500
@@ -2050,6 +2050,7 @@ int xhci_start(struct xhci_hcd *xhci);
 int xhci_reset(struct xhci_hcd *xhci);
 int xhci_run(struct usb_hcd *hcd);
 int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks);
+void xhci_shutdown(struct usb_hcd *hcd);
 void xhci_init_driver(struct hc_driver *drv,
 		      const struct xhci_driver_overrides *over);
 int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/host/xhci-hub.c linux-libre-5.3.17-gnu/drivers/usb/host/xhci-hub.c
--- linux-libre-5.3.16-gnu/drivers/usb/host/xhci-hub.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/host/xhci-hub.c	2019-12-17 14:08:41.000000000 -0500
@@ -806,7 +806,7 @@ static void xhci_del_comp_mod_timer(stru
 
 static int xhci_handle_usb2_port_link_resume(struct xhci_port *port,
 					     u32 *status, u32 portsc,
-					     unsigned long flags)
+					     unsigned long *flags)
 {
 	struct xhci_bus_state *bus_state;
 	struct xhci_hcd	*xhci;
@@ -860,11 +860,11 @@ static int xhci_handle_usb2_port_link_re
 		xhci_test_and_clear_bit(xhci, port, PORT_PLC);
 		xhci_set_link_state(xhci, port, XDEV_U0);
 
-		spin_unlock_irqrestore(&xhci->lock, flags);
+		spin_unlock_irqrestore(&xhci->lock, *flags);
 		time_left = wait_for_completion_timeout(
 			&bus_state->rexit_done[wIndex],
 			msecs_to_jiffies(XHCI_MAX_REXIT_TIMEOUT_MS));
-		spin_lock_irqsave(&xhci->lock, flags);
+		spin_lock_irqsave(&xhci->lock, *flags);
 
 		if (time_left) {
 			slot_id = xhci_find_slot_id_by_port(hcd, xhci,
@@ -920,11 +920,13 @@ static void xhci_get_usb3_port_status(st
 {
 	struct xhci_bus_state *bus_state;
 	struct xhci_hcd	*xhci;
+	struct usb_hcd *hcd;
 	u32 link_state;
 	u32 portnum;
 
 	bus_state = &port->rhub->bus_state;
 	xhci = hcd_to_xhci(port->rhub->hcd);
+	hcd = port->rhub->hcd;
 	link_state = portsc & PORT_PLS_MASK;
 	portnum = port->hcd_portnum;
 
@@ -952,12 +954,20 @@ static void xhci_get_usb3_port_status(st
 			bus_state->suspended_ports &= ~(1 << portnum);
 	}
 
+	/* remote wake resume signaling complete */
+	if (bus_state->port_remote_wakeup & (1 << portnum) &&
+	    link_state != XDEV_RESUME &&
+	    link_state != XDEV_RECOVERY) {
+		bus_state->port_remote_wakeup &= ~(1 << portnum);
+		usb_hcd_end_port_resume(&hcd->self, portnum);
+	}
+
 	xhci_hub_report_usb3_link_state(xhci, status, portsc);
 	xhci_del_comp_mod_timer(xhci, portsc, portnum);
 }
 
 static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status,
-				      u32 portsc, unsigned long flags)
+				      u32 portsc, unsigned long *flags)
 {
 	struct xhci_bus_state *bus_state;
 	u32 link_state;
@@ -1007,7 +1017,7 @@ static void xhci_get_usb2_port_status(st
 static u32 xhci_get_port_status(struct usb_hcd *hcd,
 		struct xhci_bus_state *bus_state,
 	u16 wIndex, u32 raw_port_status,
-		unsigned long flags)
+		unsigned long *flags)
 	__releases(&xhci->lock)
 	__acquires(&xhci->lock)
 {
@@ -1130,7 +1140,7 @@ int xhci_hub_control(struct usb_hcd *hcd
 		}
 		trace_xhci_get_port_status(wIndex, temp);
 		status = xhci_get_port_status(hcd, bus_state, wIndex, temp,
-					      flags);
+					      &flags);
 		if (status == 0xffffffff)
 			goto error;
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/host/xhci-mem.c linux-libre-5.3.17-gnu/drivers/usb/host/xhci-mem.c
--- linux-libre-5.3.16-gnu/drivers/usb/host/xhci-mem.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/host/xhci-mem.c	2019-12-17 14:08:41.000000000 -0500
@@ -1909,13 +1909,17 @@ no_bw:
 	xhci->usb3_rhub.num_ports = 0;
 	xhci->num_active_eps = 0;
 	kfree(xhci->usb2_rhub.ports);
+	kfree(xhci->usb2_rhub.psi);
 	kfree(xhci->usb3_rhub.ports);
+	kfree(xhci->usb3_rhub.psi);
 	kfree(xhci->hw_ports);
 	kfree(xhci->rh_bw);
 	kfree(xhci->ext_caps);
 
 	xhci->usb2_rhub.ports = NULL;
+	xhci->usb2_rhub.psi = NULL;
 	xhci->usb3_rhub.ports = NULL;
+	xhci->usb3_rhub.psi = NULL;
 	xhci->hw_ports = NULL;
 	xhci->rh_bw = NULL;
 	xhci->ext_caps = NULL;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/host/xhci-pci.c linux-libre-5.3.17-gnu/drivers/usb/host/xhci-pci.c
--- linux-libre-5.3.16-gnu/drivers/usb/host/xhci-pci.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/host/xhci-pci.c	2019-12-17 14:08:41.000000000 -0500
@@ -519,6 +519,18 @@ static int xhci_pci_resume(struct usb_hc
 }
 #endif /* CONFIG_PM */
 
+static void xhci_pci_shutdown(struct usb_hcd *hcd)
+{
+	struct xhci_hcd		*xhci = hcd_to_xhci(hcd);
+	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
+
+	xhci_shutdown(hcd);
+
+	/* Yet another workaround for spurious wakeups at shutdown with HSW */
+	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
+		pci_set_power_state(pdev, PCI_D3hot);
+}
+
 /*-------------------------------------------------------------------------*/
 
 /* PCI driver selection metadata; PCI hotplugging uses this */
@@ -554,6 +566,7 @@ static int __init xhci_pci_init(void)
 #ifdef CONFIG_PM
 	xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend;
 	xhci_pci_hc_driver.pci_resume = xhci_pci_resume;
+	xhci_pci_hc_driver.shutdown = xhci_pci_shutdown;
 #endif
 	return pci_register_driver(&xhci_pci_driver);
 }
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/host/xhci-ring.c linux-libre-5.3.17-gnu/drivers/usb/host/xhci-ring.c
--- linux-libre-5.3.16-gnu/drivers/usb/host/xhci-ring.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/host/xhci-ring.c	2019-12-17 14:08:41.000000000 -0500
@@ -1624,7 +1624,6 @@ static void handle_port_status(struct xh
 		slot_id = xhci_find_slot_id_by_port(hcd, xhci, hcd_portnum + 1);
 		if (slot_id && xhci->devs[slot_id])
 			xhci->devs[slot_id]->flags |= VDEV_PORT_ERROR;
-		bus_state->port_remote_wakeup &= ~(1 << hcd_portnum);
 	}
 
 	if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) {
@@ -1644,6 +1643,7 @@ static void handle_port_status(struct xh
 			 */
 			bus_state->port_remote_wakeup |= 1 << hcd_portnum;
 			xhci_test_and_clear_bit(xhci, port, PORT_PLC);
+			usb_hcd_start_port_resume(&hcd->self, hcd_portnum);
 			xhci_set_link_state(xhci, port, XDEV_U0);
 			/* Need to wait until the next link state change
 			 * indicates the device is actually in U0.
@@ -1684,7 +1684,6 @@ static void handle_port_status(struct xh
 		if (slot_id && xhci->devs[slot_id])
 			xhci_ring_device(xhci, slot_id);
 		if (bus_state->port_remote_wakeup & (1 << hcd_portnum)) {
-			bus_state->port_remote_wakeup &= ~(1 << hcd_portnum);
 			xhci_test_and_clear_bit(xhci, port, PORT_PLC);
 			usb_wakeup_notification(hcd->self.root_hub,
 					hcd_portnum + 1);
@@ -2378,7 +2377,8 @@ static int handle_tx_event(struct xhci_h
 	case COMP_SUCCESS:
 		if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
 			break;
-		if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
+		if (xhci->quirks & XHCI_TRUST_TX_LENGTH ||
+		    ep_ring->last_td_was_short)
 			trb_comp_code = COMP_SHORT_PACKET;
 		else
 			xhci_warn_ratelimited(xhci,
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/host/xhci-tegra.c linux-libre-5.3.17-gnu/drivers/usb/host/xhci-tegra.c
--- linux-libre-5.3.16-gnu/drivers/usb/host/xhci-tegra.c	2019-12-13 11:15:14.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/host/xhci-tegra.c	2019-12-17 16:15:34.000000000 -0500
@@ -755,7 +755,6 @@ static int tegra_xusb_runtime_suspend(st
 {
 	struct tegra_xusb *tegra = dev_get_drvdata(dev);
 
-	tegra_xusb_phy_disable(tegra);
 	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
 	tegra_xusb_clk_disable(tegra);
 
@@ -779,16 +778,8 @@ static int tegra_xusb_runtime_resume(str
 		goto disable_clk;
 	}
 
-	err = tegra_xusb_phy_enable(tegra);
-	if (err < 0) {
-		dev_err(dev, "failed to enable PHYs: %d\n", err);
-		goto disable_regulator;
-	}
-
 	return 0;
 
-disable_regulator:
-	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
 disable_clk:
 	tegra_xusb_clk_disable(tegra);
 	return err;
@@ -1181,6 +1172,12 @@ static int tegra_xusb_probe(struct platf
 	 */
 	platform_set_drvdata(pdev, tegra);
 
+	err = tegra_xusb_phy_enable(tegra);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to enable PHYs: %d\n", err);
+		goto put_hcd;
+	}
+
 	pm_runtime_enable(&pdev->dev);
 	if (pm_runtime_enabled(&pdev->dev))
 		err = pm_runtime_get_sync(&pdev->dev);
@@ -1189,7 +1186,7 @@ static int tegra_xusb_probe(struct platf
 
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to enable device: %d\n", err);
-		goto disable_rpm;
+		goto disable_phy;
 	}
 
 	tegra_xusb_config(tegra, regs);
@@ -1275,9 +1272,11 @@ remove_usb2:
 put_rpm:
 	if (!pm_runtime_status_suspended(&pdev->dev))
 		tegra_xusb_runtime_suspend(&pdev->dev);
-disable_rpm:
-	pm_runtime_disable(&pdev->dev);
+put_hcd:
 	usb_put_hcd(tegra->hcd);
+disable_phy:
+	tegra_xusb_phy_disable(tegra);
+	pm_runtime_disable(&pdev->dev);
 put_powerdomains:
 	if (!of_property_read_bool(pdev->dev.of_node, "power-domains")) {
 		tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC);
@@ -1314,6 +1313,8 @@ static int tegra_xusb_remove(struct plat
 		tegra_xusb_powerdomain_remove(&pdev->dev, tegra);
 	}
 
+	tegra_xusb_phy_disable(tegra);
+
 	tegra_xusb_padctl_put(tegra->padctl);
 
 	return 0;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/misc/adutux.c linux-libre-5.3.17-gnu/drivers/usb/misc/adutux.c
--- linux-libre-5.3.16-gnu/drivers/usb/misc/adutux.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/misc/adutux.c	2019-12-17 14:08:41.000000000 -0500
@@ -669,7 +669,7 @@ static int adu_probe(struct usb_interfac
 	init_waitqueue_head(&dev->read_wait);
 	init_waitqueue_head(&dev->write_wait);
 
-	res = usb_find_common_endpoints_reverse(&interface->altsetting[0],
+	res = usb_find_common_endpoints_reverse(interface->cur_altsetting,
 			NULL, NULL,
 			&dev->interrupt_in_endpoint,
 			&dev->interrupt_out_endpoint);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/misc/idmouse.c linux-libre-5.3.17-gnu/drivers/usb/misc/idmouse.c
--- linux-libre-5.3.16-gnu/drivers/usb/misc/idmouse.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/misc/idmouse.c	2019-12-17 14:08:41.000000000 -0500
@@ -337,7 +337,7 @@ static int idmouse_probe(struct usb_inte
 	int result;
 
 	/* check if we have gotten the data or the hid interface */
-	iface_desc = &interface->altsetting[0];
+	iface_desc = interface->cur_altsetting;
 	if (iface_desc->desc.bInterfaceClass != 0x0A)
 		return -ENODEV;
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/mon/mon_bin.c linux-libre-5.3.17-gnu/drivers/usb/mon/mon_bin.c
--- linux-libre-5.3.16-gnu/drivers/usb/mon/mon_bin.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/mon/mon_bin.c	2019-12-17 14:08:41.000000000 -0500
@@ -1039,12 +1039,18 @@ static long mon_bin_ioctl(struct file *f
 
 		mutex_lock(&rp->fetch_lock);
 		spin_lock_irqsave(&rp->b_lock, flags);
-		mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE);
-		kfree(rp->b_vec);
-		rp->b_vec  = vec;
-		rp->b_size = size;
-		rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0;
-		rp->cnt_lost = 0;
+		if (rp->mmap_active) {
+			mon_free_buff(vec, size/CHUNK_SIZE);
+			kfree(vec);
+			ret = -EBUSY;
+		} else {
+			mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE);
+			kfree(rp->b_vec);
+			rp->b_vec  = vec;
+			rp->b_size = size;
+			rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0;
+			rp->cnt_lost = 0;
+		}
 		spin_unlock_irqrestore(&rp->b_lock, flags);
 		mutex_unlock(&rp->fetch_lock);
 		}
@@ -1216,13 +1222,21 @@ mon_bin_poll(struct file *file, struct p
 static void mon_bin_vma_open(struct vm_area_struct *vma)
 {
 	struct mon_reader_bin *rp = vma->vm_private_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&rp->b_lock, flags);
 	rp->mmap_active++;
+	spin_unlock_irqrestore(&rp->b_lock, flags);
 }
 
 static void mon_bin_vma_close(struct vm_area_struct *vma)
 {
+	unsigned long flags;
+
 	struct mon_reader_bin *rp = vma->vm_private_data;
+	spin_lock_irqsave(&rp->b_lock, flags);
 	rp->mmap_active--;
+	spin_unlock_irqrestore(&rp->b_lock, flags);
 }
 
 /*
@@ -1234,16 +1248,12 @@ static vm_fault_t mon_bin_vma_fault(stru
 	unsigned long offset, chunk_idx;
 	struct page *pageptr;
 
-	mutex_lock(&rp->fetch_lock);
 	offset = vmf->pgoff << PAGE_SHIFT;
-	if (offset >= rp->b_size) {
-		mutex_unlock(&rp->fetch_lock);
+	if (offset >= rp->b_size)
 		return VM_FAULT_SIGBUS;
-	}
 	chunk_idx = offset / CHUNK_SIZE;
 	pageptr = rp->b_vec[chunk_idx].pg;
 	get_page(pageptr);
-	mutex_unlock(&rp->fetch_lock);
 	vmf->page = pageptr;
 	return 0;
 }
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/roles/class.c linux-libre-5.3.17-gnu/drivers/usb/roles/class.c
--- linux-libre-5.3.16-gnu/drivers/usb/roles/class.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/roles/class.c	2019-12-17 14:08:41.000000000 -0500
@@ -144,8 +144,8 @@ EXPORT_SYMBOL_GPL(usb_role_switch_get);
 void usb_role_switch_put(struct usb_role_switch *sw)
 {
 	if (!IS_ERR_OR_NULL(sw)) {
-		put_device(&sw->dev);
 		module_put(sw->dev.parent->driver->owner);
+		put_device(&sw->dev);
 	}
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_put);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/serial/io_edgeport.c linux-libre-5.3.17-gnu/drivers/usb/serial/io_edgeport.c
--- linux-libre-5.3.16-gnu/drivers/usb/serial/io_edgeport.c	2019-12-13 11:15:37.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/serial/io_edgeport.c	2019-12-17 16:15:57.000000000 -0500
@@ -2901,16 +2901,18 @@ static int edge_startup(struct usb_seria
 	response = 0;
 
 	if (edge_serial->is_epic) {
+		struct usb_host_interface *alt;
+
+		alt = serial->interface->cur_altsetting;
+
 		/* EPIC thing, set up our interrupt polling now and our read
 		 * urb, so that the device knows it really is connected. */
 		interrupt_in_found = bulk_in_found = bulk_out_found = false;
-		for (i = 0; i < serial->interface->altsetting[0]
-						.desc.bNumEndpoints; ++i) {
+		for (i = 0; i < alt->desc.bNumEndpoints; ++i) {
 			struct usb_endpoint_descriptor *endpoint;
 			int buffer_size;
 
-			endpoint = &serial->interface->altsetting[0].
-							endpoint[i].desc;
+			endpoint = &alt->endpoint[i].desc;
 			buffer_size = usb_endpoint_maxp(endpoint);
 			if (!interrupt_in_found &&
 			    (usb_endpoint_is_int_in(endpoint))) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/storage/uas.c linux-libre-5.3.17-gnu/drivers/usb/storage/uas.c
--- linux-libre-5.3.16-gnu/drivers/usb/storage/uas.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/storage/uas.c	2019-12-17 14:08:41.000000000 -0500
@@ -825,6 +825,10 @@ static int uas_slave_configure(struct sc
 		sdev->wce_default_on = 1;
 	}
 
+	/* Some disks cannot handle READ_CAPACITY_16 */
+	if (devinfo->flags & US_FL_NO_READ_CAPACITY_16)
+		sdev->no_read_capacity_16 = 1;
+
 	/*
 	 * Some disks return the total number of blocks in response
 	 * to READ CAPACITY rather than the highest block number.
@@ -834,6 +838,12 @@ static int uas_slave_configure(struct sc
 		sdev->fix_capacity = 1;
 
 	/*
+	 * in some cases we have to guess
+	 */
+	if (devinfo->flags & US_FL_CAPACITY_HEURISTICS)
+		sdev->guess_capacity = 1;
+
+	/*
 	 * Some devices don't like MODE SENSE with page=0x3f,
 	 * which is the command used for checking if a device
 	 * is write-protected.  Now that we tell the sd driver
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/usb/typec/class.c linux-libre-5.3.17-gnu/drivers/usb/typec/class.c
--- linux-libre-5.3.16-gnu/drivers/usb/typec/class.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/usb/typec/class.c	2019-12-17 14:08:41.000000000 -0500
@@ -1604,14 +1604,16 @@ struct typec_port *typec_register_port(s
 
 	port->sw = typec_switch_get(&port->dev);
 	if (IS_ERR(port->sw)) {
+		ret = PTR_ERR(port->sw);
 		put_device(&port->dev);
-		return ERR_CAST(port->sw);
+		return ERR_PTR(ret);
 	}
 
 	port->mux = typec_mux_get(&port->dev, NULL);
 	if (IS_ERR(port->mux)) {
+		ret = PTR_ERR(port->mux);
 		put_device(&port->dev);
-		return ERR_CAST(port->mux);
+		return ERR_PTR(ret);
 	}
 
 	ret = device_add(&port->dev);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/video/hdmi.c linux-libre-5.3.17-gnu/drivers/video/hdmi.c
--- linux-libre-5.3.16-gnu/drivers/video/hdmi.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/video/hdmi.c	2019-12-17 14:08:41.000000000 -0500
@@ -1576,12 +1576,12 @@ static int hdmi_avi_infoframe_unpack(str
 	if (ptr[0] & 0x10)
 		frame->active_aspect = ptr[1] & 0xf;
 	if (ptr[0] & 0x8) {
-		frame->top_bar = (ptr[5] << 8) + ptr[6];
-		frame->bottom_bar = (ptr[7] << 8) + ptr[8];
+		frame->top_bar = (ptr[6] << 8) | ptr[5];
+		frame->bottom_bar = (ptr[8] << 8) | ptr[7];
 	}
 	if (ptr[0] & 0x4) {
-		frame->left_bar = (ptr[9] << 8) + ptr[10];
-		frame->right_bar = (ptr[11] << 8) + ptr[12];
+		frame->left_bar = (ptr[10] << 8) | ptr[9];
+		frame->right_bar = (ptr[12] << 8) | ptr[11];
 	}
 	frame->scan_mode = ptr[0] & 0x3;
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/drivers/virtio/virtio_balloon.c linux-libre-5.3.17-gnu/drivers/virtio/virtio_balloon.c
--- linux-libre-5.3.16-gnu/drivers/virtio/virtio_balloon.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/drivers/virtio/virtio_balloon.c	2019-12-17 14:08:41.000000000 -0500
@@ -721,6 +721,17 @@ static int virtballoon_migratepage(struc
 
 	get_page(newpage); /* balloon reference */
 
+	/*
+	  * When we migrate a page to a different zone and adjusted the
+	  * managed page count when inflating, we have to fixup the count of
+	  * both involved zones.
+	  */
+	if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM) &&
+	    page_zone(page) != page_zone(newpage)) {
+		adjust_managed_page_count(page, 1);
+		adjust_managed_page_count(newpage, -1);
+	}
+
 	/* balloon's page migration 1st step  -- inflate "newpage" */
 	spin_lock_irqsave(&vb_dev_info->pages_lock, flags);
 	balloon_page_insert(vb_dev_info, newpage);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/btrfs/delayed-inode.c linux-libre-5.3.17-gnu/fs/btrfs/delayed-inode.c
--- linux-libre-5.3.16-gnu/fs/btrfs/delayed-inode.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/btrfs/delayed-inode.c	2019-12-17 14:08:41.000000000 -0500
@@ -1948,12 +1948,19 @@ void btrfs_kill_all_delayed_nodes(struct
 		}
 
 		inode_id = delayed_nodes[n - 1]->inode_id + 1;
-
-		for (i = 0; i < n; i++)
-			refcount_inc(&delayed_nodes[i]->refs);
+		for (i = 0; i < n; i++) {
+			/*
+			 * Don't increase refs in case the node is dead and
+			 * about to be removed from the tree in the loop below
+			 */
+			if (!refcount_inc_not_zero(&delayed_nodes[i]->refs))
+				delayed_nodes[i] = NULL;
+		}
 		spin_unlock(&root->inode_lock);
 
 		for (i = 0; i < n; i++) {
+			if (!delayed_nodes[i])
+				continue;
 			__btrfs_kill_delayed_node(delayed_nodes[i]);
 			btrfs_release_delayed_node(delayed_nodes[i]);
 		}
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/btrfs/extent_io.c linux-libre-5.3.17-gnu/fs/btrfs/extent_io.c
--- linux-libre-5.3.16-gnu/fs/btrfs/extent_io.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/btrfs/extent_io.c	2019-12-17 14:08:41.000000000 -0500
@@ -4117,7 +4117,7 @@ retry:
 		for (i = 0; i < nr_pages; i++) {
 			struct page *page = pvec.pages[i];
 
-			done_index = page->index;
+			done_index = page->index + 1;
 			/*
 			 * At this point we hold neither the i_pages lock nor
 			 * the page lock: the page may be truncated or
@@ -4152,16 +4152,6 @@ retry:
 
 			ret = __extent_writepage(page, wbc, epd);
 			if (ret < 0) {
-				/*
-				 * done_index is set past this page,
-				 * so media errors will not choke
-				 * background writeout for the entire
-				 * file. This has consequences for
-				 * range_cyclic semantics (ie. it may
-				 * not be suitable for data integrity
-				 * writeout).
-				 */
-				done_index = page->index + 1;
 				done = 1;
 				break;
 			}
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/btrfs/file.c linux-libre-5.3.17-gnu/fs/btrfs/file.c
--- linux-libre-5.3.16-gnu/fs/btrfs/file.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/btrfs/file.c	2019-12-17 14:08:41.000000000 -0500
@@ -1636,6 +1636,7 @@ static noinline ssize_t btrfs_buffered_w
 			break;
 		}
 
+		only_release_metadata = false;
 		sector_offset = pos & (fs_info->sectorsize - 1);
 		reserve_bytes = round_up(write_bytes + sector_offset,
 				fs_info->sectorsize);
@@ -1791,7 +1792,6 @@ again:
 			set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
 				       lockend, EXTENT_NORESERVE, NULL,
 				       NULL, GFP_NOFS);
-			only_release_metadata = false;
 		}
 
 		btrfs_drop_pages(pages, num_pages);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/btrfs/free-space-cache.c linux-libre-5.3.17-gnu/fs/btrfs/free-space-cache.c
--- linux-libre-5.3.16-gnu/fs/btrfs/free-space-cache.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/btrfs/free-space-cache.c	2019-12-17 14:08:41.000000000 -0500
@@ -384,6 +384,12 @@ static int io_ctl_prepare_pages(struct b
 		if (uptodate && !PageUptodate(page)) {
 			btrfs_readpage(NULL, page);
 			lock_page(page);
+			if (page->mapping != inode->i_mapping) {
+				btrfs_err(BTRFS_I(inode)->root->fs_info,
+					  "free space cache page truncated");
+				io_ctl_drop_pages(io_ctl);
+				return -EIO;
+			}
 			if (!PageUptodate(page)) {
 				btrfs_err(BTRFS_I(inode)->root->fs_info,
 					   "error reading free space cache");
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/btrfs/inode.c linux-libre-5.3.17-gnu/fs/btrfs/inode.c
--- linux-libre-5.3.16-gnu/fs/btrfs/inode.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/btrfs/inode.c	2019-12-17 14:08:41.000000000 -0500
@@ -2175,12 +2175,16 @@ again:
 		mapping_set_error(page->mapping, ret);
 		end_extent_writepage(page, ret, page_start, page_end);
 		ClearPageChecked(page);
-		goto out;
+		goto out_reserved;
 	}
 
 	ClearPageChecked(page);
 	set_page_dirty(page);
+out_reserved:
 	btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
+	if (ret)
+		btrfs_delalloc_release_space(inode, data_reserved, page_start,
+					     PAGE_SIZE, true);
 out:
 	unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end,
 			     &cached_state);
@@ -9529,6 +9533,9 @@ static int btrfs_rename_exchange(struct
 		goto out_notrans;
 	}
 
+	if (dest != root)
+		btrfs_record_root_in_trans(trans, dest);
+
 	/*
 	 * We need to find a free sequence number both in the source and
 	 * in the destination directory for the exchange.
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/btrfs/send.c linux-libre-5.3.17-gnu/fs/btrfs/send.c
--- linux-libre-5.3.16-gnu/fs/btrfs/send.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/btrfs/send.c	2019-12-17 14:08:41.000000000 -0500
@@ -25,6 +25,14 @@
 #include "compression.h"
 
 /*
+ * Maximum number of references an extent can have in order for us to attempt to
+ * issue clone operations instead of write operations. This currently exists to
+ * avoid hitting limitations of the backreference walking code (taking a lot of
+ * time and using too much memory for extents with large number of references).
+ */
+#define SEND_MAX_EXTENT_REFS	64
+
+/*
  * A fs_path is a helper to dynamically build path names with unknown size.
  * It reallocates the internal buffer on demand.
  * It allows fast adding of path elements on the right side (normal path) and
@@ -1287,6 +1295,7 @@ static int find_extent_clone(struct send
 	struct clone_root *cur_clone_root;
 	struct btrfs_key found_key;
 	struct btrfs_path *tmp_path;
+	struct btrfs_extent_item *ei;
 	int compressed;
 	u32 i;
 
@@ -1334,7 +1343,6 @@ static int find_extent_clone(struct send
 	ret = extent_from_logical(fs_info, disk_byte, tmp_path,
 				  &found_key, &flags);
 	up_read(&fs_info->commit_root_sem);
-	btrfs_release_path(tmp_path);
 
 	if (ret < 0)
 		goto out;
@@ -1343,6 +1351,21 @@ static int find_extent_clone(struct send
 		goto out;
 	}
 
+	ei = btrfs_item_ptr(tmp_path->nodes[0], tmp_path->slots[0],
+			    struct btrfs_extent_item);
+	/*
+	 * Backreference walking (iterate_extent_inodes() below) is currently
+	 * too expensive when an extent has a large number of references, both
+	 * in time spent and used memory. So for now just fallback to write
+	 * operations instead of clone operations when an extent has more than
+	 * a certain amount of references.
+	 */
+	if (btrfs_extent_refs(tmp_path->nodes[0], ei) > SEND_MAX_EXTENT_REFS) {
+		ret = -ENOENT;
+		goto out;
+	}
+	btrfs_release_path(tmp_path);
+
 	/*
 	 * Setup the clone roots.
 	 */
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/btrfs/volumes.h linux-libre-5.3.17-gnu/fs/btrfs/volumes.h
--- linux-libre-5.3.16-gnu/fs/btrfs/volumes.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/btrfs/volumes.h	2019-12-17 14:08:41.000000000 -0500
@@ -331,7 +331,6 @@ struct btrfs_bio {
 	u64 map_type; /* get from map_lookup->type */
 	bio_end_io_t *end_io;
 	struct bio *orig_bio;
-	unsigned long flags;
 	void *private;
 	atomic_t error;
 	int max_errors;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/ext2/inode.c linux-libre-5.3.17-gnu/fs/ext2/inode.c
--- linux-libre-5.3.16-gnu/fs/ext2/inode.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/ext2/inode.c	2019-12-17 14:08:41.000000000 -0500
@@ -701,10 +701,13 @@ static int ext2_get_blocks(struct inode
 		if (!partial) {
 			count++;
 			mutex_unlock(&ei->truncate_mutex);
-			if (err)
-				goto cleanup;
 			goto got_it;
 		}
+
+		if (err) {
+			mutex_unlock(&ei->truncate_mutex);
+			goto cleanup;
+		}
 	}
 
 	/*
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/ext4/inode.c linux-libre-5.3.17-gnu/fs/ext4/inode.c
--- linux-libre-5.3.16-gnu/fs/ext4/inode.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/ext4/inode.c	2019-12-17 14:08:41.000000000 -0500
@@ -196,7 +196,12 @@ void ext4_evict_inode(struct inode *inod
 {
 	handle_t *handle;
 	int err;
-	int extra_credits = 3;
+	/*
+	 * Credits for final inode cleanup and freeing:
+	 * sb + inode (ext4_orphan_del()), block bitmap, group descriptor
+	 * (xattr block freeing), bitmap, group descriptor (inode freeing)
+	 */
+	int extra_credits = 6;
 	struct ext4_xattr_inode_array *ea_inode_array = NULL;
 
 	trace_ext4_evict_inode(inode);
@@ -252,8 +257,12 @@ void ext4_evict_inode(struct inode *inod
 	if (!IS_NOQUOTA(inode))
 		extra_credits += EXT4_MAXQUOTAS_DEL_BLOCKS(inode->i_sb);
 
+	/*
+	 * Block bitmap, group descriptor, and inode are accounted in both
+	 * ext4_blocks_for_truncate() and extra_credits. So subtract 3.
+	 */
 	handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE,
-				 ext4_blocks_for_truncate(inode)+extra_credits);
+			 ext4_blocks_for_truncate(inode) + extra_credits - 3);
 	if (IS_ERR(handle)) {
 		ext4_std_error(inode->i_sb, PTR_ERR(handle));
 		/*
@@ -5484,11 +5493,15 @@ static void ext4_wait_for_tail_page_comm
 
 	offset = inode->i_size & (PAGE_SIZE - 1);
 	/*
-	 * All buffers in the last page remain valid? Then there's nothing to
-	 * do. We do the check mainly to optimize the common PAGE_SIZE ==
-	 * blocksize case
+	 * If the page is fully truncated, we don't need to wait for any commit
+	 * (and we even should not as __ext4_journalled_invalidatepage() may
+	 * strip all buffers from the page but keep the page dirty which can then
+	 * confuse e.g. concurrent ext4_writepage() seeing dirty page without
+	 * buffers). Also we don't need to wait for any commit if all buffers in
+	 * the page remain valid. This is most beneficial for the common case of
+	 * blocksize == PAGESIZE.
 	 */
-	if (offset > PAGE_SIZE - i_blocksize(inode))
+	if (!offset || offset > (PAGE_SIZE - i_blocksize(inode)))
 		return;
 	while (1) {
 		page = find_lock_page(inode->i_mapping,
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/ext4/namei.c linux-libre-5.3.17-gnu/fs/ext4/namei.c
--- linux-libre-5.3.16-gnu/fs/ext4/namei.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/ext4/namei.c	2019-12-17 14:08:41.000000000 -0500
@@ -3182,18 +3182,17 @@ static int ext4_unlink(struct inode *dir
 	if (IS_DIRSYNC(dir))
 		ext4_handle_sync(handle);
 
-	if (inode->i_nlink == 0) {
-		ext4_warning_inode(inode, "Deleting file '%.*s' with no links",
-				   dentry->d_name.len, dentry->d_name.name);
-		set_nlink(inode, 1);
-	}
 	retval = ext4_delete_entry(handle, dir, de, bh);
 	if (retval)
 		goto end_unlink;
 	dir->i_ctime = dir->i_mtime = current_time(dir);
 	ext4_update_dx_flag(dir);
 	ext4_mark_inode_dirty(handle, dir);
-	drop_nlink(inode);
+	if (inode->i_nlink == 0)
+		ext4_warning_inode(inode, "Deleting file '%.*s' with no links",
+				   dentry->d_name.len, dentry->d_name.name);
+	else
+		drop_nlink(inode);
 	if (!inode->i_nlink)
 		ext4_orphan_add(handle, inode);
 	inode->i_ctime = current_time(inode);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/ocfs2/quota_global.c linux-libre-5.3.17-gnu/fs/ocfs2/quota_global.c
--- linux-libre-5.3.16-gnu/fs/ocfs2/quota_global.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/ocfs2/quota_global.c	2019-12-17 14:08:41.000000000 -0500
@@ -728,7 +728,7 @@ static int ocfs2_release_dquot(struct dq
 
 	mutex_lock(&dquot->dq_lock);
 	/* Check whether we are not racing with some other dqget() */
-	if (atomic_read(&dquot->dq_count) > 1)
+	if (dquot_is_busy(dquot))
 		goto out;
 	/* Running from downconvert thread? Postpone quota processing to wq */
 	if (current == osb->dc_task) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/overlayfs/dir.c linux-libre-5.3.17-gnu/fs/overlayfs/dir.c
--- linux-libre-5.3.16-gnu/fs/overlayfs/dir.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/overlayfs/dir.c	2019-12-17 14:08:41.000000000 -0500
@@ -1170,7 +1170,7 @@ static int ovl_rename(struct inode *oldd
 	if (newdentry == trap)
 		goto out_dput;
 
-	if (WARN_ON(olddentry->d_inode == newdentry->d_inode))
+	if (olddentry->d_inode == newdentry->d_inode)
 		goto out_dput;
 
 	err = 0;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/overlayfs/inode.c linux-libre-5.3.17-gnu/fs/overlayfs/inode.c
--- linux-libre-5.3.16-gnu/fs/overlayfs/inode.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/overlayfs/inode.c	2019-12-17 14:08:41.000000000 -0500
@@ -200,8 +200,14 @@ int ovl_getattr(const struct path *path,
 			if (ovl_test_flag(OVL_INDEX, d_inode(dentry)) ||
 			    (!ovl_verify_lower(dentry->d_sb) &&
 			     (is_dir || lowerstat.nlink == 1))) {
-				stat->ino = lowerstat.ino;
 				lower_layer = ovl_layer_lower(dentry);
+				/*
+				 * Cannot use origin st_dev;st_ino because
+				 * origin inode content may differ from overlay
+				 * inode content.
+				 */
+				if (samefs || lower_layer->fsid)
+					stat->ino = lowerstat.ino;
 			}
 
 			/*
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/overlayfs/namei.c linux-libre-5.3.17-gnu/fs/overlayfs/namei.c
--- linux-libre-5.3.16-gnu/fs/overlayfs/namei.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/overlayfs/namei.c	2019-12-17 14:08:41.000000000 -0500
@@ -325,6 +325,14 @@ int ovl_check_origin_fh(struct ovl_fs *o
 	int i;
 
 	for (i = 0; i < ofs->numlower; i++) {
+		/*
+		 * If lower fs uuid is not unique among lower fs we cannot match
+		 * fh->uuid to layer.
+		 */
+		if (ofs->lower_layers[i].fsid &&
+		    ofs->lower_layers[i].fs->bad_uuid)
+			continue;
+
 		origin = ovl_decode_real_fh(fh, ofs->lower_layers[i].mnt,
 					    connected);
 		if (origin)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/overlayfs/ovl_entry.h linux-libre-5.3.17-gnu/fs/overlayfs/ovl_entry.h
--- linux-libre-5.3.16-gnu/fs/overlayfs/ovl_entry.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/overlayfs/ovl_entry.h	2019-12-17 14:08:41.000000000 -0500
@@ -22,6 +22,8 @@ struct ovl_config {
 struct ovl_sb {
 	struct super_block *sb;
 	dev_t pseudo_dev;
+	/* Unusable (conflicting) uuid */
+	bool bad_uuid;
 };
 
 struct ovl_layer {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/overlayfs/super.c linux-libre-5.3.17-gnu/fs/overlayfs/super.c
--- linux-libre-5.3.16-gnu/fs/overlayfs/super.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/overlayfs/super.c	2019-12-17 14:08:41.000000000 -0500
@@ -1255,7 +1255,7 @@ static bool ovl_lower_uuid_ok(struct ovl
 {
 	unsigned int i;
 
-	if (!ofs->config.nfs_export && !(ofs->config.index && ofs->upper_mnt))
+	if (!ofs->config.nfs_export && !ofs->upper_mnt)
 		return true;
 
 	for (i = 0; i < ofs->numlowerfs; i++) {
@@ -1263,9 +1263,13 @@ static bool ovl_lower_uuid_ok(struct ovl
 		 * We use uuid to associate an overlay lower file handle with a
 		 * lower layer, so we can accept lower fs with null uuid as long
 		 * as all lower layers with null uuid are on the same fs.
+		 * if we detect multiple lower fs with the same uuid, we
+		 * disable lower file handle decoding on all of them.
 		 */
-		if (uuid_equal(&ofs->lower_fs[i].sb->s_uuid, uuid))
+		if (uuid_equal(&ofs->lower_fs[i].sb->s_uuid, uuid)) {
+			ofs->lower_fs[i].bad_uuid = true;
 			return false;
+		}
 	}
 	return true;
 }
@@ -1277,6 +1281,7 @@ static int ovl_get_fsid(struct ovl_fs *o
 	unsigned int i;
 	dev_t dev;
 	int err;
+	bool bad_uuid = false;
 
 	/* fsid 0 is reserved for upper fs even with non upper overlay */
 	if (ofs->upper_mnt && ofs->upper_mnt->mnt_sb == sb)
@@ -1288,11 +1293,15 @@ static int ovl_get_fsid(struct ovl_fs *o
 	}
 
 	if (!ovl_lower_uuid_ok(ofs, &sb->s_uuid)) {
-		ofs->config.index = false;
-		ofs->config.nfs_export = false;
-		pr_warn("overlayfs: %s uuid detected in lower fs '%pd2', falling back to index=off,nfs_export=off.\n",
-			uuid_is_null(&sb->s_uuid) ? "null" : "conflicting",
-			path->dentry);
+		bad_uuid = true;
+		if (ofs->config.index || ofs->config.nfs_export) {
+			ofs->config.index = false;
+			ofs->config.nfs_export = false;
+			pr_warn("overlayfs: %s uuid detected in lower fs '%pd2', falling back to index=off,nfs_export=off.\n",
+				uuid_is_null(&sb->s_uuid) ? "null" :
+							    "conflicting",
+				path->dentry);
+		}
 	}
 
 	err = get_anon_bdev(&dev);
@@ -1303,6 +1312,7 @@ static int ovl_get_fsid(struct ovl_fs *o
 
 	ofs->lower_fs[ofs->numlowerfs].sb = sb;
 	ofs->lower_fs[ofs->numlowerfs].pseudo_dev = dev;
+	ofs->lower_fs[ofs->numlowerfs].bad_uuid = bad_uuid;
 	ofs->numlowerfs++;
 
 	return ofs->numlowerfs;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/quota/dquot.c linux-libre-5.3.17-gnu/fs/quota/dquot.c
--- linux-libre-5.3.16-gnu/fs/quota/dquot.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/quota/dquot.c	2019-12-17 14:08:41.000000000 -0500
@@ -497,7 +497,7 @@ int dquot_release(struct dquot *dquot)
 
 	mutex_lock(&dquot->dq_lock);
 	/* Check whether we are not racing with some other dqget() */
-	if (atomic_read(&dquot->dq_count) > 1)
+	if (dquot_is_busy(dquot))
 		goto out_dqlock;
 	if (dqopt->ops[dquot->dq_id.type]->release_dqblk) {
 		ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot);
@@ -623,7 +623,7 @@ EXPORT_SYMBOL(dquot_scan_active);
 /* Write all dquot structures to quota files */
 int dquot_writeback_dquots(struct super_block *sb, int type)
 {
-	struct list_head *dirty;
+	struct list_head dirty;
 	struct dquot *dquot;
 	struct quota_info *dqopt = sb_dqopt(sb);
 	int cnt;
@@ -637,9 +637,10 @@ int dquot_writeback_dquots(struct super_
 		if (!sb_has_quota_active(sb, cnt))
 			continue;
 		spin_lock(&dq_list_lock);
-		dirty = &dqopt->info[cnt].dqi_dirty_list;
-		while (!list_empty(dirty)) {
-			dquot = list_first_entry(dirty, struct dquot,
+		/* Move list away to avoid livelock. */
+		list_replace_init(&dqopt->info[cnt].dqi_dirty_list, &dirty);
+		while (!list_empty(&dirty)) {
+			dquot = list_first_entry(&dirty, struct dquot,
 						 dq_dirty);
 
 			WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags));
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/reiserfs/inode.c linux-libre-5.3.17-gnu/fs/reiserfs/inode.c
--- linux-libre-5.3.16-gnu/fs/reiserfs/inode.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/reiserfs/inode.c	2019-12-17 14:08:41.000000000 -0500
@@ -2097,6 +2097,15 @@ int reiserfs_new_inode(struct reiserfs_t
 		goto out_inserted_sd;
 	}
 
+	/*
+	 * Mark it private if we're creating the privroot
+	 * or something under it.
+	 */
+	if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) {
+		inode->i_flags |= S_PRIVATE;
+		inode->i_opflags &= ~IOP_XATTR;
+	}
+
 	if (reiserfs_posixacl(inode->i_sb)) {
 		reiserfs_write_unlock(inode->i_sb);
 		retval = reiserfs_inherit_default_acl(th, dir, dentry, inode);
@@ -2111,8 +2120,7 @@ int reiserfs_new_inode(struct reiserfs_t
 		reiserfs_warning(inode->i_sb, "jdm-13090",
 				 "ACLs aren't enabled in the fs, "
 				 "but vfs thinks they are!");
-	} else if (IS_PRIVATE(dir))
-		inode->i_flags |= S_PRIVATE;
+	}
 
 	if (security->name) {
 		reiserfs_write_unlock(inode->i_sb);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/reiserfs/namei.c linux-libre-5.3.17-gnu/fs/reiserfs/namei.c
--- linux-libre-5.3.16-gnu/fs/reiserfs/namei.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/reiserfs/namei.c	2019-12-17 14:08:41.000000000 -0500
@@ -377,10 +377,13 @@ static struct dentry *reiserfs_lookup(st
 
 		/*
 		 * Propagate the private flag so we know we're
-		 * in the priv tree
+		 * in the priv tree.  Also clear IOP_XATTR
+		 * since we don't have xattrs on xattr files.
 		 */
-		if (IS_PRIVATE(dir))
+		if (IS_PRIVATE(dir)) {
 			inode->i_flags |= S_PRIVATE;
+			inode->i_opflags &= ~IOP_XATTR;
+		}
 	}
 	reiserfs_write_unlock(dir->i_sb);
 	if (retval == IO_ERROR) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/reiserfs/reiserfs.h linux-libre-5.3.17-gnu/fs/reiserfs/reiserfs.h
--- linux-libre-5.3.16-gnu/fs/reiserfs/reiserfs.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/reiserfs/reiserfs.h	2019-12-17 14:08:41.000000000 -0500
@@ -1168,6 +1168,8 @@ static inline int bmap_would_wrap(unsign
 	return bmap_nr > ((1LL << 16) - 1);
 }
 
+extern const struct xattr_handler *reiserfs_xattr_handlers[];
+
 /*
  * this says about version of key of all items (but stat data) the
  * object consists of
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/reiserfs/super.c linux-libre-5.3.17-gnu/fs/reiserfs/super.c
--- linux-libre-5.3.16-gnu/fs/reiserfs/super.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/reiserfs/super.c	2019-12-17 14:08:41.000000000 -0500
@@ -2046,6 +2046,8 @@ static int reiserfs_fill_super(struct su
 	if (replay_only(s))
 		goto error_unlocked;
 
+	s->s_xattr = reiserfs_xattr_handlers;
+
 	if (bdev_read_only(s->s_bdev) && !sb_rdonly(s)) {
 		SWARN(silent, s, "clm-7000",
 		      "Detected readonly device, marking FS readonly");
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/reiserfs/xattr_acl.c linux-libre-5.3.17-gnu/fs/reiserfs/xattr_acl.c
--- linux-libre-5.3.16-gnu/fs/reiserfs/xattr_acl.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/reiserfs/xattr_acl.c	2019-12-17 14:08:41.000000000 -0500
@@ -320,10 +320,8 @@ reiserfs_inherit_default_acl(struct reis
 	 * would be useless since permissions are ignored, and a pain because
 	 * it introduces locking cycles
 	 */
-	if (IS_PRIVATE(dir)) {
-		inode->i_flags |= S_PRIVATE;
+	if (IS_PRIVATE(inode))
 		goto apply_umask;
-	}
 
 	err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
 	if (err)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/reiserfs/xattr.c linux-libre-5.3.17-gnu/fs/reiserfs/xattr.c
--- linux-libre-5.3.16-gnu/fs/reiserfs/xattr.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/reiserfs/xattr.c	2019-12-17 14:08:41.000000000 -0500
@@ -122,13 +122,13 @@ static struct dentry *open_xa_root(struc
 	struct dentry *xaroot;
 
 	if (d_really_is_negative(privroot))
-		return ERR_PTR(-ENODATA);
+		return ERR_PTR(-EOPNOTSUPP);
 
 	inode_lock_nested(d_inode(privroot), I_MUTEX_XATTR);
 
 	xaroot = dget(REISERFS_SB(sb)->xattr_root);
 	if (!xaroot)
-		xaroot = ERR_PTR(-ENODATA);
+		xaroot = ERR_PTR(-EOPNOTSUPP);
 	else if (d_really_is_negative(xaroot)) {
 		int err = -ENODATA;
 
@@ -619,6 +619,10 @@ int reiserfs_xattr_set(struct inode *ino
 	int error, error2;
 	size_t jbegin_count = reiserfs_xattr_nblocks(inode, buffer_size);
 
+	/* Check before we start a transaction and then do nothing. */
+	if (!d_really_is_positive(REISERFS_SB(inode->i_sb)->priv_root))
+		return -EOPNOTSUPP;
+
 	if (!(flags & XATTR_REPLACE))
 		jbegin_count += reiserfs_xattr_jcreate_nblocks(inode);
 
@@ -841,8 +845,7 @@ ssize_t reiserfs_listxattr(struct dentry
 	if (d_really_is_negative(dentry))
 		return -EINVAL;
 
-	if (!dentry->d_sb->s_xattr ||
-	    get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
+	if (get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
 		return -EOPNOTSUPP;
 
 	dir = open_xa_dir(d_inode(dentry), XATTR_REPLACE);
@@ -882,6 +885,7 @@ static int create_privroot(struct dentry
 	}
 
 	d_inode(dentry)->i_flags |= S_PRIVATE;
+	d_inode(dentry)->i_opflags &= ~IOP_XATTR;
 	reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
 		      "storage.\n", PRIVROOT_NAME);
 
@@ -895,7 +899,7 @@ static int create_privroot(struct dentry
 #endif
 
 /* Actual operations that are exported to VFS-land */
-static const struct xattr_handler *reiserfs_xattr_handlers[] = {
+const struct xattr_handler *reiserfs_xattr_handlers[] = {
 #ifdef CONFIG_REISERFS_FS_XATTR
 	&reiserfs_xattr_user_handler,
 	&reiserfs_xattr_trusted_handler,
@@ -966,8 +970,10 @@ int reiserfs_lookup_privroot(struct supe
 	if (!IS_ERR(dentry)) {
 		REISERFS_SB(s)->priv_root = dentry;
 		d_set_d_op(dentry, &xattr_lookup_poison_ops);
-		if (d_really_is_positive(dentry))
+		if (d_really_is_positive(dentry)) {
 			d_inode(dentry)->i_flags |= S_PRIVATE;
+			d_inode(dentry)->i_opflags &= ~IOP_XATTR;
+		}
 	} else
 		err = PTR_ERR(dentry);
 	inode_unlock(d_inode(s->s_root));
@@ -996,7 +1002,6 @@ int reiserfs_xattr_init(struct super_blo
 	}
 
 	if (d_really_is_positive(privroot)) {
-		s->s_xattr = reiserfs_xattr_handlers;
 		inode_lock(d_inode(privroot));
 		if (!REISERFS_SB(s)->xattr_root) {
 			struct dentry *dentry;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/fs/splice.c linux-libre-5.3.17-gnu/fs/splice.c
--- linux-libre-5.3.16-gnu/fs/splice.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/fs/splice.c	2019-12-17 14:08:41.000000000 -0500
@@ -945,12 +945,13 @@ ssize_t splice_direct_to_actor(struct fi
 	WARN_ON_ONCE(pipe->nrbufs != 0);
 
 	while (len) {
+		unsigned int pipe_pages;
 		size_t read_len;
 		loff_t pos = sd->pos, prev_pos = pos;
 
 		/* Don't try to read more the pipe has space for. */
-		read_len = min_t(size_t, len,
-				 (pipe->buffers - pipe->nrbufs) << PAGE_SHIFT);
+		pipe_pages = pipe->buffers - pipe->nrbufs;
+		read_len = min(len, (size_t)pipe_pages << PAGE_SHIFT);
 		ret = do_splice_to(in, &pos, pipe, read_len, flags);
 		if (unlikely(ret <= 0))
 			goto out_release;
@@ -1180,8 +1181,15 @@ static long do_splice(struct file *in, l
 
 		pipe_lock(opipe);
 		ret = wait_for_space(opipe, flags);
-		if (!ret)
+		if (!ret) {
+			unsigned int pipe_pages;
+
+			/* Don't try to read more the pipe has space for. */
+			pipe_pages = opipe->buffers - opipe->nrbufs;
+			len = min(len, (size_t)pipe_pages << PAGE_SHIFT);
+
 			ret = do_splice_to(in, &offset, opipe, len, flags);
+		}
 		pipe_unlock(opipe);
 		if (ret > 0)
 			wakeup_pipe_readers(opipe);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/include/acpi/acpi_bus.h linux-libre-5.3.17-gnu/include/acpi/acpi_bus.h
--- linux-libre-5.3.16-gnu/include/acpi/acpi_bus.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/include/acpi/acpi_bus.h	2019-12-17 14:08:41.000000000 -0500
@@ -78,9 +78,6 @@ acpi_evaluate_dsm_typed(acpi_handle hand
 bool acpi_dev_found(const char *hid);
 bool acpi_dev_present(const char *hid, const char *uid, s64 hrv);
 
-struct acpi_device *
-acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv);
-
 #ifdef CONFIG_ACPI
 
 #include <linux/proc_fs.h>
@@ -683,6 +680,9 @@ static inline bool acpi_device_can_power
 		adev->power.states[ACPI_STATE_D3_HOT].flags.explicit_set);
 }
 
+struct acpi_device *
+acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv);
+
 static inline void acpi_dev_put(struct acpi_device *adev)
 {
 	put_device(&adev->dev);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/include/linux/mfd/rk808.h linux-libre-5.3.17-gnu/include/linux/mfd/rk808.h
--- linux-libre-5.3.16-gnu/include/linux/mfd/rk808.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/include/linux/mfd/rk808.h	2019-12-17 14:08:41.000000000 -0500
@@ -610,7 +610,7 @@ enum {
 	RK808_ID = 0x0000,
 	RK809_ID = 0x8090,
 	RK817_ID = 0x8170,
-	RK818_ID = 0x8181,
+	RK818_ID = 0x8180,
 };
 
 struct rk808 {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/include/linux/quotaops.h linux-libre-5.3.17-gnu/include/linux/quotaops.h
--- linux-libre-5.3.16-gnu/include/linux/quotaops.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/include/linux/quotaops.h	2019-12-17 14:08:41.000000000 -0500
@@ -54,6 +54,16 @@ static inline struct dquot *dqgrab(struc
 	atomic_inc(&dquot->dq_count);
 	return dquot;
 }
+
+static inline bool dquot_is_busy(struct dquot *dquot)
+{
+	if (test_bit(DQ_MOD_B, &dquot->dq_flags))
+		return true;
+	if (atomic_read(&dquot->dq_count) > 1)
+		return true;
+	return false;
+}
+
 void dqput(struct dquot *dquot);
 int dquot_scan_active(struct super_block *sb,
 		      int (*fn)(struct dquot *dquot, unsigned long priv),
diff -druNp --no-dereference linux-libre-5.3.16-gnu/include/rdma/ib_verbs.h linux-libre-5.3.17-gnu/include/rdma/ib_verbs.h
--- linux-libre-5.3.16-gnu/include/rdma/ib_verbs.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/include/rdma/ib_verbs.h	2019-12-17 14:08:41.000000000 -0500
@@ -3978,9 +3978,7 @@ static inline void ib_dma_unmap_sg_attrs
  */
 static inline unsigned int ib_dma_max_seg_size(struct ib_device *dev)
 {
-	struct device_dma_parameters *p = dev->dma_device->dma_parms;
-
-	return p ? p->max_segment_size : UINT_MAX;
+	return dma_get_max_seg_size(dev->dma_device);
 }
 
 /**
diff -druNp --no-dereference linux-libre-5.3.16-gnu/include/uapi/linux/cec.h linux-libre-5.3.17-gnu/include/uapi/linux/cec.h
--- linux-libre-5.3.16-gnu/include/uapi/linux/cec.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/include/uapi/linux/cec.h	2019-12-17 14:08:41.000000000 -0500
@@ -768,8 +768,8 @@ struct cec_event {
 #define CEC_MSG_SELECT_DIGITAL_SERVICE			0x93
 #define CEC_MSG_TUNER_DEVICE_STATUS			0x07
 /* Recording Flag Operand (rec_flag) */
-#define CEC_OP_REC_FLAG_USED				0
-#define CEC_OP_REC_FLAG_NOT_USED			1
+#define CEC_OP_REC_FLAG_NOT_USED			0
+#define CEC_OP_REC_FLAG_USED				1
 /* Tuner Display Info Operand (tuner_display_info) */
 #define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL		0
 #define CEC_OP_TUNER_DISPLAY_INFO_NONE			1
diff -druNp --no-dereference linux-libre-5.3.16-gnu/kernel/cgroup/pids.c linux-libre-5.3.17-gnu/kernel/cgroup/pids.c
--- linux-libre-5.3.16-gnu/kernel/cgroup/pids.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/kernel/cgroup/pids.c	2019-12-17 14:08:41.000000000 -0500
@@ -45,7 +45,7 @@ struct pids_cgroup {
 	 * %PIDS_MAX = (%PID_MAX_LIMIT + 1).
 	 */
 	atomic64_t			counter;
-	int64_t				limit;
+	atomic64_t			limit;
 
 	/* Handle for "pids.events" */
 	struct cgroup_file		events_file;
@@ -73,8 +73,8 @@ pids_css_alloc(struct cgroup_subsys_stat
 	if (!pids)
 		return ERR_PTR(-ENOMEM);
 
-	pids->limit = PIDS_MAX;
 	atomic64_set(&pids->counter, 0);
+	atomic64_set(&pids->limit, PIDS_MAX);
 	atomic64_set(&pids->events_limit, 0);
 	return &pids->css;
 }
@@ -146,13 +146,14 @@ static int pids_try_charge(struct pids_c
 
 	for (p = pids; parent_pids(p); p = parent_pids(p)) {
 		int64_t new = atomic64_add_return(num, &p->counter);
+		int64_t limit = atomic64_read(&p->limit);
 
 		/*
 		 * Since new is capped to the maximum number of pid_t, if
 		 * p->limit is %PIDS_MAX then we know that this test will never
 		 * fail.
 		 */
-		if (new > p->limit)
+		if (new > limit)
 			goto revert;
 	}
 
@@ -277,7 +278,7 @@ set_limit:
 	 * Limit updates don't need to be mutex'd, since it isn't
 	 * critical that any racing fork()s follow the new limit.
 	 */
-	pids->limit = limit;
+	atomic64_set(&pids->limit, limit);
 	return nbytes;
 }
 
@@ -285,7 +286,7 @@ static int pids_max_show(struct seq_file
 {
 	struct cgroup_subsys_state *css = seq_css(sf);
 	struct pids_cgroup *pids = css_pids(css);
-	int64_t limit = pids->limit;
+	int64_t limit = atomic64_read(&pids->limit);
 
 	if (limit >= PIDS_MAX)
 		seq_printf(sf, "%s\n", PIDS_MAX_STR);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/kernel/workqueue.c linux-libre-5.3.17-gnu/kernel/workqueue.c
--- linux-libre-5.3.16-gnu/kernel/workqueue.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/kernel/workqueue.c	2019-12-17 14:08:41.000000000 -0500
@@ -2532,8 +2532,14 @@ repeat:
 			 */
 			if (need_to_create_worker(pool)) {
 				spin_lock(&wq_mayday_lock);
-				get_pwq(pwq);
-				list_move_tail(&pwq->mayday_node, &wq->maydays);
+				/*
+				 * Queue iff we aren't racing destruction
+				 * and somebody else hasn't queued it already.
+				 */
+				if (wq->rescuer && list_empty(&pwq->mayday_node)) {
+					get_pwq(pwq);
+					list_add_tail(&pwq->mayday_node, &wq->maydays);
+				}
 				spin_unlock(&wq_mayday_lock);
 			}
 		}
@@ -4316,9 +4322,29 @@ void destroy_workqueue(struct workqueue_
 	struct pool_workqueue *pwq;
 	int node;
 
+	/*
+	 * Remove it from sysfs first so that sanity check failure doesn't
+	 * lead to sysfs name conflicts.
+	 */
+	workqueue_sysfs_unregister(wq);
+
 	/* drain it before proceeding with destruction */
 	drain_workqueue(wq);
 
+	/* kill rescuer, if sanity checks fail, leave it w/o rescuer */
+	if (wq->rescuer) {
+		struct worker *rescuer = wq->rescuer;
+
+		/* this prevents new queueing */
+		spin_lock_irq(&wq_mayday_lock);
+		wq->rescuer = NULL;
+		spin_unlock_irq(&wq_mayday_lock);
+
+		/* rescuer will empty maydays list before exiting */
+		kthread_stop(rescuer->task);
+		kfree(rescuer);
+	}
+
 	/* sanity checks */
 	mutex_lock(&wq->mutex);
 	for_each_pwq(pwq, wq) {
@@ -4350,11 +4376,6 @@ void destroy_workqueue(struct workqueue_
 	list_del_rcu(&wq->list);
 	mutex_unlock(&wq_pool_mutex);
 
-	workqueue_sysfs_unregister(wq);
-
-	if (wq->rescuer)
-		kthread_stop(wq->rescuer->task);
-
 	if (!(wq->flags & WQ_UNBOUND)) {
 		wq_unregister_lockdep(wq);
 		/*
@@ -4629,7 +4650,8 @@ static void show_pwq(struct pool_workque
 	pr_info("  pwq %d:", pool->id);
 	pr_cont_pool_info(pool);
 
-	pr_cont(" active=%d/%d%s\n", pwq->nr_active, pwq->max_active,
+	pr_cont(" active=%d/%d refcnt=%d%s\n",
+		pwq->nr_active, pwq->max_active, pwq->refcnt,
 		!list_empty(&pwq->mayday_node) ? " MAYDAY" : "");
 
 	hash_for_each(pool->busy_hash, bkt, worker, hentry) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/lib/raid6/unroll.awk linux-libre-5.3.17-gnu/lib/raid6/unroll.awk
--- linux-libre-5.3.16-gnu/lib/raid6/unroll.awk	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/lib/raid6/unroll.awk	2019-12-17 14:08:41.000000000 -0500
@@ -13,7 +13,7 @@ BEGIN {
 	for (i = 0; i < rep; ++i) {
 		tmp = $0
 		gsub(/\$\$/, i, tmp)
-		gsub(/\$\#/, n, tmp)
+		gsub(/\$#/, n, tmp)
 		gsub(/\$\*/, "$", tmp)
 		print tmp
 	}
diff -druNp --no-dereference linux-libre-5.3.16-gnu/Makefile linux-libre-5.3.17-gnu/Makefile
--- linux-libre-5.3.16-gnu/Makefile	2019-12-13 10:35:44.000000000 -0500
+++ linux-libre-5.3.17-gnu/Makefile	2019-12-17 15:38:15.000000000 -0500
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 5
 PATCHLEVEL = 3
-SUBLEVEL = 16
+SUBLEVEL = 17
 EXTRAVERSION = -gnu
 NAME = Bobtail Squid
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/mm/shmem.c linux-libre-5.3.17-gnu/mm/shmem.c
--- linux-libre-5.3.16-gnu/mm/shmem.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/mm/shmem.c	2019-12-17 14:08:41.000000000 -0500
@@ -2198,11 +2198,14 @@ static int shmem_mmap(struct file *file,
 			return -EPERM;
 
 		/*
-		 * Since the F_SEAL_FUTURE_WRITE seals allow for a MAP_SHARED
-		 * read-only mapping, take care to not allow mprotect to revert
-		 * protections.
+		 * Since an F_SEAL_FUTURE_WRITE sealed memfd can be mapped as
+		 * MAP_SHARED and read-only, take care to not allow mprotect to
+		 * revert protections on such mappings. Do this only for shared
+		 * mappings. For private mappings, don't need to mask
+		 * VM_MAYWRITE as we still want them to be COW-writable.
 		 */
-		vma->vm_flags &= ~(VM_MAYWRITE);
+		if (vma->vm_flags & VM_SHARED)
+			vma->vm_flags &= ~(VM_MAYWRITE);
 	}
 
 	file_accessed(file);
@@ -2727,7 +2730,7 @@ static long shmem_fallocate(struct file
 		}
 
 		shmem_falloc.waitq = &shmem_falloc_waitq;
-		shmem_falloc.start = unmap_start >> PAGE_SHIFT;
+		shmem_falloc.start = (u64)unmap_start >> PAGE_SHIFT;
 		shmem_falloc.next = (unmap_end + 1) >> PAGE_SHIFT;
 		spin_lock(&inode->i_lock);
 		inode->i_private = &shmem_falloc;
diff -druNp --no-dereference linux-libre-5.3.16-gnu/mm/slab_common.c linux-libre-5.3.17-gnu/mm/slab_common.c
--- linux-libre-5.3.16-gnu/mm/slab_common.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/mm/slab_common.c	2019-12-17 14:08:41.000000000 -0500
@@ -904,6 +904,18 @@ static void flush_memcg_workqueue(struct
 	 * previous workitems on workqueue are processed.
 	 */
 	flush_workqueue(memcg_kmem_cache_wq);
+
+	/*
+	 * If we're racing with children kmem_cache deactivation, it might
+	 * take another rcu grace period to complete their destruction.
+	 * At this moment the corresponding percpu_ref_kill() call should be
+	 * done, but it might take another rcu grace period to complete
+	 * switching to the atomic mode.
+	 * Please, note that we check without grabbing the slab_mutex. It's safe
+	 * because at this moment the children list can't grow.
+	 */
+	if (!list_empty(&s->memcg_params.children))
+		rcu_barrier();
 }
 #else
 static inline int shutdown_memcg_caches(struct kmem_cache *s)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/net/sched/cls_api.c linux-libre-5.3.17-gnu/net/sched/cls_api.c
--- linux-libre-5.3.16-gnu/net/sched/cls_api.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/net/sched/cls_api.c	2019-12-17 14:08:41.000000000 -0500
@@ -2854,13 +2854,19 @@ static int tc_chain_tmplt_add(struct tcf
 			      struct netlink_ext_ack *extack)
 {
 	const struct tcf_proto_ops *ops;
+	char name[IFNAMSIZ];
 	void *tmplt_priv;
 
 	/* If kind is not set, user did not specify template. */
 	if (!tca[TCA_KIND])
 		return 0;
 
-	ops = tcf_proto_lookup_ops(nla_data(tca[TCA_KIND]), true, extack);
+	if (tcf_proto_check_kind(tca[TCA_KIND], name)) {
+		NL_SET_ERR_MSG(extack, "Specified TC chain template name too long");
+		return -EINVAL;
+	}
+
+	ops = tcf_proto_lookup_ops(name, true, extack);
 	if (IS_ERR(ops))
 		return PTR_ERR(ops);
 	if (!ops->tmplt_create || !ops->tmplt_destroy || !ops->tmplt_dump) {
diff -druNp --no-dereference linux-libre-5.3.16-gnu/net/sunrpc/xdr.c linux-libre-5.3.17-gnu/net/sunrpc/xdr.c
--- linux-libre-5.3.16-gnu/net/sunrpc/xdr.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/net/sunrpc/xdr.c	2019-12-17 14:08:41.000000000 -0500
@@ -436,13 +436,12 @@ xdr_shrink_bufhead(struct xdr_buf *buf,
 }
 
 /**
- * xdr_shrink_pagelen
+ * xdr_shrink_pagelen - shrinks buf->pages by up to @len bytes
  * @buf: xdr_buf
  * @len: bytes to remove from buf->pages
  *
- * Shrinks XDR buffer's page array buf->pages by
- * 'len' bytes. The extra data is not lost, but is instead
- * moved into the tail.
+ * The extra data is not lost, but is instead moved into buf->tail.
+ * Returns the actual number of bytes moved.
  */
 static unsigned int
 xdr_shrink_pagelen(struct xdr_buf *buf, size_t len)
@@ -455,8 +454,8 @@ xdr_shrink_pagelen(struct xdr_buf *buf,
 
 	result = 0;
 	tail = buf->tail;
-	BUG_ON (len > pglen);
-
+	if (len > buf->page_len)
+		len = buf-> page_len;
 	tailbuf_len = buf->buflen - buf->head->iov_len - buf->page_len;
 
 	/* Shift the tail first */
diff -druNp --no-dereference linux-libre-5.3.16-gnu/sound/firewire/fireface/ff-pcm.c linux-libre-5.3.17-gnu/sound/firewire/fireface/ff-pcm.c
--- linux-libre-5.3.16-gnu/sound/firewire/fireface/ff-pcm.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/sound/firewire/fireface/ff-pcm.c	2019-12-17 14:08:41.000000000 -0500
@@ -219,7 +219,7 @@ static int pcm_hw_params(struct snd_pcm_
 		mutex_unlock(&ff->mutex);
 	}
 
-	return 0;
+	return err;
 }
 
 static int pcm_hw_free(struct snd_pcm_substream *substream)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/sound/firewire/oxfw/oxfw-pcm.c linux-libre-5.3.17-gnu/sound/firewire/oxfw/oxfw-pcm.c
--- linux-libre-5.3.16-gnu/sound/firewire/oxfw/oxfw-pcm.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/sound/firewire/oxfw/oxfw-pcm.c	2019-12-17 14:08:41.000000000 -0500
@@ -255,7 +255,7 @@ static int pcm_playback_hw_params(struct
 		mutex_unlock(&oxfw->mutex);
 	}
 
-	return 0;
+	return err;
 }
 
 static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
diff -druNp --no-dereference linux-libre-5.3.16-gnu/sound/soc/codecs/rt5645.c linux-libre-5.3.17-gnu/sound/soc/codecs/rt5645.c
--- linux-libre-5.3.16-gnu/sound/soc/codecs/rt5645.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/sound/soc/codecs/rt5645.c	2019-12-17 14:08:41.000000000 -0500
@@ -3270,6 +3270,9 @@ static void rt5645_jack_detect_work(stru
 		snd_soc_jack_report(rt5645->mic_jack,
 				    report, SND_JACK_MICROPHONE);
 		return;
+	case 4:
+		val = snd_soc_component_read32(rt5645->component, RT5645_A_JD_CTRL1) & 0x0020;
+		break;
 	default: /* read rt5645 jd1_1 status */
 		val = snd_soc_component_read32(rt5645->component, RT5645_INT_IRQ_ST) & 0x1000;
 		break;
@@ -3603,7 +3606,7 @@ static const struct rt5645_platform_data
 static const struct rt5645_platform_data buddy_platform_data = {
 	.dmic1_data_pin = RT5645_DMIC_DATA_GPIO5,
 	.dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
-	.jd_mode = 3,
+	.jd_mode = 4,
 	.level_trigger_irq = true,
 };
 
@@ -3999,6 +4002,7 @@ static int rt5645_i2c_probe(struct i2c_c
 					   RT5645_JD1_MODE_1);
 			break;
 		case 3:
+		case 4:
 			regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1,
 					   RT5645_JD1_MODE_MASK,
 					   RT5645_JD1_MODE_2);
diff -druNp --no-dereference linux-libre-5.3.16-gnu/sound/soc/fsl/fsl_audmix.c linux-libre-5.3.17-gnu/sound/soc/fsl/fsl_audmix.c
--- linux-libre-5.3.16-gnu/sound/soc/fsl/fsl_audmix.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/sound/soc/fsl/fsl_audmix.c	2019-12-17 14:08:41.000000000 -0500
@@ -286,6 +286,7 @@ static int fsl_audmix_dai_trigger(struct
 				  struct snd_soc_dai *dai)
 {
 	struct fsl_audmix *priv = snd_soc_dai_get_drvdata(dai);
+	unsigned long lock_flags;
 
 	/* Capture stream shall not be handled */
 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -295,12 +296,16 @@ static int fsl_audmix_dai_trigger(struct
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		spin_lock_irqsave(&priv->lock, lock_flags);
 		priv->tdms |= BIT(dai->driver->id);
+		spin_unlock_irqrestore(&priv->lock, lock_flags);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		spin_lock_irqsave(&priv->lock, lock_flags);
 		priv->tdms &= ~BIT(dai->driver->id);
+		spin_unlock_irqrestore(&priv->lock, lock_flags);
 		break;
 	default:
 		return -EINVAL;
@@ -493,6 +498,7 @@ static int fsl_audmix_probe(struct platf
 		return PTR_ERR(priv->ipg_clk);
 	}
 
+	spin_lock_init(&priv->lock);
 	platform_set_drvdata(pdev, priv);
 	pm_runtime_enable(dev);
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/sound/soc/fsl/fsl_audmix.h linux-libre-5.3.17-gnu/sound/soc/fsl/fsl_audmix.h
--- linux-libre-5.3.16-gnu/sound/soc/fsl/fsl_audmix.h	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/sound/soc/fsl/fsl_audmix.h	2019-12-17 14:08:41.000000000 -0500
@@ -96,6 +96,7 @@ struct fsl_audmix {
 	struct platform_device *pdev;
 	struct regmap *regmap;
 	struct clk *ipg_clk;
+	spinlock_t lock; /* Protect tdms */
 	u8 tdms;
 };
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/sound/soc/soc-jack.c linux-libre-5.3.17-gnu/sound/soc/soc-jack.c
--- linux-libre-5.3.16-gnu/sound/soc/soc-jack.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/sound/soc/soc-jack.c	2019-12-17 14:08:41.000000000 -0500
@@ -100,10 +100,9 @@ void snd_soc_jack_report(struct snd_soc_
 	unsigned int sync = 0;
 	int enable;
 
-	trace_snd_soc_jack_report(jack, mask, status);
-
 	if (!jack)
 		return;
+	trace_snd_soc_jack_report(jack, mask, status);
 
 	dapm = &jack->card->dapm;
 
diff -druNp --no-dereference linux-libre-5.3.16-gnu/tools/testing/selftests/seccomp/seccomp_bpf.c linux-libre-5.3.17-gnu/tools/testing/selftests/seccomp/seccomp_bpf.c
--- linux-libre-5.3.16-gnu/tools/testing/selftests/seccomp/seccomp_bpf.c	2019-12-13 02:49:56.000000000 -0500
+++ linux-libre-5.3.17-gnu/tools/testing/selftests/seccomp/seccomp_bpf.c	2019-12-17 14:08:41.000000000 -0500
@@ -35,6 +35,7 @@
 #include <stdbool.h>
 #include <string.h>
 #include <time.h>
+#include <limits.h>
 #include <linux/elf.h>
 #include <sys/uio.h>
 #include <sys/utsname.h>
@@ -3077,7 +3078,7 @@ static int user_trap_syscall(int nr, uns
 	return seccomp(SECCOMP_SET_MODE_FILTER, flags, &prog);
 }
 
-#define USER_NOTIF_MAGIC 116983961184613L
+#define USER_NOTIF_MAGIC INT_MAX
 TEST(user_notification_basic)
 {
 	pid_t pid;
