diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi linux-libre-5.4.22-gnu/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi
--- linux-libre-5.4.21-gnu/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi	2020-02-24 02:37:04.000000000 -0500
@@ -627,7 +627,7 @@
 	pinctrl-0 = <&pinctrl_usdhc2>;
 	bus-width = <4>;
 	cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
-	wp-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+	disable-wp;
 	vmmc-supply = <&reg_3p3v_sd>;
 	vqmmc-supply = <&reg_3p3v>;
 	no-1-8-v;
@@ -640,7 +640,7 @@
 	pinctrl-0 = <&pinctrl_usdhc3>;
 	bus-width = <4>;
 	cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
-	wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+	disable-wp;
 	vmmc-supply = <&reg_3p3v_sd>;
 	vqmmc-supply = <&reg_3p3v>;
 	no-1-8-v;
@@ -774,6 +774,7 @@
 &usbh1 {
 	vbus-supply = <&reg_5p0v_main>;
 	disable-over-current;
+	maximum-speed = "full-speed";
 	status = "okay";
 };
 
@@ -1055,7 +1056,6 @@
 			MX6QDL_PAD_SD2_DAT1__SD2_DATA1		0x17059
 			MX6QDL_PAD_SD2_DAT2__SD2_DATA2		0x17059
 			MX6QDL_PAD_SD2_DAT3__SD2_DATA3		0x17059
-			MX6QDL_PAD_NANDF_D3__GPIO2_IO03		0x40010040
 			MX6QDL_PAD_NANDF_D2__GPIO2_IO02		0x40010040
 		>;
 	};
@@ -1068,7 +1068,6 @@
 			MX6QDL_PAD_SD3_DAT1__SD3_DATA1		0x17059
 			MX6QDL_PAD_SD3_DAT2__SD3_DATA2		0x17059
 			MX6QDL_PAD_SD3_DAT3__SD3_DATA3		0x17059
-			MX6QDL_PAD_NANDF_D1__GPIO2_IO01		0x40010040
 			MX6QDL_PAD_NANDF_D0__GPIO2_IO00		0x40010040
 
 		>;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm/boot/dts/r8a7779.dtsi linux-libre-5.4.22-gnu/arch/arm/boot/dts/r8a7779.dtsi
--- linux-libre-5.4.21-gnu/arch/arm/boot/dts/r8a7779.dtsi	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm/boot/dts/r8a7779.dtsi	2020-02-24 02:37:04.000000000 -0500
@@ -68,6 +68,14 @@
 		      <0xf0000100 0x100>;
 	};
 
+	timer@f0000200 {
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0xf0000200 0x100>;
+		interrupts = <GIC_PPI 11
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+		clocks = <&cpg_clocks R8A7779_CLK_ZS>;
+	};
+
 	timer@f0000600 {
 		compatible = "arm,cortex-a9-twd-timer";
 		reg = <0xf0000600 0x20>;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm/boot/dts/rk3188-bqedison2qc.dts linux-libre-5.4.22-gnu/arch/arm/boot/dts/rk3188-bqedison2qc.dts
--- linux-libre-5.4.21-gnu/arch/arm/boot/dts/rk3188-bqedison2qc.dts	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm/boot/dts/rk3188-bqedison2qc.dts	2020-02-24 02:37:04.000000000 -0500
@@ -466,9 +466,12 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>;
 	vmmcq-supply = <&vccio_wl>;
+	#address-cells = <1>;
+	#size-cells = <0>;
 	status = "okay";
 
 	brcmf: wifi@1 {
+		reg = <1>;
 		compatible = "brcm,bcm4329-fmac";
 		interrupt-parent = <&gpio3>;
 		interrupts = <RK_PD2 GPIO_ACTIVE_HIGH>;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm/boot/dts/stm32f469-disco.dts linux-libre-5.4.22-gnu/arch/arm/boot/dts/stm32f469-disco.dts
--- linux-libre-5.4.21-gnu/arch/arm/boot/dts/stm32f469-disco.dts	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm/boot/dts/stm32f469-disco.dts	2020-02-24 02:37:04.000000000 -0500
@@ -76,6 +76,13 @@
 		regulator-max-microvolt = <3300000>;
 	};
 
+	vdd_dsi: vdd-dsi {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_dsi";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
 	soc {
 		dma-ranges = <0xc0000000 0x0 0x10000000>;
 	};
@@ -155,6 +162,7 @@
 		compatible = "orisetech,otm8009a";
 		reg = <0>; /* dsi virtual channel (0..3) */
 		reset-gpios = <&gpioh 7 GPIO_ACTIVE_LOW>;
+		power-supply = <&vdd_dsi>;
 		status = "okay";
 
 		port {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm/boot/dts/sun8i-h3.dtsi linux-libre-5.4.22-gnu/arch/arm/boot/dts/sun8i-h3.dtsi
--- linux-libre-5.4.21-gnu/arch/arm/boot/dts/sun8i-h3.dtsi	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm/boot/dts/sun8i-h3.dtsi	2020-02-24 02:37:04.000000000 -0500
@@ -80,7 +80,7 @@
 			#cooling-cells = <2>;
 		};
 
-		cpu@1 {
+		cpu1: cpu@1 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
 			reg = <1>;
@@ -90,7 +90,7 @@
 			#cooling-cells = <2>;
 		};
 
-		cpu@2 {
+		cpu2: cpu@2 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
 			reg = <2>;
@@ -100,7 +100,7 @@
 			#cooling-cells = <2>;
 		};
 
-		cpu@3 {
+		cpu3: cpu@3 {
 			compatible = "arm,cortex-a7";
 			device_type = "cpu";
 			reg = <3>;
@@ -111,6 +111,15 @@
 		};
 	};
 
+	pmu {
+		compatible = "arm,cortex-a7-pmu";
+		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
 	timer {
 		compatible = "arm,armv7-timer";
 		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm/configs/exynos_defconfig linux-libre-5.4.22-gnu/arch/arm/configs/exynos_defconfig
--- linux-libre-5.4.21-gnu/arch/arm/configs/exynos_defconfig	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm/configs/exynos_defconfig	2020-02-24 02:37:04.000000000 -0500
@@ -38,6 +38,7 @@ CONFIG_CRYPTO_SHA256_ARM=m
 CONFIG_CRYPTO_SHA512_ARM=m
 CONFIG_CRYPTO_AES_ARM_BS=m
 CONFIG_CRYPTO_CHACHA20_NEON=m
+CONFIG_KALLSYMS_ALL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
@@ -92,6 +93,7 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 CONFIG_ATA=y
@@ -290,6 +292,7 @@ CONFIG_CROS_EC_SPI=y
 CONFIG_COMMON_CLK_MAX77686=y
 CONFIG_COMMON_CLK_S2MPS11=y
 CONFIG_EXYNOS_IOMMU=y
+CONFIG_PM_DEVFREQ=y
 CONFIG_DEVFREQ_GOV_PERFORMANCE=y
 CONFIG_DEVFREQ_GOV_POWERSAVE=y
 CONFIG_DEVFREQ_GOV_USERSPACE=y
@@ -354,4 +357,7 @@ CONFIG_SOFTLOCKUP_DETECTOR=y
 # CONFIG_DETECT_HUNG_TASK is not set
 CONFIG_PROVE_LOCKING=y
 CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_USER=y
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm/Kconfig linux-libre-5.4.22-gnu/arch/arm/Kconfig
--- linux-libre-5.4.21-gnu/arch/arm/Kconfig	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm/Kconfig	2020-02-24 02:37:04.000000000 -0500
@@ -75,7 +75,7 @@ config ARM
 	select HAVE_CONTEXT_TRACKING
 	select HAVE_COPY_THREAD_TLS
 	select HAVE_C_RECORDMCOUNT
-	select HAVE_DEBUG_KMEMLEAK
+	select HAVE_DEBUG_KMEMLEAK if !XIP_KERNEL
 	select HAVE_DMA_CONTIGUOUS if MMU
 	select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
@@ -1907,7 +1907,7 @@ config XIP_DEFLATED_DATA
 config KEXEC
 	bool "Kexec system call (EXPERIMENTAL)"
 	depends on (!SMP || PM_SLEEP_SMP)
-	depends on !CPU_V7M
+	depends on MMU
 	select KEXEC_CORE
 	help
 	  kexec is a system call that implements the ability to shutdown your
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi linux-libre-5.4.22-gnu/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
--- linux-libre-5.4.21-gnu/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi	2020-02-24 02:37:04.000000000 -0500
@@ -54,21 +54,21 @@
 			enable-method = "psci";
 		};
 
-		cpu@1 {
+		cpu1: cpu@1 {
 			compatible = "arm,cortex-a53";
 			device_type = "cpu";
 			reg = <1>;
 			enable-method = "psci";
 		};
 
-		cpu@2 {
+		cpu2: cpu@2 {
 			compatible = "arm,cortex-a53";
 			device_type = "cpu";
 			reg = <2>;
 			enable-method = "psci";
 		};
 
-		cpu@3 {
+		cpu3: cpu@3 {
 			compatible = "arm,cortex-a53";
 			device_type = "cpu";
 			reg = <3>;
@@ -76,6 +76,16 @@
 		};
 	};
 
+	pmu {
+		compatible = "arm,cortex-a53-pmu",
+			     "arm,armv8-pmuv3";
+		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.4.21-gnu/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi linux-libre-5.4.22-gnu/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
--- linux-libre-5.4.21-gnu/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi	2020-02-24 02:37:04.000000000 -0500
@@ -70,6 +70,16 @@
 		clock-output-names = "ext_osc32k";
 	};
 
+	pmu {
+		compatible = "arm,cortex-a53-pmu",
+			     "arm,armv8-pmuv3";
+		interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 143 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.4.21-gnu/arch/arm64/boot/dts/qcom/msm8996.dtsi linux-libre-5.4.22-gnu/arch/arm64/boot/dts/qcom/msm8996.dtsi
--- linux-libre-5.4.21-gnu/arch/arm64/boot/dts/qcom/msm8996.dtsi	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/boot/dts/qcom/msm8996.dtsi	2020-02-24 02:37:04.000000000 -0500
@@ -1598,6 +1598,8 @@
 				interrupts = <0 138 IRQ_TYPE_LEVEL_HIGH>;
 				phys = <&hsusb_phy2>;
 				phy-names = "usb2-phy";
+				snps,dis_u2_susphy_quirk;
+				snps,dis_enblslpm_quirk;
 			};
 		};
 
@@ -1628,6 +1630,8 @@
 				interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>;
 				phys = <&hsusb_phy1>, <&ssusb_phy_0>;
 				phy-names = "usb2-phy", "usb3-phy";
+				snps,dis_u2_susphy_quirk;
+				snps,dis_enblslpm_quirk;
 			};
 		};
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm64/boot/dts/qcom/sdm845-db845c.dts linux-libre-5.4.22-gnu/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
--- linux-libre-5.4.21-gnu/arch/arm64/boot/dts/qcom/sdm845-db845c.dts	2020-02-19 17:53:50.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/boot/dts/qcom/sdm845-db845c.dts	2020-02-24 06:05:16.000000000 -0500
@@ -517,6 +517,8 @@
 	vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
 	vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
 	vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
+
+	qcom,snoc-host-cap-8bit-quirk;
 };
 
 /* PINCTRL - additions to nodes defined in sdm845.dtsi */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm64/boot/dts/rockchip/px30.dtsi linux-libre-5.4.22-gnu/arch/arm64/boot/dts/rockchip/px30.dtsi
--- linux-libre-5.4.21-gnu/arch/arm64/boot/dts/rockchip/px30.dtsi	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/boot/dts/rockchip/px30.dtsi	2020-02-24 02:37:04.000000000 -0500
@@ -768,7 +768,7 @@
 		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
 			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
-		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		fifo-depth = <0x100>;
 		max-frequency = <150000000>;
 		pinctrl-names = "default";
@@ -783,7 +783,7 @@
 		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
 			 <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
-		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		fifo-depth = <0x100>;
 		max-frequency = <150000000>;
 		pinctrl-names = "default";
@@ -798,7 +798,7 @@
 		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
 			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
-		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		fifo-depth = <0x100>;
 		max-frequency = <150000000>;
 		power-domains = <&power PX30_PD_MMC_NAND>;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts linux-libre-5.4.22-gnu/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
--- linux-libre-5.4.21-gnu/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts	2020-02-24 02:37:04.000000000 -0500
@@ -669,9 +669,12 @@
 	vqmmc-supply = &vcc1v8_s3;	/* IO line */
 	vmmc-supply = &vcc_sdio;	/* card's power */
 
+	#address-cells = <1>;
+	#size-cells = <0>;
 	status = "okay";
 
 	brcmf: wifi@1 {
+		reg = <1>;
 		compatible = "brcm,bcm4329-fmac";
 		interrupt-parent = <&gpio0>;
 		interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi linux-libre-5.4.22-gnu/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
--- linux-libre-5.4.21-gnu/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi	2020-02-24 02:37:04.000000000 -0500
@@ -654,9 +654,12 @@
 	sd-uhs-sdr104;
 	vqmmc-supply = <&vcc1v8_s3>;
 	vmmc-supply = <&vccio_sd>;
+	#address-cells = <1>;
+	#size-cells = <0>;
 	status = "okay";
 
 	brcmf: wifi@1 {
+		reg = <1>;
 		compatible = "brcm,bcm4329-fmac";
 		interrupt-parent = <&gpio0>;
 		interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts linux-libre-5.4.22-gnu/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
--- linux-libre-5.4.21-gnu/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts	2020-02-24 02:37:04.000000000 -0500
@@ -94,33 +94,6 @@
 	};
 };
 
-&gpu_thermal {
-	trips {
-		gpu_warm: gpu_warm {
-			temperature = <55000>;
-			hysteresis = <2000>;
-			type = "active";
-		};
-
-		gpu_hot: gpu_hot {
-			temperature = <65000>;
-			hysteresis = <2000>;
-			type = "active";
-		};
-	};
-	cooling-maps {
-		map1 {
-			trip = <&gpu_warm>;
-			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
-		};
-
-		map2 {
-			trip = <&gpu_hot>;
-			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
-		};
-	};
-};
-
 &pinctrl {
 	ir {
 		ir_rx: ir-rx {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts linux-libre-5.4.22-gnu/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
--- linux-libre-5.4.21-gnu/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts	2020-02-24 02:37:04.000000000 -0500
@@ -648,9 +648,12 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
 	sd-uhs-sdr104;
+	#address-cells = <1>;
+	#size-cells = <0>;
 	status = "okay";
 
 	brcmf: wifi@1 {
+		reg = <1>;
 		compatible = "brcm,bcm4329-fmac";
 		interrupt-parent = <&gpio0>;
 		interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi linux-libre-5.4.22-gnu/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
--- linux-libre-5.4.21-gnu/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi	2020-02-24 02:37:04.000000000 -0500
@@ -43,6 +43,7 @@
 	smmu0: smmu@36600000 {
 		compatible = "arm,smmu-v3";
 		reg = <0x0 0x36600000 0x0 0x100000>;
+		power-domains = <&k3_pds 229 TI_SCI_PD_EXCLUSIVE>;
 		interrupt-parent = <&gic500>;
 		interrupts = <GIC_SPI 772 IRQ_TYPE_EDGE_RISING>,
 			     <GIC_SPI 768 IRQ_TYPE_EDGE_RISING>;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm64/include/asm/alternative.h linux-libre-5.4.22-gnu/arch/arm64/include/asm/alternative.h
--- linux-libre-5.4.21-gnu/arch/arm64/include/asm/alternative.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/include/asm/alternative.h	2020-02-24 02:37:04.000000000 -0500
@@ -35,13 +35,16 @@ void apply_alternatives_module(void *sta
 static inline void apply_alternatives_module(void *start, size_t length) { }
 #endif
 
-#define ALTINSTR_ENTRY(feature,cb)					      \
+#define ALTINSTR_ENTRY(feature)					              \
 	" .word 661b - .\n"				/* label           */ \
-	" .if " __stringify(cb) " == 0\n"				      \
 	" .word 663f - .\n"				/* new instruction */ \
-	" .else\n"							      \
+	" .hword " __stringify(feature) "\n"		/* feature bit     */ \
+	" .byte 662b-661b\n"				/* source len      */ \
+	" .byte 664f-663f\n"				/* replacement len */
+
+#define ALTINSTR_ENTRY_CB(feature, cb)					      \
+	" .word 661b - .\n"				/* label           */ \
 	" .word " __stringify(cb) "- .\n"		/* callback */	      \
-	" .endif\n"							      \
 	" .hword " __stringify(feature) "\n"		/* feature bit     */ \
 	" .byte 662b-661b\n"				/* source len      */ \
 	" .byte 664f-663f\n"				/* replacement len */
@@ -62,15 +65,14 @@ static inline void apply_alternatives_mo
  *
  * Alternatives with callbacks do not generate replacement instructions.
  */
-#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled, cb)	\
+#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled)	\
 	".if "__stringify(cfg_enabled)" == 1\n"				\
 	"661:\n\t"							\
 	oldinstr "\n"							\
 	"662:\n"							\
 	".pushsection .altinstructions,\"a\"\n"				\
-	ALTINSTR_ENTRY(feature,cb)					\
+	ALTINSTR_ENTRY(feature)						\
 	".popsection\n"							\
-	" .if " __stringify(cb) " == 0\n"				\
 	".pushsection .altinstr_replacement, \"a\"\n"			\
 	"663:\n\t"							\
 	newinstr "\n"							\
@@ -78,17 +80,25 @@ static inline void apply_alternatives_mo
 	".popsection\n\t"						\
 	".org	. - (664b-663b) + (662b-661b)\n\t"			\
 	".org	. - (662b-661b) + (664b-663b)\n"			\
-	".else\n\t"							\
+	".endif\n"
+
+#define __ALTERNATIVE_CFG_CB(oldinstr, feature, cfg_enabled, cb)	\
+	".if "__stringify(cfg_enabled)" == 1\n"				\
+	"661:\n\t"							\
+	oldinstr "\n"							\
+	"662:\n"							\
+	".pushsection .altinstructions,\"a\"\n"				\
+	ALTINSTR_ENTRY_CB(feature, cb)					\
+	".popsection\n"							\
 	"663:\n\t"							\
 	"664:\n\t"							\
-	".endif\n"							\
 	".endif\n"
 
 #define _ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg, ...)	\
-	__ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg), 0)
+	__ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg))
 
 #define ALTERNATIVE_CB(oldinstr, cb) \
-	__ALTERNATIVE_CFG(oldinstr, "NOT_AN_INSTRUCTION", ARM64_CB_PATCH, 1, cb)
+	__ALTERNATIVE_CFG_CB(oldinstr, ARM64_CB_PATCH, 1, cb)
 #else
 
 #include <asm/assembler.h>
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm64/include/asm/atomic_lse.h linux-libre-5.4.22-gnu/arch/arm64/include/asm/atomic_lse.h
--- linux-libre-5.4.21-gnu/arch/arm64/include/asm/atomic_lse.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/include/asm/atomic_lse.h	2020-02-24 02:37:04.000000000 -0500
@@ -14,6 +14,7 @@
 static inline void __lse_atomic_##op(int i, atomic_t *v)			\
 {									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 "	" #asm_op "	%w[i], %[v]\n"					\
 	: [i] "+r" (i), [v] "+Q" (v->counter)				\
 	: "r" (v));							\
@@ -30,6 +31,7 @@ ATOMIC_OP(add, stadd)
 static inline int __lse_atomic_fetch_##op##name(int i, atomic_t *v)	\
 {									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 "	" #asm_op #mb "	%w[i], %w[i], %[v]"				\
 	: [i] "+r" (i), [v] "+Q" (v->counter)				\
 	: "r" (v)							\
@@ -58,6 +60,7 @@ static inline int __lse_atomic_add_retur
 	u32 tmp;							\
 									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 	"	ldadd" #mb "	%w[i], %w[tmp], %[v]\n"			\
 	"	add	%w[i], %w[i], %w[tmp]"				\
 	: [i] "+r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)	\
@@ -77,6 +80,7 @@ ATOMIC_OP_ADD_RETURN(        , al, "memo
 static inline void __lse_atomic_and(int i, atomic_t *v)
 {
 	asm volatile(
+	__LSE_PREAMBLE
 	"	mvn	%w[i], %w[i]\n"
 	"	stclr	%w[i], %[v]"
 	: [i] "+&r" (i), [v] "+Q" (v->counter)
@@ -87,6 +91,7 @@ static inline void __lse_atomic_and(int
 static inline int __lse_atomic_fetch_and##name(int i, atomic_t *v)	\
 {									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 	"	mvn	%w[i], %w[i]\n"					\
 	"	ldclr" #mb "	%w[i], %w[i], %[v]"			\
 	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
@@ -106,6 +111,7 @@ ATOMIC_FETCH_OP_AND(        , al, "memor
 static inline void __lse_atomic_sub(int i, atomic_t *v)
 {
 	asm volatile(
+	__LSE_PREAMBLE
 	"	neg	%w[i], %w[i]\n"
 	"	stadd	%w[i], %[v]"
 	: [i] "+&r" (i), [v] "+Q" (v->counter)
@@ -118,6 +124,7 @@ static inline int __lse_atomic_sub_retur
 	u32 tmp;							\
 									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 	"	neg	%w[i], %w[i]\n"					\
 	"	ldadd" #mb "	%w[i], %w[tmp], %[v]\n"			\
 	"	add	%w[i], %w[i], %w[tmp]"				\
@@ -139,6 +146,7 @@ ATOMIC_OP_SUB_RETURN(        , al, "memo
 static inline int __lse_atomic_fetch_sub##name(int i, atomic_t *v)	\
 {									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 	"	neg	%w[i], %w[i]\n"					\
 	"	ldadd" #mb "	%w[i], %w[i], %[v]"			\
 	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
@@ -159,6 +167,7 @@ ATOMIC_FETCH_OP_SUB(        , al, "memor
 static inline void __lse_atomic64_##op(s64 i, atomic64_t *v)		\
 {									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 "	" #asm_op "	%[i], %[v]\n"					\
 	: [i] "+r" (i), [v] "+Q" (v->counter)				\
 	: "r" (v));							\
@@ -175,6 +184,7 @@ ATOMIC64_OP(add, stadd)
 static inline long __lse_atomic64_fetch_##op##name(s64 i, atomic64_t *v)\
 {									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 "	" #asm_op #mb "	%[i], %[i], %[v]"				\
 	: [i] "+r" (i), [v] "+Q" (v->counter)				\
 	: "r" (v)							\
@@ -203,6 +213,7 @@ static inline long __lse_atomic64_add_re
 	unsigned long tmp;						\
 									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 	"	ldadd" #mb "	%[i], %x[tmp], %[v]\n"			\
 	"	add	%[i], %[i], %x[tmp]"				\
 	: [i] "+r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)	\
@@ -222,6 +233,7 @@ ATOMIC64_OP_ADD_RETURN(        , al, "me
 static inline void __lse_atomic64_and(s64 i, atomic64_t *v)
 {
 	asm volatile(
+	__LSE_PREAMBLE
 	"	mvn	%[i], %[i]\n"
 	"	stclr	%[i], %[v]"
 	: [i] "+&r" (i), [v] "+Q" (v->counter)
@@ -232,6 +244,7 @@ static inline void __lse_atomic64_and(s6
 static inline long __lse_atomic64_fetch_and##name(s64 i, atomic64_t *v)	\
 {									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 	"	mvn	%[i], %[i]\n"					\
 	"	ldclr" #mb "	%[i], %[i], %[v]"			\
 	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
@@ -251,6 +264,7 @@ ATOMIC64_FETCH_OP_AND(        , al, "mem
 static inline void __lse_atomic64_sub(s64 i, atomic64_t *v)
 {
 	asm volatile(
+	__LSE_PREAMBLE
 	"	neg	%[i], %[i]\n"
 	"	stadd	%[i], %[v]"
 	: [i] "+&r" (i), [v] "+Q" (v->counter)
@@ -263,6 +277,7 @@ static inline long __lse_atomic64_sub_re
 	unsigned long tmp;						\
 									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 	"	neg	%[i], %[i]\n"					\
 	"	ldadd" #mb "	%[i], %x[tmp], %[v]\n"			\
 	"	add	%[i], %[i], %x[tmp]"				\
@@ -284,6 +299,7 @@ ATOMIC64_OP_SUB_RETURN(        , al, "me
 static inline long __lse_atomic64_fetch_sub##name(s64 i, atomic64_t *v)	\
 {									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 	"	neg	%[i], %[i]\n"					\
 	"	ldadd" #mb "	%[i], %[i], %[v]"			\
 	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
@@ -305,6 +321,7 @@ static inline s64 __lse_atomic64_dec_if_
 	unsigned long tmp;
 
 	asm volatile(
+	__LSE_PREAMBLE
 	"1:	ldr	%x[tmp], %[v]\n"
 	"	subs	%[ret], %x[tmp], #1\n"
 	"	b.lt	2f\n"
@@ -332,6 +349,7 @@ __lse__cmpxchg_case_##name##sz(volatile
 	unsigned long tmp;						\
 									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 	"	mov	%" #w "[tmp], %" #w "[old]\n"			\
 	"	cas" #mb #sfx "\t%" #w "[tmp], %" #w "[new], %[v]\n"	\
 	"	mov	%" #w "[ret], %" #w "[tmp]"			\
@@ -379,6 +397,7 @@ __lse__cmpxchg_double##name(unsigned lon
 	register unsigned long x4 asm ("x4") = (unsigned long)ptr;	\
 									\
 	asm volatile(							\
+	__LSE_PREAMBLE							\
 	"	casp" #mb "\t%[old1], %[old2], %[new1], %[new2], %[v]\n"\
 	"	eor	%[old1], %[old1], %[oldval1]\n"			\
 	"	eor	%[old2], %[old2], %[oldval2]\n"			\
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/arm64/include/asm/lse.h linux-libre-5.4.22-gnu/arch/arm64/include/asm/lse.h
--- linux-libre-5.4.21-gnu/arch/arm64/include/asm/lse.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/arm64/include/asm/lse.h	2020-02-24 02:37:04.000000000 -0500
@@ -6,6 +6,8 @@
 
 #if defined(CONFIG_AS_LSE) && defined(CONFIG_ARM64_LSE_ATOMICS)
 
+#define __LSE_PREAMBLE	".arch armv8-a+lse\n"
+
 #include <linux/compiler_types.h>
 #include <linux/export.h>
 #include <linux/jump_label.h>
@@ -14,8 +16,6 @@
 #include <asm/atomic_lse.h>
 #include <asm/cpucaps.h>
 
-__asm__(".arch_extension	lse");
-
 extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
 extern struct static_key_false arm64_const_caps_ready;
 
@@ -34,7 +34,7 @@ static inline bool system_uses_lse_atomi
 
 /* In-line patching at runtime */
 #define ARM64_LSE_ATOMIC_INSN(llsc, lse)				\
-	ALTERNATIVE(llsc, lse, ARM64_HAS_LSE_ATOMICS)
+	ALTERNATIVE(llsc, __LSE_PREAMBLE lse, ARM64_HAS_LSE_ATOMICS)
 
 #else	/* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/Kconfig linux-libre-5.4.22-gnu/arch/Kconfig
--- linux-libre-5.4.21-gnu/arch/Kconfig	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/Kconfig	2020-02-24 02:37:04.000000000 -0500
@@ -399,6 +399,9 @@ config HAVE_RCU_TABLE_FREE
 config HAVE_MMU_GATHER_PAGE_SIZE
 	bool
 
+config MMU_GATHER_NO_RANGE
+	bool
+
 config HAVE_MMU_GATHER_NO_GATHER
 	bool
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/microblaze/kernel/cpu/cache.c linux-libre-5.4.22-gnu/arch/microblaze/kernel/cpu/cache.c
--- linux-libre-5.4.21-gnu/arch/microblaze/kernel/cpu/cache.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/microblaze/kernel/cpu/cache.c	2020-02-24 02:37:04.000000000 -0500
@@ -92,7 +92,8 @@ static inline void __disable_dcache_noms
 #define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size)	\
 do {									\
 	int align = ~(cache_line_length - 1);				\
-	end = min(start + cache_size, end);				\
+	if (start <  UINT_MAX - cache_size)				\
+		end = min(start + cache_size, end);			\
 	start &= align;							\
 } while (0)
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/mips/loongson64/loongson-3/platform.c linux-libre-5.4.22-gnu/arch/mips/loongson64/loongson-3/platform.c
--- linux-libre-5.4.21-gnu/arch/mips/loongson64/loongson-3/platform.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/mips/loongson64/loongson-3/platform.c	2020-02-24 02:37:04.000000000 -0500
@@ -27,6 +27,9 @@ static int __init loongson3_platform_ini
 			continue;
 
 		pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
+		if (!pdev)
+			return -ENOMEM;
+
 		pdev->name = loongson_sysconf.sensors[i].name;
 		pdev->id = loongson_sysconf.sensors[i].id;
 		pdev->dev.platform_data = &loongson_sysconf.sensors[i];
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/powerpc/kernel/eeh_driver.c linux-libre-5.4.22-gnu/arch/powerpc/kernel/eeh_driver.c
--- linux-libre-5.4.21-gnu/arch/powerpc/kernel/eeh_driver.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/powerpc/kernel/eeh_driver.c	2020-02-24 02:37:04.000000000 -0500
@@ -541,12 +541,6 @@ static void eeh_rmv_device(struct eeh_de
 
 		pci_iov_remove_virtfn(edev->physfn, pdn->vf_index);
 		edev->pdev = NULL;
-
-		/*
-		 * We have to set the VF PE number to invalid one, which is
-		 * required to plug the VF successfully.
-		 */
-		pdn->pe_number = IODA_INVALID_PE;
 #endif
 		if (rmv_data)
 			list_add(&edev->rmv_entry, &rmv_data->removed_vf_list);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/powerpc/kernel/pci_dn.c linux-libre-5.4.22-gnu/arch/powerpc/kernel/pci_dn.c
--- linux-libre-5.4.21-gnu/arch/powerpc/kernel/pci_dn.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/powerpc/kernel/pci_dn.c	2020-02-24 02:37:04.000000000 -0500
@@ -244,9 +244,22 @@ void remove_dev_pci_data(struct pci_dev
 				continue;
 
 #ifdef CONFIG_EEH
-			/* Release EEH device for the VF */
+			/*
+			 * Release EEH state for this VF. The PCI core
+			 * has already torn down the pci_dev for this VF, but
+			 * we're responsible to removing the eeh_dev since it
+			 * has the same lifetime as the pci_dn that spawned it.
+			 */
 			edev = pdn_to_eeh_dev(pdn);
 			if (edev) {
+				/*
+				 * We allocate pci_dn's for the totalvfs count,
+				 * but only only the vfs that were activated
+				 * have a configured PE.
+				 */
+				if (edev->pe)
+					eeh_rmv_from_parent_pe(edev);
+
 				pdn->edev = NULL;
 				kfree(edev);
 			}
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/powerpc/kvm/emulate_loadstore.c linux-libre-5.4.22-gnu/arch/powerpc/kvm/emulate_loadstore.c
--- linux-libre-5.4.21-gnu/arch/powerpc/kvm/emulate_loadstore.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/powerpc/kvm/emulate_loadstore.c	2020-02-24 02:37:04.000000000 -0500
@@ -73,7 +73,6 @@ int kvmppc_emulate_loadstore(struct kvm_
 {
 	struct kvm_run *run = vcpu->run;
 	u32 inst;
-	int ra, rs, rt;
 	enum emulation_result emulated = EMULATE_FAIL;
 	int advance = 1;
 	struct instruction_op op;
@@ -85,10 +84,6 @@ int kvmppc_emulate_loadstore(struct kvm_
 	if (emulated != EMULATE_DONE)
 		return emulated;
 
-	ra = get_ra(inst);
-	rs = get_rs(inst);
-	rt = get_rt(inst);
-
 	vcpu->arch.mmio_vsx_copy_nums = 0;
 	vcpu->arch.mmio_vsx_offset = 0;
 	vcpu->arch.mmio_copy_type = KVMPPC_VSX_COPY_NONE;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/powerpc/Makefile.postlink linux-libre-5.4.22-gnu/arch/powerpc/Makefile.postlink
--- linux-libre-5.4.21-gnu/arch/powerpc/Makefile.postlink	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/powerpc/Makefile.postlink	2020-02-24 02:37:04.000000000 -0500
@@ -17,11 +17,11 @@ quiet_cmd_head_check = CHKHEAD $@
 quiet_cmd_relocs_check = CHKREL  $@
 ifdef CONFIG_PPC_BOOK3S_64
       cmd_relocs_check =						\
-	$(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" ; \
+	$(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@" ; \
 	$(BASH) $(srctree)/arch/powerpc/tools/unrel_branch_check.sh "$(OBJDUMP)" "$@"
 else
       cmd_relocs_check =						\
-	$(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@"
+	$(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@"
 endif
 
 # `@true` prevents complaint when there is nothing to be done
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/powerpc/mm/fault.c linux-libre-5.4.22-gnu/arch/powerpc/mm/fault.c
--- linux-libre-5.4.21-gnu/arch/powerpc/mm/fault.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/powerpc/mm/fault.c	2020-02-24 02:37:04.000000000 -0500
@@ -354,6 +354,9 @@ static void sanity_check_fault(bool is_w
 	 * Userspace trying to access kernel address, we get PROTFAULT for that.
 	 */
 	if (is_user && address >= TASK_SIZE) {
+		if ((long)address == -1)
+			return;
+
 		pr_crit_ratelimited("%s[%d]: User access of kernel address (%lx) - exploit attempt? (uid: %d)\n",
 				   current->comm, current->pid, address,
 				   from_kuid(&init_user_ns, current_uid()));
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/powerpc/platforms/powernv/pci.c linux-libre-5.4.22-gnu/arch/powerpc/platforms/powernv/pci.c
--- linux-libre-5.4.21-gnu/arch/powerpc/platforms/powernv/pci.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/powerpc/platforms/powernv/pci.c	2020-02-24 02:37:04.000000000 -0500
@@ -814,24 +814,6 @@ void pnv_pci_dma_dev_setup(struct pci_de
 {
 	struct pci_controller *hose = pci_bus_to_host(pdev->bus);
 	struct pnv_phb *phb = hose->private_data;
-#ifdef CONFIG_PCI_IOV
-	struct pnv_ioda_pe *pe;
-	struct pci_dn *pdn;
-
-	/* Fix the VF pdn PE number */
-	if (pdev->is_virtfn) {
-		pdn = pci_get_pdn(pdev);
-		WARN_ON(pdn->pe_number != IODA_INVALID_PE);
-		list_for_each_entry(pe, &phb->ioda.pe_list, list) {
-			if (pe->rid == ((pdev->bus->number << 8) |
-			    (pdev->devfn & 0xff))) {
-				pdn->pe_number = pe->pe_number;
-				pe->pdev = pdev;
-				break;
-			}
-		}
-	}
-#endif /* CONFIG_PCI_IOV */
 
 	if (phb && phb->dma_dev_setup)
 		phb->dma_dev_setup(phb, pdev);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/powerpc/platforms/powernv/pci-ioda.c linux-libre-5.4.22-gnu/arch/powerpc/platforms/powernv/pci-ioda.c
--- linux-libre-5.4.21-gnu/arch/powerpc/platforms/powernv/pci-ioda.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/powerpc/platforms/powernv/pci-ioda.c	2020-02-24 02:37:04.000000000 -0500
@@ -1558,6 +1558,10 @@ static void pnv_ioda_setup_vf_PE(struct
 
 	/* Reserve PE for each VF */
 	for (vf_index = 0; vf_index < num_vfs; vf_index++) {
+		int vf_devfn = pci_iov_virtfn_devfn(pdev, vf_index);
+		int vf_bus = pci_iov_virtfn_bus(pdev, vf_index);
+		struct pci_dn *vf_pdn;
+
 		if (pdn->m64_single_mode)
 			pe_num = pdn->pe_num_map[vf_index];
 		else
@@ -1570,13 +1574,11 @@ static void pnv_ioda_setup_vf_PE(struct
 		pe->pbus = NULL;
 		pe->parent_dev = pdev;
 		pe->mve_number = -1;
-		pe->rid = (pci_iov_virtfn_bus(pdev, vf_index) << 8) |
-			   pci_iov_virtfn_devfn(pdev, vf_index);
+		pe->rid = (vf_bus << 8) | vf_devfn;
 
 		pe_info(pe, "VF %04d:%02d:%02d.%d associated with PE#%x\n",
 			hose->global_number, pdev->bus->number,
-			PCI_SLOT(pci_iov_virtfn_devfn(pdev, vf_index)),
-			PCI_FUNC(pci_iov_virtfn_devfn(pdev, vf_index)), pe_num);
+			PCI_SLOT(vf_devfn), PCI_FUNC(vf_devfn), pe_num);
 
 		if (pnv_ioda_configure_pe(phb, pe)) {
 			/* XXX What do we do here ? */
@@ -1590,6 +1592,15 @@ static void pnv_ioda_setup_vf_PE(struct
 		list_add_tail(&pe->list, &phb->ioda.pe_list);
 		mutex_unlock(&phb->ioda.pe_list_mutex);
 
+		/* associate this pe to it's pdn */
+		list_for_each_entry(vf_pdn, &pdn->parent->child_list, list) {
+			if (vf_pdn->busno == vf_bus &&
+			    vf_pdn->devfn == vf_devfn) {
+				vf_pdn->pe_number = pe_num;
+				break;
+			}
+		}
+
 		pnv_pci_ioda2_setup_dma_pe(phb, pe);
 #ifdef CONFIG_IOMMU_API
 		iommu_register_group(&pe->table_group,
@@ -2889,9 +2900,6 @@ static void pnv_pci_ioda_fixup_iov_resou
 	struct pci_dn *pdn;
 	int mul, total_vfs;
 
-	if (!pdev->is_physfn || pci_dev_is_added(pdev))
-		return;
-
 	pdn = pci_get_pdn(pdev);
 	pdn->vfs_expanded = 0;
 	pdn->m64_single_mode = false;
@@ -2966,6 +2974,30 @@ truncate_iov:
 		res->end = res->start - 1;
 	}
 }
+
+static void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev)
+{
+	if (WARN_ON(pci_dev_is_added(pdev)))
+		return;
+
+	if (pdev->is_virtfn) {
+		struct pnv_ioda_pe *pe = pnv_ioda_get_pe(pdev);
+
+		/*
+		 * VF PEs are single-device PEs so their pdev pointer needs to
+		 * be set. The pdev doesn't exist when the PE is allocated (in
+		 * (pcibios_sriov_enable()) so we fix it up here.
+		 */
+		pe->pdev = pdev;
+		WARN_ON(!(pe->flags & PNV_IODA_PE_VF));
+	} else if (pdev->is_physfn) {
+		/*
+		 * For PFs adjust their allocated IOV resources to match what
+		 * the PHB can support using it's M64 BAR table.
+		 */
+		pnv_pci_ioda_fixup_iov_resources(pdev);
+	}
+}
 #endif /* CONFIG_PCI_IOV */
 
 static void pnv_ioda_setup_pe_res(struct pnv_ioda_pe *pe,
@@ -3862,7 +3894,7 @@ static void __init pnv_pci_init_ioda_phb
 	ppc_md.pcibios_default_alignment = pnv_pci_default_alignment;
 
 #ifdef CONFIG_PCI_IOV
-	ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources;
+	ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov;
 	ppc_md.pcibios_iov_resource_alignment = pnv_pci_iov_resource_alignment;
 	ppc_md.pcibios_sriov_enable = pnv_pcibios_sriov_enable;
 	ppc_md.pcibios_sriov_disable = pnv_pcibios_sriov_disable;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/powerpc/platforms/pseries/lparcfg.c linux-libre-5.4.22-gnu/arch/powerpc/platforms/pseries/lparcfg.c
--- linux-libre-5.4.21-gnu/arch/powerpc/platforms/pseries/lparcfg.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/powerpc/platforms/pseries/lparcfg.c	2020-02-24 02:37:04.000000000 -0500
@@ -435,10 +435,10 @@ static void maxmem_data(struct seq_file
 {
 	unsigned long maxmem = 0;
 
-	maxmem += drmem_info->n_lmbs * drmem_info->lmb_size;
+	maxmem += (unsigned long)drmem_info->n_lmbs * drmem_info->lmb_size;
 	maxmem += hugetlb_total_pages() * PAGE_SIZE;
 
-	seq_printf(m, "MaxMem=%ld\n", maxmem);
+	seq_printf(m, "MaxMem=%lu\n", maxmem);
 }
 
 static int pseries_lparcfg_data(struct seq_file *m, void *v)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/powerpc/tools/relocs_check.sh linux-libre-5.4.22-gnu/arch/powerpc/tools/relocs_check.sh
--- linux-libre-5.4.21-gnu/arch/powerpc/tools/relocs_check.sh	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/powerpc/tools/relocs_check.sh	2020-02-24 02:37:04.000000000 -0500
@@ -10,14 +10,21 @@
 # based on relocs_check.pl
 # Copyright © 2009 IBM Corporation
 
-if [ $# -lt 2 ]; then
-	echo "$0 [path to objdump] [path to vmlinux]" 1>&2
+if [ $# -lt 3 ]; then
+	echo "$0 [path to objdump] [path to nm] [path to vmlinux]" 1>&2
 	exit 1
 fi
 
-# Have Kbuild supply the path to objdump so we handle cross compilation.
+# Have Kbuild supply the path to objdump and nm so we handle cross compilation.
 objdump="$1"
-vmlinux="$2"
+nm="$2"
+vmlinux="$3"
+
+# Remove from the bad relocations those that match an undefined weak symbol
+# which will result in an absolute relocation to 0.
+# Weak unresolved symbols are of that form in nm output:
+# "                  w _binary__btf_vmlinux_bin_end"
+undef_weak_symbols=$($nm "$vmlinux" | awk '$1 ~ /w/ { print $2 }')
 
 bad_relocs=$(
 $objdump -R "$vmlinux" |
@@ -26,8 +33,6 @@ $objdump -R "$vmlinux" |
 	# These relocations are okay
 	# On PPC64:
 	#	R_PPC64_RELATIVE, R_PPC64_NONE
-	#	R_PPC64_ADDR64 mach_<name>
-	#	R_PPC64_ADDR64 __crc_<name>
 	# On PPC:
 	#	R_PPC_RELATIVE, R_PPC_ADDR16_HI,
 	#	R_PPC_ADDR16_HA,R_PPC_ADDR16_LO,
@@ -39,8 +44,7 @@ R_PPC_ADDR16_HI
 R_PPC_ADDR16_HA
 R_PPC_RELATIVE
 R_PPC_NONE' |
-	grep -E -v '\<R_PPC64_ADDR64[[:space:]]+mach_' |
-	grep -E -v '\<R_PPC64_ADDR64[[:space:]]+__crc_'
+	([ "$undef_weak_symbols" ] && grep -F -w -v "$undef_weak_symbols" || cat)
 )
 
 if [ -z "$bad_relocs" ]; then
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/s390/include/asm/pci.h linux-libre-5.4.22-gnu/arch/s390/include/asm/pci.h
--- linux-libre-5.4.21-gnu/arch/s390/include/asm/pci.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/s390/include/asm/pci.h	2020-02-24 02:37:04.000000000 -0500
@@ -183,7 +183,7 @@ void zpci_remove_reserved_devices(void);
 /* CLP */
 int clp_scan_pci_devices(void);
 int clp_rescan_pci_devices(void);
-int clp_rescan_pci_devices_simple(void);
+int clp_rescan_pci_devices_simple(u32 *fid);
 int clp_add_pci_device(u32, u32, int);
 int clp_enable_fh(struct zpci_dev *, u8);
 int clp_disable_fh(struct zpci_dev *);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/s390/kernel/mcount.S linux-libre-5.4.22-gnu/arch/s390/kernel/mcount.S
--- linux-libre-5.4.21-gnu/arch/s390/kernel/mcount.S	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/s390/kernel/mcount.S	2020-02-24 02:37:04.000000000 -0500
@@ -26,6 +26,12 @@ ENDPROC(ftrace_stub)
 #define STACK_PTREGS	  (STACK_FRAME_OVERHEAD)
 #define STACK_PTREGS_GPRS (STACK_PTREGS + __PT_GPRS)
 #define STACK_PTREGS_PSW  (STACK_PTREGS + __PT_PSW)
+#ifdef __PACK_STACK
+/* allocate just enough for r14, r15 and backchain */
+#define TRACED_FUNC_FRAME_SIZE	24
+#else
+#define TRACED_FUNC_FRAME_SIZE	STACK_FRAME_OVERHEAD
+#endif
 
 ENTRY(_mcount)
 	BR_EX	%r14
@@ -39,9 +45,16 @@ ENTRY(ftrace_caller)
 #if !(defined(CC_USING_HOTPATCH) || defined(CC_USING_NOP_MCOUNT))
 	aghi	%r0,MCOUNT_RETURN_FIXUP
 #endif
-	aghi	%r15,-STACK_FRAME_SIZE
+	# allocate stack frame for ftrace_caller to contain traced function
+	aghi	%r15,-TRACED_FUNC_FRAME_SIZE
 	stg	%r1,__SF_BACKCHAIN(%r15)
+	stg	%r0,(__SF_GPRS+8*8)(%r15)
+	stg	%r15,(__SF_GPRS+9*8)(%r15)
+	# allocate pt_regs and stack frame for ftrace_trace_function
+	aghi	%r15,-STACK_FRAME_SIZE
 	stg	%r1,(STACK_PTREGS_GPRS+15*8)(%r15)
+	aghi	%r1,-TRACED_FUNC_FRAME_SIZE
+	stg	%r1,__SF_BACKCHAIN(%r15)
 	stg	%r0,(STACK_PTREGS_PSW+8)(%r15)
 	stmg	%r2,%r14,(STACK_PTREGS_GPRS+2*8)(%r15)
 #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/s390/kvm/interrupt.c linux-libre-5.4.22-gnu/arch/s390/kvm/interrupt.c
--- linux-libre-5.4.21-gnu/arch/s390/kvm/interrupt.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/s390/kvm/interrupt.c	2020-02-24 02:37:04.000000000 -0500
@@ -2191,7 +2191,7 @@ static int flic_ais_mode_get_all(struct
 		return -EINVAL;
 
 	if (!test_kvm_facility(kvm, 72))
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 
 	mutex_lock(&fi->ais_lock);
 	ais.simm = fi->simm;
@@ -2500,7 +2500,7 @@ static int modify_ais_mode(struct kvm *k
 	int ret = 0;
 
 	if (!test_kvm_facility(kvm, 72))
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 
 	if (copy_from_user(&req, (void __user *)attr->addr, sizeof(req)))
 		return -EFAULT;
@@ -2580,7 +2580,7 @@ static int flic_ais_mode_set_all(struct
 	struct kvm_s390_ais_all ais;
 
 	if (!test_kvm_facility(kvm, 72))
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 
 	if (copy_from_user(&ais, (void __user *)attr->addr, sizeof(ais)))
 		return -EFAULT;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/s390/Makefile linux-libre-5.4.22-gnu/arch/s390/Makefile
--- linux-libre-5.4.21-gnu/arch/s390/Makefile	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/s390/Makefile	2020-02-24 02:37:04.000000000 -0500
@@ -69,7 +69,7 @@ cflags-y += -Wa,-I$(srctree)/arch/$(ARCH
 #
 cflags-$(CONFIG_FRAME_POINTER) += -fno-optimize-sibling-calls
 
-ifeq ($(call cc-option-yn,-mpacked-stack),y)
+ifeq ($(call cc-option-yn,-mpacked-stack -mbackchain -msoft-float),y)
 cflags-$(CONFIG_PACK_STACK)  += -mpacked-stack -D__PACK_STACK
 aflags-$(CONFIG_PACK_STACK)  += -D__PACK_STACK
 endif
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/s390/pci/pci.c linux-libre-5.4.22-gnu/arch/s390/pci/pci.c
--- linux-libre-5.4.21-gnu/arch/s390/pci/pci.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/s390/pci/pci.c	2020-02-24 02:37:04.000000000 -0500
@@ -934,5 +934,5 @@ subsys_initcall_sync(pci_base_init);
 void zpci_rescan(void)
 {
 	if (zpci_is_enabled())
-		clp_rescan_pci_devices_simple();
+		clp_rescan_pci_devices_simple(NULL);
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/s390/pci/pci_clp.c linux-libre-5.4.22-gnu/arch/s390/pci/pci_clp.c
--- linux-libre-5.4.21-gnu/arch/s390/pci/pci_clp.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/s390/pci/pci_clp.c	2020-02-24 02:37:04.000000000 -0500
@@ -240,12 +240,14 @@ error:
 }
 
 /*
- * Enable/Disable a given PCI function defined by its function handle.
+ * Enable/Disable a given PCI function and update its function handle if
+ * necessary
  */
-static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command)
+static int clp_set_pci_fn(struct zpci_dev *zdev, u8 nr_dma_as, u8 command)
 {
 	struct clp_req_rsp_set_pci *rrb;
 	int rc, retries = 100;
+	u32 fid = zdev->fid;
 
 	rrb = clp_alloc_block(GFP_KERNEL);
 	if (!rrb)
@@ -256,7 +258,7 @@ static int clp_set_pci_fn(u32 *fh, u8 nr
 		rrb->request.hdr.len = sizeof(rrb->request);
 		rrb->request.hdr.cmd = CLP_SET_PCI_FN;
 		rrb->response.hdr.len = sizeof(rrb->response);
-		rrb->request.fh = *fh;
+		rrb->request.fh = zdev->fh;
 		rrb->request.oc = command;
 		rrb->request.ndas = nr_dma_as;
 
@@ -269,12 +271,17 @@ static int clp_set_pci_fn(u32 *fh, u8 nr
 		}
 	} while (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY);
 
-	if (!rc && rrb->response.hdr.rsp == CLP_RC_OK)
-		*fh = rrb->response.fh;
-	else {
+	if (rc || rrb->response.hdr.rsp != CLP_RC_OK) {
 		zpci_err("Set PCI FN:\n");
 		zpci_err_clp(rrb->response.hdr.rsp, rc);
-		rc = -EIO;
+	}
+
+	if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
+		zdev->fh = rrb->response.fh;
+	} else if (!rc && rrb->response.hdr.rsp == CLP_RC_SETPCIFN_ALRDY &&
+			rrb->response.fh == 0) {
+		/* Function is already in desired state - update handle */
+		rc = clp_rescan_pci_devices_simple(&fid);
 	}
 	clp_free_block(rrb);
 	return rc;
@@ -282,18 +289,17 @@ static int clp_set_pci_fn(u32 *fh, u8 nr
 
 int clp_enable_fh(struct zpci_dev *zdev, u8 nr_dma_as)
 {
-	u32 fh = zdev->fh;
 	int rc;
 
-	rc = clp_set_pci_fn(&fh, nr_dma_as, CLP_SET_ENABLE_PCI_FN);
-	zpci_dbg(3, "ena fid:%x, fh:%x, rc:%d\n", zdev->fid, fh, rc);
+	rc = clp_set_pci_fn(zdev, nr_dma_as, CLP_SET_ENABLE_PCI_FN);
+	zpci_dbg(3, "ena fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc);
 	if (rc)
 		goto out;
 
-	zdev->fh = fh;
 	if (zpci_use_mio(zdev)) {
-		rc = clp_set_pci_fn(&fh, nr_dma_as, CLP_SET_ENABLE_MIO);
-		zpci_dbg(3, "ena mio fid:%x, fh:%x, rc:%d\n", zdev->fid, fh, rc);
+		rc = clp_set_pci_fn(zdev, nr_dma_as, CLP_SET_ENABLE_MIO);
+		zpci_dbg(3, "ena mio fid:%x, fh:%x, rc:%d\n",
+				zdev->fid, zdev->fh, rc);
 		if (rc)
 			clp_disable_fh(zdev);
 	}
@@ -309,11 +315,8 @@ int clp_disable_fh(struct zpci_dev *zdev
 	if (!zdev_enabled(zdev))
 		return 0;
 
-	rc = clp_set_pci_fn(&fh, 0, CLP_SET_DISABLE_PCI_FN);
+	rc = clp_set_pci_fn(zdev, 0, CLP_SET_DISABLE_PCI_FN);
 	zpci_dbg(3, "dis fid:%x, fh:%x, rc:%d\n", zdev->fid, fh, rc);
-	if (!rc)
-		zdev->fh = fh;
-
 	return rc;
 }
 
@@ -370,10 +373,14 @@ static void __clp_add(struct clp_fh_list
 static void __clp_update(struct clp_fh_list_entry *entry, void *data)
 {
 	struct zpci_dev *zdev;
+	u32 *fid = data;
 
 	if (!entry->vendor_id)
 		return;
 
+	if (fid && *fid != entry->fid)
+		return;
+
 	zdev = get_zdev_by_fid(entry->fid);
 	if (!zdev)
 		return;
@@ -413,7 +420,10 @@ int clp_rescan_pci_devices(void)
 	return rc;
 }
 
-int clp_rescan_pci_devices_simple(void)
+/* Rescan PCI functions and refresh function handles. If fid is non-NULL only
+ * refresh the handle of the function matching @fid
+ */
+int clp_rescan_pci_devices_simple(u32 *fid)
 {
 	struct clp_req_rsp_list_pci *rrb;
 	int rc;
@@ -422,7 +432,7 @@ int clp_rescan_pci_devices_simple(void)
 	if (!rrb)
 		return -ENOMEM;
 
-	rc = clp_list_pci(rrb, NULL, __clp_update);
+	rc = clp_list_pci(rrb, fid, __clp_update);
 
 	clp_free_block(rrb);
 	return rc;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/s390/pci/pci_sysfs.c linux-libre-5.4.22-gnu/arch/s390/pci/pci_sysfs.c
--- linux-libre-5.4.21-gnu/arch/s390/pci/pci_sysfs.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/s390/pci/pci_sysfs.c	2020-02-24 02:37:04.000000000 -0500
@@ -13,6 +13,8 @@
 #include <linux/stat.h>
 #include <linux/pci.h>
 
+#include "../../../drivers/pci/pci.h"
+
 #include <asm/sclp.h>
 
 #define zpci_attr(name, fmt, member)					\
@@ -49,31 +51,50 @@ static DEVICE_ATTR_RO(mio_enabled);
 static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
 			     const char *buf, size_t count)
 {
+	struct kernfs_node *kn;
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct zpci_dev *zdev = to_zpci(pdev);
-	int ret;
+	int ret = 0;
 
-	if (!device_remove_file_self(dev, attr))
-		return count;
+	/* Can't use device_remove_self() here as that would lead us to lock
+	 * the pci_rescan_remove_lock while holding the device' kernfs lock.
+	 * This would create a possible deadlock with disable_slot() which is
+	 * not directly protected by the device' kernfs lock but takes it
+	 * during the device removal which happens under
+	 * pci_rescan_remove_lock.
+	 *
+	 * This is analogous to sdev_store_delete() in
+	 * drivers/scsi/scsi_sysfs.c
+	 */
+	kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
+	WARN_ON_ONCE(!kn);
+	/* device_remove_file() serializes concurrent calls ignoring all but
+	 * the first
+	 */
+	device_remove_file(dev, attr);
 
+	/* A concurrent call to recover_store() may slip between
+	 * sysfs_break_active_protection() and the sysfs file removal.
+	 * Once it unblocks from pci_lock_rescan_remove() the original pdev
+	 * will already be removed.
+	 */
 	pci_lock_rescan_remove();
-	pci_stop_and_remove_bus_device(pdev);
-	ret = zpci_disable_device(zdev);
-	if (ret)
-		goto error;
-
-	ret = zpci_enable_device(zdev);
-	if (ret)
-		goto error;
-
-	pci_rescan_bus(zdev->bus);
-	pci_unlock_rescan_remove();
-
-	return count;
+	if (pci_dev_is_added(pdev)) {
+		pci_stop_and_remove_bus_device(pdev);
+		ret = zpci_disable_device(zdev);
+		if (ret)
+			goto out;
 
-error:
+		ret = zpci_enable_device(zdev);
+		if (ret)
+			goto out;
+		pci_rescan_bus(zdev->bus);
+	}
+out:
 	pci_unlock_rescan_remove();
-	return ret;
+	if (kn)
+		sysfs_unbreak_active_protection(kn);
+	return ret ? ret : count;
 }
 static DEVICE_ATTR_WO(recover);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/sh/include/cpu-sh2a/cpu/sh7269.h linux-libre-5.4.22-gnu/arch/sh/include/cpu-sh2a/cpu/sh7269.h
--- linux-libre-5.4.21-gnu/arch/sh/include/cpu-sh2a/cpu/sh7269.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/sh/include/cpu-sh2a/cpu/sh7269.h	2020-02-24 02:37:04.000000000 -0500
@@ -78,8 +78,15 @@ enum {
 	GPIO_FN_WDTOVF,
 
 	/* CAN */
-	GPIO_FN_CTX1, GPIO_FN_CRX1, GPIO_FN_CTX0, GPIO_FN_CTX0_CTX1,
-	GPIO_FN_CRX0, GPIO_FN_CRX0_CRX1, GPIO_FN_CRX0_CRX1_CRX2,
+	GPIO_FN_CTX2, GPIO_FN_CRX2,
+	GPIO_FN_CTX1, GPIO_FN_CRX1,
+	GPIO_FN_CTX0, GPIO_FN_CRX0,
+	GPIO_FN_CTX0_CTX1, GPIO_FN_CRX0_CRX1,
+	GPIO_FN_CTX0_CTX1_CTX2, GPIO_FN_CRX0_CRX1_CRX2,
+	GPIO_FN_CTX2_PJ21, GPIO_FN_CRX2_PJ20,
+	GPIO_FN_CTX1_PJ23, GPIO_FN_CRX1_PJ22,
+	GPIO_FN_CTX0_CTX1_PJ23, GPIO_FN_CRX0_CRX1_PJ22,
+	GPIO_FN_CTX0_CTX1_CTX2_PJ21, GPIO_FN_CRX0_CRX1_CRX2_PJ20,
 
 	/* DMAC */
 	GPIO_FN_TEND0, GPIO_FN_DACK0, GPIO_FN_DREQ0,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/sparc/kernel/vmlinux.lds.S linux-libre-5.4.22-gnu/arch/sparc/kernel/vmlinux.lds.S
--- linux-libre-5.4.21-gnu/arch/sparc/kernel/vmlinux.lds.S	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/sparc/kernel/vmlinux.lds.S	2020-02-24 02:37:04.000000000 -0500
@@ -172,12 +172,14 @@ SECTIONS
 	}
 	PERCPU_SECTION(SMP_CACHE_BYTES)
 
-#ifdef CONFIG_JUMP_LABEL
 	. = ALIGN(PAGE_SIZE);
 	.exit.text : {
 		EXIT_TEXT
 	}
-#endif
+
+	.exit.data : {
+		EXIT_DATA
+	}
 
 	. = ALIGN(PAGE_SIZE);
 	__init_end = .;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/x86/entry/vdso/vdso32-setup.c linux-libre-5.4.22-gnu/arch/x86/entry/vdso/vdso32-setup.c
--- linux-libre-5.4.21-gnu/arch/x86/entry/vdso/vdso32-setup.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/x86/entry/vdso/vdso32-setup.c	2020-02-24 02:37:04.000000000 -0500
@@ -11,6 +11,7 @@
 #include <linux/smp.h>
 #include <linux/kernel.h>
 #include <linux/mm_types.h>
+#include <linux/elf.h>
 
 #include <asm/processor.h>
 #include <asm/vdso.h>
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/x86/events/amd/core.c linux-libre-5.4.22-gnu/arch/x86/events/amd/core.c
--- linux-libre-5.4.21-gnu/arch/x86/events/amd/core.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/x86/events/amd/core.c	2020-02-24 02:37:04.000000000 -0500
@@ -302,6 +302,25 @@ static inline int amd_pmu_addr_offset(in
 	return offset;
 }
 
+/*
+ * AMD64 events are detected based on their event codes.
+ */
+static inline unsigned int amd_get_event_code(struct hw_perf_event *hwc)
+{
+	return ((hwc->config >> 24) & 0x0f00) | (hwc->config & 0x00ff);
+}
+
+static inline bool amd_is_pair_event_code(struct hw_perf_event *hwc)
+{
+	if (!(x86_pmu.flags & PMU_FL_PAIR))
+		return false;
+
+	switch (amd_get_event_code(hwc)) {
+	case 0x003:	return true;	/* Retired SSE/AVX FLOPs */
+	default:	return false;
+	}
+}
+
 static int amd_core_hw_config(struct perf_event *event)
 {
 	if (event->attr.exclude_host && event->attr.exclude_guest)
@@ -320,14 +339,6 @@ static int amd_core_hw_config(struct per
 	return 0;
 }
 
-/*
- * AMD64 events are detected based on their event codes.
- */
-static inline unsigned int amd_get_event_code(struct hw_perf_event *hwc)
-{
-	return ((hwc->config >> 24) & 0x0f00) | (hwc->config & 0x00ff);
-}
-
 static inline int amd_is_nb_event(struct hw_perf_event *hwc)
 {
 	return (hwc->config & 0xe0) == 0xe0;
@@ -865,6 +876,20 @@ amd_get_event_constraints_f15h(struct cp
 	}
 }
 
+static struct event_constraint pair_constraint;
+
+static struct event_constraint *
+amd_get_event_constraints_f17h(struct cpu_hw_events *cpuc, int idx,
+			       struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (amd_is_pair_event_code(hwc))
+		return &pair_constraint;
+
+	return &unconstrained;
+}
+
 static ssize_t amd_event_sysfs_show(char *page, u64 config)
 {
 	u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT) |
@@ -908,33 +933,15 @@ static __initconst const struct x86_pmu
 
 static int __init amd_core_pmu_init(void)
 {
+	u64 even_ctr_mask = 0ULL;
+	int i;
+
 	if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE))
 		return 0;
 
-	/* Avoid calulating the value each time in the NMI handler */
+	/* Avoid calculating the value each time in the NMI handler */
 	perf_nmi_window = msecs_to_jiffies(100);
 
-	switch (boot_cpu_data.x86) {
-	case 0x15:
-		pr_cont("Fam15h ");
-		x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
-		break;
-	case 0x17:
-		pr_cont("Fam17h ");
-		/*
-		 * In family 17h, there are no event constraints in the PMC hardware.
-		 * We fallback to using default amd_get_event_constraints.
-		 */
-		break;
-	case 0x18:
-		pr_cont("Fam18h ");
-		/* Using default amd_get_event_constraints. */
-		break;
-	default:
-		pr_err("core perfctr but no constraints; unknown hardware!\n");
-		return -ENODEV;
-	}
-
 	/*
 	 * If core performance counter extensions exists, we must use
 	 * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also
@@ -949,6 +956,30 @@ static int __init amd_core_pmu_init(void
 	 */
 	x86_pmu.amd_nb_constraints = 0;
 
+	if (boot_cpu_data.x86 == 0x15) {
+		pr_cont("Fam15h ");
+		x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
+	}
+	if (boot_cpu_data.x86 >= 0x17) {
+		pr_cont("Fam17h+ ");
+		/*
+		 * Family 17h and compatibles have constraints for Large
+		 * Increment per Cycle events: they may only be assigned an
+		 * even numbered counter that has a consecutive adjacent odd
+		 * numbered counter following it.
+		 */
+		for (i = 0; i < x86_pmu.num_counters - 1; i += 2)
+			even_ctr_mask |= 1 << i;
+
+		pair_constraint = (struct event_constraint)
+				    __EVENT_CONSTRAINT(0, even_ctr_mask, 0,
+				    x86_pmu.num_counters / 2, 0,
+				    PERF_X86_EVENT_PAIR);
+
+		x86_pmu.get_event_constraints = amd_get_event_constraints_f17h;
+		x86_pmu.flags |= PMU_FL_PAIR;
+	}
+
 	pr_cont("core perfctr, ");
 	return 0;
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/x86/events/perf_event.h linux-libre-5.4.22-gnu/arch/x86/events/perf_event.h
--- linux-libre-5.4.21-gnu/arch/x86/events/perf_event.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/x86/events/perf_event.h	2020-02-24 02:37:04.000000000 -0500
@@ -77,6 +77,7 @@ static inline bool constraint_match(stru
 #define PERF_X86_EVENT_AUTO_RELOAD	0x0200 /* use PEBS auto-reload */
 #define PERF_X86_EVENT_LARGE_PEBS	0x0400 /* use large PEBS */
 #define PERF_X86_EVENT_PEBS_VIA_PT	0x0800 /* use PT buffer for PEBS */
+#define PERF_X86_EVENT_PAIR		0x1000 /* Large Increment per Cycle */
 
 struct amd_nb {
 	int nb_id;  /* NorthBridge id */
@@ -735,6 +736,7 @@ do {									\
 #define PMU_FL_EXCL_ENABLED	0x8 /* exclusive counter active */
 #define PMU_FL_PEBS_ALL		0x10 /* all events are valid PEBS events */
 #define PMU_FL_TFA		0x20 /* deal with TSX force abort */
+#define PMU_FL_PAIR		0x40 /* merge counters for large incr. events */
 
 #define EVENT_VAR(_id)  event_attr_##_id
 #define EVENT_PTR(_id) &event_attr_##_id.attr.attr
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/x86/include/asm/nmi.h linux-libre-5.4.22-gnu/arch/x86/include/asm/nmi.h
--- linux-libre-5.4.21-gnu/arch/x86/include/asm/nmi.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/x86/include/asm/nmi.h	2020-02-24 02:37:04.000000000 -0500
@@ -41,7 +41,6 @@ struct nmiaction {
 	struct list_head	list;
 	nmi_handler_t		handler;
 	u64			max_duration;
-	struct irq_work		irq_work;
 	unsigned long		flags;
 	const char		*name;
 };
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/x86/kernel/fpu/signal.c linux-libre-5.4.22-gnu/arch/x86/kernel/fpu/signal.c
--- linux-libre-5.4.21-gnu/arch/x86/kernel/fpu/signal.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/x86/kernel/fpu/signal.c	2020-02-24 02:37:04.000000000 -0500
@@ -352,6 +352,7 @@ static int __fpu__restore_sig(void __use
 			fpregs_unlock();
 			return 0;
 		}
+		fpregs_deactivate(fpu);
 		fpregs_unlock();
 	}
 
@@ -403,6 +404,8 @@ static int __fpu__restore_sig(void __use
 	}
 	if (!ret)
 		fpregs_mark_activate();
+	else
+		fpregs_deactivate(fpu);
 	fpregs_unlock();
 
 err_out:
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/x86/kernel/nmi.c linux-libre-5.4.22-gnu/arch/x86/kernel/nmi.c
--- linux-libre-5.4.21-gnu/arch/x86/kernel/nmi.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/x86/kernel/nmi.c	2020-02-24 02:37:04.000000000 -0500
@@ -104,18 +104,22 @@ static int __init nmi_warning_debugfs(vo
 }
 fs_initcall(nmi_warning_debugfs);
 
-static void nmi_max_handler(struct irq_work *w)
+static void nmi_check_duration(struct nmiaction *action, u64 duration)
 {
-	struct nmiaction *a = container_of(w, struct nmiaction, irq_work);
+	u64 whole_msecs = READ_ONCE(action->max_duration);
 	int remainder_ns, decimal_msecs;
-	u64 whole_msecs = READ_ONCE(a->max_duration);
+
+	if (duration < nmi_longest_ns || duration < action->max_duration)
+		return;
+
+	action->max_duration = duration;
 
 	remainder_ns = do_div(whole_msecs, (1000 * 1000));
 	decimal_msecs = remainder_ns / 1000;
 
 	printk_ratelimited(KERN_INFO
 		"INFO: NMI handler (%ps) took too long to run: %lld.%03d msecs\n",
-		a->handler, whole_msecs, decimal_msecs);
+		action->handler, whole_msecs, decimal_msecs);
 }
 
 static int nmi_handle(unsigned int type, struct pt_regs *regs)
@@ -142,11 +146,7 @@ static int nmi_handle(unsigned int type,
 		delta = sched_clock() - delta;
 		trace_nmi_handler(a->handler, (int)delta, thishandled);
 
-		if (delta < nmi_longest_ns || delta < a->max_duration)
-			continue;
-
-		a->max_duration = delta;
-		irq_work_queue(&a->irq_work);
+		nmi_check_duration(a, delta);
 	}
 
 	rcu_read_unlock();
@@ -164,8 +164,6 @@ int __register_nmi_handler(unsigned int
 	if (!action->handler)
 		return -EINVAL;
 
-	init_irq_work(&action->irq_work, nmi_max_handler);
-
 	raw_spin_lock_irqsave(&desc->lock, flags);
 
 	/*
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/x86/kernel/sysfb_simplefb.c linux-libre-5.4.22-gnu/arch/x86/kernel/sysfb_simplefb.c
--- linux-libre-5.4.21-gnu/arch/x86/kernel/sysfb_simplefb.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/x86/kernel/sysfb_simplefb.c	2020-02-24 02:37:04.000000000 -0500
@@ -90,11 +90,11 @@ __init int create_simplefb(const struct
 	if (si->orig_video_isVGA == VIDEO_TYPE_VLFB)
 		size <<= 16;
 	length = mode->height * mode->stride;
-	length = PAGE_ALIGN(length);
 	if (length > size) {
 		printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n");
 		return -EINVAL;
 	}
+	length = PAGE_ALIGN(length);
 
 	/* setup IORESOURCE_MEM as framebuffer memory */
 	memset(&res, 0, sizeof(res));
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/x86/lib/x86-opcode-map.txt linux-libre-5.4.22-gnu/arch/x86/lib/x86-opcode-map.txt
--- linux-libre-5.4.21-gnu/arch/x86/lib/x86-opcode-map.txt	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/x86/lib/x86-opcode-map.txt	2020-02-24 02:37:04.000000000 -0500
@@ -909,7 +909,7 @@ EndTable
 
 GrpTable: Grp3_2
 0: TEST Ev,Iz
-1:
+1: TEST Ev,Iz
 2: NOT Ev
 3: NEG Ev
 4: MUL rAX,Ev
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/x86/mm/pageattr.c linux-libre-5.4.22-gnu/arch/x86/mm/pageattr.c
--- linux-libre-5.4.21-gnu/arch/x86/mm/pageattr.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/x86/mm/pageattr.c	2020-02-24 02:37:04.000000000 -0500
@@ -2215,7 +2215,7 @@ int __init kernel_map_pages_in_pgd(pgd_t
 		.pgd = pgd,
 		.numpages = numpages,
 		.mask_set = __pgprot(0),
-		.mask_clr = __pgprot(0),
+		.mask_clr = __pgprot(~page_flags & (_PAGE_NX|_PAGE_RW)),
 		.flags = 0,
 	};
 
@@ -2224,12 +2224,6 @@ int __init kernel_map_pages_in_pgd(pgd_t
 	if (!(__supported_pte_mask & _PAGE_NX))
 		goto out;
 
-	if (!(page_flags & _PAGE_NX))
-		cpa.mask_clr = __pgprot(_PAGE_NX);
-
-	if (!(page_flags & _PAGE_RW))
-		cpa.mask_clr = __pgprot(_PAGE_RW);
-
 	if (!(page_flags & _PAGE_ENC))
 		cpa.mask_clr = pgprot_encrypted(cpa.mask_clr);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/x86/platform/efi/efi_64.c linux-libre-5.4.22-gnu/arch/x86/platform/efi/efi_64.c
--- linux-libre-5.4.21-gnu/arch/x86/platform/efi/efi_64.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/x86/platform/efi/efi_64.c	2020-02-24 02:37:04.000000000 -0500
@@ -392,11 +392,12 @@ int __init efi_setup_page_tables(unsigne
 		return 0;
 
 	page = alloc_page(GFP_KERNEL|__GFP_DMA32);
-	if (!page)
-		panic("Unable to allocate EFI runtime stack < 4GB\n");
+	if (!page) {
+		pr_err("Unable to allocate EFI runtime stack < 4GB\n");
+		return 1;
+	}
 
-	efi_scratch.phys_stack = virt_to_phys(page_address(page));
-	efi_scratch.phys_stack += PAGE_SIZE; /* stack grows down */
+	efi_scratch.phys_stack = page_to_phys(page + 1); /* stack grows down */
 
 	npages = (_etext - _text) >> PAGE_SHIFT;
 	text = __pa(_text);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/arch/x86/platform/efi/efi.c linux-libre-5.4.22-gnu/arch/x86/platform/efi/efi.c
--- linux-libre-5.4.21-gnu/arch/x86/platform/efi/efi.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/arch/x86/platform/efi/efi.c	2020-02-24 02:37:04.000000000 -0500
@@ -504,7 +504,6 @@ void __init efi_init(void)
 	efi_char16_t *c16;
 	char vendor[100] = "unknown";
 	int i = 0;
-	void *tmp;
 
 #ifdef CONFIG_X86_32
 	if (boot_params.efi_info.efi_systab_hi ||
@@ -529,14 +528,16 @@ void __init efi_init(void)
 	/*
 	 * Show what we know for posterity
 	 */
-	c16 = tmp = early_memremap(efi.systab->fw_vendor, 2);
+	c16 = early_memremap_ro(efi.systab->fw_vendor,
+				sizeof(vendor) * sizeof(efi_char16_t));
 	if (c16) {
-		for (i = 0; i < sizeof(vendor) - 1 && *c16; ++i)
-			vendor[i] = *c16++;
+		for (i = 0; i < sizeof(vendor) - 1 && c16[i]; ++i)
+			vendor[i] = c16[i];
 		vendor[i] = '\0';
-	} else
+		early_memunmap(c16, sizeof(vendor) * sizeof(efi_char16_t));
+	} else {
 		pr_err("Could not map the firmware vendor!\n");
-	early_memunmap(tmp, 2);
+	}
 
 	pr_info("EFI v%u.%.02u by %s\n",
 		efi.systab->hdr.revision >> 16,
@@ -953,16 +954,14 @@ static void __init __efi_enter_virtual_m
 
 	if (efi_alloc_page_tables()) {
 		pr_err("Failed to allocate EFI page tables\n");
-		clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
-		return;
+		goto err;
 	}
 
 	efi_merge_regions();
 	new_memmap = efi_map_regions(&count, &pg_shift);
 	if (!new_memmap) {
 		pr_err("Error reallocating memory, EFI runtime non-functional!\n");
-		clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
-		return;
+		goto err;
 	}
 
 	pa = __pa(new_memmap);
@@ -976,8 +975,7 @@ static void __init __efi_enter_virtual_m
 
 	if (efi_memmap_init_late(pa, efi.memmap.desc_size * count)) {
 		pr_err("Failed to remap late EFI memory map\n");
-		clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
-		return;
+		goto err;
 	}
 
 	if (efi_enabled(EFI_DBG)) {
@@ -985,12 +983,11 @@ static void __init __efi_enter_virtual_m
 		efi_print_memmap();
 	}
 
-	BUG_ON(!efi.systab);
+	if (WARN_ON(!efi.systab))
+		goto err;
 
-	if (efi_setup_page_tables(pa, 1 << pg_shift)) {
-		clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
-		return;
-	}
+	if (efi_setup_page_tables(pa, 1 << pg_shift))
+		goto err;
 
 	efi_sync_low_kernel_mappings();
 
@@ -1010,9 +1007,9 @@ static void __init __efi_enter_virtual_m
 	}
 
 	if (status != EFI_SUCCESS) {
-		pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n",
-			 status);
-		panic("EFI call to SetVirtualAddressMap() failed!");
+		pr_err("Unable to switch EFI into virtual mode (status=%lx)!\n",
+		       status);
+		goto err;
 	}
 
 	efi_free_boot_services();
@@ -1041,6 +1038,10 @@ static void __init __efi_enter_virtual_m
 
 	/* clean DUMMY object */
 	efi_delete_dummy_variable();
+	return;
+
+err:
+	clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
 }
 
 void __init efi_enter_virtual_mode(void)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/block/bfq-iosched.c linux-libre-5.4.22-gnu/block/bfq-iosched.c
--- linux-libre-5.4.21-gnu/block/bfq-iosched.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/block/bfq-iosched.c	2020-02-24 02:37:04.000000000 -0500
@@ -3444,6 +3444,10 @@ static void bfq_dispatch_remove(struct r
 static bool idling_needed_for_service_guarantees(struct bfq_data *bfqd,
 						 struct bfq_queue *bfqq)
 {
+	/* No point in idling for bfqq if it won't get requests any longer */
+	if (unlikely(!bfqq_process_refs(bfqq)))
+		return false;
+
 	return (bfqq->wr_coeff > 1 &&
 		(bfqd->wr_busy_queues <
 		 bfq_tot_busy_queues(bfqd) ||
@@ -4077,6 +4081,10 @@ static bool idling_boosts_thr_without_is
 		bfqq_sequential_and_IO_bound,
 		idling_boosts_thr;
 
+	/* No point in idling for bfqq if it won't get requests any longer */
+	if (unlikely(!bfqq_process_refs(bfqq)))
+		return false;
+
 	bfqq_sequential_and_IO_bound = !BFQQ_SEEKY(bfqq) &&
 		bfq_bfqq_IO_bound(bfqq) && bfq_bfqq_has_short_ttime(bfqq);
 
@@ -4170,6 +4178,10 @@ static bool bfq_better_to_idle(struct bf
 	struct bfq_data *bfqd = bfqq->bfqd;
 	bool idling_boosts_thr_with_no_issue, idling_needed_for_service_guar;
 
+	/* No point in idling for bfqq if it won't get requests any longer */
+	if (unlikely(!bfqq_process_refs(bfqq)))
+		return false;
+
 	if (unlikely(bfqd->strict_guarantees))
 		return true;
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/crypto/Kconfig linux-libre-5.4.22-gnu/crypto/Kconfig
--- linux-libre-5.4.21-gnu/crypto/Kconfig	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/crypto/Kconfig	2020-02-24 02:37:04.000000000 -0500
@@ -500,10 +500,10 @@ config CRYPTO_ESSIV
 	  encryption.
 
 	  This driver implements a crypto API template that can be
-	  instantiated either as a skcipher or as a aead (depending on the
+	  instantiated either as an skcipher or as an AEAD (depending on the
 	  type of the first template argument), and which defers encryption
 	  and decryption requests to the encapsulated cipher after applying
-	  ESSIV to the input IV. Note that in the aead case, it is assumed
+	  ESSIV to the input IV. Note that in the AEAD case, it is assumed
 	  that the keys are presented in the same format used by the authenc
 	  template, and that the IV appears at the end of the authenticated
 	  associated data (AAD) region (which is how dm-crypt uses it.)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/Documentation/fb/fbcon.rst linux-libre-5.4.22-gnu/Documentation/fb/fbcon.rst
--- linux-libre-5.4.21-gnu/Documentation/fb/fbcon.rst	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/Documentation/fb/fbcon.rst	2020-02-24 02:37:04.000000000 -0500
@@ -127,7 +127,7 @@ C. Boot options
 	is typically located on the same video card.  Thus, the consoles that
 	are controlled by the VGA console will be garbled.
 
-4. fbcon=rotate:<n>
+5. fbcon=rotate:<n>
 
 	This option changes the orientation angle of the console display. The
 	value 'n' accepts the following:
@@ -152,21 +152,21 @@ C. Boot options
 	Actually, the underlying fb driver is totally ignorant of console
 	rotation.
 
-5. fbcon=margin:<color>
+6. fbcon=margin:<color>
 
 	This option specifies the color of the margins. The margins are the
 	leftover area at the right and the bottom of the screen that are not
 	used by text. By default, this area will be black. The 'color' value
 	is an integer number that depends on the framebuffer driver being used.
 
-6. fbcon=nodefer
+7. fbcon=nodefer
 
 	If the kernel is compiled with deferred fbcon takeover support, normally
 	the framebuffer contents, left in place by the firmware/bootloader, will
 	be preserved until there actually is some text is output to the console.
 	This option causes fbcon to bind immediately to the fbdev device.
 
-7. fbcon=logo-pos:<location>
+8. fbcon=logo-pos:<location>
 
 	The only possible 'location' is 'center' (without quotes), and when
 	given, the bootup logo is moved from the default top-left corner
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/acpi/acpica/dsfield.c linux-libre-5.4.22-gnu/drivers/acpi/acpica/dsfield.c
--- linux-libre-5.4.21-gnu/drivers/acpi/acpica/dsfield.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/acpi/acpica/dsfield.c	2020-02-24 02:37:04.000000000 -0500
@@ -244,7 +244,7 @@ cleanup:
  * FUNCTION:    acpi_ds_get_field_names
  *
  * PARAMETERS:  info            - create_field info structure
- *  `           walk_state      - Current method state
+ *              walk_state      - Current method state
  *              arg             - First parser arg for the field name list
  *
  * RETURN:      Status
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/acpi/acpica/dswload.c linux-libre-5.4.22-gnu/drivers/acpi/acpica/dswload.c
--- linux-libre-5.4.21-gnu/drivers/acpi/acpica/dswload.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/acpi/acpica/dswload.c	2020-02-24 02:37:04.000000000 -0500
@@ -410,6 +410,27 @@ acpi_status acpi_ds_load1_end_op(struct
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
 			  walk_state));
 
+	/*
+	 * Disassembler: handle create field operators here.
+	 *
+	 * create_buffer_field is a deferred op that is typically processed in load
+	 * pass 2. However, disassembly of control method contents walk the parse
+	 * tree with ACPI_PARSE_LOAD_PASS1 and AML_CREATE operators are processed
+	 * in a later walk. This is a problem when there is a control method that
+	 * has the same name as the AML_CREATE object. In this case, any use of the
+	 * name segment will be detected as a method call rather than a reference
+	 * to a buffer field.
+	 *
+	 * This earlier creation during disassembly solves this issue by inserting
+	 * the named object in the ACPI namespace so that references to this name
+	 * would be a name string rather than a method call.
+	 */
+	if ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) &&
+	    (walk_state->op_info->flags & AML_CREATE)) {
+		status = acpi_ds_create_buffer_field(op, walk_state);
+		return_ACPI_STATUS(status);
+	}
+
 	/* We are only interested in opcodes that have an associated name */
 
 	if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/acpi/button.c linux-libre-5.4.22-gnu/drivers/acpi/button.c
--- linux-libre-5.4.21-gnu/drivers/acpi/button.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/acpi/button.c	2020-02-24 02:37:04.000000000 -0500
@@ -89,6 +89,17 @@ static const struct dmi_system_id lid_bl
 		},
 		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
 	},
+	{
+		/*
+		 * Razer Blade Stealth 13 late 2019, notification of the LID device
+		 * only happens on close, not on open and _LID always returns closed.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Razer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Razer Blade Stealth 13 Late 2019"),
+		},
+		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
+	},
 	{}
 };
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/atm/fore200e.c linux-libre-5.4.22-gnu/drivers/atm/fore200e.c
--- linux-libre-5.4.21-gnu/drivers/atm/fore200e.c	2020-02-19 17:17:12.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/atm/fore200e.c	2020-02-24 05:29:29.000000000 -0500
@@ -1414,12 +1414,14 @@ fore200e_open(struct atm_vcc *vcc)
 static void
 fore200e_close(struct atm_vcc* vcc)
 {
-    struct fore200e*        fore200e = FORE200E_DEV(vcc->dev);
     struct fore200e_vcc*    fore200e_vcc;
+    struct fore200e*        fore200e;
     struct fore200e_vc_map* vc_map;
     unsigned long           flags;
 
     ASSERT(vcc);
+    fore200e = FORE200E_DEV(vcc->dev);
+
     ASSERT((vcc->vpi >= 0) && (vcc->vpi < 1<<FORE200E_VPI_BITS));
     ASSERT((vcc->vci >= 0) && (vcc->vci < 1<<FORE200E_VCI_BITS));
 
@@ -1464,10 +1466,10 @@ fore200e_close(struct atm_vcc* vcc)
 static int
 fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb)
 {
-    struct fore200e*        fore200e     = FORE200E_DEV(vcc->dev);
-    struct fore200e_vcc*    fore200e_vcc = FORE200E_VCC(vcc);
+    struct fore200e*        fore200e;
+    struct fore200e_vcc*    fore200e_vcc;
     struct fore200e_vc_map* vc_map;
-    struct host_txq*        txq          = &fore200e->host_txq;
+    struct host_txq*        txq;
     struct host_txq_entry*  entry;
     struct tpd*             tpd;
     struct tpd_haddr        tpd_haddr;
@@ -1480,9 +1482,18 @@ fore200e_send(struct atm_vcc *vcc, struc
     unsigned char*          data;
     unsigned long           flags;
 
-    ASSERT(vcc);
-    ASSERT(fore200e);
-    ASSERT(fore200e_vcc);
+    if (!vcc)
+        return -EINVAL;
+
+    fore200e = FORE200E_DEV(vcc->dev);
+    fore200e_vcc = FORE200E_VCC(vcc);
+
+    if (!fore200e)
+        return -EINVAL;
+
+    txq = &fore200e->host_txq;
+    if (!fore200e_vcc)
+        return -EINVAL;
 
     if (!test_bit(ATM_VF_READY, &vcc->flags)) {
 	DPRINTK(1, "VC %d.%d.%d not ready for tx\n", vcc->itf, vcc->vpi, vcc->vpi);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/base/dd.c linux-libre-5.4.22-gnu/drivers/base/dd.c
--- linux-libre-5.4.21-gnu/drivers/base/dd.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/base/dd.c	2020-02-24 02:37:04.000000000 -0500
@@ -516,7 +516,10 @@ static int really_probe(struct device *d
 	atomic_inc(&probe_count);
 	pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
 		 drv->bus->name, __func__, drv->name, dev_name(dev));
-	WARN_ON(!list_empty(&dev->devres_head));
+	if (!list_empty(&dev->devres_head)) {
+		dev_crit(dev, "Resources present before probing\n");
+		return -EBUSY;
+	}
 
 re_probe:
 	dev->driver = drv;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/base/platform.c linux-libre-5.4.22-gnu/drivers/base/platform.c
--- linux-libre-5.4.21-gnu/drivers/base/platform.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/base/platform.c	2020-02-24 02:37:04.000000000 -0500
@@ -27,6 +27,7 @@
 #include <linux/limits.h>
 #include <linux/property.h>
 #include <linux/kmemleak.h>
+#include <linux/types.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -48,7 +49,7 @@ EXPORT_SYMBOL_GPL(platform_bus);
 struct resource *platform_get_resource(struct platform_device *dev,
 				       unsigned int type, unsigned int num)
 {
-	int i;
+	u32 i;
 
 	for (i = 0; i < dev->num_resources; i++) {
 		struct resource *r = &dev->resource[i];
@@ -226,7 +227,7 @@ struct resource *platform_get_resource_b
 					      unsigned int type,
 					      const char *name)
 {
-	int i;
+	u32 i;
 
 	for (i = 0; i < dev->num_resources; i++) {
 		struct resource *r = &dev->resource[i];
@@ -473,7 +474,8 @@ EXPORT_SYMBOL_GPL(platform_device_add_pr
  */
 int platform_device_add(struct platform_device *pdev)
 {
-	int i, ret;
+	u32 i;
+	int ret;
 
 	if (!pdev)
 		return -EINVAL;
@@ -541,7 +543,7 @@ int platform_device_add(struct platform_
 		pdev->id = PLATFORM_DEVID_AUTO;
 	}
 
-	while (--i >= 0) {
+	while (i--) {
 		struct resource *r = &pdev->resource[i];
 		if (r->parent)
 			release_resource(r);
@@ -562,7 +564,7 @@ EXPORT_SYMBOL_GPL(platform_device_add);
  */
 void platform_device_del(struct platform_device *pdev)
 {
-	int i;
+	u32 i;
 
 	if (!IS_ERR_OR_NULL(pdev)) {
 		device_del(&pdev->dev);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/block/brd.c linux-libre-5.4.22-gnu/drivers/block/brd.c
--- linux-libre-5.4.21-gnu/drivers/block/brd.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/block/brd.c	2020-02-24 02:37:04.000000000 -0500
@@ -470,6 +470,25 @@ static struct kobject *brd_probe(dev_t d
 	return kobj;
 }
 
+static inline void brd_check_and_reset_par(void)
+{
+	if (unlikely(!max_part))
+		max_part = 1;
+
+	/*
+	 * make sure 'max_part' can be divided exactly by (1U << MINORBITS),
+	 * otherwise, it is possiable to get same dev_t when adding partitions.
+	 */
+	if ((1U << MINORBITS) % max_part != 0)
+		max_part = 1UL << fls(max_part);
+
+	if (max_part > DISK_MAX_PARTS) {
+		pr_info("brd: max_part can't be larger than %d, reset max_part = %d.\n",
+			DISK_MAX_PARTS, DISK_MAX_PARTS);
+		max_part = DISK_MAX_PARTS;
+	}
+}
+
 static int __init brd_init(void)
 {
 	struct brd_device *brd, *next;
@@ -493,8 +512,7 @@ static int __init brd_init(void)
 	if (register_blkdev(RAMDISK_MAJOR, "ramdisk"))
 		return -EIO;
 
-	if (unlikely(!max_part))
-		max_part = 1;
+	brd_check_and_reset_par();
 
 	for (i = 0; i < rd_nr; i++) {
 		brd = brd_alloc(i);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/block/nbd.c linux-libre-5.4.22-gnu/drivers/block/nbd.c
--- linux-libre-5.4.21-gnu/drivers/block/nbd.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/block/nbd.c	2020-02-24 02:37:04.000000000 -0500
@@ -1265,6 +1265,16 @@ static int nbd_start_device(struct nbd_d
 		args = kzalloc(sizeof(*args), GFP_KERNEL);
 		if (!args) {
 			sock_shutdown(nbd);
+			/*
+			 * If num_connections is m (2 < m),
+			 * and NO.1 ~ NO.n(1 < n < m) kzallocs are successful.
+			 * But NO.(n + 1) failed. We still have n recv threads.
+			 * So, add flush_workqueue here to prevent recv threads
+			 * dropping the last config_refs and trying to destroy
+			 * the workqueue from inside the workqueue.
+			 */
+			if (i)
+				flush_workqueue(nbd->recv_workq);
 			return -ENOMEM;
 		}
 		sk_set_memalloc(config->socks[i]->sock->sk);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/block/rbd.c linux-libre-5.4.22-gnu/drivers/block/rbd.c
--- linux-libre-5.4.21-gnu/drivers/block/rbd.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/block/rbd.c	2020-02-24 02:37:04.000000000 -0500
@@ -2739,7 +2739,7 @@ static int rbd_img_fill_nodata(struct rb
 			       u64 off, u64 len)
 {
 	struct ceph_file_extent ex = { off, len };
-	union rbd_img_fill_iter dummy;
+	union rbd_img_fill_iter dummy = {};
 	struct rbd_img_fill_ctx fctx = {
 		.pos_type = OBJ_REQUEST_NODATA,
 		.pos = &dummy,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/block/zram/zram_drv.c linux-libre-5.4.22-gnu/drivers/block/zram/zram_drv.c
--- linux-libre-5.4.21-gnu/drivers/block/zram/zram_drv.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/block/zram/zram_drv.c	2020-02-24 02:37:04.000000000 -0500
@@ -626,7 +626,7 @@ static ssize_t writeback_store(struct de
 	struct bio bio;
 	struct bio_vec bio_vec;
 	struct page *page;
-	ssize_t ret;
+	ssize_t ret = len;
 	int mode;
 	unsigned long blk_idx = 0;
 
@@ -762,7 +762,6 @@ next:
 
 	if (blk_idx)
 		free_block_bdev(zram, blk_idx);
-	ret = len;
 	__free_page(page);
 release_init_lock:
 	up_read(&zram->init_lock);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/bus/ti-sysc.c linux-libre-5.4.22-gnu/drivers/bus/ti-sysc.c
--- linux-libre-5.4.21-gnu/drivers/bus/ti-sysc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/bus/ti-sysc.c	2020-02-24 02:37:04.000000000 -0500
@@ -479,7 +479,7 @@ static void sysc_clkdm_deny_idle(struct
 {
 	struct ti_sysc_platform_data *pdata;
 
-	if (ddata->legacy_mode)
+	if (ddata->legacy_mode || (ddata->cfg.quirks & SYSC_QUIRK_CLKDM_NOAUTO))
 		return;
 
 	pdata = dev_get_platdata(ddata->dev);
@@ -491,7 +491,7 @@ static void sysc_clkdm_allow_idle(struct
 {
 	struct ti_sysc_platform_data *pdata;
 
-	if (ddata->legacy_mode)
+	if (ddata->legacy_mode || (ddata->cfg.quirks & SYSC_QUIRK_CLKDM_NOAUTO))
 		return;
 
 	pdata = dev_get_platdata(ddata->dev);
@@ -1251,6 +1251,12 @@ static const struct sysc_revision_quirk
 	/* Quirks that need to be set based on detected module */
 	SYSC_QUIRK("aess", 0, 0, 0x10, -1, 0x40000000, 0xffffffff,
 		   SYSC_MODULE_QUIRK_AESS),
+	SYSC_QUIRK("dcan", 0x48480000, 0x20, -1, -1, 0xa3170504, 0xffffffff,
+		   SYSC_QUIRK_CLKDM_NOAUTO),
+	SYSC_QUIRK("dwc3", 0x48880000, 0, 0x10, -1, 0x500a0200, 0xffffffff,
+		   SYSC_QUIRK_CLKDM_NOAUTO),
+	SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -1, 0x500a0200, 0xffffffff,
+		   SYSC_QUIRK_CLKDM_NOAUTO),
 	SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff,
 		   SYSC_MODULE_QUIRK_HDQ1W),
 	SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/char/hpet.c linux-libre-5.4.22-gnu/drivers/char/hpet.c
--- linux-libre-5.4.21-gnu/drivers/char/hpet.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/char/hpet.c	2020-02-24 02:37:04.000000000 -0500
@@ -855,7 +855,7 @@ int hpet_alloc(struct hpet_data *hdp)
 		return 0;
 	}
 
-	hpetp = kzalloc(struct_size(hpetp, hp_dev, hdp->hd_nirqs - 1),
+	hpetp = kzalloc(struct_size(hpetp, hp_dev, hdp->hd_nirqs),
 			GFP_KERNEL);
 
 	if (!hpetp)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/char/random.c linux-libre-5.4.22-gnu/drivers/char/random.c
--- linux-libre-5.4.21-gnu/drivers/char/random.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/char/random.c	2020-02-24 02:37:04.000000000 -0500
@@ -1687,8 +1687,9 @@ static void _warn_unseeded_randomness(co
 	print_once = true;
 #endif
 	if (__ratelimit(&unseeded_warning))
-		pr_notice("random: %s called from %pS with crng_init=%d\n",
-			  func_name, caller, crng_init);
+		printk_deferred(KERN_NOTICE "random: %s called from %pS "
+				"with crng_init=%d\n", func_name, caller,
+				crng_init);
 }
 
 /*
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clk/at91/sam9x60.c linux-libre-5.4.22-gnu/drivers/clk/at91/sam9x60.c
--- linux-libre-5.4.21-gnu/drivers/clk/at91/sam9x60.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clk/at91/sam9x60.c	2020-02-24 02:37:04.000000000 -0500
@@ -47,6 +47,7 @@ static const struct clk_programmable_lay
 	.pres_shift = 8,
 	.css_mask = 0x1f,
 	.have_slck_mck = 0,
+	.is_pres_direct = 1,
 };
 
 static const struct clk_pcr_layout sam9x60_pcr_layout = {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clk/clk.c linux-libre-5.4.22-gnu/drivers/clk/clk.c
--- linux-libre-5.4.21-gnu/drivers/clk/clk.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clk/clk.c	2020-02-24 02:37:04.000000000 -0500
@@ -3320,6 +3320,21 @@ static int __clk_core_init(struct clk_co
 		goto out;
 	}
 
+	/*
+	 * optional platform-specific magic
+	 *
+	 * The .init callback is not used by any of the basic clock types, but
+	 * exists for weird hardware that must perform initialization magic.
+	 * Please consider other ways of solving initialization problems before
+	 * using this callback, as its use is discouraged.
+	 *
+	 * If it exist, this callback should called before any other callback of
+	 * the clock
+	 */
+	if (core->ops->init)
+		core->ops->init(core->hw);
+
+
 	core->parent = __clk_init_parent(core);
 
 	/*
@@ -3345,17 +3360,6 @@ static int __clk_core_init(struct clk_co
 	}
 
 	/*
-	 * optional platform-specific magic
-	 *
-	 * The .init callback is not used by any of the basic clock types, but
-	 * exists for weird hardware that must perform initialization magic.
-	 * Please consider other ways of solving initialization problems before
-	 * using this callback, as its use is discouraged.
-	 */
-	if (core->ops->init)
-		core->ops->init(core->hw);
-
-	/*
 	 * Set clk's accuracy.  The preferred method is to use
 	 * .recalc_accuracy. For simple clocks and lazy developers the default
 	 * fallback is to use the parent's accuracy.  If a clock doesn't have a
@@ -3715,6 +3719,28 @@ fail_out:
 }
 
 /**
+ * dev_or_parent_of_node() - Get device node of @dev or @dev's parent
+ * @dev: Device to get device node of
+ *
+ * Return: device node pointer of @dev, or the device node pointer of
+ * @dev->parent if dev doesn't have a device node, or NULL if neither
+ * @dev or @dev->parent have a device node.
+ */
+static struct device_node *dev_or_parent_of_node(struct device *dev)
+{
+	struct device_node *np;
+
+	if (!dev)
+		return NULL;
+
+	np = dev_of_node(dev);
+	if (!np)
+		np = dev_of_node(dev->parent);
+
+	return np;
+}
+
+/**
  * clk_register - allocate a new clock, register it and return an opaque cookie
  * @dev: device that is registering this clock
  * @hw: link to hardware-specific clock data
@@ -3729,7 +3755,7 @@ fail_out:
  */
 struct clk *clk_register(struct device *dev, struct clk_hw *hw)
 {
-	return __clk_register(dev, dev_of_node(dev), hw);
+	return __clk_register(dev, dev_or_parent_of_node(dev), hw);
 }
 EXPORT_SYMBOL_GPL(clk_register);
 
@@ -3745,7 +3771,8 @@ EXPORT_SYMBOL_GPL(clk_register);
  */
 int clk_hw_register(struct device *dev, struct clk_hw *hw)
 {
-	return PTR_ERR_OR_ZERO(__clk_register(dev, dev_of_node(dev), hw));
+	return PTR_ERR_OR_ZERO(__clk_register(dev, dev_or_parent_of_node(dev),
+			       hw));
 }
 EXPORT_SYMBOL_GPL(clk_hw_register);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clk/imx/clk.h linux-libre-5.4.22-gnu/drivers/clk/imx/clk.h
--- linux-libre-5.4.21-gnu/drivers/clk/imx/clk.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clk/imx/clk.h	2020-02-24 02:37:04.000000000 -0500
@@ -51,48 +51,48 @@ struct imx_pll14xx_clk {
 };
 
 #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
-	imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk
+	to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))
 
 #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
 				cgr_val, clk_gate_flags, lock, share_count) \
-	clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
-				cgr_val, clk_gate_flags, lock, share_count)->clk
+	to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
+				cgr_val, clk_gate_flags, lock, share_count))
 
 #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \
-	imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)->clk
+	to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask))
 
 #define imx_clk_pfd(name, parent_name, reg, idx) \
-	imx_clk_hw_pfd(name, parent_name, reg, idx)->clk
+	to_clk(imx_clk_hw_pfd(name, parent_name, reg, idx))
 
 #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \
-	imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)->clk
+	to_clk(imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask))
 
 #define imx_clk_fixed_factor(name, parent, mult, div) \
-	imx_clk_hw_fixed_factor(name, parent, mult, div)->clk
+	to_clk(imx_clk_hw_fixed_factor(name, parent, mult, div))
 
 #define imx_clk_divider2(name, parent, reg, shift, width) \
-	imx_clk_hw_divider2(name, parent, reg, shift, width)->clk
+	to_clk(imx_clk_hw_divider2(name, parent, reg, shift, width))
 
 #define imx_clk_gate_dis(name, parent, reg, shift) \
-	imx_clk_hw_gate_dis(name, parent, reg, shift)->clk
+	to_clk(imx_clk_hw_gate_dis(name, parent, reg, shift))
 
 #define imx_clk_gate2(name, parent, reg, shift) \
-	imx_clk_hw_gate2(name, parent, reg, shift)->clk
+	to_clk(imx_clk_hw_gate2(name, parent, reg, shift))
 
 #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \
-	imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)->clk
+	to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags))
 
 #define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \
-	imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)->clk
+	to_clk(imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count))
 
 #define imx_clk_gate3(name, parent, reg, shift) \
-	imx_clk_hw_gate3(name, parent, reg, shift)->clk
+	to_clk(imx_clk_hw_gate3(name, parent, reg, shift))
 
 #define imx_clk_gate4(name, parent, reg, shift) \
-	imx_clk_hw_gate4(name, parent, reg, shift)->clk
+	to_clk(imx_clk_hw_gate4(name, parent, reg, shift))
 
 #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \
-	imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)->clk
+	to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents))
 
 struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
 		 void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
@@ -195,6 +195,13 @@ struct clk_hw *imx_clk_hw_fixup_mux(cons
 			      u8 shift, u8 width, const char * const *parents,
 			      int num_parents, void (*fixup)(u32 *val));
 
+static inline struct clk *to_clk(struct clk_hw *hw)
+{
+	if (IS_ERR_OR_NULL(hw))
+		return ERR_CAST(hw);
+	return hw->clk;
+}
+
 static inline struct clk *imx_clk_fixed(const char *name, int rate)
 {
 	return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clk/meson/clk-pll.c linux-libre-5.4.22-gnu/drivers/clk/meson/clk-pll.c
--- linux-libre-5.4.21-gnu/drivers/clk/meson/clk-pll.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clk/meson/clk-pll.c	2020-02-24 02:37:04.000000000 -0500
@@ -77,6 +77,15 @@ static unsigned long meson_clk_pll_recal
 	unsigned int m, n, frac;
 
 	n = meson_parm_read(clk->map, &pll->n);
+
+	/*
+	 * On some HW, N is set to zero on init. This value is invalid as
+	 * it would result in a division by zero. The rate can't be
+	 * calculated in this case
+	 */
+	if (n == 0)
+		return 0;
+
 	m = meson_parm_read(clk->map, &pll->m);
 
 	frac = MESON_PARM_APPLICABLE(&pll->frac) ?
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clk/meson/meson8b.c linux-libre-5.4.22-gnu/drivers/clk/meson/meson8b.c
--- linux-libre-5.4.21-gnu/drivers/clk/meson/meson8b.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clk/meson/meson8b.c	2020-02-24 02:37:04.000000000 -0500
@@ -1764,8 +1764,11 @@ static struct clk_regmap meson8b_hdmi_sy
 
 /*
  * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
- * muxed by a glitch-free switch on Meson8b and Meson8m2. Meson8 only
- * has mali_0 and no glitch-free mux.
+ * muxed by a glitch-free switch on Meson8b and Meson8m2. The CCF can
+ * actually manage this glitch-free mux because it does top-to-bottom
+ * updates the each clock tree and switches to the "inactive" one when
+ * CLK_SET_RATE_GATE is set.
+ * Meson8 only has mali_0 and no glitch-free mux.
  */
 static const struct clk_hw *meson8b_mali_0_1_parent_hws[] = {
 	&meson8b_xtal.hw,
@@ -1830,7 +1833,7 @@ static struct clk_regmap meson8b_mali_0
 			&meson8b_mali_0_div.hw
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
+		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
 	},
 };
 
@@ -1885,7 +1888,7 @@ static struct clk_regmap meson8b_mali_1
 			&meson8b_mali_1_div.hw
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
+		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
 	},
 };
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clk/qcom/clk-rcg2.c linux-libre-5.4.22-gnu/drivers/clk/qcom/clk-rcg2.c
--- linux-libre-5.4.21-gnu/drivers/clk/qcom/clk-rcg2.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clk/qcom/clk-rcg2.c	2020-02-24 02:37:04.000000000 -0500
@@ -217,6 +217,9 @@ static int _freq_tbl_determine_rate(stru
 
 	clk_flags = clk_hw_get_flags(hw);
 	p = clk_hw_get_parent_by_index(hw, index);
+	if (!p)
+		return -EINVAL;
+
 	if (clk_flags & CLK_SET_RATE_PARENT) {
 		rate = f->freq;
 		if (f->pre_div) {
@@ -952,7 +955,7 @@ static void clk_rcg2_dfs_populate_freq(s
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 	struct clk_hw *p;
 	unsigned long prate = 0;
-	u32 val, mask, cfg, mode;
+	u32 val, mask, cfg, mode, src;
 	int i, num_parents;
 
 	regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_DFSR(l), &cfg);
@@ -962,12 +965,12 @@ static void clk_rcg2_dfs_populate_freq(s
 	if (cfg & mask)
 		f->pre_div = cfg & mask;
 
-	cfg &= CFG_SRC_SEL_MASK;
-	cfg >>= CFG_SRC_SEL_SHIFT;
+	src = cfg & CFG_SRC_SEL_MASK;
+	src >>= CFG_SRC_SEL_SHIFT;
 
 	num_parents = clk_hw_get_num_parents(hw);
 	for (i = 0; i < num_parents; i++) {
-		if (cfg == rcg->parent_map[i].cfg) {
+		if (src == rcg->parent_map[i].cfg) {
 			f->src = rcg->parent_map[i].src;
 			p = clk_hw_get_parent_by_index(&rcg->clkr.hw, i);
 			prate = clk_hw_get_rate(p);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clk/qcom/clk-smd-rpm.c linux-libre-5.4.22-gnu/drivers/clk/qcom/clk-smd-rpm.c
--- linux-libre-5.4.21-gnu/drivers/clk/qcom/clk-smd-rpm.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clk/qcom/clk-smd-rpm.c	2020-02-24 02:37:04.000000000 -0500
@@ -648,6 +648,7 @@ static const struct rpm_smd_clk_desc rpm
 };
 
 /* msm8998 */
+DEFINE_CLK_SMD_RPM(msm8998, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
 DEFINE_CLK_SMD_RPM(msm8998, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
 DEFINE_CLK_SMD_RPM(msm8998, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
 DEFINE_CLK_SMD_RPM(msm8998, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
@@ -671,6 +672,8 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm
 DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6);
 DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6);
 static struct clk_smd_rpm *msm8998_clks[] = {
+	[RPM_SMD_BIMC_CLK] = &msm8998_bimc_clk,
+	[RPM_SMD_BIMC_A_CLK] = &msm8998_bimc_a_clk,
 	[RPM_SMD_PCNOC_CLK] = &msm8998_pcnoc_clk,
 	[RPM_SMD_PCNOC_A_CLK] = &msm8998_pcnoc_a_clk,
 	[RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clk/renesas/rcar-gen3-cpg.c linux-libre-5.4.22-gnu/drivers/clk/renesas/rcar-gen3-cpg.c
--- linux-libre-5.4.21-gnu/drivers/clk/renesas/rcar-gen3-cpg.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clk/renesas/rcar-gen3-cpg.c	2020-02-24 02:37:04.000000000 -0500
@@ -464,7 +464,8 @@ static struct clk * __init cpg_rpc_clk_r
 
 	clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
 				     &rpc->div.hw,  &clk_divider_ops,
-				     &rpc->gate.hw, &clk_gate_ops, 0);
+				     &rpc->gate.hw, &clk_gate_ops,
+				     CLK_SET_RATE_PARENT);
 	if (IS_ERR(clk)) {
 		kfree(rpc);
 		return clk;
@@ -500,7 +501,8 @@ static struct clk * __init cpg_rpcd2_clk
 
 	clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
 				     &rpcd2->fixed.hw, &clk_fixed_factor_ops,
-				     &rpcd2->gate.hw, &clk_gate_ops, 0);
+				     &rpcd2->gate.hw, &clk_gate_ops,
+				     CLK_SET_RATE_PARENT);
 	if (IS_ERR(clk))
 		kfree(rpcd2);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clk/sunxi-ng/ccu-sun50i-a64.c linux-libre-5.4.22-gnu/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
--- linux-libre-5.4.21-gnu/drivers/clk/sunxi-ng/ccu-sun50i-a64.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clk/sunxi-ng/ccu-sun50i-a64.c	2020-02-24 02:37:04.000000000 -0500
@@ -921,11 +921,26 @@ static const struct sunxi_ccu_desc sun50
 	.num_resets	= ARRAY_SIZE(sun50i_a64_ccu_resets),
 };
 
+static struct ccu_pll_nb sun50i_a64_pll_cpu_nb = {
+	.common	= &pll_cpux_clk.common,
+	/* copy from pll_cpux_clk */
+	.enable	= BIT(31),
+	.lock	= BIT(28),
+};
+
+static struct ccu_mux_nb sun50i_a64_cpu_nb = {
+	.common		= &cpux_clk.common,
+	.cm		= &cpux_clk.mux,
+	.delay_us	= 1, /* > 8 clock cycles at 24 MHz */
+	.bypass_index	= 1, /* index of 24 MHz oscillator */
+};
+
 static int sun50i_a64_ccu_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	void __iomem *reg;
 	u32 val;
+	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	reg = devm_ioremap_resource(&pdev->dev, res);
@@ -939,7 +954,18 @@ static int sun50i_a64_ccu_probe(struct p
 
 	writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
 
-	return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
+	ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
+	if (ret)
+		return ret;
+
+	/* Gate then ungate PLL CPU after any rate changes */
+	ccu_pll_notifier_register(&sun50i_a64_pll_cpu_nb);
+
+	/* Reparent CPU during PLL CPU rate changes */
+	ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
+				  &sun50i_a64_cpu_nb);
+
+	return 0;
 }
 
 static const struct of_device_id sun50i_a64_ccu_ids[] = {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clk/ti/clk-7xx.c linux-libre-5.4.22-gnu/drivers/clk/ti/clk-7xx.c
--- linux-libre-5.4.21-gnu/drivers/clk/ti/clk-7xx.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clk/ti/clk-7xx.c	2020-02-24 02:37:04.000000000 -0500
@@ -405,7 +405,7 @@ static const struct omap_clkctrl_bit_dat
 };
 
 static const struct omap_clkctrl_reg_data dra7_gmac_clkctrl_regs[] __initconst = {
-	{ DRA7_GMAC_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "dpll_gmac_ck" },
+	{ DRA7_GMAC_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "gmac_main_clk" },
 	{ 0 },
 };
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clk/uniphier/clk-uniphier-peri.c linux-libre-5.4.22-gnu/drivers/clk/uniphier/clk-uniphier-peri.c
--- linux-libre-5.4.21-gnu/drivers/clk/uniphier/clk-uniphier-peri.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clk/uniphier/clk-uniphier-peri.c	2020-02-24 02:37:04.000000000 -0500
@@ -18,8 +18,8 @@
 #define UNIPHIER_PERI_CLK_FI2C(idx, ch)					\
 	UNIPHIER_CLK_GATE("i2c" #ch, (idx), "i2c", 0x24, 24 + (ch))
 
-#define UNIPHIER_PERI_CLK_SCSSI(idx)					\
-	UNIPHIER_CLK_GATE("scssi", (idx), "spi", 0x20, 17)
+#define UNIPHIER_PERI_CLK_SCSSI(idx, ch)				\
+	UNIPHIER_CLK_GATE("scssi" #ch, (idx), "spi", 0x20, 17 + (ch))
 
 #define UNIPHIER_PERI_CLK_MCSSI(idx)					\
 	UNIPHIER_CLK_GATE("mcssi", (idx), "spi", 0x24, 14)
@@ -35,7 +35,7 @@ const struct uniphier_clk_data uniphier_
 	UNIPHIER_PERI_CLK_I2C(6, 2),
 	UNIPHIER_PERI_CLK_I2C(7, 3),
 	UNIPHIER_PERI_CLK_I2C(8, 4),
-	UNIPHIER_PERI_CLK_SCSSI(11),
+	UNIPHIER_PERI_CLK_SCSSI(11, 0),
 	{ /* sentinel */ }
 };
 
@@ -51,7 +51,10 @@ const struct uniphier_clk_data uniphier_
 	UNIPHIER_PERI_CLK_FI2C(8, 4),
 	UNIPHIER_PERI_CLK_FI2C(9, 5),
 	UNIPHIER_PERI_CLK_FI2C(10, 6),
-	UNIPHIER_PERI_CLK_SCSSI(11),
-	UNIPHIER_PERI_CLK_MCSSI(12),
+	UNIPHIER_PERI_CLK_SCSSI(11, 0),
+	UNIPHIER_PERI_CLK_SCSSI(12, 1),
+	UNIPHIER_PERI_CLK_SCSSI(13, 2),
+	UNIPHIER_PERI_CLK_SCSSI(14, 3),
+	UNIPHIER_PERI_CLK_MCSSI(15),
 	{ /* sentinel */ }
 };
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clocksource/bcm2835_timer.c linux-libre-5.4.22-gnu/drivers/clocksource/bcm2835_timer.c
--- linux-libre-5.4.21-gnu/drivers/clocksource/bcm2835_timer.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clocksource/bcm2835_timer.c	2020-02-24 02:37:04.000000000 -0500
@@ -121,7 +121,7 @@ static int __init bcm2835_timer_init(str
 	ret = setup_irq(irq, &timer->act);
 	if (ret) {
 		pr_err("Can't set up timer IRQ\n");
-		goto err_iounmap;
+		goto err_timer_free;
 	}
 
 	clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff);
@@ -130,6 +130,9 @@ static int __init bcm2835_timer_init(str
 
 	return 0;
 
+err_timer_free:
+	kfree(timer);
+
 err_iounmap:
 	iounmap(base);
 	return ret;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/clocksource/timer-davinci.c linux-libre-5.4.22-gnu/drivers/clocksource/timer-davinci.c
--- linux-libre-5.4.21-gnu/drivers/clocksource/timer-davinci.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/clocksource/timer-davinci.c	2020-02-24 02:37:04.000000000 -0500
@@ -302,10 +302,6 @@ int __init davinci_timer_register(struct
 		return rv;
 	}
 
-	clockevents_config_and_register(&clockevent->dev, tick_rate,
-					DAVINCI_TIMER_MIN_DELTA,
-					DAVINCI_TIMER_MAX_DELTA);
-
 	davinci_clocksource.dev.rating = 300;
 	davinci_clocksource.dev.read = davinci_clocksource_read;
 	davinci_clocksource.dev.mask =
@@ -323,6 +319,10 @@ int __init davinci_timer_register(struct
 		davinci_clocksource_init_tim34(base);
 	}
 
+	clockevents_config_and_register(&clockevent->dev, tick_rate,
+					DAVINCI_TIMER_MIN_DELTA,
+					DAVINCI_TIMER_MAX_DELTA);
+
 	rv = clocksource_register_hz(&davinci_clocksource.dev, tick_rate);
 	if (rv) {
 		pr_err("Unable to register clocksource");
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/crypto/chelsio/chtls/chtls_cm.c linux-libre-5.4.22-gnu/drivers/crypto/chelsio/chtls/chtls_cm.c
--- linux-libre-5.4.21-gnu/drivers/crypto/chelsio/chtls/chtls_cm.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/crypto/chelsio/chtls/chtls_cm.c	2020-02-24 02:37:04.000000000 -0500
@@ -727,6 +727,14 @@ static int chtls_close_listsrv_rpl(struc
 	return 0;
 }
 
+static void chtls_purge_wr_queue(struct sock *sk)
+{
+	struct sk_buff *skb;
+
+	while ((skb = dequeue_wr(sk)) != NULL)
+		kfree_skb(skb);
+}
+
 static void chtls_release_resources(struct sock *sk)
 {
 	struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
@@ -741,6 +749,11 @@ static void chtls_release_resources(stru
 	kfree_skb(csk->txdata_skb_cache);
 	csk->txdata_skb_cache = NULL;
 
+	if (csk->wr_credits != csk->wr_max_credits) {
+		chtls_purge_wr_queue(sk);
+		chtls_reset_wr_list(csk);
+	}
+
 	if (csk->l2t_entry) {
 		cxgb4_l2t_release(csk->l2t_entry);
 		csk->l2t_entry = NULL;
@@ -1735,6 +1748,7 @@ static void chtls_peer_close(struct sock
 		else
 			sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
 	}
+	kfree_skb(skb);
 }
 
 static void chtls_close_con_rpl(struct sock *sk, struct sk_buff *skb)
@@ -2062,19 +2076,6 @@ rel_skb:
 	return 0;
 }
 
-static struct sk_buff *dequeue_wr(struct sock *sk)
-{
-	struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
-	struct sk_buff *skb = csk->wr_skb_head;
-
-	if (likely(skb)) {
-	/* Don't bother clearing the tail */
-		csk->wr_skb_head = WR_SKB_CB(skb)->next_wr;
-		WR_SKB_CB(skb)->next_wr = NULL;
-	}
-	return skb;
-}
-
 static void chtls_rx_ack(struct sock *sk, struct sk_buff *skb)
 {
 	struct cpl_fw4_ack *hdr = cplhdr(skb) + RSS_HDR;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/crypto/chelsio/chtls/chtls_cm.h linux-libre-5.4.22-gnu/drivers/crypto/chelsio/chtls/chtls_cm.h
--- linux-libre-5.4.21-gnu/drivers/crypto/chelsio/chtls/chtls_cm.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/crypto/chelsio/chtls/chtls_cm.h	2020-02-24 02:37:04.000000000 -0500
@@ -185,6 +185,12 @@ static inline void chtls_kfree_skb(struc
 	kfree_skb(skb);
 }
 
+static inline void chtls_reset_wr_list(struct chtls_sock *csk)
+{
+	csk->wr_skb_head = NULL;
+	csk->wr_skb_tail = NULL;
+}
+
 static inline void enqueue_wr(struct chtls_sock *csk, struct sk_buff *skb)
 {
 	WR_SKB_CB(skb)->next_wr = NULL;
@@ -197,4 +203,19 @@ static inline void enqueue_wr(struct cht
 		WR_SKB_CB(csk->wr_skb_tail)->next_wr = skb;
 	csk->wr_skb_tail = skb;
 }
+
+static inline struct sk_buff *dequeue_wr(struct sock *sk)
+{
+	struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+	struct sk_buff *skb = NULL;
+
+	skb = csk->wr_skb_head;
+
+	if (likely(skb)) {
+	 /* Don't bother clearing the tail */
+		csk->wr_skb_head = WR_SKB_CB(skb)->next_wr;
+		WR_SKB_CB(skb)->next_wr = NULL;
+	}
+	return skb;
+}
 #endif
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/crypto/chelsio/chtls/chtls_hw.c linux-libre-5.4.22-gnu/drivers/crypto/chelsio/chtls/chtls_hw.c
--- linux-libre-5.4.21-gnu/drivers/crypto/chelsio/chtls/chtls_hw.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/crypto/chelsio/chtls/chtls_hw.c	2020-02-24 02:37:04.000000000 -0500
@@ -350,6 +350,7 @@ int chtls_setkey(struct chtls_sock *csk,
 	kwr->sc_imm.cmd_more = cpu_to_be32(ULPTX_CMD_V(ULP_TX_SC_IMM));
 	kwr->sc_imm.len = cpu_to_be32(klen);
 
+	lock_sock(sk);
 	/* key info */
 	kctx = (struct _key_ctx *)(kwr + 1);
 	ret = chtls_key_info(csk, kctx, keylen, optname);
@@ -388,8 +389,10 @@ int chtls_setkey(struct chtls_sock *csk,
 		csk->tlshws.txkey = keyid;
 	}
 
+	release_sock(sk);
 	return ret;
 out_notcb:
+	release_sock(sk);
 	free_tls_keyid(sk);
 out_nokey:
 	kfree_skb(skb);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/crypto/Kconfig linux-libre-5.4.22-gnu/drivers/crypto/Kconfig
--- linux-libre-5.4.21-gnu/drivers/crypto/Kconfig	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/crypto/Kconfig	2020-02-24 02:37:04.000000000 -0500
@@ -739,7 +739,7 @@ source "drivers/crypto/stm32/Kconfig"
 
 config CRYPTO_DEV_SAFEXCEL
 	tristate "Inside Secure's SafeXcel cryptographic engine driver"
-	depends on OF || PCI || COMPILE_TEST
+	depends on (OF || PCI || COMPILE_TEST) && HAS_IOMEM
 	select CRYPTO_LIB_AES
 	select CRYPTO_AUTHENC
 	select CRYPTO_BLKCIPHER
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/devfreq/event/exynos-ppmu.c linux-libre-5.4.22-gnu/drivers/devfreq/event/exynos-ppmu.c
--- linux-libre-5.4.21-gnu/drivers/devfreq/event/exynos-ppmu.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/devfreq/event/exynos-ppmu.c	2020-02-24 02:37:04.000000000 -0500
@@ -101,17 +101,22 @@ static struct __exynos_ppmu_events {
 	PPMU_EVENT(dmc1_1),
 };
 
-static int exynos_ppmu_find_ppmu_id(struct devfreq_event_dev *edev)
+static int __exynos_ppmu_find_ppmu_id(const char *edev_name)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(ppmu_events); i++)
-		if (!strcmp(edev->desc->name, ppmu_events[i].name))
+		if (!strcmp(edev_name, ppmu_events[i].name))
 			return ppmu_events[i].id;
 
 	return -EINVAL;
 }
 
+static int exynos_ppmu_find_ppmu_id(struct devfreq_event_dev *edev)
+{
+	return __exynos_ppmu_find_ppmu_id(edev->desc->name);
+}
+
 /*
  * The devfreq-event ops structure for PPMU v1.1
  */
@@ -556,13 +561,11 @@ static int of_get_devfreq_events(struct
 			 * use default if not.
 			 */
 			if (info->ppmu_type == EXYNOS_TYPE_PPMU_V2) {
-				struct devfreq_event_dev edev;
 				int id;
 				/* Not all registers take the same value for
 				 * read+write data count.
 				 */
-				edev.desc = &desc[j];
-				id = exynos_ppmu_find_ppmu_id(&edev);
+				id = __exynos_ppmu_find_ppmu_id(desc[j].name);
 
 				switch (id) {
 				case PPMU_PMNCNT0:
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/devfreq/event/Kconfig linux-libre-5.4.22-gnu/drivers/devfreq/event/Kconfig
--- linux-libre-5.4.21-gnu/drivers/devfreq/event/Kconfig	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/devfreq/event/Kconfig	2020-02-24 02:37:04.000000000 -0500
@@ -34,7 +34,7 @@ config DEVFREQ_EVENT_EXYNOS_PPMU
 
 config DEVFREQ_EVENT_ROCKCHIP_DFI
 	tristate "ROCKCHIP DFI DEVFREQ event Driver"
-	depends on ARCH_ROCKCHIP
+	depends on ARCH_ROCKCHIP || COMPILE_TEST
 	help
 	  This add the devfreq-event driver for Rockchip SoC. It provides DFI
 	  (DDR Monitor Module) driver to count ddr load.
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/devfreq/Kconfig linux-libre-5.4.22-gnu/drivers/devfreq/Kconfig
--- linux-libre-5.4.21-gnu/drivers/devfreq/Kconfig	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/devfreq/Kconfig	2020-02-24 02:37:04.000000000 -0500
@@ -118,7 +118,8 @@ config ARM_TEGRA20_DEVFREQ
 
 config ARM_RK3399_DMC_DEVFREQ
 	tristate "ARM RK3399 DMC DEVFREQ Driver"
-	depends on ARCH_ROCKCHIP
+	depends on (ARCH_ROCKCHIP && HAVE_ARM_SMCCC) || \
+		(COMPILE_TEST && HAVE_ARM_SMCCC)
 	select DEVFREQ_EVENT_ROCKCHIP_DFI
 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
 	select PM_DEVFREQ_EVENT
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/dma/dmaengine.c linux-libre-5.4.22-gnu/drivers/dma/dmaengine.c
--- linux-libre-5.4.21-gnu/drivers/dma/dmaengine.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/dma/dmaengine.c	2020-02-24 02:37:04.000000000 -0500
@@ -179,7 +179,7 @@ __dma_device_satisfies_mask(struct dma_d
 
 static struct module *dma_chan_to_owner(struct dma_chan *chan)
 {
-	return chan->device->dev->driver->owner;
+	return chan->device->owner;
 }
 
 /**
@@ -919,6 +919,8 @@ int dma_async_device_register(struct dma
 		return -EIO;
 	}
 
+	device->owner = device->dev->driver->owner;
+
 	if (dma_has_cap(DMA_MEMCPY, device->cap_mask) && !device->device_prep_dma_memcpy) {
 		dev_err(device->dev,
 			"Device claims capability %s, but op is not defined\n",
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/dma/fsl-qdma.c linux-libre-5.4.22-gnu/drivers/dma/fsl-qdma.c
--- linux-libre-5.4.21-gnu/drivers/dma/fsl-qdma.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/dma/fsl-qdma.c	2020-02-24 02:37:04.000000000 -0500
@@ -304,7 +304,7 @@ static void fsl_qdma_free_chan_resources
 
 	vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
 
-	if (!fsl_queue->comp_pool && !fsl_queue->comp_pool)
+	if (!fsl_queue->comp_pool && !fsl_queue->desc_pool)
 		return;
 
 	list_for_each_entry_safe(comp_temp, _comp_temp,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/dma/imx-sdma.c linux-libre-5.4.22-gnu/drivers/dma/imx-sdma.c
--- linux-libre-5.4.21-gnu/drivers/dma/imx-sdma.c	2020-02-19 17:23:47.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/dma/imx-sdma.c	2020-02-24 05:35:07.000000000 -0500
@@ -760,12 +760,8 @@ static void sdma_start_desc(struct sdma_
 		return;
 	}
 	sdmac->desc = desc = to_sdma_desc(&vd->tx);
-	/*
-	 * Do not delete the node in desc_issued list in cyclic mode, otherwise
-	 * the desc allocated will never be freed in vchan_dma_desc_free_list
-	 */
-	if (!(sdmac->flags & IMX_DMA_SG_LOOP))
-		list_del(&vd->node);
+
+	list_del(&vd->node);
 
 	sdma->channel_control[channel].base_bd_ptr = desc->bd_phys;
 	sdma->channel_control[channel].current_bd_ptr = desc->bd_phys;
@@ -1071,7 +1067,6 @@ static void sdma_channel_terminate_work(
 
 	spin_lock_irqsave(&sdmac->vc.lock, flags);
 	vchan_get_all_descriptors(&sdmac->vc, &head);
-	sdmac->desc = NULL;
 	spin_unlock_irqrestore(&sdmac->vc.lock, flags);
 	vchan_dma_desc_free_list(&sdmac->vc, &head);
 	sdmac->context_loaded = false;
@@ -1080,11 +1075,19 @@ static void sdma_channel_terminate_work(
 static int sdma_disable_channel_async(struct dma_chan *chan)
 {
 	struct sdma_channel *sdmac = to_sdma_chan(chan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdmac->vc.lock, flags);
 
 	sdma_disable_channel(chan);
 
-	if (sdmac->desc)
+	if (sdmac->desc) {
+		vchan_terminate_vdesc(&sdmac->desc->vd);
+		sdmac->desc = NULL;
 		schedule_work(&sdmac->terminate_worker);
+	}
+
+	spin_unlock_irqrestore(&sdmac->vc.lock, flags);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/edac/sifive_edac.c linux-libre-5.4.22-gnu/drivers/edac/sifive_edac.c
--- linux-libre-5.4.21-gnu/drivers/edac/sifive_edac.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/edac/sifive_edac.c	2020-02-24 02:37:04.000000000 -0500
@@ -54,8 +54,8 @@ static int ecc_register(struct platform_
 	p->dci = edac_device_alloc_ctl_info(0, "sifive_ecc", 1, "sifive_ecc",
 					    1, 1, NULL, 0,
 					    edac_device_alloc_index());
-	if (IS_ERR(p->dci))
-		return PTR_ERR(p->dci);
+	if (!p->dci)
+		return -ENOMEM;
 
 	p->dci->dev = &pdev->dev;
 	p->dci->mod_name = "Sifive ECC Manager";
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpio/gpio-grgpio.c linux-libre-5.4.22-gnu/drivers/gpio/gpio-grgpio.c
--- linux-libre-5.4.21-gnu/drivers/gpio/gpio-grgpio.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpio/gpio-grgpio.c	2020-02-24 02:37:04.000000000 -0500
@@ -253,17 +253,16 @@ static int grgpio_irq_map(struct irq_dom
 	lirq->irq = irq;
 	uirq = &priv->uirqs[lirq->index];
 	if (uirq->refcnt == 0) {
+		spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
 		ret = request_irq(uirq->uirq, grgpio_irq_handler, 0,
 				  dev_name(priv->dev), priv);
 		if (ret) {
 			dev_err(priv->dev,
 				"Could not request underlying irq %d\n",
 				uirq->uirq);
-
-			spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
-
 			return ret;
 		}
+		spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
 	}
 	uirq->refcnt++;
 
@@ -309,8 +308,11 @@ static void grgpio_irq_unmap(struct irq_
 	if (index >= 0) {
 		uirq = &priv->uirqs[lirq->index];
 		uirq->refcnt--;
-		if (uirq->refcnt == 0)
+		if (uirq->refcnt == 0) {
+			spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
 			free_irq(uirq->uirq, priv);
+			return;
+		}
 	}
 
 	spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpio/gpiolib.c linux-libre-5.4.22-gnu/drivers/gpio/gpiolib.c
--- linux-libre-5.4.21-gnu/drivers/gpio/gpiolib.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpio/gpiolib.c	2020-02-24 02:37:04.000000000 -0500
@@ -1924,6 +1924,7 @@ static int gpiochip_hierarchy_irq_domain
 				     parent_type);
 	chip_info(gc, "alloc_irqs_parent for %d parent hwirq %d\n",
 		  irq, parent_hwirq);
+	irq_set_lockdep_class(irq, gc->irq.lock_key, gc->irq.request_key);
 	ret = irq_domain_alloc_irqs_parent(d, irq, 1, &parent_fwspec);
 	if (ret)
 		chip_err(gc,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c	2020-02-24 02:37:04.000000000 -0500
@@ -338,17 +338,9 @@ bool amdgpu_atombios_get_connector_info_
 		path_size += le16_to_cpu(path->usSize);
 
 		if (device_support & le16_to_cpu(path->usDeviceTag)) {
-			uint8_t con_obj_id, con_obj_num, con_obj_type;
-
-			con_obj_id =
+			uint8_t con_obj_id =
 			    (le16_to_cpu(path->usConnObjectId) & OBJECT_ID_MASK)
 			    >> OBJECT_ID_SHIFT;
-			con_obj_num =
-			    (le16_to_cpu(path->usConnObjectId) & ENUM_ID_MASK)
-			    >> ENUM_ID_SHIFT;
-			con_obj_type =
-			    (le16_to_cpu(path->usConnObjectId) &
-			     OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
 
 			/* Skip TV/CV support */
 			if ((le16_to_cpu(path->usDeviceTag) ==
@@ -373,14 +365,7 @@ bool amdgpu_atombios_get_connector_info_
 			router.ddc_valid = false;
 			router.cd_valid = false;
 			for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) {
-				uint8_t grph_obj_id, grph_obj_num, grph_obj_type;
-
-				grph_obj_id =
-				    (le16_to_cpu(path->usGraphicObjIds[j]) &
-				     OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
-				grph_obj_num =
-				    (le16_to_cpu(path->usGraphicObjIds[j]) &
-				     ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+				uint8_t grph_obj_type=
 				grph_obj_type =
 				    (le16_to_cpu(path->usGraphicObjIds[j]) &
 				     OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c	2020-02-19 17:20:54.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c	2020-02-24 05:32:31.000000000 -0500
@@ -3457,8 +3457,6 @@ static int amdgpu_device_reset_sriov(str
 	if (r)
 		return r;
 
-	amdgpu_amdkfd_pre_reset(adev);
-
 	/* Resume IP prior to SMC */
 	r = amdgpu_device_ip_reinit_early_sriov(adev);
 	if (r)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdgpu/nv.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdgpu/nv.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdgpu/nv.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdgpu/nv.c	2020-02-24 02:37:04.000000000 -0500
@@ -660,6 +660,12 @@ static int nv_common_early_init(void *ha
 		adev->pg_flags = AMD_PG_SUPPORT_VCN |
 			AMD_PG_SUPPORT_VCN_DPG |
 			AMD_PG_SUPPORT_ATHUB;
+		/* guest vm gets 0xffffffff when reading RCC_DEV0_EPF0_STRAP0,
+		 * as a consequence, the rev_id and external_rev_id are wrong.
+		 * workaround it by hardcoding rev_id to 0 (default value).
+		 */
+		if (amdgpu_sriov_vf(adev))
+			adev->rev_id = 0;
 		adev->external_rev_id = adev->rev_id + 0xa;
 		break;
 	default:
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdgpu/soc15_common.h linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdgpu/soc15_common.h
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdgpu/soc15_common.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdgpu/soc15_common.h	2020-02-24 02:37:04.000000000 -0500
@@ -52,6 +52,7 @@
 		uint32_t old_ = 0;	\
 		uint32_t tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \
 		uint32_t loop = adev->usec_timeout;		\
+		ret = 0;					\
 		while ((tmp_ & (mask)) != (expected_value)) {	\
 			if (old_ != tmp_) {			\
 				loop = adev->usec_timeout;	\
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c	2020-02-24 02:37:04.000000000 -0500
@@ -93,7 +93,7 @@ void kfd_debugfs_init(void)
 			    kfd_debugfs_hqds_by_device, &kfd_debugfs_fops);
 	debugfs_create_file("rls", S_IFREG | 0444, debugfs_root,
 			    kfd_debugfs_rls_by_device, &kfd_debugfs_fops);
-	debugfs_create_file("hang_hws", S_IFREG | 0644, debugfs_root,
+	debugfs_create_file("hang_hws", S_IFREG | 0200, debugfs_root,
 			    NULL, &kfd_debugfs_hang_hws_fops);
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c	2020-02-24 02:37:04.000000000 -0500
@@ -1181,16 +1181,18 @@ static int create_queue_cpsch(struct dev
 
 	list_add(&q->list, &qpd->queues_list);
 	qpd->queue_count++;
+
+	if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+		dqm->sdma_queue_count++;
+	else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
+		dqm->xgmi_sdma_queue_count++;
+
 	if (q->properties.is_active) {
 		dqm->queue_count++;
 		retval = execute_queues_cpsch(dqm,
 				KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
 	}
 
-	if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
-		dqm->sdma_queue_count++;
-	else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
-		dqm->xgmi_sdma_queue_count++;
 	/*
 	 * Unconditionally increment this counter, regardless of the queue's
 	 * type or whether the queue is active.
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,43 +0,0 @@
-/*
- * Copyright 2017 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: AMD
- *
- */
-
-#ifndef _DCN_CALC_MATH_H_
-#define _DCN_CALC_MATH_H_
-
-float dcn_bw_mod(const float arg1, const float arg2);
-float dcn_bw_min2(const float arg1, const float arg2);
-unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2);
-float dcn_bw_max2(const float arg1, const float arg2);
-float dcn_bw_floor2(const float arg, const float significance);
-float dcn_bw_floor(const float arg);
-float dcn_bw_ceil2(const float arg, const float significance);
-float dcn_bw_ceil(const float arg);
-float dcn_bw_max3(float v1, float v2, float v3);
-float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5);
-float dcn_bw_pow(float a, float exp);
-float dcn_bw_log(float a, float b);
-double dcn_bw_fabs(double a);
-
-#endif /* _DCN_CALC_MATH_H_ */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c	2020-02-24 02:37:04.000000000 -0500
@@ -1438,6 +1438,7 @@ void dcn_bw_update_from_pplib(struct dc
 	struct dc_context *ctx = dc->ctx;
 	struct dm_pp_clock_levels_with_voltage fclks = {0}, dcfclks = {0};
 	bool res;
+	unsigned vmin0p65_idx, vmid0p72_idx, vnom0p8_idx, vmax0p9_idx;
 
 	/* TODO: This is not the proper way to obtain fabric_and_dram_bandwidth, should be min(fclk, memclk) */
 	res = dm_pp_get_clock_levels_by_type_with_voltage(
@@ -1449,17 +1450,28 @@ void dcn_bw_update_from_pplib(struct dc
 		res = verify_clock_values(&fclks);
 
 	if (res) {
-		ASSERT(fclks.num_levels >= 3);
-		dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = 32 * (fclks.data[0].clocks_in_khz / 1000.0) / 1000.0;
-		dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc->number_of_channels *
-				(fclks.data[fclks.num_levels - (fclks.num_levels > 2 ? 3 : 2)].clocks_in_khz / 1000.0)
-				* ddr4_dram_factor_single_Channel / 1000.0;
-		dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 = dc->dcn_soc->number_of_channels *
-				(fclks.data[fclks.num_levels - 2].clocks_in_khz / 1000.0)
-				* ddr4_dram_factor_single_Channel / 1000.0;
-		dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = dc->dcn_soc->number_of_channels *
-				(fclks.data[fclks.num_levels - 1].clocks_in_khz / 1000.0)
-				* ddr4_dram_factor_single_Channel / 1000.0;
+		ASSERT(fclks.num_levels);
+
+		vmin0p65_idx = 0;
+		vmid0p72_idx = fclks.num_levels -
+			(fclks.num_levels > 2 ? 3 : (fclks.num_levels > 1 ? 2 : 1));
+		vnom0p8_idx = fclks.num_levels - (fclks.num_levels > 1 ? 2 : 1);
+		vmax0p9_idx = fclks.num_levels - 1;
+
+		dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 =
+			32 * (fclks.data[vmin0p65_idx].clocks_in_khz / 1000.0) / 1000.0;
+		dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 =
+			dc->dcn_soc->number_of_channels *
+			(fclks.data[vmid0p72_idx].clocks_in_khz / 1000.0)
+			* ddr4_dram_factor_single_Channel / 1000.0;
+		dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 =
+			dc->dcn_soc->number_of_channels *
+			(fclks.data[vnom0p8_idx].clocks_in_khz / 1000.0)
+			* ddr4_dram_factor_single_Channel / 1000.0;
+		dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 =
+			dc->dcn_soc->number_of_channels *
+			(fclks.data[vmax0p9_idx].clocks_in_khz / 1000.0)
+			* ddr4_dram_factor_single_Channel / 1000.0;
 	} else
 		BREAK_TO_DEBUGGER();
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/core/dc.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/core/dc.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/core/dc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/core/dc.c	2020-02-24 02:37:04.000000000 -0500
@@ -2267,12 +2267,7 @@ void dc_set_power_state(
 	enum dc_acpi_cm_power_state power_state)
 {
 	struct kref refcount;
-	struct display_mode_lib *dml = kzalloc(sizeof(struct display_mode_lib),
-						GFP_KERNEL);
-
-	ASSERT(dml);
-	if (!dml)
-		return;
+	struct display_mode_lib *dml;
 
 	switch (power_state) {
 	case DC_ACPI_CM_POWER_STATE_D0:
@@ -2294,6 +2289,12 @@ void dc_set_power_state(
 		 * clean state, and dc hw programming optimizations will not
 		 * cause any trouble.
 		 */
+		dml = kzalloc(sizeof(struct display_mode_lib),
+				GFP_KERNEL);
+
+		ASSERT(dml);
+		if (!dml)
+			return;
 
 		/* Preserve refcount */
 		refcount = dc->current_state->refcount;
@@ -2307,10 +2308,10 @@ void dc_set_power_state(
 		dc->current_state->refcount = refcount;
 		dc->current_state->bw_ctx.dml = *dml;
 
+		kfree(dml);
+
 		break;
 	}
-
-	kfree(dml);
 }
 
 void dc_resume(struct dc *dc)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/core/dc_link.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/core/dc_link.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/core/dc_link.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/core/dc_link.c	2020-02-24 02:37:04.000000000 -0500
@@ -948,8 +948,7 @@ bool dc_link_detect(struct dc_link *link
 			same_edid = is_same_edid(&prev_sink->dc_edid, &sink->dc_edid);
 
 		if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
-			sink_caps.transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX &&
-			reason != DETECT_REASON_HPDRX) {
+			sink_caps.transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
 			/*
 			 * TODO debug why Dell 2413 doesn't like
 			 *  two link trainings
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c	2020-02-24 02:37:04.000000000 -0500
@@ -233,12 +233,13 @@ void optc2_set_odm_combine(struct timing
 		struct dc_crtc_timing *timing)
 {
 	struct optc *optc1 = DCN10TG_FROM_TG(optc);
-	/* 2 pieces of memory required for up to 5120 displays, 4 for up to 8192 */
 	int mpcc_hactive = (timing->h_addressable + timing->h_border_left + timing->h_border_right)
 			/ opp_cnt;
-	int memory_mask = mpcc_hactive <= 2560 ? 0x3 : 0xf;
+	uint32_t memory_mask;
 	uint32_t data_fmt = 0;
 
+	ASSERT(opp_cnt == 2);
+
 	/* TODO: In pseudocode but does not affect maximus, delete comment if we dont need on asic
 	 * REG_SET(OTG_GLOBAL_CONTROL2, 0, GLOBAL_UPDATE_LOCK_EN, 1);
 	 * Program OTG register MASTER_UPDATE_LOCK_DB_X/Y to the position before DP frame start
@@ -246,9 +247,17 @@ void optc2_set_odm_combine(struct timing
 	 *		MASTER_UPDATE_LOCK_DB_X, 160,
 	 *		MASTER_UPDATE_LOCK_DB_Y, 240);
 	 */
+
+	/* 2 pieces of memory required for up to 5120 displays, 4 for up to 8192,
+	 * however, for ODM combine we can simplify by always using 4.
+	 * To make sure there's no overlap, each instance "reserves" 2 memories and
+	 * they are uniquely combined here.
+	 */
+	memory_mask = 0x3 << (opp_id[0] * 2) | 0x3 << (opp_id[1] * 2);
+
 	if (REG(OPTC_MEMORY_CONFIG))
 		REG_SET(OPTC_MEMORY_CONFIG, 0,
-			OPTC_MEM_SEL, memory_mask << (optc->inst * 4));
+			OPTC_MEM_SEL, memory_mask);
 
 	if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
 		data_fmt = 1;
@@ -257,7 +266,6 @@ void optc2_set_odm_combine(struct timing
 
 	REG_UPDATE(OPTC_DATA_FORMAT_CONTROL, OPTC_DATA_FORMAT, data_fmt);
 
-	ASSERT(opp_cnt == 2);
 	REG_SET_3(OPTC_DATA_SOURCE_SELECT, 0,
 			OPTC_NUM_OF_INPUT_SEGMENT, 1,
 			OPTC_SEG0_SRC_SEL, opp_id[0],
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c	2020-02-24 02:37:04.000000000 -0500
@@ -24,7 +24,7 @@
  */
 
 #include "dml_common_defs.h"
-#include "../calcs/dcn_calc_math.h"
+#include "dcn_calc_math.h"
 
 #include "dml_inline_defs.h"
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h	2020-02-24 02:37:04.000000000 -0500
@@ -27,7 +27,7 @@
 #define __DML_INLINE_DEFS_H__
 
 #include "dml_common_defs.h"
-#include "../calcs/dcn_calc_math.h"
+#include "dcn_calc_math.h"
 #include "dml_logger.h"
 
 static inline double dml_min(double a, double b)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/inc/dcn_calc_math.h linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/inc/dcn_calc_math.h
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/dc/inc/dcn_calc_math.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/dc/inc/dcn_calc_math.h	2020-02-24 02:37:04.000000000 -0500
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef _DCN_CALC_MATH_H_
+#define _DCN_CALC_MATH_H_
+
+float dcn_bw_mod(const float arg1, const float arg2);
+float dcn_bw_min2(const float arg1, const float arg2);
+unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2);
+float dcn_bw_max2(const float arg1, const float arg2);
+float dcn_bw_floor2(const float arg, const float significance);
+float dcn_bw_floor(const float arg);
+float dcn_bw_ceil2(const float arg, const float significance);
+float dcn_bw_ceil(const float arg);
+float dcn_bw_max3(float v1, float v2, float v3);
+float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5);
+float dcn_bw_pow(float a, float exp);
+float dcn_bw_log(float a, float b);
+double dcn_bw_fabs(double a);
+
+#endif /* _DCN_CALC_MATH_H_ */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/modules/freesync/freesync.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/display/modules/freesync/freesync.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/display/modules/freesync/freesync.c	2020-02-24 02:37:04.000000000 -0500
@@ -803,6 +803,7 @@ void mod_freesync_build_vrr_params(struc
 			2 * in_out_vrr->min_refresh_in_uhz)
 		in_out_vrr->btr.btr_enabled = false;
 
+	in_out_vrr->fixed.fixed_active = false;
 	in_out_vrr->btr.btr_active = false;
 	in_out_vrr->btr.inserted_duration_in_us = 0;
 	in_out_vrr->btr.frames_to_insert = 0;
@@ -822,6 +823,7 @@ void mod_freesync_build_vrr_params(struc
 		in_out_vrr->adjust.v_total_max = stream->timing.v_total;
 	} else if (in_out_vrr->state == VRR_STATE_ACTIVE_VARIABLE &&
 			refresh_range >= MIN_REFRESH_RANGE_IN_US) {
+
 		in_out_vrr->adjust.v_total_min =
 			calc_v_total_from_refresh(stream,
 				in_out_vrr->max_refresh_in_uhz);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c	2020-02-24 02:37:04.000000000 -0500
@@ -1026,12 +1026,15 @@ static int smu10_get_clock_by_type_with_
 
 	clocks->num_levels = 0;
 	for (i = 0; i < pclk_vol_table->count; i++) {
-		clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk * 10;
-		clocks->data[i].latency_in_us = latency_required ?
-						smu10_get_mem_latency(hwmgr,
-						pclk_vol_table->entries[i].clk) :
-						0;
-		clocks->num_levels++;
+		if (pclk_vol_table->entries[i].clk) {
+			clocks->data[clocks->num_levels].clocks_in_khz =
+				pclk_vol_table->entries[i].clk * 10;
+			clocks->data[clocks->num_levels].latency_in_us = latency_required ?
+				smu10_get_mem_latency(hwmgr,
+						      pclk_vol_table->entries[i].clk) :
+				0;
+			clocks->num_levels++;
+		}
 	}
 
 	return 0;
@@ -1077,9 +1080,11 @@ static int smu10_get_clock_by_type_with_
 
 	clocks->num_levels = 0;
 	for (i = 0; i < pclk_vol_table->count; i++) {
-		clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk  * 10;
-		clocks->data[i].voltage_in_mv = pclk_vol_table->entries[i].vol;
-		clocks->num_levels++;
+		if (pclk_vol_table->entries[i].clk) {
+			clocks->data[clocks->num_levels].clocks_in_khz = pclk_vol_table->entries[i].clk  * 10;
+			clocks->data[clocks->num_levels].voltage_in_mv = pclk_vol_table->entries[i].vol;
+			clocks->num_levels++;
+		}
 	}
 
 	return 0;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/drm_client_modeset.c linux-libre-5.4.22-gnu/drivers/gpu/drm/drm_client_modeset.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/drm_client_modeset.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/drm_client_modeset.c	2020-02-24 02:37:04.000000000 -0500
@@ -115,6 +115,33 @@ drm_client_find_modeset(struct drm_clien
 }
 
 static struct drm_display_mode *
+drm_connector_get_tiled_mode(struct drm_connector *connector)
+{
+	struct drm_display_mode *mode;
+
+	list_for_each_entry(mode, &connector->modes, head) {
+		if (mode->hdisplay == connector->tile_h_size &&
+		    mode->vdisplay == connector->tile_v_size)
+			return mode;
+	}
+	return NULL;
+}
+
+static struct drm_display_mode *
+drm_connector_fallback_non_tiled_mode(struct drm_connector *connector)
+{
+	struct drm_display_mode *mode;
+
+	list_for_each_entry(mode, &connector->modes, head) {
+		if (mode->hdisplay == connector->tile_h_size &&
+		    mode->vdisplay == connector->tile_v_size)
+			continue;
+		return mode;
+	}
+	return NULL;
+}
+
+static struct drm_display_mode *
 drm_connector_has_preferred_mode(struct drm_connector *connector, int width, int height)
 {
 	struct drm_display_mode *mode;
@@ -348,8 +375,15 @@ static bool drm_client_target_preferred(
 	struct drm_connector *connector;
 	u64 conn_configured = 0;
 	int tile_pass = 0;
+	int num_tiled_conns = 0;
 	int i;
 
+	for (i = 0; i < connector_count; i++) {
+		if (connectors[i]->has_tile &&
+		    connectors[i]->status == connector_status_connected)
+			num_tiled_conns++;
+	}
+
 retry:
 	for (i = 0; i < connector_count; i++) {
 		connector = connectors[i];
@@ -399,6 +433,28 @@ retry:
 			list_for_each_entry(modes[i], &connector->modes, head)
 				break;
 		}
+		/*
+		 * In case of tiled mode if all tiles not present fallback to
+		 * first available non tiled mode.
+		 * After all tiles are present, try to find the tiled mode
+		 * for all and if tiled mode not present due to fbcon size
+		 * limitations, use first non tiled mode only for
+		 * tile 0,0 and set to no mode for all other tiles.
+		 */
+		if (connector->has_tile) {
+			if (num_tiled_conns <
+			    connector->num_h_tile * connector->num_v_tile ||
+			    (connector->tile_h_loc == 0 &&
+			     connector->tile_v_loc == 0 &&
+			     !drm_connector_get_tiled_mode(connector))) {
+				DRM_DEBUG_KMS("Falling back to non tiled mode on Connector %d\n",
+					      connector->base.id);
+				modes[i] = drm_connector_fallback_non_tiled_mode(connector);
+			} else {
+				modes[i] = drm_connector_get_tiled_mode(connector);
+			}
+		}
+
 		DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
 			  "none");
 		conn_configured |= BIT_ULL(i);
@@ -516,6 +572,7 @@ static bool drm_client_firmware_config(s
 	bool fallback = true, ret = true;
 	int num_connectors_enabled = 0;
 	int num_connectors_detected = 0;
+	int num_tiled_conns = 0;
 	struct drm_modeset_acquire_ctx ctx;
 
 	if (!drm_drv_uses_atomic_modeset(dev))
@@ -533,6 +590,11 @@ static bool drm_client_firmware_config(s
 	memcpy(save_enabled, enabled, count);
 	mask = GENMASK(count - 1, 0);
 	conn_configured = 0;
+	for (i = 0; i < count; i++) {
+		if (connectors[i]->has_tile &&
+		    connectors[i]->status == connector_status_connected)
+			num_tiled_conns++;
+	}
 retry:
 	conn_seq = conn_configured;
 	for (i = 0; i < count; i++) {
@@ -632,6 +694,16 @@ retry:
 				      connector->name);
 			modes[i] = &connector->state->crtc->mode;
 		}
+		/*
+		 * In case of tiled modes, if all tiles are not present
+		 * then fallback to a non tiled mode.
+		 */
+		if (connector->has_tile &&
+		    num_tiled_conns < connector->num_h_tile * connector->num_v_tile) {
+			DRM_DEBUG_KMS("Falling back to non tiled mode on Connector %d\n",
+				      connector->base.id);
+			modes[i] = drm_connector_fallback_non_tiled_mode(connector);
+		}
 		crtcs[i] = new_crtc;
 
 		DRM_DEBUG_KMS("connector %s on [CRTC:%d:%s]: %dx%d%s\n",
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/drm_debugfs_crc.c linux-libre-5.4.22-gnu/drivers/gpu/drm/drm_debugfs_crc.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/drm_debugfs_crc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/drm_debugfs_crc.c	2020-02-24 02:37:04.000000000 -0500
@@ -140,8 +140,8 @@ static ssize_t crc_control_write(struct
 	if (IS_ERR(source))
 		return PTR_ERR(source);
 
-	if (source[len] == '\n')
-		source[len] = '\0';
+	if (source[len - 1] == '\n')
+		source[len - 1] = '\0';
 
 	ret = crtc->funcs->verify_crc_source(crtc, source, &values_cnt);
 	if (ret)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/drm_mipi_dbi.c linux-libre-5.4.22-gnu/drivers/gpu/drm/drm_mipi_dbi.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/drm_mipi_dbi.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/drm_mipi_dbi.c	2020-02-24 02:37:04.000000000 -0500
@@ -367,9 +367,9 @@ static void mipi_dbi_blank(struct mipi_d
 	memset(dbidev->tx_buf, 0, len);
 
 	mipi_dbi_command(dbi, MIPI_DCS_SET_COLUMN_ADDRESS, 0, 0,
-			 (width >> 8) & 0xFF, (width - 1) & 0xFF);
+			 ((width - 1) >> 8) & 0xFF, (width - 1) & 0xFF);
 	mipi_dbi_command(dbi, MIPI_DCS_SET_PAGE_ADDRESS, 0, 0,
-			 (height >> 8) & 0xFF, (height - 1) & 0xFF);
+			 ((height - 1) >> 8) & 0xFF, (height - 1) & 0xFF);
 	mipi_dbi_command_buf(dbi, MIPI_DCS_WRITE_MEMORY_START,
 			     (u8 *)dbidev->tx_buf, len);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/gma500/framebuffer.c linux-libre-5.4.22-gnu/drivers/gpu/drm/gma500/framebuffer.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/gma500/framebuffer.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/gma500/framebuffer.c	2020-02-24 02:37:04.000000000 -0500
@@ -462,6 +462,7 @@ static int psbfb_probe(struct drm_fb_hel
 		container_of(helper, struct psb_fbdev, psb_fb_helper);
 	struct drm_device *dev = psb_fbdev->psb_fb_helper.dev;
 	struct drm_psb_private *dev_priv = dev->dev_private;
+	unsigned int fb_size;
 	int bytespp;
 
 	bytespp = sizes->surface_bpp / 8;
@@ -471,8 +472,11 @@ static int psbfb_probe(struct drm_fb_hel
 	/* If the mode will not fit in 32bit then switch to 16bit to get
 	   a console on full resolution. The X mode setting server will
 	   allocate its own 32bit GEM framebuffer */
-	if (ALIGN(sizes->fb_width * bytespp, 64) * sizes->fb_height >
-	                dev_priv->vram_stolen_size) {
+	fb_size = ALIGN(sizes->surface_width * bytespp, 64) *
+		  sizes->surface_height;
+	fb_size = ALIGN(fb_size, PAGE_SIZE);
+
+	if (fb_size > dev_priv->vram_stolen_size) {
                 sizes->surface_bpp = 16;
                 sizes->surface_depth = 16;
         }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/ingenic/ingenic-drm.c linux-libre-5.4.22-gnu/drivers/gpu/drm/ingenic/ingenic-drm.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/ingenic/ingenic-drm.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/ingenic/ingenic-drm.c	2020-02-24 02:37:04.000000000 -0500
@@ -371,14 +371,18 @@ static void ingenic_drm_plane_atomic_upd
 	struct ingenic_drm *priv = drm_plane_get_priv(plane);
 	struct drm_plane_state *state = plane->state;
 	unsigned int width, height, cpp;
+	dma_addr_t addr;
 
-	width = state->crtc->state->adjusted_mode.hdisplay;
-	height = state->crtc->state->adjusted_mode.vdisplay;
-	cpp = state->fb->format->cpp[plane->index];
+	if (state && state->fb) {
+		addr = drm_fb_cma_get_gem_addr(state->fb, state, 0);
+		width = state->crtc->state->adjusted_mode.hdisplay;
+		height = state->crtc->state->adjusted_mode.vdisplay;
+		cpp = state->fb->format->cpp[plane->index];
 
-	priv->dma_hwdesc->addr = drm_fb_cma_get_gem_addr(state->fb, state, 0);
-	priv->dma_hwdesc->cmd = width * height * cpp / 4;
-	priv->dma_hwdesc->cmd |= JZ_LCD_CMD_EOF_IRQ;
+		priv->dma_hwdesc->addr = addr;
+		priv->dma_hwdesc->cmd = width * height * cpp / 4;
+		priv->dma_hwdesc->cmd |= JZ_LCD_CMD_EOF_IRQ;
+	}
 }
 
 static void ingenic_drm_encoder_atomic_mode_set(struct drm_encoder *encoder,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/mediatek/mtk_drm_crtc.c linux-libre-5.4.22-gnu/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/mediatek/mtk_drm_crtc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/mediatek/mtk_drm_crtc.c	2020-02-24 02:37:04.000000000 -0500
@@ -298,6 +298,7 @@ err_pm_runtime_put:
 static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
 {
 	struct drm_device *drm = mtk_crtc->base.dev;
+	struct drm_crtc *crtc = &mtk_crtc->base;
 	int i;
 
 	DRM_DEBUG_DRIVER("%s\n", __func__);
@@ -319,6 +320,13 @@ static void mtk_crtc_ddp_hw_fini(struct
 	mtk_disp_mutex_unprepare(mtk_crtc->mutex);
 
 	pm_runtime_put(drm->dev);
+
+	if (crtc->state->event && !crtc->state->active) {
+		spin_lock_irq(&crtc->dev->event_lock);
+		drm_crtc_send_vblank_event(crtc, crtc->state->event);
+		crtc->state->event = NULL;
+		spin_unlock_irq(&crtc->dev->event_lock);
+	}
 }
 
 static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
@@ -529,6 +537,7 @@ int mtk_drm_crtc_create(struct drm_devic
 	int pipe = priv->num_pipes;
 	int ret;
 	int i;
+	uint gamma_lut_size = 0;
 
 	if (!path)
 		return 0;
@@ -579,6 +588,9 @@ int mtk_drm_crtc_create(struct drm_devic
 		}
 
 		mtk_crtc->ddp_comp[i] = comp;
+
+		if (comp->funcs && comp->funcs->gamma_set)
+			gamma_lut_size = MTK_LUT_SIZE;
 	}
 
 	mtk_crtc->layer_nr = mtk_ddp_comp_layer_nr(mtk_crtc->ddp_comp[0]);
@@ -601,8 +613,10 @@ int mtk_drm_crtc_create(struct drm_devic
 				NULL, pipe);
 	if (ret < 0)
 		return ret;
-	drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE);
-	drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, false, MTK_LUT_SIZE);
+
+	if (gamma_lut_size)
+		drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
+	drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, false, gamma_lut_size);
 	priv->num_pipes++;
 
 	return 0;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/msm/adreno/a5xx_gpu.c linux-libre-5.4.22-gnu/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/msm/adreno/a5xx_gpu.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/msm/adreno/a5xx_gpu.c	2020-02-24 02:37:04.000000000 -0500
@@ -726,11 +726,18 @@ static int a5xx_hw_init(struct msm_gpu *
 		gpu->funcs->flush(gpu, gpu->rb[0]);
 		if (!a5xx_idle(gpu, gpu->rb[0]))
 			return -EINVAL;
-	} else {
-		/* Print a warning so if we die, we know why */
+	} else if (ret == -ENODEV) {
+		/*
+		 * This device does not use zap shader (but print a warning
+		 * just in case someone got their dt wrong.. hopefully they
+		 * have a debug UART to realize the error of their ways...
+		 * if you mess this up you are about to crash horribly)
+		 */
 		dev_warn_once(gpu->dev->dev,
 			"Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
 		gpu_write(gpu, REG_A5XX_RBBM_SECVID_TRUST_CNTL, 0x0);
+	} else {
+		return ret;
 	}
 
 	/* Last step - yield the ringbuffer */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/msm/adreno/a6xx_gpu.c linux-libre-5.4.22-gnu/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/msm/adreno/a6xx_gpu.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/msm/adreno/a6xx_gpu.c	2020-02-24 02:37:04.000000000 -0500
@@ -537,12 +537,19 @@ static int a6xx_hw_init(struct msm_gpu *
 		a6xx_flush(gpu, gpu->rb[0]);
 		if (!a6xx_idle(gpu, gpu->rb[0]))
 			return -EINVAL;
-	} else {
-		/* Print a warning so if we die, we know why */
+	} else if (ret == -ENODEV) {
+		/*
+		 * This device does not use zap shader (but print a warning
+		 * just in case someone got their dt wrong.. hopefully they
+		 * have a debug UART to realize the error of their ways...
+		 * if you mess this up you are about to crash horribly)
+		 */
 		dev_warn_once(gpu->dev->dev,
 			"Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
 		gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
 		ret = 0;
+	} else {
+		return ret;
 	}
 
 out:
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nouveau_dmem.c linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nouveau_dmem.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nouveau_dmem.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nouveau_dmem.c	2020-02-24 02:37:04.000000000 -0500
@@ -635,10 +635,10 @@ nouveau_dmem_migrate_vma(struct nouveau_
 	unsigned long c, i;
 	int ret = -ENOMEM;
 
-	args.src = kcalloc(max, sizeof(args.src), GFP_KERNEL);
+	args.src = kcalloc(max, sizeof(*args.src), GFP_KERNEL);
 	if (!args.src)
 		goto out;
-	args.dst = kcalloc(max, sizeof(args.dst), GFP_KERNEL);
+	args.dst = kcalloc(max, sizeof(*args.dst), GFP_KERNEL);
 	if (!args.dst)
 		goto out_free_src;
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nouveau_fence.c linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nouveau_fence.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nouveau_fence.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nouveau_fence.c	2020-02-24 02:37:04.000000000 -0500
@@ -156,7 +156,7 @@ nouveau_fence_wait_uevent_handler(struct
 
 		fence = list_entry(fctx->pending.next, typeof(*fence), head);
 		chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock));
-		if (nouveau_fence_update(fence->channel, fctx))
+		if (nouveau_fence_update(chan, fctx))
 			ret = NVIF_NOTIFY_DROP;
 	}
 	spin_unlock_irqrestore(&fctx->lock, flags);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nouveau_ttm.c linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nouveau_ttm.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nouveau_ttm.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nouveau_ttm.c	2020-02-24 02:37:04.000000000 -0500
@@ -63,14 +63,12 @@ nouveau_vram_manager_new(struct ttm_mem_
 {
 	struct nouveau_bo *nvbo = nouveau_bo(bo);
 	struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
-	struct nouveau_mem *mem;
 	int ret;
 
 	if (drm->client.device.info.ram_size == 0)
 		return -ENOMEM;
 
 	ret = nouveau_mem_new(&drm->master, nvbo->kind, nvbo->comp, reg);
-	mem = nouveau_mem(reg);
 	if (ret)
 		return ret;
 
@@ -103,11 +101,9 @@ nouveau_gart_manager_new(struct ttm_mem_
 {
 	struct nouveau_bo *nvbo = nouveau_bo(bo);
 	struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
-	struct nouveau_mem *mem;
 	int ret;
 
 	ret = nouveau_mem_new(&drm->master, nvbo->kind, nvbo->comp, reg);
-	mem = nouveau_mem(reg);
 	if (ret)
 		return ret;
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nvkm/core/memory.c linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nvkm/core/memory.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nvkm/core/memory.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nvkm/core/memory.c	2020-02-24 02:37:04.000000000 -0500
@@ -91,8 +91,8 @@ nvkm_memory_tags_get(struct nvkm_memory
 	}
 
 	refcount_set(&tags->refcount, 1);
+	*ptags = memory->tags = tags;
 	mutex_unlock(&fb->subdev.mutex);
-	*ptags = tags;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c	2020-02-24 02:37:04.000000000 -0500
@@ -74,6 +74,8 @@ nv50_disp_chan_mthd(struct nv50_disp_cha
 
 	if (debug > subdev->debug)
 		return;
+	if (!mthd)
+		return;
 
 	for (i = 0; (list = mthd->data[i].mthd) != NULL; i++) {
 		u32 base = chan->head * mthd->addr;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c	2020-02-24 02:37:04.000000000 -0500
@@ -143,23 +143,24 @@ gk20a_gr_av_to_method(struct gf100_gr *g
 
 	nent = (fuc.size / sizeof(struct gk20a_fw_av));
 
-	pack = vzalloc((sizeof(*pack) * max_classes) +
-		       (sizeof(*init) * (nent + 1)));
+	pack = vzalloc((sizeof(*pack) * (max_classes + 1)) +
+		       (sizeof(*init) * (nent + max_classes + 1)));
 	if (!pack) {
 		ret = -ENOMEM;
 		goto end;
 	}
 
-	init = (void *)(pack + max_classes);
+	init = (void *)(pack + max_classes + 1);
 
-	for (i = 0; i < nent; i++) {
-		struct gf100_gr_init *ent = &init[i];
+	for (i = 0; i < nent; i++, init++) {
 		struct gk20a_fw_av *av = &((struct gk20a_fw_av *)fuc.data)[i];
 		u32 class = av->addr & 0xffff;
 		u32 addr = (av->addr & 0xffff0000) >> 14;
 
 		if (prevclass != class) {
-			pack[classidx].init = ent;
+			if (prevclass) /* Add terminator to the method list. */
+				init++;
+			pack[classidx].init = init;
 			pack[classidx].type = class;
 			prevclass = class;
 			if (++classidx >= max_classes) {
@@ -169,10 +170,10 @@ gk20a_gr_av_to_method(struct gf100_gr *g
 			}
 		}
 
-		ent->addr = addr;
-		ent->data = av->data;
-		ent->count = 1;
-		ent->pitch = 1;
+		init->addr = addr;
+		init->data = av->data;
+		init->count = 1;
+		init->pitch = 1;
 	}
 
 	*ppack = pack;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c	2020-02-24 02:37:04.000000000 -0500
@@ -146,6 +146,7 @@ nvkm_fault_dtor(struct nvkm_subdev *subd
 	struct nvkm_fault *fault = nvkm_fault(subdev);
 	int i;
 
+	nvkm_notify_fini(&fault->nrpfb);
 	nvkm_event_fini(&fault->event);
 
 	for (i = 0; i < fault->buffer_nr; i++) {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c	2020-02-19 17:22:42.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c	2020-02-24 05:34:03.000000000 -0500
@@ -108,6 +108,7 @@ gm20b_secboot_new(struct nvkm_device *de
 	struct gm200_secboot *gsb;
 	struct nvkm_acr *acr;
 
+	*psb = NULL;
 	acr = acr_r352_new(BIT(NVKM_SECBOOT_FALCON_FECS) |
 			   BIT(NVKM_SECBOOT_FALCON_PMU));
 	if (IS_ERR(acr))
@@ -116,10 +117,8 @@ gm20b_secboot_new(struct nvkm_device *de
 	acr->optional_falcons = BIT(NVKM_SECBOOT_FALCON_PMU);
 
 	gsb = kzalloc(sizeof(*gsb), GFP_KERNEL);
-	if (!gsb) {
-		psb = NULL;
+	if (!gsb)
 		return -ENOMEM;
-	}
 	*psb = &gsb->base;
 
 	ret = nvkm_secboot_ctor(&gm20b_secboot, acr, device, index, &gsb->base);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/panel/panel-simple.c linux-libre-5.4.22-gnu/drivers/gpu/drm/panel/panel-simple.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/panel/panel-simple.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/panel/panel-simple.c	2020-02-24 02:37:04.000000000 -0500
@@ -2048,6 +2048,40 @@ static const struct drm_display_mode mit
 	.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
 };
 
+static const struct drm_display_mode logicpd_type_28_mode = {
+	.clock = 9000,
+	.hdisplay = 480,
+	.hsync_start = 480 + 3,
+	.hsync_end = 480 + 3 + 42,
+	.htotal = 480 + 3 + 42 + 2,
+
+	.vdisplay = 272,
+	.vsync_start = 272 + 2,
+	.vsync_end = 272 + 2 + 11,
+	.vtotal = 272 + 2 + 11 + 3,
+	.vrefresh = 60,
+	.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
+};
+
+static const struct panel_desc logicpd_type_28 = {
+	.modes = &logicpd_type_28_mode,
+	.num_modes = 1,
+	.bpc = 8,
+	.size = {
+		.width = 105,
+		.height = 67,
+	},
+	.delay = {
+		.prepare = 200,
+		.enable = 200,
+		.unprepare = 200,
+		.disable = 200,
+	},
+	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+	.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE |
+		     DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE,
+};
+
 static const struct panel_desc mitsubishi_aa070mc01 = {
 	.modes = &mitsubishi_aa070mc01_mode,
 	.num_modes = 1,
@@ -3265,6 +3299,9 @@ static const struct of_device_id platfor
 		.compatible = "lg,lp129qe",
 		.data = &lg_lp129qe,
 	}, {
+		.compatible = "logicpd,type28",
+		.data = &logicpd_type_28,
+	}, {
 		.compatible = "mitsubishi,aa070mc01-ca1",
 		.data = &mitsubishi_aa070mc01,
 	}, {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/qxl/qxl_kms.c linux-libre-5.4.22-gnu/drivers/gpu/drm/qxl/qxl_kms.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/qxl/qxl_kms.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/qxl/qxl_kms.c	2020-02-24 02:37:04.000000000 -0500
@@ -184,7 +184,7 @@ int qxl_device_init(struct qxl_device *q
 
 	if (!qxl_check_device(qdev)) {
 		r = -ENODEV;
-		goto surface_mapping_free;
+		goto rom_unmap;
 	}
 
 	r = qxl_bo_init(qdev);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/radeon/radeon_display.c linux-libre-5.4.22-gnu/drivers/gpu/drm/radeon/radeon_display.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/radeon/radeon_display.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/radeon/radeon_display.c	2020-02-24 02:37:04.000000000 -0500
@@ -127,6 +127,8 @@ static void dce5_crtc_load_lut(struct dr
 
 	DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
 
+	msleep(10);
+
 	WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
 	       (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) |
 		NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS)));
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c linux-libre-5.4.22-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
--- linux-libre-5.4.21-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c	2020-02-24 02:37:04.000000000 -0500
@@ -209,8 +209,10 @@ int vmw_cmdbuf_res_add(struct vmw_cmdbuf
 
 	cres->hash.key = user_key | (res_type << 24);
 	ret = drm_ht_insert_item(&man->resources, &cres->hash);
-	if (unlikely(ret != 0))
+	if (unlikely(ret != 0)) {
+		kfree(cres);
 		goto out_invalid_key;
+	}
 
 	cres->state = VMW_CMDBUF_RES_ADD;
 	cres->res = vmw_resource_reference(res);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/ide/cmd64x.c linux-libre-5.4.22-gnu/drivers/ide/cmd64x.c
--- linux-libre-5.4.21-gnu/drivers/ide/cmd64x.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/ide/cmd64x.c	2020-02-24 02:37:04.000000000 -0500
@@ -66,6 +66,9 @@ static void cmd64x_program_timings(ide_d
 	struct ide_timing t;
 	u8 arttim = 0;
 
+	if (drive->dn >= ARRAY_SIZE(drwtim_regs))
+		return;
+
 	ide_timing_compute(drive, mode, &t, T, 0);
 
 	/*
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/ide/serverworks.c linux-libre-5.4.22-gnu/drivers/ide/serverworks.c
--- linux-libre-5.4.21-gnu/drivers/ide/serverworks.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/ide/serverworks.c	2020-02-24 02:37:04.000000000 -0500
@@ -115,6 +115,9 @@ static void svwks_set_pio_mode(ide_hwif_
 	struct pci_dev *dev = to_pci_dev(hwif->dev);
 	const u8 pio = drive->pio_mode - XFER_PIO_0;
 
+	if (drive->dn >= ARRAY_SIZE(drive_pci))
+		return;
+
 	pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]);
 
 	if (svwks_csb_check(dev)) {
@@ -141,6 +144,9 @@ static void svwks_set_dma_mode(ide_hwif_
 
 	u8 ultra_enable	 = 0, ultra_timing = 0, dma_timing = 0;
 
+	if (drive->dn >= ARRAY_SIZE(drive_pci2))
+		return;
+
 	pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing);
 	pci_read_config_byte(dev, 0x54, &ultra_enable);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/infiniband/core/cache.c linux-libre-5.4.22-gnu/drivers/infiniband/core/cache.c
--- linux-libre-5.4.21-gnu/drivers/infiniband/core/cache.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/infiniband/core/cache.c	2020-02-24 02:37:04.000000000 -0500
@@ -51,9 +51,8 @@ struct ib_pkey_cache {
 
 struct ib_update_work {
 	struct work_struct work;
-	struct ib_device  *device;
-	u8                 port_num;
-	bool		   enforce_security;
+	struct ib_event event;
+	bool enforce_security;
 };
 
 union ib_gid zgid;
@@ -130,7 +129,7 @@ static void dispatch_gid_change_event(st
 	event.element.port_num	= port;
 	event.event		= IB_EVENT_GID_CHANGE;
 
-	ib_dispatch_event(&event);
+	ib_dispatch_event_clients(&event);
 }
 
 static const char * const gid_type_str[] = {
@@ -1387,9 +1386,8 @@ err:
 	return ret;
 }
 
-static void ib_cache_update(struct ib_device *device,
-			    u8                port,
-			    bool	      enforce_security)
+static int
+ib_cache_update(struct ib_device *device, u8 port, bool enforce_security)
 {
 	struct ib_port_attr       *tprops = NULL;
 	struct ib_pkey_cache      *pkey_cache = NULL, *old_pkey_cache;
@@ -1397,11 +1395,11 @@ static void ib_cache_update(struct ib_de
 	int                        ret;
 
 	if (!rdma_is_port_valid(device, port))
-		return;
+		return -EINVAL;
 
 	tprops = kmalloc(sizeof *tprops, GFP_KERNEL);
 	if (!tprops)
-		return;
+		return -ENOMEM;
 
 	ret = ib_query_port(device, port, tprops);
 	if (ret) {
@@ -1419,8 +1417,10 @@ static void ib_cache_update(struct ib_de
 	pkey_cache = kmalloc(struct_size(pkey_cache, table,
 					 tprops->pkey_tbl_len),
 			     GFP_KERNEL);
-	if (!pkey_cache)
+	if (!pkey_cache) {
+		ret = -ENOMEM;
 		goto err;
+	}
 
 	pkey_cache->table_len = tprops->pkey_tbl_len;
 
@@ -1452,50 +1452,84 @@ static void ib_cache_update(struct ib_de
 
 	kfree(old_pkey_cache);
 	kfree(tprops);
-	return;
+	return 0;
 
 err:
 	kfree(pkey_cache);
 	kfree(tprops);
+	return ret;
 }
 
-static void ib_cache_task(struct work_struct *_work)
+static void ib_cache_event_task(struct work_struct *_work)
 {
 	struct ib_update_work *work =
 		container_of(_work, struct ib_update_work, work);
+	int ret;
+
+	/* Before distributing the cache update event, first sync
+	 * the cache.
+	 */
+	ret = ib_cache_update(work->event.device, work->event.element.port_num,
+			      work->enforce_security);
+
+	/* GID event is notified already for individual GID entries by
+	 * dispatch_gid_change_event(). Hence, notifiy for rest of the
+	 * events.
+	 */
+	if (!ret && work->event.event != IB_EVENT_GID_CHANGE)
+		ib_dispatch_event_clients(&work->event);
 
-	ib_cache_update(work->device,
-			work->port_num,
-			work->enforce_security);
 	kfree(work);
 }
 
-static void ib_cache_event(struct ib_event_handler *handler,
-			   struct ib_event *event)
+static void ib_generic_event_task(struct work_struct *_work)
+{
+	struct ib_update_work *work =
+		container_of(_work, struct ib_update_work, work);
+
+	ib_dispatch_event_clients(&work->event);
+	kfree(work);
+}
+
+static bool is_cache_update_event(const struct ib_event *event)
+{
+	return (event->event == IB_EVENT_PORT_ERR    ||
+		event->event == IB_EVENT_PORT_ACTIVE ||
+		event->event == IB_EVENT_LID_CHANGE  ||
+		event->event == IB_EVENT_PKEY_CHANGE ||
+		event->event == IB_EVENT_CLIENT_REREGISTER ||
+		event->event == IB_EVENT_GID_CHANGE);
+}
+
+/**
+ * ib_dispatch_event - Dispatch an asynchronous event
+ * @event:Event to dispatch
+ *
+ * Low-level drivers must call ib_dispatch_event() to dispatch the
+ * event to all registered event handlers when an asynchronous event
+ * occurs.
+ */
+void ib_dispatch_event(const struct ib_event *event)
 {
 	struct ib_update_work *work;
 
-	if (event->event == IB_EVENT_PORT_ERR    ||
-	    event->event == IB_EVENT_PORT_ACTIVE ||
-	    event->event == IB_EVENT_LID_CHANGE  ||
-	    event->event == IB_EVENT_PKEY_CHANGE ||
-	    event->event == IB_EVENT_CLIENT_REREGISTER ||
-	    event->event == IB_EVENT_GID_CHANGE) {
-		work = kmalloc(sizeof *work, GFP_ATOMIC);
-		if (work) {
-			INIT_WORK(&work->work, ib_cache_task);
-			work->device   = event->device;
-			work->port_num = event->element.port_num;
-			if (event->event == IB_EVENT_PKEY_CHANGE ||
-			    event->event == IB_EVENT_GID_CHANGE)
-				work->enforce_security = true;
-			else
-				work->enforce_security = false;
+	work = kzalloc(sizeof(*work), GFP_ATOMIC);
+	if (!work)
+		return;
 
-			queue_work(ib_wq, &work->work);
-		}
-	}
+	if (is_cache_update_event(event))
+		INIT_WORK(&work->work, ib_cache_event_task);
+	else
+		INIT_WORK(&work->work, ib_generic_event_task);
+
+	work->event = *event;
+	if (event->event == IB_EVENT_PKEY_CHANGE ||
+	    event->event == IB_EVENT_GID_CHANGE)
+		work->enforce_security = true;
+
+	queue_work(ib_wq, &work->work);
 }
+EXPORT_SYMBOL(ib_dispatch_event);
 
 int ib_cache_setup_one(struct ib_device *device)
 {
@@ -1511,9 +1545,6 @@ int ib_cache_setup_one(struct ib_device
 	rdma_for_each_port (device, p)
 		ib_cache_update(device, p, true);
 
-	INIT_IB_EVENT_HANDLER(&device->cache.event_handler,
-			      device, ib_cache_event);
-	ib_register_event_handler(&device->cache.event_handler);
 	return 0;
 }
 
@@ -1535,14 +1566,12 @@ void ib_cache_release_one(struct ib_devi
 
 void ib_cache_cleanup_one(struct ib_device *device)
 {
-	/* The cleanup function unregisters the event handler,
-	 * waits for all in-progress workqueue elements and cleans
-	 * up the GID cache. This function should be called after
-	 * the device was removed from the devices list and all
-	 * clients were removed, so the cache exists but is
+	/* The cleanup function waits for all in-progress workqueue
+	 * elements and cleans up the GID cache. This function should be
+	 * called after the device was removed from the devices list and
+	 * all clients were removed, so the cache exists but is
 	 * non-functional and shouldn't be updated anymore.
 	 */
-	ib_unregister_event_handler(&device->cache.event_handler);
 	flush_workqueue(ib_wq);
 	gid_table_cleanup_one(device);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/infiniband/core/core_priv.h linux-libre-5.4.22-gnu/drivers/infiniband/core/core_priv.h
--- linux-libre-5.4.21-gnu/drivers/infiniband/core/core_priv.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/infiniband/core/core_priv.h	2020-02-24 02:37:04.000000000 -0500
@@ -149,6 +149,7 @@ unsigned long roce_gid_type_mask_support
 int ib_cache_setup_one(struct ib_device *device);
 void ib_cache_cleanup_one(struct ib_device *device);
 void ib_cache_release_one(struct ib_device *device);
+void ib_dispatch_event_clients(struct ib_event *event);
 
 #ifdef CONFIG_CGROUP_RDMA
 void ib_device_register_rdmacg(struct ib_device *device);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/infiniband/core/device.c linux-libre-5.4.22-gnu/drivers/infiniband/core/device.c
--- linux-libre-5.4.21-gnu/drivers/infiniband/core/device.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/infiniband/core/device.c	2020-02-24 02:37:04.000000000 -0500
@@ -591,6 +591,7 @@ struct ib_device *_ib_alloc_device(size_
 
 	INIT_LIST_HEAD(&device->event_handler_list);
 	spin_lock_init(&device->event_handler_lock);
+	init_rwsem(&device->event_handler_rwsem);
 	mutex_init(&device->unregistration_lock);
 	/*
 	 * client_data needs to be alloc because we don't want our mark to be
@@ -1932,17 +1933,15 @@ EXPORT_SYMBOL(ib_set_client_data);
  *
  * ib_register_event_handler() registers an event handler that will be
  * called back when asynchronous IB events occur (as defined in
- * chapter 11 of the InfiniBand Architecture Specification).  This
- * callback may occur in interrupt context.
+ * chapter 11 of the InfiniBand Architecture Specification). This
+ * callback occurs in workqueue context.
  */
 void ib_register_event_handler(struct ib_event_handler *event_handler)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&event_handler->device->event_handler_lock, flags);
+	down_write(&event_handler->device->event_handler_rwsem);
 	list_add_tail(&event_handler->list,
 		      &event_handler->device->event_handler_list);
-	spin_unlock_irqrestore(&event_handler->device->event_handler_lock, flags);
+	up_write(&event_handler->device->event_handler_rwsem);
 }
 EXPORT_SYMBOL(ib_register_event_handler);
 
@@ -1955,35 +1954,23 @@ EXPORT_SYMBOL(ib_register_event_handler)
  */
 void ib_unregister_event_handler(struct ib_event_handler *event_handler)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&event_handler->device->event_handler_lock, flags);
+	down_write(&event_handler->device->event_handler_rwsem);
 	list_del(&event_handler->list);
-	spin_unlock_irqrestore(&event_handler->device->event_handler_lock, flags);
+	up_write(&event_handler->device->event_handler_rwsem);
 }
 EXPORT_SYMBOL(ib_unregister_event_handler);
 
-/**
- * ib_dispatch_event - Dispatch an asynchronous event
- * @event:Event to dispatch
- *
- * Low-level drivers must call ib_dispatch_event() to dispatch the
- * event to all registered event handlers when an asynchronous event
- * occurs.
- */
-void ib_dispatch_event(struct ib_event *event)
+void ib_dispatch_event_clients(struct ib_event *event)
 {
-	unsigned long flags;
 	struct ib_event_handler *handler;
 
-	spin_lock_irqsave(&event->device->event_handler_lock, flags);
+	down_read(&event->device->event_handler_rwsem);
 
 	list_for_each_entry(handler, &event->device->event_handler_list, list)
 		handler->handler(handler, event);
 
-	spin_unlock_irqrestore(&event->device->event_handler_lock, flags);
+	up_read(&event->device->event_handler_rwsem);
 }
-EXPORT_SYMBOL(ib_dispatch_event);
 
 static int iw_query_port(struct ib_device *device,
 			   u8 port_num,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/infiniband/hw/hfi1/chip.c linux-libre-5.4.22-gnu/drivers/infiniband/hw/hfi1/chip.c
--- linux-libre-5.4.21-gnu/drivers/infiniband/hw/hfi1/chip.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/infiniband/hw/hfi1/chip.c	2020-02-24 02:37:04.000000000 -0500
@@ -1685,6 +1685,14 @@ static u64 access_sw_pio_drain(const str
 	return dd->verbs_dev.n_piodrain;
 }
 
+static u64 access_sw_ctx0_seq_drop(const struct cntr_entry *entry,
+				   void *context, int vl, int mode, u64 data)
+{
+	struct hfi1_devdata *dd = context;
+
+	return dd->ctx0_seq_drop;
+}
+
 static u64 access_sw_vtx_wait(const struct cntr_entry *entry,
 			      void *context, int vl, int mode, u64 data)
 {
@@ -4106,6 +4114,7 @@ def_access_ibp_counter(rc_crwaits);
 static struct cntr_entry dev_cntrs[DEV_CNTR_LAST] = {
 [C_RCV_OVF] = RXE32_DEV_CNTR_ELEM(RcvOverflow, RCV_BUF_OVFL_CNT, CNTR_SYNTH),
 [C_RX_LEN_ERR] = RXE32_DEV_CNTR_ELEM(RxLenErr, RCV_LENGTH_ERR_CNT, CNTR_SYNTH),
+[C_RX_SHORT_ERR] = RXE32_DEV_CNTR_ELEM(RxShrErr, RCV_SHORT_ERR_CNT, CNTR_SYNTH),
 [C_RX_ICRC_ERR] = RXE32_DEV_CNTR_ELEM(RxICrcErr, RCV_ICRC_ERR_CNT, CNTR_SYNTH),
 [C_RX_EBP] = RXE32_DEV_CNTR_ELEM(RxEbpCnt, RCV_EBP_CNT, CNTR_SYNTH),
 [C_RX_TID_FULL] = RXE32_DEV_CNTR_ELEM(RxTIDFullEr, RCV_TID_FULL_ERR_CNT,
@@ -4249,6 +4258,8 @@ static struct cntr_entry dev_cntrs[DEV_C
 			    access_sw_cpu_intr),
 [C_SW_CPU_RCV_LIM] = CNTR_ELEM("RcvLimit", 0, 0, CNTR_NORMAL,
 			    access_sw_cpu_rcv_limit),
+[C_SW_CTX0_SEQ_DROP] = CNTR_ELEM("SeqDrop0", 0, 0, CNTR_NORMAL,
+			    access_sw_ctx0_seq_drop),
 [C_SW_VTX_WAIT] = CNTR_ELEM("vTxWait", 0, 0, CNTR_NORMAL,
 			    access_sw_vtx_wait),
 [C_SW_PIO_WAIT] = CNTR_ELEM("PioWait", 0, 0, CNTR_NORMAL,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/infiniband/hw/hfi1/chip.h linux-libre-5.4.22-gnu/drivers/infiniband/hw/hfi1/chip.h
--- linux-libre-5.4.21-gnu/drivers/infiniband/hw/hfi1/chip.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/infiniband/hw/hfi1/chip.h	2020-02-24 02:37:04.000000000 -0500
@@ -859,6 +859,7 @@ static inline int idx_from_vl(int vl)
 enum {
 	C_RCV_OVF = 0,
 	C_RX_LEN_ERR,
+	C_RX_SHORT_ERR,
 	C_RX_ICRC_ERR,
 	C_RX_EBP,
 	C_RX_TID_FULL,
@@ -926,6 +927,7 @@ enum {
 	C_DC_PG_STS_TX_MBE_CNT,
 	C_SW_CPU_INTR,
 	C_SW_CPU_RCV_LIM,
+	C_SW_CTX0_SEQ_DROP,
 	C_SW_VTX_WAIT,
 	C_SW_PIO_WAIT,
 	C_SW_PIO_DRAIN,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/infiniband/hw/hfi1/chip_registers.h linux-libre-5.4.22-gnu/drivers/infiniband/hw/hfi1/chip_registers.h
--- linux-libre-5.4.21-gnu/drivers/infiniband/hw/hfi1/chip_registers.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/infiniband/hw/hfi1/chip_registers.h	2020-02-24 02:37:04.000000000 -0500
@@ -381,6 +381,7 @@
 #define DC_LCB_STS_LINK_TRANSFER_ACTIVE (DC_LCB_CSRS + 0x000000000468)
 #define DC_LCB_STS_ROUND_TRIP_LTP_CNT (DC_LCB_CSRS + 0x0000000004B0)
 #define RCV_LENGTH_ERR_CNT 0
+#define RCV_SHORT_ERR_CNT 2
 #define RCV_ICRC_ERR_CNT 6
 #define RCV_EBP_CNT 9
 #define RCV_BUF_OVFL_CNT 10
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/infiniband/hw/hfi1/driver.c linux-libre-5.4.22-gnu/drivers/infiniband/hw/hfi1/driver.c
--- linux-libre-5.4.21-gnu/drivers/infiniband/hw/hfi1/driver.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/infiniband/hw/hfi1/driver.c	2020-02-24 02:37:04.000000000 -0500
@@ -734,6 +734,7 @@ static noinline int skip_rcv_packet(stru
 {
 	int ret;
 
+	packet->rcd->dd->ctx0_seq_drop++;
 	/* Set up for the next packet */
 	packet->rhqoff += packet->rsize;
 	if (packet->rhqoff >= packet->maxcnt)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/infiniband/hw/hfi1/hfi.h linux-libre-5.4.22-gnu/drivers/infiniband/hw/hfi1/hfi.h
--- linux-libre-5.4.21-gnu/drivers/infiniband/hw/hfi1/hfi.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/infiniband/hw/hfi1/hfi.h	2020-02-24 02:37:04.000000000 -0500
@@ -1153,6 +1153,8 @@ struct hfi1_devdata {
 
 	char *boardname; /* human readable board info */
 
+	u64 ctx0_seq_drop;
+
 	/* reset value */
 	u64 z_int_counter;
 	u64 z_rcv_limit;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/infiniband/hw/hns/hns_roce_mr.c linux-libre-5.4.22-gnu/drivers/infiniband/hw/hns/hns_roce_mr.c
--- linux-libre-5.4.21-gnu/drivers/infiniband/hw/hns/hns_roce_mr.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/infiniband/hw/hns/hns_roce_mr.c	2020-02-24 02:37:04.000000000 -0500
@@ -1062,8 +1062,8 @@ int hns_roce_ib_umem_write_mtt(struct hn
 		if (!(npage % (1 << (mtt->page_shift - PAGE_SHIFT)))) {
 			if (page_addr & ((1 << mtt->page_shift) - 1)) {
 				dev_err(dev,
-					"page_addr 0x%llx is not page_shift %d alignment!\n",
-					page_addr, mtt->page_shift);
+					"page_addr is not page_shift %d alignment!\n",
+					mtt->page_shift);
 				ret = -EINVAL;
 				goto out;
 			}
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/infiniband/hw/mlx5/main.c linux-libre-5.4.22-gnu/drivers/infiniband/hw/mlx5/main.c
--- linux-libre-5.4.21-gnu/drivers/infiniband/hw/mlx5/main.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/infiniband/hw/mlx5/main.c	2020-02-24 02:37:04.000000000 -0500
@@ -829,6 +829,7 @@ static int mlx5_ib_query_device(struct i
 				struct ib_device_attr *props,
 				struct ib_udata *uhw)
 {
+	size_t uhw_outlen = (uhw) ? uhw->outlen : 0;
 	struct mlx5_ib_dev *dev = to_mdev(ibdev);
 	struct mlx5_core_dev *mdev = dev->mdev;
 	int err = -ENOMEM;
@@ -842,12 +843,12 @@ static int mlx5_ib_query_device(struct i
 	u64 max_tso;
 
 	resp_len = sizeof(resp.comp_mask) + sizeof(resp.response_length);
-	if (uhw->outlen && uhw->outlen < resp_len)
+	if (uhw_outlen && uhw_outlen < resp_len)
 		return -EINVAL;
 	else
 		resp.response_length = resp_len;
 
-	if (uhw->inlen && !ib_is_udata_cleared(uhw, 0, uhw->inlen))
+	if (uhw && uhw->inlen && !ib_is_udata_cleared(uhw, 0, uhw->inlen))
 		return -EINVAL;
 
 	memset(props, 0, sizeof(*props));
@@ -911,7 +912,7 @@ static int mlx5_ib_query_device(struct i
 			props->raw_packet_caps |=
 				IB_RAW_PACKET_CAP_CVLAN_STRIPPING;
 
-		if (field_avail(typeof(resp), tso_caps, uhw->outlen)) {
+		if (field_avail(typeof(resp), tso_caps, uhw_outlen)) {
 			max_tso = MLX5_CAP_ETH(mdev, max_lso_cap);
 			if (max_tso) {
 				resp.tso_caps.max_tso = 1 << max_tso;
@@ -921,7 +922,7 @@ static int mlx5_ib_query_device(struct i
 			}
 		}
 
-		if (field_avail(typeof(resp), rss_caps, uhw->outlen)) {
+		if (field_avail(typeof(resp), rss_caps, uhw_outlen)) {
 			resp.rss_caps.rx_hash_function =
 						MLX5_RX_HASH_FUNC_TOEPLITZ;
 			resp.rss_caps.rx_hash_fields_mask =
@@ -941,9 +942,9 @@ static int mlx5_ib_query_device(struct i
 			resp.response_length += sizeof(resp.rss_caps);
 		}
 	} else {
-		if (field_avail(typeof(resp), tso_caps, uhw->outlen))
+		if (field_avail(typeof(resp), tso_caps, uhw_outlen))
 			resp.response_length += sizeof(resp.tso_caps);
-		if (field_avail(typeof(resp), rss_caps, uhw->outlen))
+		if (field_avail(typeof(resp), rss_caps, uhw_outlen))
 			resp.response_length += sizeof(resp.rss_caps);
 	}
 
@@ -1066,7 +1067,7 @@ static int mlx5_ib_query_device(struct i
 						MLX5_MAX_CQ_PERIOD;
 	}
 
-	if (field_avail(typeof(resp), cqe_comp_caps, uhw->outlen)) {
+	if (field_avail(typeof(resp), cqe_comp_caps, uhw_outlen)) {
 		resp.response_length += sizeof(resp.cqe_comp_caps);
 
 		if (MLX5_CAP_GEN(dev->mdev, cqe_compression)) {
@@ -1084,7 +1085,7 @@ static int mlx5_ib_query_device(struct i
 		}
 	}
 
-	if (field_avail(typeof(resp), packet_pacing_caps, uhw->outlen) &&
+	if (field_avail(typeof(resp), packet_pacing_caps, uhw_outlen) &&
 	    raw_support) {
 		if (MLX5_CAP_QOS(mdev, packet_pacing) &&
 		    MLX5_CAP_GEN(mdev, qos)) {
@@ -1103,7 +1104,7 @@ static int mlx5_ib_query_device(struct i
 	}
 
 	if (field_avail(typeof(resp), mlx5_ib_support_multi_pkt_send_wqes,
-			uhw->outlen)) {
+			uhw_outlen)) {
 		if (MLX5_CAP_ETH(mdev, multi_pkt_send_wqe))
 			resp.mlx5_ib_support_multi_pkt_send_wqes =
 				MLX5_IB_ALLOW_MPW;
@@ -1116,7 +1117,7 @@ static int mlx5_ib_query_device(struct i
 			sizeof(resp.mlx5_ib_support_multi_pkt_send_wqes);
 	}
 
-	if (field_avail(typeof(resp), flags, uhw->outlen)) {
+	if (field_avail(typeof(resp), flags, uhw_outlen)) {
 		resp.response_length += sizeof(resp.flags);
 
 		if (MLX5_CAP_GEN(mdev, cqe_compression_128))
@@ -1132,8 +1133,7 @@ static int mlx5_ib_query_device(struct i
 		resp.flags |= MLX5_IB_QUERY_DEV_RESP_FLAGS_SCAT2CQE_DCT;
 	}
 
-	if (field_avail(typeof(resp), sw_parsing_caps,
-			uhw->outlen)) {
+	if (field_avail(typeof(resp), sw_parsing_caps, uhw_outlen)) {
 		resp.response_length += sizeof(resp.sw_parsing_caps);
 		if (MLX5_CAP_ETH(mdev, swp)) {
 			resp.sw_parsing_caps.sw_parsing_offloads |=
@@ -1153,7 +1153,7 @@ static int mlx5_ib_query_device(struct i
 		}
 	}
 
-	if (field_avail(typeof(resp), striding_rq_caps, uhw->outlen) &&
+	if (field_avail(typeof(resp), striding_rq_caps, uhw_outlen) &&
 	    raw_support) {
 		resp.response_length += sizeof(resp.striding_rq_caps);
 		if (MLX5_CAP_GEN(mdev, striding_rq)) {
@@ -1170,8 +1170,7 @@ static int mlx5_ib_query_device(struct i
 		}
 	}
 
-	if (field_avail(typeof(resp), tunnel_offloads_caps,
-			uhw->outlen)) {
+	if (field_avail(typeof(resp), tunnel_offloads_caps, uhw_outlen)) {
 		resp.response_length += sizeof(resp.tunnel_offloads_caps);
 		if (MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan))
 			resp.tunnel_offloads_caps |=
@@ -1192,7 +1191,7 @@ static int mlx5_ib_query_device(struct i
 				MLX5_IB_TUNNELED_OFFLOADS_MPLS_UDP;
 	}
 
-	if (uhw->outlen) {
+	if (uhw_outlen) {
 		err = ib_copy_to_udata(uhw, &resp, resp.response_length);
 
 		if (err)
@@ -4738,7 +4737,6 @@ static int __get_port_caps(struct mlx5_i
 	struct ib_device_attr *dprops = NULL;
 	struct ib_port_attr *pprops = NULL;
 	int err = -ENOMEM;
-	struct ib_udata uhw = {.inlen = 0, .outlen = 0};
 
 	pprops = kzalloc(sizeof(*pprops), GFP_KERNEL);
 	if (!pprops)
@@ -4748,7 +4746,7 @@ static int __get_port_caps(struct mlx5_i
 	if (!dprops)
 		goto out;
 
-	err = mlx5_ib_query_device(&dev->ib_dev, dprops, &uhw);
+	err = mlx5_ib_query_device(&dev->ib_dev, dprops, NULL);
 	if (err) {
 		mlx5_ib_warn(dev, "query_device failed %d\n", err);
 		goto out;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/infiniband/sw/rxe/rxe_verbs.h linux-libre-5.4.22-gnu/drivers/infiniband/sw/rxe/rxe_verbs.h
--- linux-libre-5.4.21-gnu/drivers/infiniband/sw/rxe/rxe_verbs.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/infiniband/sw/rxe/rxe_verbs.h	2020-02-24 02:37:04.000000000 -0500
@@ -407,7 +407,7 @@ struct rxe_dev {
 	struct list_head	pending_mmaps;
 
 	spinlock_t		mmap_offset_lock; /* guard mmap_offset */
-	int			mmap_offset;
+	u64			mmap_offset;
 
 	atomic64_t		stats_counters[RXE_NUM_OF_COUNTERS];
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/input/touchscreen/edt-ft5x06.c linux-libre-5.4.22-gnu/drivers/input/touchscreen/edt-ft5x06.c
--- linux-libre-5.4.21-gnu/drivers/input/touchscreen/edt-ft5x06.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/input/touchscreen/edt-ft5x06.c	2020-02-24 02:37:04.000000000 -0500
@@ -1041,6 +1041,7 @@ static int edt_ft5x06_ts_probe(struct i2
 {
 	const struct edt_i2c_chip_data *chip_data;
 	struct edt_ft5x06_ts_data *tsdata;
+	u8 buf[2] = { 0xfc, 0x00 };
 	struct input_dev *input;
 	unsigned long irq_flags;
 	int error;
@@ -1110,6 +1111,12 @@ static int edt_ft5x06_ts_probe(struct i2
 		return error;
 	}
 
+	/*
+	 * Dummy read access. EP0700MLP1 returns bogus data on the first
+	 * register read access and ignores writes.
+	 */
+	edt_ft5x06_ts_readwrite(tsdata->client, 2, buf, 2, buf);
+
 	edt_ft5x06_ts_set_regs(tsdata);
 	edt_ft5x06_ts_get_defaults(&client->dev, tsdata);
 	edt_ft5x06_ts_get_parameters(tsdata);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/iommu/amd_iommu.c linux-libre-5.4.22-gnu/drivers/iommu/amd_iommu.c
--- linux-libre-5.4.21-gnu/drivers/iommu/amd_iommu.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/iommu/amd_iommu.c	2020-02-24 02:37:04.000000000 -0500
@@ -272,11 +272,8 @@ static struct pci_dev *setup_aliases(str
 	 */
 	ivrs_alias = amd_iommu_alias_table[pci_dev_id(pdev)];
 	if (ivrs_alias != pci_dev_id(pdev) &&
-	    PCI_BUS_NUM(ivrs_alias) == pdev->bus->number) {
-		pci_add_dma_alias(pdev, ivrs_alias & 0xff);
-		pci_info(pdev, "Added PCI DMA alias %02x.%d\n",
-			PCI_SLOT(ivrs_alias), PCI_FUNC(ivrs_alias));
-	}
+	    PCI_BUS_NUM(ivrs_alias) == pdev->bus->number)
+		pci_add_dma_alias(pdev, ivrs_alias & 0xff, 1);
 
 	clone_aliases(pdev);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/iommu/amd_iommu_init.c linux-libre-5.4.22-gnu/drivers/iommu/amd_iommu_init.c
--- linux-libre-5.4.21-gnu/drivers/iommu/amd_iommu_init.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/iommu/amd_iommu_init.c	2020-02-24 02:37:04.000000000 -0500
@@ -147,7 +147,7 @@ bool amd_iommu_dump;
 bool amd_iommu_irq_remap __read_mostly;
 
 int amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_VAPIC;
-static int amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE;
+static int amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;
 
 static bool amd_iommu_detected;
 static bool __initdata amd_iommu_disabled;
@@ -1523,8 +1523,6 @@ static int __init init_iommu_one(struct
 			iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
 		if (((h->efr_attr & (0x1 << IOMMU_FEAT_GASUP_SHIFT)) == 0))
 			amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
-		if (((h->efr_attr & (0x1 << IOMMU_FEAT_XTSUP_SHIFT)) == 0))
-			amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;
 		break;
 	case 0x11:
 	case 0x40:
@@ -1534,8 +1532,15 @@ static int __init init_iommu_one(struct
 			iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
 		if (((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0))
 			amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
-		if (((h->efr_reg & (0x1 << IOMMU_EFR_XTSUP_SHIFT)) == 0))
-			amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;
+		/*
+		 * Note: Since iommu_update_intcapxt() leverages
+		 * the IOMMU MMIO access to MSI capability block registers
+		 * for MSI address lo/hi/data, we need to check both
+		 * EFR[XtSup] and EFR[MsiCapMmioSup] for x2APIC support.
+		 */
+		if ((h->efr_reg & BIT(IOMMU_EFR_XTSUP_SHIFT)) &&
+		    (h->efr_reg & BIT(IOMMU_EFR_MSICAPMMIOSUP_SHIFT)))
+			amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE;
 		break;
 	default:
 		return -EINVAL;
@@ -1996,8 +2001,8 @@ static int iommu_init_intcapxt(struct am
 	struct irq_affinity_notify *notify = &iommu->intcapxt_notify;
 
 	/**
-	 * IntCapXT requires XTSup=1, which can be inferred
-	 * amd_iommu_xt_mode.
+	 * IntCapXT requires XTSup=1 and MsiCapMmioSup=1,
+	 * which can be inferred from amd_iommu_xt_mode.
 	 */
 	if (amd_iommu_xt_mode != IRQ_REMAP_X2APIC_MODE)
 		return 0;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/iommu/amd_iommu_types.h linux-libre-5.4.22-gnu/drivers/iommu/amd_iommu_types.h
--- linux-libre-5.4.21-gnu/drivers/iommu/amd_iommu_types.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/iommu/amd_iommu_types.h	2020-02-24 02:37:04.000000000 -0500
@@ -377,12 +377,12 @@
 #define IOMMU_CAP_EFR     27
 
 /* IOMMU Feature Reporting Field (for IVHD type 10h */
-#define IOMMU_FEAT_XTSUP_SHIFT	0
 #define IOMMU_FEAT_GASUP_SHIFT	6
 
 /* IOMMU Extended Feature Register (EFR) */
 #define IOMMU_EFR_XTSUP_SHIFT	2
 #define IOMMU_EFR_GASUP_SHIFT	7
+#define IOMMU_EFR_MSICAPMMIOSUP_SHIFT	46
 
 #define MAX_DOMAIN_ID 65536
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/iommu/arm-smmu-v3.c linux-libre-5.4.22-gnu/drivers/iommu/arm-smmu-v3.c
--- linux-libre-5.4.21-gnu/drivers/iommu/arm-smmu-v3.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/iommu/arm-smmu-v3.c	2020-02-24 02:37:04.000000000 -0500
@@ -1643,7 +1643,8 @@ static void arm_smmu_write_strtab_ent(st
 						 STRTAB_STE_1_EATS_TRANS));
 
 	arm_smmu_sync_ste_for_sid(smmu, sid);
-	dst[0] = cpu_to_le64(val);
+	/* See comment in arm_smmu_write_ctx_desc() */
+	WRITE_ONCE(dst[0], cpu_to_le64(val));
 	arm_smmu_sync_ste_for_sid(smmu, sid);
 
 	/* It's likely that we'll want to use the new STE soon */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/iommu/dmar.c linux-libre-5.4.22-gnu/drivers/iommu/dmar.c
--- linux-libre-5.4.21-gnu/drivers/iommu/dmar.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/iommu/dmar.c	2020-02-24 02:37:04.000000000 -0500
@@ -1351,7 +1351,6 @@ void qi_flush_dev_iotlb(struct intel_iom
 	struct qi_desc desc;
 
 	if (mask) {
-		WARN_ON_ONCE(addr & ((1ULL << (VTD_PAGE_SHIFT + mask)) - 1));
 		addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1;
 		desc.qw1 = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE;
 	} else
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/iommu/intel-iommu.c linux-libre-5.4.22-gnu/drivers/iommu/intel-iommu.c
--- linux-libre-5.4.21-gnu/drivers/iommu/intel-iommu.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/iommu/intel-iommu.c	2020-02-24 02:37:04.000000000 -0500
@@ -3401,7 +3401,8 @@ static unsigned long intel_alloc_iova(st
 	iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
 				   IOVA_PFN(dma_mask), true);
 	if (unlikely(!iova_pfn)) {
-		dev_err(dev, "Allocating %ld-page iova failed", nrpages);
+		dev_err_once(dev, "Allocating %ld-page iova failed\n",
+			     nrpages);
 		return 0;
 	}
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/iommu/intel-pasid.c linux-libre-5.4.22-gnu/drivers/iommu/intel-pasid.c
--- linux-libre-5.4.21-gnu/drivers/iommu/intel-pasid.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/iommu/intel-pasid.c	2020-02-24 02:37:04.000000000 -0500
@@ -499,8 +499,16 @@ int intel_pasid_setup_first_level(struct
 	}
 
 #ifdef CONFIG_X86
-	if (cpu_feature_enabled(X86_FEATURE_LA57))
-		pasid_set_flpm(pte, 1);
+	/* Both CPU and IOMMU paging mode need to match */
+	if (cpu_feature_enabled(X86_FEATURE_LA57)) {
+		if (cap_5lp_support(iommu->cap)) {
+			pasid_set_flpm(pte, 1);
+		} else {
+			pr_err("VT-d has no 5-level paging support for CPU\n");
+			pasid_clear_entry(pte);
+			return -EINVAL;
+		}
+	}
 #endif /* CONFIG_X86 */
 
 	pasid_set_domain_id(pte, did);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/iommu/intel-svm.c linux-libre-5.4.22-gnu/drivers/iommu/intel-svm.c
--- linux-libre-5.4.21-gnu/drivers/iommu/intel-svm.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/iommu/intel-svm.c	2020-02-24 02:37:04.000000000 -0500
@@ -317,7 +317,7 @@ int intel_svm_bind_mm(struct device *dev
 		/* Do not use PASID 0 in caching mode (virtualised IOMMU) */
 		ret = intel_pasid_alloc_id(svm,
 					   !!cap_caching_mode(iommu->cap),
-					   pasid_max - 1, GFP_KERNEL);
+					   pasid_max, GFP_KERNEL);
 		if (ret < 0) {
 			kfree(svm);
 			kfree(sdev);
@@ -654,11 +654,10 @@ static irqreturn_t prq_event_thread(int
 			if (req->priv_data_present)
 				memcpy(&resp.qw2, req->priv_data,
 				       sizeof(req->priv_data));
+			resp.qw2 = 0;
+			resp.qw3 = 0;
+			qi_submit_sync(&resp, iommu);
 		}
-		resp.qw2 = 0;
-		resp.qw3 = 0;
-		qi_submit_sync(&resp, iommu);
-
 		head = (head + sizeof(*req)) & PRQ_RING_MASK;
 	}
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/iommu/iova.c linux-libre-5.4.22-gnu/drivers/iommu/iova.c
--- linux-libre-5.4.21-gnu/drivers/iommu/iova.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/iommu/iova.c	2020-02-24 02:37:04.000000000 -0500
@@ -233,7 +233,7 @@ static DEFINE_MUTEX(iova_cache_mutex);
 
 struct iova *alloc_iova_mem(void)
 {
-	return kmem_cache_zalloc(iova_cache, GFP_ATOMIC);
+	return kmem_cache_zalloc(iova_cache, GFP_ATOMIC | __GFP_NOWARN);
 }
 EXPORT_SYMBOL(alloc_iova_mem);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/irqchip/irq-gic-v3.c linux-libre-5.4.22-gnu/drivers/irqchip/irq-gic-v3.c
--- linux-libre-5.4.21-gnu/drivers/irqchip/irq-gic-v3.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/irqchip/irq-gic-v3.c	2020-02-24 02:37:04.000000000 -0500
@@ -1801,6 +1801,7 @@ static struct
 	struct redist_region *redist_regs;
 	u32 nr_redist_regions;
 	bool single_redist;
+	int enabled_rdists;
 	u32 maint_irq;
 	int maint_irq_mode;
 	phys_addr_t vcpu_base;
@@ -1895,8 +1896,10 @@ static int __init gic_acpi_match_gicc(un
 	 * If GICC is enabled and has valid gicr base address, then it means
 	 * GICR base is presented via GICC
 	 */
-	if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address)
+	if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) {
+		acpi_data.enabled_rdists++;
 		return 0;
+	}
 
 	/*
 	 * It's perfectly valid firmware can pass disabled GICC entry, driver
@@ -1926,8 +1929,10 @@ static int __init gic_acpi_count_gicr_re
 
 	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
 				      gic_acpi_match_gicc, 0);
-	if (count > 0)
+	if (count > 0) {
 		acpi_data.single_redist = true;
+		count = acpi_data.enabled_rdists;
+	}
 
 	return count;
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/irqchip/irq-gic-v3-its.c linux-libre-5.4.22-gnu/drivers/irqchip/irq-gic-v3-its.c
--- linux-libre-5.4.21-gnu/drivers/irqchip/irq-gic-v3-its.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/irqchip/irq-gic-v3-its.c	2020-02-24 02:37:04.000000000 -0500
@@ -571,7 +571,7 @@ static struct its_collection *its_build_
 						   struct its_cmd_desc *desc)
 {
 	its_encode_cmd(cmd, GITS_CMD_INVALL);
-	its_encode_collection(cmd, desc->its_mapc_cmd.col->col_id);
+	its_encode_collection(cmd, desc->its_invall_cmd.col->col_id);
 
 	its_fixup_cmd(cmd);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/irqchip/irq-mbigen.c linux-libre-5.4.22-gnu/drivers/irqchip/irq-mbigen.c
--- linux-libre-5.4.21-gnu/drivers/irqchip/irq-mbigen.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/irqchip/irq-mbigen.c	2020-02-24 02:37:04.000000000 -0500
@@ -374,6 +374,7 @@ static struct platform_driver mbigen_pla
 		.name		= "Hisilicon MBIGEN-V2",
 		.of_match_table	= mbigen_of_match,
 		.acpi_match_table = ACPI_PTR(mbigen_acpi_match),
+		.suppress_bind_attrs = true,
 	},
 	.probe			= mbigen_device_probe,
 };
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/leds/leds-pca963x.c linux-libre-5.4.22-gnu/drivers/leds/leds-pca963x.c
--- linux-libre-5.4.21-gnu/drivers/leds/leds-pca963x.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/leds/leds-pca963x.c	2020-02-24 02:37:04.000000000 -0500
@@ -40,6 +40,8 @@
 #define PCA963X_LED_PWM		0x2	/* Controlled through PWM */
 #define PCA963X_LED_GRP_PWM	0x3	/* Controlled through PWM/GRPPWM */
 
+#define PCA963X_MODE2_OUTDRV	0x04	/* Open-drain or totem pole */
+#define PCA963X_MODE2_INVRT	0x10	/* Normal or inverted direction */
 #define PCA963X_MODE2_DMBLNK	0x20	/* Enable blinking */
 
 #define PCA963X_MODE1		0x00
@@ -438,12 +440,12 @@ static int pca963x_probe(struct i2c_clie
 						    PCA963X_MODE2);
 		/* Configure output: open-drain or totem pole (push-pull) */
 		if (pdata->outdrv == PCA963X_OPEN_DRAIN)
-			mode2 |= 0x01;
+			mode2 &= ~PCA963X_MODE2_OUTDRV;
 		else
-			mode2 |= 0x05;
+			mode2 |= PCA963X_MODE2_OUTDRV;
 		/* Configure direction: normal or inverted */
 		if (pdata->dir == PCA963X_INVERTED)
-			mode2 |= 0x10;
+			mode2 |= PCA963X_MODE2_INVRT;
 		i2c_smbus_write_byte_data(pca963x->chip->client, PCA963X_MODE2,
 					  mode2);
 	}
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/md/bcache/bset.h linux-libre-5.4.22-gnu/drivers/md/bcache/bset.h
--- linux-libre-5.4.21-gnu/drivers/md/bcache/bset.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/md/bcache/bset.h	2020-02-24 02:37:04.000000000 -0500
@@ -397,7 +397,8 @@ void bch_btree_keys_stats(struct btree_k
 
 /* Bkey utility code */
 
-#define bset_bkey_last(i)	bkey_idx((struct bkey *) (i)->d, (i)->keys)
+#define bset_bkey_last(i)	bkey_idx((struct bkey *) (i)->d, \
+					 (unsigned int)(i)->keys)
 
 static inline struct bkey *bset_bkey_idx(struct bset *i, unsigned int idx)
 {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/md/bcache/journal.c linux-libre-5.4.22-gnu/drivers/md/bcache/journal.c
--- linux-libre-5.4.21-gnu/drivers/md/bcache/journal.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/md/bcache/journal.c	2020-02-24 02:37:04.000000000 -0500
@@ -422,7 +422,8 @@ err:
 static void btree_flush_write(struct cache_set *c)
 {
 	struct btree *b, *t, *btree_nodes[BTREE_FLUSH_NR];
-	unsigned int i, nr, ref_nr;
+	unsigned int i, nr;
+	int ref_nr;
 	atomic_t *fifo_front_p, *now_fifo_front_p;
 	size_t mask;
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/md/bcache/stats.c linux-libre-5.4.22-gnu/drivers/md/bcache/stats.c
--- linux-libre-5.4.21-gnu/drivers/md/bcache/stats.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/md/bcache/stats.c	2020-02-24 02:37:04.000000000 -0500
@@ -109,9 +109,13 @@ int bch_cache_accounting_add_kobjs(struc
 
 void bch_cache_accounting_clear(struct cache_accounting *acc)
 {
-	memset(&acc->total.cache_hits,
-	       0,
-	       sizeof(struct cache_stats));
+	acc->total.cache_hits = 0;
+	acc->total.cache_misses = 0;
+	acc->total.cache_bypass_hits = 0;
+	acc->total.cache_bypass_misses = 0;
+	acc->total.cache_readaheads = 0;
+	acc->total.cache_miss_collisions = 0;
+	acc->total.sectors_bypassed = 0;
 }
 
 void bch_cache_accounting_destroy(struct cache_accounting *acc)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/md/bcache/super.c linux-libre-5.4.22-gnu/drivers/md/bcache/super.c
--- linux-libre-5.4.21-gnu/drivers/md/bcache/super.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/md/bcache/super.c	2020-02-24 02:37:04.000000000 -0500
@@ -1274,6 +1274,9 @@ static void cached_dev_free(struct closu
 
 	mutex_unlock(&bch_register_lock);
 
+	if (dc->sb_bio.bi_inline_vecs[0].bv_page)
+		put_page(bio_first_page_all(&dc->sb_bio));
+
 	if (!IS_ERR_OR_NULL(dc->bdev))
 		blkdev_put(dc->bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
 
@@ -2369,29 +2372,35 @@ static bool bch_is_open(struct block_dev
 static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 			       const char *buffer, size_t size)
 {
-	ssize_t ret = -EINVAL;
-	const char *err = "cannot allocate memory";
+	const char *err;
 	char *path = NULL;
-	struct cache_sb *sb = NULL;
+	struct cache_sb *sb;
 	struct block_device *bdev = NULL;
-	struct page *sb_page = NULL;
+	struct page *sb_page;
+	ssize_t ret;
 
+	ret = -EBUSY;
+	err = "failed to reference bcache module";
 	if (!try_module_get(THIS_MODULE))
-		return -EBUSY;
+		goto out;
 
 	/* For latest state of bcache_is_reboot */
 	smp_mb();
+	err = "bcache is in reboot";
 	if (bcache_is_reboot)
-		return -EBUSY;
+		goto out_module_put;
 
+	ret = -ENOMEM;
+	err = "cannot allocate memory";
 	path = kstrndup(buffer, size, GFP_KERNEL);
 	if (!path)
-		goto err;
+		goto out_module_put;
 
 	sb = kmalloc(sizeof(struct cache_sb), GFP_KERNEL);
 	if (!sb)
-		goto err;
+		goto out_free_path;
 
+	ret = -EINVAL;
 	err = "failed to open device";
 	bdev = blkdev_get_by_path(strim(path),
 				  FMODE_READ|FMODE_WRITE|FMODE_EXCL,
@@ -2408,57 +2417,69 @@ static ssize_t register_bcache(struct ko
 			if (!IS_ERR(bdev))
 				bdput(bdev);
 			if (attr == &ksysfs_register_quiet)
-				goto quiet_out;
+				goto done;
 		}
-		goto err;
+		goto out_free_sb;
 	}
 
 	err = "failed to set blocksize";
 	if (set_blocksize(bdev, 4096))
-		goto err_close;
+		goto out_blkdev_put;
 
 	err = read_super(sb, bdev, &sb_page);
 	if (err)
-		goto err_close;
+		goto out_blkdev_put;
 
 	err = "failed to register device";
 	if (SB_IS_BDEV(sb)) {
 		struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
 
 		if (!dc)
-			goto err_close;
+			goto out_put_sb_page;
 
 		mutex_lock(&bch_register_lock);
 		ret = register_bdev(sb, sb_page, bdev, dc);
 		mutex_unlock(&bch_register_lock);
 		/* blkdev_put() will be called in cached_dev_free() */
-		if (ret < 0)
-			goto err;
+		if (ret < 0) {
+			bdev = NULL;
+			goto out_put_sb_page;
+		}
 	} else {
 		struct cache *ca = kzalloc(sizeof(*ca), GFP_KERNEL);
 
 		if (!ca)
-			goto err_close;
+			goto out_put_sb_page;
 
 		/* blkdev_put() will be called in bch_cache_release() */
-		if (register_cache(sb, sb_page, bdev, ca) != 0)
-			goto err;
+		if (register_cache(sb, sb_page, bdev, ca) != 0) {
+			bdev = NULL;
+			goto out_put_sb_page;
+		}
 	}
-quiet_out:
-	ret = size;
-out:
-	if (sb_page)
-		put_page(sb_page);
+
+	put_page(sb_page);
+done:
 	kfree(sb);
 	kfree(path);
 	module_put(THIS_MODULE);
-	return ret;
+	return size;
 
-err_close:
-	blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
-err:
-	pr_info("error %s: %s", path, err);
-	goto out;
+out_put_sb_page:
+	put_page(sb_page);
+out_blkdev_put:
+	if (bdev)
+		blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
+out_free_sb:
+	kfree(sb);
+out_free_path:
+	kfree(path);
+	path = NULL;
+out_module_put:
+	module_put(THIS_MODULE);
+out:
+	pr_info("error %s: %s", path?path:"", err);
+	return ret;
 }
 
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/md/dm-thin.c linux-libre-5.4.22-gnu/drivers/md/dm-thin.c
--- linux-libre-5.4.21-gnu/drivers/md/dm-thin.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/md/dm-thin.c	2020-02-24 02:37:04.000000000 -0500
@@ -231,6 +231,7 @@ struct pool {
 	struct dm_target *ti;	/* Only set if a pool target is bound */
 
 	struct mapped_device *pool_md;
+	struct block_device *data_dev;
 	struct block_device *md_dev;
 	struct dm_pool_metadata *pmd;
 
@@ -2945,6 +2946,7 @@ static struct kmem_cache *_new_mapping_c
 
 static struct pool *pool_create(struct mapped_device *pool_md,
 				struct block_device *metadata_dev,
+				struct block_device *data_dev,
 				unsigned long block_size,
 				int read_only, char **error)
 {
@@ -3052,6 +3054,7 @@ static struct pool *pool_create(struct m
 	pool->last_commit_jiffies = jiffies;
 	pool->pool_md = pool_md;
 	pool->md_dev = metadata_dev;
+	pool->data_dev = data_dev;
 	__pool_table_insert(pool);
 
 	return pool;
@@ -3093,6 +3096,7 @@ static void __pool_dec(struct pool *pool
 
 static struct pool *__pool_find(struct mapped_device *pool_md,
 				struct block_device *metadata_dev,
+				struct block_device *data_dev,
 				unsigned long block_size, int read_only,
 				char **error, int *created)
 {
@@ -3103,19 +3107,23 @@ static struct pool *__pool_find(struct m
 			*error = "metadata device already in use by a pool";
 			return ERR_PTR(-EBUSY);
 		}
+		if (pool->data_dev != data_dev) {
+			*error = "data device already in use by a pool";
+			return ERR_PTR(-EBUSY);
+		}
 		__pool_inc(pool);
 
 	} else {
 		pool = __pool_table_lookup(pool_md);
 		if (pool) {
-			if (pool->md_dev != metadata_dev) {
+			if (pool->md_dev != metadata_dev || pool->data_dev != data_dev) {
 				*error = "different pool cannot replace a pool";
 				return ERR_PTR(-EINVAL);
 			}
 			__pool_inc(pool);
 
 		} else {
-			pool = pool_create(pool_md, metadata_dev, block_size, read_only, error);
+			pool = pool_create(pool_md, metadata_dev, data_dev, block_size, read_only, error);
 			*created = 1;
 		}
 	}
@@ -3368,7 +3376,7 @@ static int pool_ctr(struct dm_target *ti
 		goto out;
 	}
 
-	pool = __pool_find(dm_table_get_md(ti->table), metadata_dev->bdev,
+	pool = __pool_find(dm_table_get_md(ti->table), metadata_dev->bdev, data_dev->bdev,
 			   block_size, pf.mode == PM_READ_ONLY, &ti->error, &pool_created);
 	if (IS_ERR(pool)) {
 		r = PTR_ERR(pool);
@@ -4114,7 +4122,7 @@ static struct target_type pool_target =
 	.name = "thin-pool",
 	.features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
 		    DM_TARGET_IMMUTABLE,
-	.version = {1, 21, 0},
+	.version = {1, 22, 0},
 	.module = THIS_MODULE,
 	.ctr = pool_ctr,
 	.dtr = pool_dtr,
@@ -4493,7 +4501,7 @@ static void thin_io_hints(struct dm_targ
 
 static struct target_type thin_target = {
 	.name = "thin",
-	.version = {1, 21, 0},
+	.version = {1, 22, 0},
 	.module	= THIS_MODULE,
 	.ctr = thin_ctr,
 	.dtr = thin_dtr,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/media/i2c/mt9v032.c linux-libre-5.4.22-gnu/drivers/media/i2c/mt9v032.c
--- linux-libre-5.4.21-gnu/drivers/media/i2c/mt9v032.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/media/i2c/mt9v032.c	2020-02-24 02:37:04.000000000 -0500
@@ -428,10 +428,12 @@ static int mt9v032_enum_mbus_code(struct
 				  struct v4l2_subdev_pad_config *cfg,
 				  struct v4l2_subdev_mbus_code_enum *code)
 {
+	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+
 	if (code->index > 0)
 		return -EINVAL;
 
-	code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+	code->code = mt9v032->format.code;
 	return 0;
 }
 
@@ -439,7 +441,11 @@ static int mt9v032_enum_frame_size(struc
 				   struct v4l2_subdev_pad_config *cfg,
 				   struct v4l2_subdev_frame_size_enum *fse)
 {
-	if (fse->index >= 3 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
+	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+
+	if (fse->index >= 3)
+		return -EINVAL;
+	if (mt9v032->format.code != fse->code)
 		return -EINVAL;
 
 	fse->min_width = MT9V032_WINDOW_WIDTH_DEF / (1 << fse->index);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/media/i2c/ov5640.c linux-libre-5.4.22-gnu/drivers/media/i2c/ov5640.c
--- linux-libre-5.4.21-gnu/drivers/media/i2c/ov5640.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/media/i2c/ov5640.c	2020-02-24 02:37:04.000000000 -0500
@@ -874,7 +874,7 @@ static unsigned long ov5640_calc_sys_clk
 			 * We have reached the maximum allowed PLL1 output,
 			 * increase sysdiv.
 			 */
-			if (!rate)
+			if (!_rate)
 				break;
 
 			/*
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/media/pci/cx23885/cx23885-cards.c linux-libre-5.4.22-gnu/drivers/media/pci/cx23885/cx23885-cards.c
--- linux-libre-5.4.21-gnu/drivers/media/pci/cx23885/cx23885-cards.c	2020-02-19 17:30:16.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/media/pci/cx23885/cx23885-cards.c	2020-02-24 05:41:40.000000000 -0500
@@ -801,6 +801,25 @@ struct cx23885_board cx23885_boards[] =
 		.name		= "Hauppauge WinTV-Starburst2",
 		.portb		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_AVERMEDIA_CE310B] = {
+		.name		= "AVerMedia CE310B",
+		.porta		= CX23885_ANALOG_VIDEO,
+		.force_bff	= 1,
+		.input          = {{
+			.type   = CX23885_VMUX_COMPOSITE1,
+			.vmux   = CX25840_VIN1_CH1 |
+				  CX25840_NONE_CH2 |
+				  CX25840_NONE0_CH3,
+			.amux   = CX25840_AUDIO7,
+		}, {
+			.type   = CX23885_VMUX_SVIDEO,
+			.vmux   = CX25840_VIN8_CH1 |
+				  CX25840_NONE_CH2 |
+				  CX25840_VIN7_CH3 |
+				  CX25840_SVIDEO_ON,
+			.amux   = CX25840_AUDIO7,
+		} },
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -1124,6 +1143,10 @@ struct cx23885_subid cx23885_subids[] =
 		.subvendor = 0x0070,
 		.subdevice = 0xf02a,
 		.card      = CX23885_BOARD_HAUPPAUGE_STARBURST2,
+	}, {
+		.subvendor = 0x1461,
+		.subdevice = 0x3100,
+		.card      = CX23885_BOARD_AVERMEDIA_CE310B,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -2348,6 +2371,7 @@ void cx23885_card_setup(struct cx23885_d
 	case CX23885_BOARD_DVBSKY_T982:
 	case CX23885_BOARD_VIEWCAST_260E:
 	case CX23885_BOARD_VIEWCAST_460E:
+	case CX23885_BOARD_AVERMEDIA_CE310B:
 		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_bus[2].i2c_adap,
 				"cx25840", 0x88 >> 1, NULL);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/media/pci/cx23885/cx23885.h linux-libre-5.4.22-gnu/drivers/media/pci/cx23885/cx23885.h
--- linux-libre-5.4.21-gnu/drivers/media/pci/cx23885/cx23885.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/media/pci/cx23885/cx23885.h	2020-02-24 02:37:04.000000000 -0500
@@ -101,6 +101,7 @@
 #define CX23885_BOARD_HAUPPAUGE_STARBURST2     59
 #define CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885 60
 #define CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885 61
+#define CX23885_BOARD_AVERMEDIA_CE310B         62
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/media/pci/cx23885/cx23885-video.c linux-libre-5.4.22-gnu/drivers/media/pci/cx23885/cx23885-video.c
--- linux-libre-5.4.21-gnu/drivers/media/pci/cx23885/cx23885-video.c	2020-02-19 17:30:21.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/media/pci/cx23885/cx23885-video.c	2020-02-24 05:41:44.000000000 -0500
@@ -257,7 +257,8 @@ static int cx23885_video_mux(struct cx23
 		(dev->board == CX23885_BOARD_MYGICA_X8507) ||
 		(dev->board == CX23885_BOARD_AVERMEDIA_HC81R) ||
 		(dev->board == CX23885_BOARD_VIEWCAST_260E) ||
-		(dev->board == CX23885_BOARD_VIEWCAST_460E)) {
+		(dev->board == CX23885_BOARD_VIEWCAST_460E) ||
+		(dev->board == CX23885_BOARD_AVERMEDIA_CE310B)) {
 		/* Configure audio routing */
 		v4l2_subdev_call(dev->sd_cx25840, audio, s_routing,
 			INPUT(input)->amux, 0, 0);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/media/platform/sti/bdisp/bdisp-hw.c linux-libre-5.4.22-gnu/drivers/media/platform/sti/bdisp/bdisp-hw.c
--- linux-libre-5.4.21-gnu/drivers/media/platform/sti/bdisp/bdisp-hw.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/media/platform/sti/bdisp/bdisp-hw.c	2020-02-24 02:37:04.000000000 -0500
@@ -14,8 +14,8 @@
 #define MAX_SRC_WIDTH           2048
 
 /* Reset & boot poll config */
-#define POLL_RST_MAX            50
-#define POLL_RST_DELAY_MS       20
+#define POLL_RST_MAX            500
+#define POLL_RST_DELAY_MS       2
 
 enum bdisp_target_plan {
 	BDISP_RGB,
@@ -382,7 +382,7 @@ int bdisp_hw_reset(struct bdisp_dev *bdi
 	for (i = 0; i < POLL_RST_MAX; i++) {
 		if (readl(bdisp->regs + BLT_STA1) & BLT_STA1_IDLE)
 			break;
-		msleep(POLL_RST_DELAY_MS);
+		udelay(POLL_RST_DELAY_MS * 1000);
 	}
 	if (i == POLL_RST_MAX)
 		dev_err(bdisp->dev, "Reset timeout\n");
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c linux-libre-5.4.22-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
--- linux-libre-5.4.21-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c	2020-02-24 02:37:04.000000000 -0500
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
@@ -155,6 +156,27 @@ static int sun4i_csi_probe(struct platfo
 	subdev = &csi->subdev;
 	vdev = &csi->vdev;
 
+	/*
+	 * On Allwinner SoCs, some high memory bandwidth devices do DMA
+	 * directly over the memory bus (called MBUS), instead of the
+	 * system bus. The memory bus has a different addressing scheme
+	 * without the DRAM starting offset.
+	 *
+	 * In some cases this can be described by an interconnect in
+	 * the device tree. In other cases where the hardware is not
+	 * fully understood and the interconnect is left out of the
+	 * device tree, fall back to a default offset.
+	 */
+	if (of_find_property(csi->dev->of_node, "interconnects", NULL)) {
+		ret = of_dma_configure(csi->dev, csi->dev->of_node, true);
+		if (ret)
+			return ret;
+	} else {
+#ifdef PHYS_PFN_OFFSET
+		csi->dev->dma_pfn_offset = PHYS_PFN_OFFSET;
+#endif
+	}
+
 	csi->mdev.dev = csi->dev;
 	strscpy(csi->mdev.model, "Allwinner Video Capture Device",
 		sizeof(csi->mdev.model));
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h linux-libre-5.4.22-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h
--- linux-libre-5.4.21-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h	2020-02-24 02:37:04.000000000 -0500
@@ -22,8 +22,8 @@
 #define CSI_CFG_INPUT_FMT(fmt)			((fmt) << 20)
 #define CSI_CFG_OUTPUT_FMT(fmt)			((fmt) << 16)
 #define CSI_CFG_YUV_DATA_SEQ(seq)		((seq) << 8)
-#define CSI_CFG_VSYNC_POL(pol)			((pol) << 2)
-#define CSI_CFG_HSYNC_POL(pol)			((pol) << 1)
+#define CSI_CFG_VREF_POL(pol)			((pol) << 2)
+#define CSI_CFG_HREF_POL(pol)			((pol) << 1)
 #define CSI_CFG_PCLK_POL(pol)			((pol) << 0)
 
 #define CSI_CPT_CTRL_REG		0x08
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c linux-libre-5.4.22-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c
--- linux-libre-5.4.21-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c	2020-02-24 02:37:04.000000000 -0500
@@ -228,7 +228,7 @@ static int sun4i_csi_start_streaming(str
 	struct sun4i_csi *csi = vb2_get_drv_priv(vq);
 	struct v4l2_fwnode_bus_parallel *bus = &csi->bus;
 	const struct sun4i_csi_format *csi_fmt;
-	unsigned long hsync_pol, pclk_pol, vsync_pol;
+	unsigned long href_pol, pclk_pol, vref_pol;
 	unsigned long flags;
 	unsigned int i;
 	int ret;
@@ -278,13 +278,21 @@ static int sun4i_csi_start_streaming(str
 	writel(CSI_WIN_CTRL_H_ACTIVE(csi->fmt.height),
 	       csi->regs + CSI_WIN_CTRL_H_REG);
 
-	hsync_pol = !!(bus->flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH);
-	pclk_pol = !!(bus->flags & V4L2_MBUS_DATA_ACTIVE_HIGH);
-	vsync_pol = !!(bus->flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH);
+	/*
+	 * This hardware uses [HV]REF instead of [HV]SYNC. Based on the
+	 * provided timing diagrams in the manual, positive polarity
+	 * equals active high [HV]REF.
+	 *
+	 * When the back porch is 0, [HV]REF is more or less equivalent
+	 * to [HV]SYNC inverted.
+	 */
+	href_pol = !!(bus->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
+	vref_pol = !!(bus->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
+	pclk_pol = !!(bus->flags & V4L2_MBUS_PCLK_SAMPLE_RISING);
 	writel(CSI_CFG_INPUT_FMT(csi_fmt->input) |
 	       CSI_CFG_OUTPUT_FMT(csi_fmt->output) |
-	       CSI_CFG_VSYNC_POL(vsync_pol) |
-	       CSI_CFG_HSYNC_POL(hsync_pol) |
+	       CSI_CFG_VREF_POL(vref_pol) |
+	       CSI_CFG_HREF_POL(href_pol) |
 	       CSI_CFG_PCLK_POL(pclk_pol),
 	       csi->regs + CSI_CFG_REG);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/media/usb/uvc/uvc_driver.c linux-libre-5.4.22-gnu/drivers/media/usb/uvc/uvc_driver.c
--- linux-libre-5.4.21-gnu/drivers/media/usb/uvc/uvc_driver.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/media/usb/uvc/uvc_driver.c	2020-02-24 02:37:04.000000000 -0500
@@ -497,6 +497,22 @@ static int uvc_parse_format(struct uvc_d
 			}
 		}
 
+		/* Some devices report bpp that doesn't match the format. */
+		if (dev->quirks & UVC_QUIRK_FORCE_BPP) {
+			const struct v4l2_format_info *info =
+				v4l2_format_info(format->fcc);
+
+			if (info) {
+				unsigned int div = info->hdiv * info->vdiv;
+
+				n = info->bpp[0] * div;
+				for (i = 1; i < info->comp_planes; i++)
+					n += info->bpp[i];
+
+				format->bpp = DIV_ROUND_UP(8 * n, div);
+			}
+		}
+
 		if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) {
 			ftype = UVC_VS_FRAME_UNCOMPRESSED;
 		} else {
@@ -2874,6 +2890,15 @@ static const struct usb_device_id uvc_id
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= (kernel_ulong_t)&uvc_quirk_force_y8 },
+	/* GEO Semiconductor GC6500 */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x29fe,
+	  .idProduct		= 0x4d53,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_FORCE_BPP) },
 	/* Intel RealSense D4M */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/media/usb/uvc/uvcvideo.h linux-libre-5.4.22-gnu/drivers/media/usb/uvc/uvcvideo.h
--- linux-libre-5.4.21-gnu/drivers/media/usb/uvc/uvcvideo.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/media/usb/uvc/uvcvideo.h	2020-02-24 02:37:04.000000000 -0500
@@ -198,6 +198,7 @@
 #define UVC_QUIRK_RESTRICT_FRAME_RATE	0x00000200
 #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT	0x00000400
 #define UVC_QUIRK_FORCE_Y8		0x00000800
+#define UVC_QUIRK_FORCE_BPP		0x00001000
 
 /* Format flags */
 #define UVC_FMT_FLAG_COMPRESSED		0x00000001
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/misc/xilinx_sdfec.c linux-libre-5.4.22-gnu/drivers/misc/xilinx_sdfec.c
--- linux-libre-5.4.21-gnu/drivers/misc/xilinx_sdfec.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/misc/xilinx_sdfec.c	2020-02-24 02:37:04.000000000 -0500
@@ -1025,25 +1025,25 @@ static long xsdfec_dev_compat_ioctl(stru
 }
 #endif
 
-static unsigned int xsdfec_poll(struct file *file, poll_table *wait)
+static __poll_t xsdfec_poll(struct file *file, poll_table *wait)
 {
-	unsigned int mask = 0;
+	__poll_t mask = 0;
 	struct xsdfec_dev *xsdfec;
 
 	xsdfec = container_of(file->private_data, struct xsdfec_dev, miscdev);
 
 	if (!xsdfec)
-		return POLLNVAL | POLLHUP;
+		return EPOLLNVAL | EPOLLHUP;
 
 	poll_wait(file, &xsdfec->waitq, wait);
 
 	/* XSDFEC ISR detected an error */
 	spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags);
 	if (xsdfec->state_updated)
-		mask |= POLLIN | POLLPRI;
+		mask |= EPOLLIN | EPOLLPRI;
 
 	if (xsdfec->stats_updated)
-		mask |= POLLIN | POLLRDNORM;
+		mask |= EPOLLIN | EPOLLRDNORM;
 	spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags);
 
 	return mask;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c linux-libre-5.4.22-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c
--- linux-libre-5.4.21-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c	2020-02-24 02:37:04.000000000 -0500
@@ -942,6 +942,7 @@ static struct sk_buff *bnxt_rx_page_skb(
 	dma_addr -= bp->rx_dma_offset;
 	dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir,
 			     DMA_ATTR_WEAK_ORDERING);
+	page_pool_release_page(rxr->page_pool, page);
 
 	if (unlikely(!payload))
 		payload = eth_get_headlen(bp->dev, data_ptr, len);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/ethernet/cisco/enic/enic_main.c linux-libre-5.4.22-gnu/drivers/net/ethernet/cisco/enic/enic_main.c
--- linux-libre-5.4.21-gnu/drivers/net/ethernet/cisco/enic/enic_main.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/ethernet/cisco/enic/enic_main.c	2020-02-24 02:37:04.000000000 -0500
@@ -2013,10 +2013,10 @@ static int enic_stop(struct net_device *
 		napi_disable(&enic->napi[i]);
 
 	netif_carrier_off(netdev);
-	netif_tx_disable(netdev);
 	if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
 		for (i = 0; i < enic->wq_count; i++)
 			napi_disable(&enic->napi[enic_cq_wq(enic, i)]);
+	netif_tx_disable(netdev);
 
 	if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic))
 		enic_dev_del_station_addr(enic);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/ethernet/freescale/gianfar.c linux-libre-5.4.22-gnu/drivers/net/ethernet/freescale/gianfar.c
--- linux-libre-5.4.21-gnu/drivers/net/ethernet/freescale/gianfar.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/ethernet/freescale/gianfar.c	2020-02-24 02:37:04.000000000 -0500
@@ -2204,13 +2204,17 @@ static void gfar_clean_tx_ring(struct gf
 	skb_dirtytx = tx_queue->skb_dirtytx;
 
 	while ((skb = tx_queue->tx_skbuff[skb_dirtytx])) {
+		bool do_tstamp;
+
+		do_tstamp = (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+			    priv->hwts_tx_en;
 
 		frags = skb_shinfo(skb)->nr_frags;
 
 		/* When time stamping, one additional TxBD must be freed.
 		 * Also, we need to dma_unmap_single() the TxPAL.
 		 */
-		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
+		if (unlikely(do_tstamp))
 			nr_txbds = frags + 2;
 		else
 			nr_txbds = frags + 1;
@@ -2224,7 +2228,7 @@ static void gfar_clean_tx_ring(struct gf
 		    (lstatus & BD_LENGTH_MASK))
 			break;
 
-		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
+		if (unlikely(do_tstamp)) {
 			next = next_txbd(bdp, base, tx_ring_size);
 			buflen = be16_to_cpu(next->length) +
 				 GMAC_FCB_LEN + GMAC_TXPAL_LEN;
@@ -2234,7 +2238,7 @@ static void gfar_clean_tx_ring(struct gf
 		dma_unmap_single(priv->dev, be32_to_cpu(bdp->bufPtr),
 				 buflen, DMA_TO_DEVICE);
 
-		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
+		if (unlikely(do_tstamp)) {
 			struct skb_shared_hwtstamps shhwtstamps;
 			u64 *ns = (u64 *)(((uintptr_t)skb->data + 0x10) &
 					  ~0x7UL);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/ethernet/intel/i40e/i40e_xsk.c linux-libre-5.4.22-gnu/drivers/net/ethernet/intel/i40e/i40e_xsk.c
--- linux-libre-5.4.21-gnu/drivers/net/ethernet/intel/i40e/i40e_xsk.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/ethernet/intel/i40e/i40e_xsk.c	2020-02-24 02:37:04.000000000 -0500
@@ -791,7 +791,7 @@ int i40e_xsk_wakeup(struct net_device *d
 	struct i40e_ring *ring;
 
 	if (test_bit(__I40E_CONFIG_BUSY, pf->state))
-		return -ENETDOWN;
+		return -EAGAIN;
 
 	if (test_bit(__I40E_VSI_DOWN, vsi->state))
 		return -ENETDOWN;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c linux-libre-5.4.22-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
--- linux-libre-5.4.21-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c	2020-02-24 02:37:04.000000000 -0500
@@ -297,6 +297,9 @@ static void mlx5e_grp_sw_update_stats(st
 			s->tx_tls_drop_bypass_req   += sq_stats->tls_drop_bypass_req;
 #endif
 			s->tx_cqes		+= sq_stats->cqes;
+
+			/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92657 */
+			barrier();
 		}
 	}
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c linux-libre-5.4.22-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
--- linux-libre-5.4.21-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c	2020-02-24 02:37:04.000000000 -0500
@@ -215,7 +215,7 @@ mlxsw_sp_dpipe_table_erif_entries_dump(v
 start_again:
 	err = devlink_dpipe_entry_ctx_prepare(dump_ctx);
 	if (err)
-		return err;
+		goto err_ctx_prepare;
 	j = 0;
 	for (; i < rif_count; i++) {
 		struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
@@ -247,6 +247,7 @@ start_again:
 	return 0;
 err_entry_append:
 err_entry_get:
+err_ctx_prepare:
 	rtnl_unlock();
 	devlink_dpipe_entry_clear(&entry);
 	return err;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/ethernet/netronome/nfp/abm/cls.c linux-libre-5.4.22-gnu/drivers/net/ethernet/netronome/nfp/abm/cls.c
--- linux-libre-5.4.21-gnu/drivers/net/ethernet/netronome/nfp/abm/cls.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/ethernet/netronome/nfp/abm/cls.c	2020-02-24 02:37:04.000000000 -0500
@@ -176,10 +176,8 @@ nfp_abm_u32_knode_replace(struct nfp_abm
 	u8 mask, val;
 	int err;
 
-	if (!nfp_abm_u32_check_knode(alink->abm, knode, proto, extack)) {
-		err = -EOPNOTSUPP;
+	if (!nfp_abm_u32_check_knode(alink->abm, knode, proto, extack))
 		goto err_delete;
-	}
 
 	tos_off = proto == htons(ETH_P_IP) ? 16 : 20;
 
@@ -200,18 +198,14 @@ nfp_abm_u32_knode_replace(struct nfp_abm
 		if ((iter->val & cmask) == (val & cmask) &&
 		    iter->band != knode->res->classid) {
 			NL_SET_ERR_MSG_MOD(extack, "conflict with already offloaded filter");
-			err = -EOPNOTSUPP;
 			goto err_delete;
 		}
 	}
 
 	if (!match) {
 		match = kzalloc(sizeof(*match), GFP_KERNEL);
-		if (!match) {
-			err = -ENOMEM;
-			goto err_delete;
-		}
-
+		if (!match)
+			return -ENOMEM;
 		list_add(&match->list, &alink->dscp_map);
 	}
 	match->handle = knode->handle;
@@ -227,7 +221,7 @@ nfp_abm_u32_knode_replace(struct nfp_abm
 
 err_delete:
 	nfp_abm_u32_knode_delete(alink, knode);
-	return err;
+	return -EOPNOTSUPP;
 }
 
 static int nfp_abm_setup_tc_block_cb(enum tc_setup_type type,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/ethernet/realtek/r8169_main.c linux-libre-5.4.22-gnu/drivers/net/ethernet/realtek/r8169_main.c
--- linux-libre-5.4.21-gnu/drivers/net/ethernet/realtek/r8169_main.c	2020-02-19 17:34:23.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/ethernet/realtek/r8169_main.c	2020-02-24 05:45:45.000000000 -0500
@@ -7045,6 +7045,15 @@ static int rtl_init_one(struct pci_dev *
 	int chipset, region;
 	int jumbo_max, rc;
 
+	/* Some tools for creating an initramfs don't consider softdeps, then
+	 * r8169.ko may be in initramfs, but realtek.ko not. Then the generic
+	 * PHY driver is used that doesn't work with most chip versions.
+	 */
+	if (!driver_find("RTL8201CP Ethernet", &mdio_bus_type)) {
+		dev_err(&pdev->dev, "realtek.ko not loaded, maybe it needs to be added to initramfs?\n");
+		return -ENOENT;
+	}
+
 	dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp));
 	if (!dev)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/ethernet/xscale/ixp4xx_eth.c linux-libre-5.4.22-gnu/drivers/net/ethernet/xscale/ixp4xx_eth.c
--- linux-libre-5.4.21-gnu/drivers/net/ethernet/xscale/ixp4xx_eth.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/ethernet/xscale/ixp4xx_eth.c	2020-02-24 02:37:04.000000000 -0500
@@ -517,25 +517,14 @@ static int ixp4xx_mdio_write(struct mii_
 	return ret;
 }
 
-static int ixp4xx_mdio_register(void)
+static int ixp4xx_mdio_register(struct eth_regs __iomem *regs)
 {
 	int err;
 
 	if (!(mdio_bus = mdiobus_alloc()))
 		return -ENOMEM;
 
-	if (cpu_is_ixp43x()) {
-		/* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */
-		if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH))
-			return -ENODEV;
-		mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT;
-	} else {
-		/* All MII PHY accesses use NPE-B Ethernet registers */
-		if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0))
-			return -ENODEV;
-		mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT;
-	}
-
+	mdio_regs = regs;
 	__raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control);
 	spin_lock_init(&mdio_lock);
 	mdio_bus->name = "IXP4xx MII Bus";
@@ -1374,7 +1363,7 @@ static const struct net_device_ops ixp4x
 	.ndo_validate_addr = eth_validate_addr,
 };
 
-static int eth_init_one(struct platform_device *pdev)
+static int ixp4xx_eth_probe(struct platform_device *pdev)
 {
 	struct port *port;
 	struct net_device *dev;
@@ -1384,7 +1373,7 @@ static int eth_init_one(struct platform_
 	char phy_id[MII_BUS_ID_SIZE + 3];
 	int err;
 
-	if (!(dev = alloc_etherdev(sizeof(struct port))))
+	if (!(dev = devm_alloc_etherdev(&pdev->dev, sizeof(struct port))))
 		return -ENOMEM;
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
@@ -1394,20 +1383,51 @@ static int eth_init_one(struct platform_
 
 	switch (port->id) {
 	case IXP4XX_ETH_NPEA:
+		/* If the MDIO bus is not up yet, defer probe */
+		if (!mdio_bus)
+			return -EPROBE_DEFER;
 		port->regs = (struct eth_regs __iomem *)IXP4XX_EthA_BASE_VIRT;
 		regs_phys  = IXP4XX_EthA_BASE_PHYS;
 		break;
 	case IXP4XX_ETH_NPEB:
+		/*
+		 * On all except IXP43x, NPE-B is used for the MDIO bus.
+		 * If there is no NPE-B in the feature set, bail out, else
+		 * register the MDIO bus.
+		 */
+		if (!cpu_is_ixp43x()) {
+			if (!(ixp4xx_read_feature_bits() &
+			      IXP4XX_FEATURE_NPEB_ETH0))
+				return -ENODEV;
+			/* Else register the MDIO bus on NPE-B */
+			if ((err = ixp4xx_mdio_register(IXP4XX_EthC_BASE_VIRT)))
+				return err;
+		}
+		if (!mdio_bus)
+			return -EPROBE_DEFER;
 		port->regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT;
 		regs_phys  = IXP4XX_EthB_BASE_PHYS;
 		break;
 	case IXP4XX_ETH_NPEC:
+		/*
+		 * IXP43x lacks NPE-B and uses NPE-C for the MDIO bus access,
+		 * of there is no NPE-C, no bus, nothing works, so bail out.
+		 */
+		if (cpu_is_ixp43x()) {
+			if (!(ixp4xx_read_feature_bits() &
+			      IXP4XX_FEATURE_NPEC_ETH))
+				return -ENODEV;
+			/* Else register the MDIO bus on NPE-C */
+			if ((err = ixp4xx_mdio_register(IXP4XX_EthC_BASE_VIRT)))
+				return err;
+		}
+		if (!mdio_bus)
+			return -EPROBE_DEFER;
 		port->regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT;
 		regs_phys  = IXP4XX_EthC_BASE_PHYS;
 		break;
 	default:
-		err = -ENODEV;
-		goto err_free;
+		return -ENODEV;
 	}
 
 	dev->netdev_ops = &ixp4xx_netdev_ops;
@@ -1416,10 +1436,8 @@ static int eth_init_one(struct platform_
 
 	netif_napi_add(dev, &port->napi, eth_poll, NAPI_WEIGHT);
 
-	if (!(port->npe = npe_request(NPE_ID(port->id)))) {
-		err = -EIO;
-		goto err_free;
-	}
+	if (!(port->npe = npe_request(NPE_ID(port->id))))
+		return -EIO;
 
 	port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name);
 	if (!port->mem_res) {
@@ -1465,12 +1483,10 @@ err_free_mem:
 	release_resource(port->mem_res);
 err_npe_rel:
 	npe_release(port->npe);
-err_free:
-	free_netdev(dev);
 	return err;
 }
 
-static int eth_remove_one(struct platform_device *pdev)
+static int ixp4xx_eth_remove(struct platform_device *pdev)
 {
 	struct net_device *dev = platform_get_drvdata(pdev);
 	struct phy_device *phydev = dev->phydev;
@@ -1478,45 +1494,21 @@ static int eth_remove_one(struct platfor
 
 	unregister_netdev(dev);
 	phy_disconnect(phydev);
+	ixp4xx_mdio_remove();
 	npe_port_tab[NPE_ID(port->id)] = NULL;
 	npe_release(port->npe);
 	release_resource(port->mem_res);
-	free_netdev(dev);
 	return 0;
 }
 
 static struct platform_driver ixp4xx_eth_driver = {
 	.driver.name	= DRV_NAME,
-	.probe		= eth_init_one,
-	.remove		= eth_remove_one,
+	.probe		= ixp4xx_eth_probe,
+	.remove		= ixp4xx_eth_remove,
 };
-
-static int __init eth_init_module(void)
-{
-	int err;
-
-	/*
-	 * FIXME: we bail out on device tree boot but this really needs
-	 * to be fixed in a nicer way: this registers the MDIO bus before
-	 * even matching the driver infrastructure, we should only probe
-	 * detected hardware.
-	 */
-	if (of_have_populated_dt())
-		return -ENODEV;
-	if ((err = ixp4xx_mdio_register()))
-		return err;
-	return platform_driver_register(&ixp4xx_eth_driver);
-}
-
-static void __exit eth_cleanup_module(void)
-{
-	platform_driver_unregister(&ixp4xx_eth_driver);
-	ixp4xx_mdio_remove();
-}
+module_platform_driver(ixp4xx_eth_driver);
 
 MODULE_AUTHOR("Krzysztof Halasa");
 MODULE_DESCRIPTION("Intel IXP4xx Ethernet driver");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:ixp4xx_eth");
-module_init(eth_init_module);
-module_exit(eth_cleanup_module);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/phy/fixed_phy.c linux-libre-5.4.22-gnu/drivers/net/phy/fixed_phy.c
--- linux-libre-5.4.21-gnu/drivers/net/phy/fixed_phy.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/phy/fixed_phy.c	2020-02-24 02:37:04.000000000 -0500
@@ -212,16 +212,13 @@ static struct gpio_desc *fixed_phy_get_g
 	 */
 	gpiod = gpiod_get_from_of_node(fixed_link_node, "link-gpios", 0,
 				       GPIOD_IN, "mdio");
-	of_node_put(fixed_link_node);
-	if (IS_ERR(gpiod)) {
-		if (PTR_ERR(gpiod) == -EPROBE_DEFER)
-			return gpiod;
-
+	if (IS_ERR(gpiod) && PTR_ERR(gpiod) != -EPROBE_DEFER) {
 		if (PTR_ERR(gpiod) != -ENOENT)
 			pr_err("error getting GPIO for fixed link %pOF, proceed without\n",
 			       fixed_link_node);
 		gpiod = NULL;
 	}
+	of_node_put(fixed_link_node);
 
 	return gpiod;
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/phy/realtek.c linux-libre-5.4.22-gnu/drivers/net/phy/realtek.c
--- linux-libre-5.4.21-gnu/drivers/net/phy/realtek.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/phy/realtek.c	2020-02-24 02:37:04.000000000 -0500
@@ -171,7 +171,9 @@ static int rtl8211c_config_init(struct p
 
 static int rtl8211f_config_init(struct phy_device *phydev)
 {
+	struct device *dev = &phydev->mdio.dev;
 	u16 val;
+	int ret;
 
 	/* enable TX-delay for rgmii-{id,txid}, and disable it for rgmii and
 	 * rgmii-rxid. The RX-delay can be enabled by the external RXDLY pin.
@@ -189,7 +191,22 @@ static int rtl8211f_config_init(struct p
 		return 0;
 	}
 
-	return phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, val);
+	ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
+				       val);
+	if (ret < 0) {
+		dev_err(dev, "Failed to update the TX delay register\n");
+		return ret;
+	} else if (ret) {
+		dev_dbg(dev,
+			"%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
+			val ? "Enabling" : "Disabling");
+	} else {
+		dev_dbg(dev,
+			"2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
+			val ? "enabled" : "disabled");
+	}
+
+	return 0;
 }
 
 static int rtl8211e_config_init(struct phy_device *phydev)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wan/fsl_ucc_hdlc.c linux-libre-5.4.22-gnu/drivers/net/wan/fsl_ucc_hdlc.c
--- linux-libre-5.4.21-gnu/drivers/net/wan/fsl_ucc_hdlc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wan/fsl_ucc_hdlc.c	2020-02-24 02:37:04.000000000 -0500
@@ -245,6 +245,11 @@ static int uhdlc_init(struct ucc_hdlc_pr
 		ret = -ENOMEM;
 		goto free_riptr;
 	}
+	if (riptr != (u16)riptr || tiptr != (u16)tiptr) {
+		dev_err(priv->dev, "MURAM allocation out of addressable range\n");
+		ret = -ENOMEM;
+		goto free_tiptr;
+	}
 
 	/* Set RIPTR, TIPTR */
 	iowrite16be(riptr, &priv->ucc_pram->riptr);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wan/hdlc_x25.c linux-libre-5.4.22-gnu/drivers/net/wan/hdlc_x25.c
--- linux-libre-5.4.21-gnu/drivers/net/wan/hdlc_x25.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wan/hdlc_x25.c	2020-02-24 02:37:04.000000000 -0500
@@ -62,11 +62,12 @@ static int x25_data_indication(struct ne
 {
 	unsigned char *ptr;
 
-	skb_push(skb, 1);
-
 	if (skb_cow(skb, 1))
 		return NET_RX_DROP;
 
+	skb_push(skb, 1);
+	skb_reset_network_header(skb);
+
 	ptr  = skb->data;
 	*ptr = X25_IFACE_DATA;
 
@@ -79,6 +80,13 @@ static int x25_data_indication(struct ne
 static void x25_data_transmit(struct net_device *dev, struct sk_buff *skb)
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
+
+	skb_reset_network_header(skb);
+	skb->protocol = hdlc_type_trans(skb, dev);
+
+	if (dev_nit_active(dev))
+		dev_queue_xmit_nit(skb, dev);
+
 	hdlc->xmit(skb, dev); /* Ignore return value :-( */
 }
 
@@ -93,6 +101,7 @@ static netdev_tx_t x25_xmit(struct sk_bu
 	switch (skb->data[0]) {
 	case X25_IFACE_DATA:	/* Data to be transmitted */
 		skb_pull(skb, 1);
+		skb_reset_network_header(skb);
 		if ((result = lapb_data_request(dev, skb)) != LAPB_OK)
 			dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wan/ixp4xx_hss.c linux-libre-5.4.22-gnu/drivers/net/wan/ixp4xx_hss.c
--- linux-libre-5.4.21-gnu/drivers/net/wan/ixp4xx_hss.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wan/ixp4xx_hss.c	2020-02-24 02:37:04.000000000 -0500
@@ -258,7 +258,7 @@ struct port {
 	struct hss_plat_info *plat;
 	buffer_t *rx_buff_tab[RX_DESCS], *tx_buff_tab[TX_DESCS];
 	struct desc *desc_tab;	/* coherent */
-	u32 desc_tab_phys;
+	dma_addr_t desc_tab_phys;
 	unsigned int id;
 	unsigned int clock_type, clock_rate, loopback;
 	unsigned int initialized, carrier;
@@ -858,7 +858,7 @@ static int hss_hdlc_xmit(struct sk_buff
 		dev->stats.tx_dropped++;
 		return NETDEV_TX_OK;
 	}
-	memcpy_swab32(mem, (u32 *)((int)skb->data & ~3), bytes / 4);
+	memcpy_swab32(mem, (u32 *)((uintptr_t)skb->data & ~3), bytes / 4);
 	dev_kfree_skb(skb);
 #endif
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/ath/ath10k/snoc.c linux-libre-5.4.22-gnu/drivers/net/wireless/ath/ath10k/snoc.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/ath/ath10k/snoc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/ath/ath10k/snoc.c	2020-02-24 02:37:04.000000000 -0500
@@ -1729,13 +1729,16 @@ static int ath10k_snoc_probe(struct plat
 	ret = ath10k_qmi_init(ar, msa_size);
 	if (ret) {
 		ath10k_warn(ar, "failed to register wlfw qmi client: %d\n", ret);
-		goto err_core_destroy;
+		goto err_power_off;
 	}
 
 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n");
 
 	return 0;
 
+err_power_off:
+	ath10k_hw_power_off(ar);
+
 err_free_irq:
 	ath10k_snoc_free_irq(ar);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/ath/ath10k/wmi.c linux-libre-5.4.22-gnu/drivers/net/wireless/ath/ath10k/wmi.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/ath/ath10k/wmi.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/ath/ath10k/wmi.c	2020-02-24 02:37:04.000000000 -0500
@@ -9422,7 +9422,7 @@ static int ath10k_wmi_mgmt_tx_clean_up_p
 
 	msdu = pkt_addr->vaddr;
 	dma_unmap_single(ar->dev, pkt_addr->paddr,
-			 msdu->len, DMA_FROM_DEVICE);
+			 msdu->len, DMA_TO_DEVICE);
 	ieee80211_free_txskb(ar->hw, msdu);
 
 	return 0;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/ath/ath10k/wmi-tlv.c linux-libre-5.4.22-gnu/drivers/net/wireless/ath/ath10k/wmi-tlv.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/ath/ath10k/wmi-tlv.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/ath/ath10k/wmi-tlv.c	2020-02-24 02:37:04.000000000 -0500
@@ -3650,6 +3650,7 @@ ath10k_wmi_tlv_op_gen_config_pno_start(s
 	struct wmi_tlv *tlv;
 	struct sk_buff *skb;
 	__le32 *channel_list;
+	u16 tlv_len;
 	size_t len;
 	void *ptr;
 	u32 i;
@@ -3707,10 +3708,12 @@ ath10k_wmi_tlv_op_gen_config_pno_start(s
 	/* nlo_configured_parameters(nlo_list) */
 	cmd->no_of_ssids = __cpu_to_le32(min_t(u8, pno->uc_networks_count,
 					       WMI_NLO_MAX_SSIDS));
+	tlv_len = __le32_to_cpu(cmd->no_of_ssids) *
+		sizeof(struct nlo_configured_parameters);
 
 	tlv = ptr;
 	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
-	tlv->len = __cpu_to_le16(len);
+	tlv->len = __cpu_to_le16(tlv_len);
 
 	ptr += sizeof(*tlv);
 	nlo_list = ptr;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/ath/wil6210/txrx_edma.c linux-libre-5.4.22-gnu/drivers/net/wireless/ath/wil6210/txrx_edma.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/ath/wil6210/txrx_edma.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/ath/wil6210/txrx_edma.c	2020-02-24 02:37:04.000000000 -0500
@@ -880,6 +880,7 @@ static struct sk_buff *wil_sring_reap_rx
 	u8 data_offset;
 	struct wil_rx_status_extended *s;
 	u16 sring_idx = sring - wil->srings;
+	int invalid_buff_id_retry;
 
 	BUILD_BUG_ON(sizeof(struct wil_rx_status_extended) > sizeof(skb->cb));
 
@@ -893,9 +894,9 @@ again:
 	/* Extract the buffer ID from the status message */
 	buff_id = le16_to_cpu(wil_rx_status_get_buff_id(msg));
 
+	invalid_buff_id_retry = 0;
 	while (!buff_id) {
 		struct wil_rx_status_extended *s;
-		int invalid_buff_id_retry = 0;
 
 		wil_dbg_txrx(wil,
 			     "buff_id is not updated yet by HW, (swhead 0x%x)\n",
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/broadcom/b43legacy/main.c linux-libre-5.4.22-gnu/drivers/net/wireless/broadcom/b43legacy/main.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/broadcom/b43legacy/main.c	2020-02-19 17:35:56.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/broadcom/b43legacy/main.c	2020-02-24 05:47:22.000000000 -0500
@@ -1274,8 +1274,9 @@ static void handle_irq_ucode_debug(struc
 }
 
 /* Interrupt handler bottom-half */
-static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev)
+static void b43legacy_interrupt_tasklet(unsigned long data)
 {
+	struct b43legacy_wldev *dev = (struct b43legacy_wldev *)data;
 	u32 reason;
 	u32 dma_reason[ARRAY_SIZE(dev->dma_reason)];
 	u32 merged_dma_reason = 0;
@@ -3738,7 +3739,7 @@ static int b43legacy_one_core_attach(str
 	b43legacy_set_status(wldev, B43legacy_STAT_UNINIT);
 	wldev->bad_frames_preempt = modparam_bad_frames_preempt;
 	tasklet_init(&wldev->isr_tasklet,
-		     (void (*)(unsigned long))b43legacy_interrupt_tasklet,
+		     b43legacy_interrupt_tasklet,
 		     (unsigned long)wldev);
 	if (modparam_pio)
 		wldev->__using_pio = true;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c linux-libre-5.4.22-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c	2020-02-24 02:37:04.000000000 -0500
@@ -2092,7 +2092,8 @@ static struct wireless_dev *brcmf_p2p_cr
 	/* firmware requires unique mac address for p2pdev interface */
 	if (addr && ether_addr_equal(addr, pri_ifp->mac_addr)) {
 		bphy_err(drvr, "discovery vif must be different from primary interface\n");
-		return ERR_PTR(-EINVAL);
+		err = -EINVAL;
+		goto fail;
 	}
 
 	brcmf_p2p_generate_bss_mac(p2p, addr);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c linux-libre-5.4.22-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c	2020-02-19 17:36:12.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c	2020-02-24 05:47:40.000000000 -0500
@@ -1935,6 +1935,7 @@ static uint brcmf_sdio_readframes(struct
 					       BRCMF_SDIO_FT_NORMAL)) {
 				rd->len = 0;
 				brcmu_pkt_buf_free_skb(pkt);
+				continue;
 			}
 			bus->sdcnt.rx_readahead_cnt++;
 			if (rd->len != roundup(rd_new.len, 16)) {
@@ -4225,6 +4226,12 @@ static void brcmf_sdio_firmware_callback
 	}
 
 	if (err == 0) {
+		/* Assign bus interface call back */
+		sdiod->bus_if->dev = sdiod->dev;
+		sdiod->bus_if->ops = &brcmf_sdio_bus_ops;
+		sdiod->bus_if->chip = bus->ci->chip;
+		sdiod->bus_if->chiprev = bus->ci->chiprev;
+
 		/* Allow full data communication using DPC from now on. */
 		brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
 
@@ -4241,12 +4248,6 @@ static void brcmf_sdio_firmware_callback
 
 	sdio_release_host(sdiod->func1);
 
-	/* Assign bus interface call back */
-	sdiod->bus_if->dev = sdiod->dev;
-	sdiod->bus_if->ops = &brcmf_sdio_bus_ops;
-	sdiod->bus_if->chip = bus->ci->chip;
-	sdiod->bus_if->chiprev = bus->ci->chiprev;
-
 	err = brcmf_alloc(sdiod->dev, sdiod->settings);
 	if (err) {
 		brcmf_err("brcmf_alloc failed\n");
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/intel/ipw2x00/ipw2100.c linux-libre-5.4.22-gnu/drivers/net/wireless/intel/ipw2x00/ipw2100.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/intel/ipw2x00/ipw2100.c	2020-02-19 17:36:36.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/intel/ipw2x00/ipw2100.c	2020-02-24 05:48:03.000000000 -0500
@@ -3206,8 +3206,9 @@ static void ipw2100_tx_send_data(struct
 	}
 }
 
-static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
+static void ipw2100_irq_tasklet(unsigned long data)
 {
+	struct ipw2100_priv *priv = (struct ipw2100_priv *)data;
 	struct net_device *dev = priv->net_dev;
 	unsigned long flags;
 	u32 inta, tmp;
@@ -6007,7 +6008,7 @@ static void ipw2100_rf_kill(struct work_
 	spin_unlock_irqrestore(&priv->low_lock, flags);
 }
 
-static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
+static void ipw2100_irq_tasklet(unsigned long data);
 
 static const struct net_device_ops ipw2100_netdev_ops = {
 	.ndo_open		= ipw2100_open,
@@ -6137,7 +6138,7 @@ static struct net_device *ipw2100_alloc_
 	INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill);
 	INIT_DELAYED_WORK(&priv->scan_event, ipw2100_scan_event);
 
-	tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+	tasklet_init(&priv->irq_tasklet,
 		     ipw2100_irq_tasklet, (unsigned long)priv);
 
 	/* NOTE:  We do not start the deferred work for status checks yet */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/intel/ipw2x00/ipw2200.c linux-libre-5.4.22-gnu/drivers/net/wireless/intel/ipw2x00/ipw2200.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/intel/ipw2x00/ipw2200.c	2020-02-19 17:36:47.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/intel/ipw2x00/ipw2200.c	2020-02-24 05:48:14.000000000 -0500
@@ -1945,8 +1945,9 @@ static void notify_wx_assoc_event(struct
 	wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
 }
 
-static void ipw_irq_tasklet(struct ipw_priv *priv)
+static void ipw_irq_tasklet(unsigned long data)
 {
+	struct ipw_priv *priv = (struct ipw_priv *)data;
 	u32 inta, inta_mask, handled = 0;
 	unsigned long flags;
 	int rc = 0;
@@ -10680,7 +10681,7 @@ static int ipw_setup_deferred_work(struc
 	INIT_WORK(&priv->qos_activate, ipw_bg_qos_activate);
 #endif				/* CONFIG_IPW2200_QOS */
 
-	tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+	tasklet_init(&priv->irq_tasklet,
 		     ipw_irq_tasklet, (unsigned long)priv);
 
 	return ret;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/intel/iwlegacy/3945-mac.c linux-libre-5.4.22-gnu/drivers/net/wireless/intel/iwlegacy/3945-mac.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/intel/iwlegacy/3945-mac.c	2020-02-19 17:36:53.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/intel/iwlegacy/3945-mac.c	2020-02-24 05:48:20.000000000 -0500
@@ -1376,8 +1376,9 @@ il3945_dump_nic_error_log(struct il_priv
 }
 
 static void
-il3945_irq_tasklet(struct il_priv *il)
+il3945_irq_tasklet(unsigned long data)
 {
+	struct il_priv *il = (struct il_priv *)data;
 	u32 inta, handled = 0;
 	u32 inta_fh;
 	unsigned long flags;
@@ -3403,7 +3404,7 @@ il3945_setup_deferred_work(struct il_pri
 	timer_setup(&il->watchdog, il_bg_watchdog, 0);
 
 	tasklet_init(&il->irq_tasklet,
-		     (void (*)(unsigned long))il3945_irq_tasklet,
+		     il3945_irq_tasklet,
 		     (unsigned long)il);
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/intel/iwlegacy/4965-mac.c linux-libre-5.4.22-gnu/drivers/net/wireless/intel/iwlegacy/4965-mac.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/intel/iwlegacy/4965-mac.c	2020-02-19 17:37:03.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/intel/iwlegacy/4965-mac.c	2020-02-24 05:48:31.000000000 -0500
@@ -4344,8 +4344,9 @@ il4965_synchronize_irq(struct il_priv *i
 }
 
 static void
-il4965_irq_tasklet(struct il_priv *il)
+il4965_irq_tasklet(unsigned long data)
 {
+	struct il_priv *il = (struct il_priv *)data;
 	u32 inta, handled = 0;
 	u32 inta_fh;
 	unsigned long flags;
@@ -6238,7 +6239,7 @@ il4965_setup_deferred_work(struct il_pri
 	timer_setup(&il->watchdog, il_bg_watchdog, 0);
 
 	tasklet_init(&il->irq_tasklet,
-		     (void (*)(unsigned long))il4965_irq_tasklet,
+		     il4965_irq_tasklet,
 		     (unsigned long)il);
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/intel/iwlegacy/common.c linux-libre-5.4.22-gnu/drivers/net/wireless/intel/iwlegacy/common.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/intel/iwlegacy/common.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/intel/iwlegacy/common.c	2020-02-24 02:37:04.000000000 -0500
@@ -699,7 +699,7 @@ il_eeprom_init(struct il_priv *il)
 	u32 gp = _il_rd(il, CSR_EEPROM_GP);
 	int sz;
 	int ret;
-	u16 addr;
+	int addr;
 
 	/* allocate eeprom */
 	sz = il->cfg->eeprom_size;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c linux-libre-5.4.22-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c	2020-02-24 02:37:04.000000000 -0500
@@ -5,10 +5,9 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 - 2019 Intel Corporation
+ * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -28,10 +27,9 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 - 2019 Intel Corporation
+ * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -2025,7 +2023,7 @@ static void iwl_mvm_cfg_he_sta(struct iw
 	rcu_read_lock();
 
 	sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_ctxt_cmd.sta_id]);
-	if (IS_ERR(sta)) {
+	if (IS_ERR_OR_NULL(sta)) {
 		rcu_read_unlock();
 		WARN(1, "Can't find STA to configure HE\n");
 		return;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tt.c linux-libre-5.4.22-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tt.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tt.c	2020-02-24 02:37:04.000000000 -0500
@@ -731,7 +731,8 @@ static  struct thermal_zone_device_ops t
 static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
 {
 	int i;
-	char name[] = "iwlwifi";
+	char name[16];
+	static atomic_t counter = ATOMIC_INIT(0);
 
 	if (!iwl_mvm_is_tt_in_fw(mvm)) {
 		mvm->tz_device.tzone = NULL;
@@ -741,6 +742,7 @@ static void iwl_mvm_thermal_zone_registe
 
 	BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
 
+	sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF);
 	mvm->tz_device.tzone = thermal_zone_device_register(name,
 							IWL_MAX_DTS_TRIPS,
 							IWL_WRITABLE_TRIPS_MSK,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/intersil/hostap/hostap_ap.c linux-libre-5.4.22-gnu/drivers/net/wireless/intersil/hostap/hostap_ap.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/intersil/hostap/hostap_ap.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/intersil/hostap/hostap_ap.c	2020-02-24 02:37:04.000000000 -0500
@@ -2508,7 +2508,7 @@ static int prism2_hostapd_add_sta(struct
 		sta->supported_rates[0] = 2;
 	if (sta->tx_supp_rates & WLAN_RATE_2M)
 		sta->supported_rates[1] = 4;
- 	if (sta->tx_supp_rates & WLAN_RATE_5M5)
+	if (sta->tx_supp_rates & WLAN_RATE_5M5)
 		sta->supported_rates[2] = 11;
 	if (sta->tx_supp_rates & WLAN_RATE_11M)
 		sta->supported_rates[3] = 22;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/intersil/orinoco/orinoco_usb.c linux-libre-5.4.22-gnu/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/intersil/orinoco/orinoco_usb.c	2020-02-19 17:36:28.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/intersil/orinoco/orinoco_usb.c	2020-02-24 05:47:54.000000000 -0500
@@ -1361,7 +1361,8 @@ static int ezusb_init(struct hermes *hw)
 	int retval;
 
 	BUG_ON(in_interrupt());
-	BUG_ON(!upriv);
+	if (!upriv)
+		return -EINVAL;
 
 	upriv->reply_count = 0;
 	/* Write the MAGIC number on the simulated registers to keep
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/realtek/rtlwifi/pci.c linux-libre-5.4.22-gnu/drivers/net/wireless/realtek/rtlwifi/pci.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/realtek/rtlwifi/pci.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/realtek/rtlwifi/pci.c	2020-02-24 02:37:04.000000000 -0500
@@ -1061,13 +1061,15 @@ done:
 	return ret;
 }
 
-static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
+static void _rtl_pci_irq_tasklet(unsigned long data)
 {
+	struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
 	_rtl_pci_tx_chk_waitq(hw);
 }
 
-static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
+static void _rtl_pci_prepare_bcn_tasklet(unsigned long data)
 {
+	struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -1193,10 +1195,10 @@ static void _rtl_pci_init_struct(struct
 
 	/*task */
 	tasklet_init(&rtlpriv->works.irq_tasklet,
-		     (void (*)(unsigned long))_rtl_pci_irq_tasklet,
+		     _rtl_pci_irq_tasklet,
 		     (unsigned long)hw);
 	tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
-		     (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
+		     _rtl_pci_prepare_bcn_tasklet,
 		     (unsigned long)hw);
 	INIT_WORK(&rtlpriv->works.lps_change_work,
 		  rtl_lps_change_work_callback);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/realtek/rtw88/main.c linux-libre-5.4.22-gnu/drivers/net/wireless/realtek/rtw88/main.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/realtek/rtw88/main.c	2020-02-19 17:42:46.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/realtek/rtw88/main.c	2020-02-24 05:54:23.000000000 -0500
@@ -556,8 +556,8 @@ void rtw_update_sta_info(struct rtw_dev
 		if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)
 			is_support_sgi = true;
 	} else if (sta->ht_cap.ht_supported) {
-		ra_mask |= (sta->ht_cap.mcs.rx_mask[NL80211_BAND_5GHZ] << 20) |
-			   (sta->ht_cap.mcs.rx_mask[NL80211_BAND_2GHZ] << 12);
+		ra_mask |= (sta->ht_cap.mcs.rx_mask[1] << 20) |
+			   (sta->ht_cap.mcs.rx_mask[0] << 12);
 		if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
 			stbc_en = HT_STBC_EN;
 		if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)
@@ -567,6 +567,9 @@ void rtw_update_sta_info(struct rtw_dev
 			is_support_sgi = true;
 	}
 
+	if (efuse->hw_cap.nss == 1)
+		ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS;
+
 	if (hal->current_band_type == RTW_BAND_5G) {
 		ra_mask |= (u64)sta->supp_rates[NL80211_BAND_5GHZ] << 4;
 		if (sta->vht_cap.vht_supported) {
@@ -600,11 +603,6 @@ void rtw_update_sta_info(struct rtw_dev
 		wireless_set = 0;
 	}
 
-	if (efuse->hw_cap.nss == 1) {
-		ra_mask &= RA_MASK_VHT_RATES_1SS;
-		ra_mask &= RA_MASK_HT_RATES_1SS;
-	}
-
 	switch (sta->bandwidth) {
 	case IEEE80211_STA_RX_BW_80:
 		bw_mode = RTW_CHANNEL_WIDTH_80;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/net/wireless/realtek/rtw88/pci.c linux-libre-5.4.22-gnu/drivers/net/wireless/realtek/rtw88/pci.c
--- linux-libre-5.4.21-gnu/drivers/net/wireless/realtek/rtw88/pci.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/net/wireless/realtek/rtw88/pci.c	2020-02-24 02:37:04.000000000 -0500
@@ -762,6 +762,11 @@ static void rtw_pci_tx_isr(struct rtw_de
 
 	while (count--) {
 		skb = skb_dequeue(&ring->queue);
+		if (!skb) {
+			rtw_err(rtwdev, "failed to dequeue %d skb TX queue %d, BD=0x%08x, rp %d -> %d\n",
+				count, hw_queue, bd_idx, ring->r.rp, cur_rp);
+			break;
+		}
 		tx_data = rtw_pci_get_tx_data(skb);
 		pci_unmap_single(rtwpci->pdev, tx_data->dma, skb->len,
 				 PCI_DMA_TODEVICE);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/nfc/port100.c linux-libre-5.4.22-gnu/drivers/nfc/port100.c
--- linux-libre-5.4.21-gnu/drivers/nfc/port100.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/nfc/port100.c	2020-02-24 02:37:04.000000000 -0500
@@ -565,7 +565,7 @@ static void port100_tx_update_payload_le
 {
 	struct port100_frame *frame = _frame;
 
-	frame->datalen = cpu_to_le16(le16_to_cpu(frame->datalen) + len);
+	le16_add_cpu(&frame->datalen, len);
 }
 
 static bool port100_rx_frame_is_valid(void *_frame)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/nvme/host/pci.c linux-libre-5.4.22-gnu/drivers/nvme/host/pci.c
--- linux-libre-5.4.21-gnu/drivers/nvme/host/pci.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/nvme/host/pci.c	2020-02-24 02:37:04.000000000 -0500
@@ -167,7 +167,6 @@ struct nvme_queue {
 	 /* only used for poll queues: */
 	spinlock_t cq_poll_lock ____cacheline_aligned_in_smp;
 	volatile struct nvme_completion *cqes;
-	struct blk_mq_tags **tags;
 	dma_addr_t sq_dma_addr;
 	dma_addr_t cq_dma_addr;
 	u32 __iomem *q_db;
@@ -377,29 +376,17 @@ static int nvme_admin_init_hctx(struct b
 
 	WARN_ON(hctx_idx != 0);
 	WARN_ON(dev->admin_tagset.tags[0] != hctx->tags);
-	WARN_ON(nvmeq->tags);
 
 	hctx->driver_data = nvmeq;
-	nvmeq->tags = &dev->admin_tagset.tags[0];
 	return 0;
 }
 
-static void nvme_admin_exit_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx)
-{
-	struct nvme_queue *nvmeq = hctx->driver_data;
-
-	nvmeq->tags = NULL;
-}
-
 static int nvme_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
 			  unsigned int hctx_idx)
 {
 	struct nvme_dev *dev = data;
 	struct nvme_queue *nvmeq = &dev->queues[hctx_idx + 1];
 
-	if (!nvmeq->tags)
-		nvmeq->tags = &dev->tagset.tags[hctx_idx];
-
 	WARN_ON(dev->tagset.tags[hctx_idx] != hctx->tags);
 	hctx->driver_data = nvmeq;
 	return 0;
@@ -950,6 +937,13 @@ static inline void nvme_ring_cq_doorbell
 		writel(head, nvmeq->q_db + nvmeq->dev->db_stride);
 }
 
+static inline struct blk_mq_tags *nvme_queue_tagset(struct nvme_queue *nvmeq)
+{
+	if (!nvmeq->qid)
+		return nvmeq->dev->admin_tagset.tags[0];
+	return nvmeq->dev->tagset.tags[nvmeq->qid - 1];
+}
+
 static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx)
 {
 	volatile struct nvme_completion *cqe = &nvmeq->cqes[idx];
@@ -975,7 +969,7 @@ static inline void nvme_handle_cqe(struc
 		return;
 	}
 
-	req = blk_mq_tag_to_rq(*nvmeq->tags, cqe->command_id);
+	req = blk_mq_tag_to_rq(nvme_queue_tagset(nvmeq), cqe->command_id);
 	trace_nvme_sq(req, cqe->sq_head, nvmeq->sq_tail);
 	nvme_end_request(req, cqe->status, cqe->result);
 }
@@ -1578,7 +1572,6 @@ static const struct blk_mq_ops nvme_mq_a
 	.queue_rq	= nvme_queue_rq,
 	.complete	= nvme_pci_complete_rq,
 	.init_hctx	= nvme_admin_init_hctx,
-	.exit_hctx      = nvme_admin_exit_hctx,
 	.init_request	= nvme_init_request,
 	.timeout	= nvme_timeout,
 };
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/nvme/target/core.c linux-libre-5.4.22-gnu/drivers/nvme/target/core.c
--- linux-libre-5.4.21-gnu/drivers/nvme/target/core.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/nvme/target/core.c	2020-02-24 02:37:04.000000000 -0500
@@ -555,7 +555,8 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
 	} else {
 		struct nvmet_ns *old;
 
-		list_for_each_entry_rcu(old, &subsys->namespaces, dev_link) {
+		list_for_each_entry_rcu(old, &subsys->namespaces, dev_link,
+					lockdep_is_held(&subsys->lock)) {
 			BUG_ON(ns->nsid == old->nsid);
 			if (ns->nsid < old->nsid)
 				break;
@@ -1174,7 +1175,8 @@ static void nvmet_setup_p2p_ns_map(struc
 
 	ctrl->p2p_client = get_device(req->p2p_client);
 
-	list_for_each_entry_rcu(ns, &ctrl->subsys->namespaces, dev_link)
+	list_for_each_entry_rcu(ns, &ctrl->subsys->namespaces, dev_link,
+				lockdep_is_held(&ctrl->subsys->lock))
 		nvmet_p2pmem_ns_add_p2p(ctrl, ns);
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/opp/of.c linux-libre-5.4.22-gnu/drivers/opp/of.c
--- linux-libre-5.4.21-gnu/drivers/opp/of.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/opp/of.c	2020-02-24 02:37:04.000000000 -0500
@@ -678,15 +678,17 @@ static int _of_add_opp_table_v2(struct d
 			dev_err(dev, "%s: Failed to add OPP, %d\n", __func__,
 				ret);
 			of_node_put(np);
-			return ret;
+			goto put_list_kref;
 		} else if (opp) {
 			count++;
 		}
 	}
 
 	/* There should be one of more OPP defined */
-	if (WARN_ON(!count))
-		return -ENOENT;
+	if (WARN_ON(!count)) {
+		ret = -ENOENT;
+		goto put_list_kref;
+	}
 
 	list_for_each_entry(opp, &opp_table->opp_list, node)
 		pstate_count += !!opp->pstate;
@@ -695,7 +697,8 @@ static int _of_add_opp_table_v2(struct d
 	if (pstate_count && pstate_count != count) {
 		dev_err(dev, "Not all nodes have performance state set (%d: %d)\n",
 			count, pstate_count);
-		return -ENOENT;
+		ret = -ENOENT;
+		goto put_list_kref;
 	}
 
 	if (pstate_count)
@@ -704,6 +707,11 @@ static int _of_add_opp_table_v2(struct d
 	opp_table->parsed_static_opps = true;
 
 	return 0;
+
+put_list_kref:
+	_put_opp_list_kref(opp_table);
+
+	return ret;
 }
 
 /* Initializes OPP tables based on old-deprecated bindings */
@@ -738,6 +746,7 @@ static int _of_add_opp_table_v1(struct d
 		if (ret) {
 			dev_err(dev, "%s: Failed to add OPP %ld (%d)\n",
 				__func__, freq, ret);
+			_put_opp_list_kref(opp_table);
 			return ret;
 		}
 		nr -= 2;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/pci/controller/pcie-iproc.c linux-libre-5.4.22-gnu/drivers/pci/controller/pcie-iproc.c
--- linux-libre-5.4.21-gnu/drivers/pci/controller/pcie-iproc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/pci/controller/pcie-iproc.c	2020-02-24 02:37:04.000000000 -0500
@@ -1608,6 +1608,30 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BR
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804,
 			quirk_paxc_disable_msi_parsing);
 
+static void quirk_paxc_bridge(struct pci_dev *pdev)
+{
+	/*
+	 * The PCI config space is shared with the PAXC root port and the first
+	 * Ethernet device.  So, we need to workaround this by telling the PCI
+	 * code that the bridge is not an Ethernet device.
+	 */
+	if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+		pdev->class = PCI_CLASS_BRIDGE_PCI << 8;
+
+	/*
+	 * MPSS is not being set properly (as it is currently 0).  This is
+	 * because that area of the PCI config space is hard coded to zero, and
+	 * is not modifiable by firmware.  Set this to 2 (e.g., 512 byte MPS)
+	 * so that the MPS can be set to the real max value.
+	 */
+	pdev->pcie_mpss = 2;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, quirk_paxc_bridge);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd750, quirk_paxc_bridge);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802, quirk_paxc_bridge);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, quirk_paxc_bridge);
+
 MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
 MODULE_DESCRIPTION("Broadcom iPROC PCIe common driver");
 MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/pci/pci.c linux-libre-5.4.22-gnu/drivers/pci/pci.c
--- linux-libre-5.4.21-gnu/drivers/pci/pci.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/pci/pci.c	2020-02-24 02:37:04.000000000 -0500
@@ -5875,7 +5875,8 @@ EXPORT_SYMBOL_GPL(pci_pr3_present);
 /**
  * pci_add_dma_alias - Add a DMA devfn alias for a device
  * @dev: the PCI device for which alias is added
- * @devfn: alias slot and function
+ * @devfn_from: alias slot and function
+ * @nr_devfns: number of subsequent devfns to alias
  *
  * This helper encodes an 8-bit devfn as a bit number in dma_alias_mask
  * which is used to program permissible bus-devfn source addresses for DMA
@@ -5891,18 +5892,29 @@ EXPORT_SYMBOL_GPL(pci_pr3_present);
  * cannot be left as a userspace activity).  DMA aliases should therefore
  * be configured via quirks, such as the PCI fixup header quirk.
  */
-void pci_add_dma_alias(struct pci_dev *dev, u8 devfn)
+void pci_add_dma_alias(struct pci_dev *dev, u8 devfn_from, unsigned nr_devfns)
 {
+	int devfn_to;
+
+	nr_devfns = min(nr_devfns, (unsigned) MAX_NR_DEVFNS - devfn_from);
+	devfn_to = devfn_from + nr_devfns - 1;
+
 	if (!dev->dma_alias_mask)
-		dev->dma_alias_mask = bitmap_zalloc(U8_MAX, GFP_KERNEL);
+		dev->dma_alias_mask = bitmap_zalloc(MAX_NR_DEVFNS, GFP_KERNEL);
 	if (!dev->dma_alias_mask) {
 		pci_warn(dev, "Unable to allocate DMA alias mask\n");
 		return;
 	}
 
-	set_bit(devfn, dev->dma_alias_mask);
-	pci_info(dev, "Enabling fixed DMA alias to %02x.%d\n",
-		 PCI_SLOT(devfn), PCI_FUNC(devfn));
+	bitmap_set(dev->dma_alias_mask, devfn_from, nr_devfns);
+
+	if (nr_devfns == 1)
+		pci_info(dev, "Enabling fixed DMA alias to %02x.%d\n",
+				PCI_SLOT(devfn_from), PCI_FUNC(devfn_from));
+	else if (nr_devfns > 1)
+		pci_info(dev, "Enabling fixed DMA alias for devfn range from %02x.%d to %02x.%d\n",
+				PCI_SLOT(devfn_from), PCI_FUNC(devfn_from),
+				PCI_SLOT(devfn_to), PCI_FUNC(devfn_to));
 }
 
 bool pci_devs_are_dma_aliases(struct pci_dev *dev1, struct pci_dev *dev2)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/pci/pci.h linux-libre-5.4.22-gnu/drivers/pci/pci.h
--- linux-libre-5.4.21-gnu/drivers/pci/pci.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/pci/pci.h	2020-02-24 02:37:04.000000000 -0500
@@ -4,6 +4,9 @@
 
 #include <linux/pci.h>
 
+/* Number of possible devfns: 0.0 to 1f.7 inclusive */
+#define MAX_NR_DEVFNS 256
+
 #define PCI_FIND_CAP_TTL	48
 
 #define PCI_VSEC_ID_INTEL_TBT	0x1234	/* Thunderbolt */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/pci/quirks.c linux-libre-5.4.22-gnu/drivers/pci/quirks.c
--- linux-libre-5.4.21-gnu/drivers/pci/quirks.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/pci/quirks.c	2020-02-24 02:37:04.000000000 -0500
@@ -1871,19 +1871,40 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	0x260a, quirk_intel_pcie_pm);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	0x260b, quirk_intel_pcie_pm);
 
+static void quirk_d3hot_delay(struct pci_dev *dev, unsigned int delay)
+{
+	if (dev->d3_delay >= delay)
+		return;
+
+	dev->d3_delay = delay;
+	pci_info(dev, "extending delay after power-on from D3hot to %d msec\n",
+		 dev->d3_delay);
+}
+
 static void quirk_radeon_pm(struct pci_dev *dev)
 {
 	if (dev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
-	    dev->subsystem_device == 0x00e2) {
-		if (dev->d3_delay < 20) {
-			dev->d3_delay = 20;
-			pci_info(dev, "extending delay after power-on from D3 to %d msec\n",
-				 dev->d3_delay);
-		}
-	}
+	    dev->subsystem_device == 0x00e2)
+		quirk_d3hot_delay(dev, 20);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6741, quirk_radeon_pm);
 
+/*
+ * Ryzen5/7 XHCI controllers fail upon resume from runtime suspend or s2idle.
+ * https://bugzilla.kernel.org/show_bug.cgi?id=205587
+ *
+ * The kernel attempts to transition these devices to D3cold, but that seems
+ * to be ineffective on the platforms in question; the PCI device appears to
+ * remain on in D3hot state. The D3hot-to-D0 transition then requires an
+ * extended delay in order to succeed.
+ */
+static void quirk_ryzen_xhci_d3hot(struct pci_dev *dev)
+{
+	quirk_d3hot_delay(dev, 20);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e0, quirk_ryzen_xhci_d3hot);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e1, quirk_ryzen_xhci_d3hot);
+
 #ifdef CONFIG_X86_IO_APIC
 static int dmi_disable_ioapicreroute(const struct dmi_system_id *d)
 {
@@ -2381,32 +2402,6 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_B
 			 PCI_DEVICE_ID_TIGON3_5719,
 			 quirk_brcm_5719_limit_mrrs);
 
-#ifdef CONFIG_PCIE_IPROC_PLATFORM
-static void quirk_paxc_bridge(struct pci_dev *pdev)
-{
-	/*
-	 * The PCI config space is shared with the PAXC root port and the first
-	 * Ethernet device.  So, we need to workaround this by telling the PCI
-	 * code that the bridge is not an Ethernet device.
-	 */
-	if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
-		pdev->class = PCI_CLASS_BRIDGE_PCI << 8;
-
-	/*
-	 * MPSS is not being set properly (as it is currently 0).  This is
-	 * because that area of the PCI config space is hard coded to zero, and
-	 * is not modifiable by firmware.  Set this to 2 (e.g., 512 byte MPS)
-	 * so that the MPS can be set to the real max value.
-	 */
-	pdev->pcie_mpss = 2;
-}
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, quirk_paxc_bridge);
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge);
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd750, quirk_paxc_bridge);
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802, quirk_paxc_bridge);
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, quirk_paxc_bridge);
-#endif
-
 /*
  * Originally in EDAC sources for i82875P: Intel tells BIOS developers to
  * hide device 6 which configures the overflow device access containing the
@@ -3932,7 +3927,7 @@ int pci_dev_specific_reset(struct pci_de
 static void quirk_dma_func0_alias(struct pci_dev *dev)
 {
 	if (PCI_FUNC(dev->devfn) != 0)
-		pci_add_dma_alias(dev, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+		pci_add_dma_alias(dev, PCI_DEVFN(PCI_SLOT(dev->devfn), 0), 1);
 }
 
 /*
@@ -3946,7 +3941,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_R
 static void quirk_dma_func1_alias(struct pci_dev *dev)
 {
 	if (PCI_FUNC(dev->devfn) != 1)
-		pci_add_dma_alias(dev, PCI_DEVFN(PCI_SLOT(dev->devfn), 1));
+		pci_add_dma_alias(dev, PCI_DEVFN(PCI_SLOT(dev->devfn), 1), 1);
 }
 
 /*
@@ -4031,7 +4026,7 @@ static void quirk_fixed_dma_alias(struct
 
 	id = pci_match_id(fixed_dma_alias_tbl, dev);
 	if (id)
-		pci_add_dma_alias(dev, id->driver_data);
+		pci_add_dma_alias(dev, id->driver_data, 1);
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADAPTEC2, 0x0285, quirk_fixed_dma_alias);
@@ -4073,9 +4068,9 @@ DECLARE_PCI_FIXUP_HEADER(0x8086, 0x244e,
  */
 static void quirk_mic_x200_dma_alias(struct pci_dev *pdev)
 {
-	pci_add_dma_alias(pdev, PCI_DEVFN(0x10, 0x0));
-	pci_add_dma_alias(pdev, PCI_DEVFN(0x11, 0x0));
-	pci_add_dma_alias(pdev, PCI_DEVFN(0x12, 0x3));
+	pci_add_dma_alias(pdev, PCI_DEVFN(0x10, 0x0), 1);
+	pci_add_dma_alias(pdev, PCI_DEVFN(0x11, 0x0), 1);
+	pci_add_dma_alias(pdev, PCI_DEVFN(0x12, 0x3), 1);
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2260, quirk_mic_x200_dma_alias);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2264, quirk_mic_x200_dma_alias);
@@ -4099,13 +4094,8 @@ static void quirk_pex_vca_alias(struct p
 	const unsigned int num_pci_slots = 0x20;
 	unsigned int slot;
 
-	for (slot = 0; slot < num_pci_slots; slot++) {
-		pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x0));
-		pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x1));
-		pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x2));
-		pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x3));
-		pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x4));
-	}
+	for (slot = 0; slot < num_pci_slots; slot++)
+		pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x0), 5);
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2954, quirk_pex_vca_alias);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2955, quirk_pex_vca_alias);
@@ -5320,7 +5310,7 @@ static void quirk_switchtec_ntb_dma_alia
 			pci_dbg(pdev,
 				"Aliasing Partition %d Proxy ID %02x.%d\n",
 				pp, PCI_SLOT(devfn), PCI_FUNC(devfn));
-			pci_add_dma_alias(pdev, devfn);
+			pci_add_dma_alias(pdev, devfn, 1);
 		}
 	}
 
@@ -5363,6 +5353,21 @@ SWITCHTEC_QUIRK(0x8575);  /* PFXI 80XG3
 SWITCHTEC_QUIRK(0x8576);  /* PFXI 96XG3 */
 
 /*
+ * The PLX NTB uses devfn proxy IDs to move TLPs between NT endpoints.
+ * These IDs are used to forward responses to the originator on the other
+ * side of the NTB.  Alias all possible IDs to the NTB to permit access when
+ * the IOMMU is turned on.
+ */
+static void quirk_plx_ntb_dma_alias(struct pci_dev *pdev)
+{
+	pci_info(pdev, "Setting PLX NTB proxy ID aliases\n");
+	/* PLX NTB may use all 256 devfns */
+	pci_add_dma_alias(pdev, 0, 256);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PLX, 0x87b0, quirk_plx_ntb_dma_alias);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PLX, 0x87b1, quirk_plx_ntb_dma_alias);
+
+/*
  * On Lenovo Thinkpad P50 SKUs with a Nvidia Quadro M1000M, the BIOS does
  * not always reset the secondary Nvidia GPU between reboots if the system
  * is configured to use Hybrid Graphics mode.  This results in the GPU
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/pci/search.c linux-libre-5.4.22-gnu/drivers/pci/search.c
--- linux-libre-5.4.21-gnu/drivers/pci/search.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/pci/search.c	2020-02-24 02:37:04.000000000 -0500
@@ -41,9 +41,9 @@ int pci_for_each_dma_alias(struct pci_de
 	 * DMA, iterate over that too.
 	 */
 	if (unlikely(pdev->dma_alias_mask)) {
-		u8 devfn;
+		unsigned int devfn;
 
-		for_each_set_bit(devfn, pdev->dma_alias_mask, U8_MAX) {
+		for_each_set_bit(devfn, pdev->dma_alias_mask, MAX_NR_DEVFNS) {
 			ret = fn(pdev, PCI_DEVID(pdev->bus->number, devfn),
 				 data);
 			if (ret)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/perf/fsl_imx8_ddr_perf.c linux-libre-5.4.22-gnu/drivers/perf/fsl_imx8_ddr_perf.c
--- linux-libre-5.4.21-gnu/drivers/perf/fsl_imx8_ddr_perf.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/perf/fsl_imx8_ddr_perf.c	2020-02-24 02:37:04.000000000 -0500
@@ -572,13 +572,17 @@ static int ddr_perf_probe(struct platfor
 
 	if (ret < 0) {
 		dev_err(&pdev->dev, "cpuhp_setup_state_multi failed\n");
-		goto ddr_perf_err;
+		goto cpuhp_state_err;
 	}
 
 	pmu->cpuhp_state = ret;
 
 	/* Register the pmu instance for cpu hotplug */
-	cpuhp_state_add_instance_nocalls(pmu->cpuhp_state, &pmu->node);
+	ret = cpuhp_state_add_instance_nocalls(pmu->cpuhp_state, &pmu->node);
+	if (ret) {
+		dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
+		goto cpuhp_instance_err;
+	}
 
 	/* Request irq */
 	irq = of_irq_get(np, 0);
@@ -612,9 +616,10 @@ static int ddr_perf_probe(struct platfor
 	return 0;
 
 ddr_perf_err:
-	if (pmu->cpuhp_state)
-		cpuhp_state_remove_instance_nocalls(pmu->cpuhp_state, &pmu->node);
-
+	cpuhp_state_remove_instance_nocalls(pmu->cpuhp_state, &pmu->node);
+cpuhp_instance_err:
+	cpuhp_remove_multi_state(pmu->cpuhp_state);
+cpuhp_state_err:
 	ida_simple_remove(&ddr_ida, pmu->id);
 	dev_warn(&pdev->dev, "i.MX8 DDR Perf PMU failed (%d), disabled\n", ret);
 	return ret;
@@ -625,6 +630,7 @@ static int ddr_perf_remove(struct platfo
 	struct ddr_pmu *pmu = platform_get_drvdata(pdev);
 
 	cpuhp_state_remove_instance_nocalls(pmu->cpuhp_state, &pmu->node);
+	cpuhp_remove_multi_state(pmu->cpuhp_state);
 	irq_set_affinity_hint(pmu->irq, NULL);
 
 	perf_pmu_unregister(&pmu->pmu);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/pinctrl/intel/pinctrl-baytrail.c linux-libre-5.4.22-gnu/drivers/pinctrl/intel/pinctrl-baytrail.c
--- linux-libre-5.4.21-gnu/drivers/pinctrl/intel/pinctrl-baytrail.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/pinctrl/intel/pinctrl-baytrail.c	2020-02-24 02:37:04.000000000 -0500
@@ -752,7 +752,13 @@ static void byt_gpio_clear_triggering(st
 
 	raw_spin_lock_irqsave(&byt_lock, flags);
 	value = readl(reg);
-	value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
+
+	/* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */
+	if (value & BYT_DIRECT_IRQ_EN)
+		/* nothing to do */ ;
+	else
+		value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
+
 	writel(value, reg);
 	raw_spin_unlock_irqrestore(&byt_lock, flags);
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/pinctrl/sh-pfc/pfc-sh7264.c linux-libre-5.4.22-gnu/drivers/pinctrl/sh-pfc/pfc-sh7264.c
--- linux-libre-5.4.21-gnu/drivers/pinctrl/sh-pfc/pfc-sh7264.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/pinctrl/sh-pfc/pfc-sh7264.c	2020-02-24 02:37:04.000000000 -0500
@@ -497,17 +497,15 @@ enum {
 	SD_WP_MARK, SD_CLK_MARK, SD_CMD_MARK,
 	CRX0_MARK, CRX1_MARK,
 	CTX0_MARK, CTX1_MARK,
+	CRX0_CRX1_MARK, CTX0_CTX1_MARK,
 
 	PWM1A_MARK, PWM1B_MARK, PWM1C_MARK, PWM1D_MARK,
 	PWM1E_MARK, PWM1F_MARK, PWM1G_MARK, PWM1H_MARK,
 	PWM2A_MARK, PWM2B_MARK, PWM2C_MARK, PWM2D_MARK,
 	PWM2E_MARK, PWM2F_MARK, PWM2G_MARK, PWM2H_MARK,
 	IERXD_MARK, IETXD_MARK,
-	CRX0_CRX1_MARK,
 	WDTOVF_MARK,
 
-	CRX0X1_MARK,
-
 	/* DMAC */
 	TEND0_MARK, DACK0_MARK, DREQ0_MARK,
 	TEND1_MARK, DACK1_MARK, DREQ1_MARK,
@@ -995,12 +993,12 @@ static const u16 pinmux_data[] = {
 
 	PINMUX_DATA(PJ3_DATA, PJ3MD_00),
 	PINMUX_DATA(CRX1_MARK, PJ3MD_01),
-	PINMUX_DATA(CRX0X1_MARK, PJ3MD_10),
+	PINMUX_DATA(CRX0_CRX1_MARK, PJ3MD_10),
 	PINMUX_DATA(IRQ1_PJ_MARK, PJ3MD_11),
 
 	PINMUX_DATA(PJ2_DATA, PJ2MD_000),
 	PINMUX_DATA(CTX1_MARK, PJ2MD_001),
-	PINMUX_DATA(CRX0_CRX1_MARK, PJ2MD_010),
+	PINMUX_DATA(CTX0_CTX1_MARK, PJ2MD_010),
 	PINMUX_DATA(CS2_MARK, PJ2MD_011),
 	PINMUX_DATA(SCK0_MARK, PJ2MD_100),
 	PINMUX_DATA(LCD_M_DISP_MARK, PJ2MD_101),
@@ -1245,6 +1243,7 @@ static const struct pinmux_func pinmux_f
 	GPIO_FN(CTX1),
 	GPIO_FN(CRX1),
 	GPIO_FN(CTX0),
+	GPIO_FN(CTX0_CTX1),
 	GPIO_FN(CRX0),
 	GPIO_FN(CRX0_CRX1),
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/pinctrl/sh-pfc/pfc-sh7269.c linux-libre-5.4.22-gnu/drivers/pinctrl/sh-pfc/pfc-sh7269.c
--- linux-libre-5.4.21-gnu/drivers/pinctrl/sh-pfc/pfc-sh7269.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/pinctrl/sh-pfc/pfc-sh7269.c	2020-02-24 02:37:04.000000000 -0500
@@ -737,13 +737,12 @@ enum {
 	CRX0_MARK, CTX0_MARK,
 	CRX1_MARK, CTX1_MARK,
 	CRX2_MARK, CTX2_MARK,
-	CRX0_CRX1_MARK,
-	CRX0_CRX1_CRX2_MARK,
-	CTX0CTX1CTX2_MARK,
+	CRX0_CRX1_MARK, CTX0_CTX1_MARK,
+	CRX0_CRX1_CRX2_MARK, CTX0_CTX1_CTX2_MARK,
 	CRX1_PJ22_MARK, CTX1_PJ23_MARK,
 	CRX2_PJ20_MARK, CTX2_PJ21_MARK,
-	CRX0CRX1_PJ22_MARK,
-	CRX0CRX1CRX2_PJ20_MARK,
+	CRX0_CRX1_PJ22_MARK, CTX0_CTX1_PJ23_MARK,
+	CRX0_CRX1_CRX2_PJ20_MARK, CTX0_CTX1_CTX2_PJ21_MARK,
 
 	/* VDC */
 	DV_CLK_MARK,
@@ -821,6 +820,7 @@ static const u16 pinmux_data[] = {
 	PINMUX_DATA(CS3_MARK, PC8MD_001),
 	PINMUX_DATA(TXD7_MARK, PC8MD_010),
 	PINMUX_DATA(CTX1_MARK, PC8MD_011),
+	PINMUX_DATA(CTX0_CTX1_MARK, PC8MD_100),
 
 	PINMUX_DATA(PC7_DATA, PC7MD_000),
 	PINMUX_DATA(CKE_MARK, PC7MD_001),
@@ -833,11 +833,12 @@ static const u16 pinmux_data[] = {
 	PINMUX_DATA(CAS_MARK, PC6MD_001),
 	PINMUX_DATA(SCK7_MARK, PC6MD_010),
 	PINMUX_DATA(CTX0_MARK, PC6MD_011),
+	PINMUX_DATA(CTX0_CTX1_CTX2_MARK, PC6MD_100),
 
 	PINMUX_DATA(PC5_DATA, PC5MD_000),
 	PINMUX_DATA(RAS_MARK, PC5MD_001),
 	PINMUX_DATA(CRX0_MARK, PC5MD_011),
-	PINMUX_DATA(CTX0CTX1CTX2_MARK, PC5MD_100),
+	PINMUX_DATA(CTX0_CTX1_CTX2_MARK, PC5MD_100),
 	PINMUX_DATA(IRQ0_PC_MARK, PC5MD_101),
 
 	PINMUX_DATA(PC4_DATA, PC4MD_00),
@@ -1289,30 +1290,32 @@ static const u16 pinmux_data[] = {
 	PINMUX_DATA(LCD_DATA23_PJ23_MARK, PJ23MD_010),
 	PINMUX_DATA(LCD_TCON6_MARK, PJ23MD_011),
 	PINMUX_DATA(IRQ3_PJ_MARK, PJ23MD_100),
-	PINMUX_DATA(CTX1_MARK, PJ23MD_101),
+	PINMUX_DATA(CTX1_PJ23_MARK, PJ23MD_101),
+	PINMUX_DATA(CTX0_CTX1_PJ23_MARK, PJ23MD_110),
 
 	PINMUX_DATA(PJ22_DATA, PJ22MD_000),
 	PINMUX_DATA(DV_DATA22_MARK, PJ22MD_001),
 	PINMUX_DATA(LCD_DATA22_PJ22_MARK, PJ22MD_010),
 	PINMUX_DATA(LCD_TCON5_MARK, PJ22MD_011),
 	PINMUX_DATA(IRQ2_PJ_MARK, PJ22MD_100),
-	PINMUX_DATA(CRX1_MARK, PJ22MD_101),
-	PINMUX_DATA(CRX0_CRX1_MARK, PJ22MD_110),
+	PINMUX_DATA(CRX1_PJ22_MARK, PJ22MD_101),
+	PINMUX_DATA(CRX0_CRX1_PJ22_MARK, PJ22MD_110),
 
 	PINMUX_DATA(PJ21_DATA, PJ21MD_000),
 	PINMUX_DATA(DV_DATA21_MARK, PJ21MD_001),
 	PINMUX_DATA(LCD_DATA21_PJ21_MARK, PJ21MD_010),
 	PINMUX_DATA(LCD_TCON4_MARK, PJ21MD_011),
 	PINMUX_DATA(IRQ1_PJ_MARK, PJ21MD_100),
-	PINMUX_DATA(CTX2_MARK, PJ21MD_101),
+	PINMUX_DATA(CTX2_PJ21_MARK, PJ21MD_101),
+	PINMUX_DATA(CTX0_CTX1_CTX2_PJ21_MARK, PJ21MD_110),
 
 	PINMUX_DATA(PJ20_DATA, PJ20MD_000),
 	PINMUX_DATA(DV_DATA20_MARK, PJ20MD_001),
 	PINMUX_DATA(LCD_DATA20_PJ20_MARK, PJ20MD_010),
 	PINMUX_DATA(LCD_TCON3_MARK, PJ20MD_011),
 	PINMUX_DATA(IRQ0_PJ_MARK, PJ20MD_100),
-	PINMUX_DATA(CRX2_MARK, PJ20MD_101),
-	PINMUX_DATA(CRX0CRX1CRX2_PJ20_MARK, PJ20MD_110),
+	PINMUX_DATA(CRX2_PJ20_MARK, PJ20MD_101),
+	PINMUX_DATA(CRX0_CRX1_CRX2_PJ20_MARK, PJ20MD_110),
 
 	PINMUX_DATA(PJ19_DATA, PJ19MD_000),
 	PINMUX_DATA(DV_DATA19_MARK, PJ19MD_001),
@@ -1663,12 +1666,24 @@ static const struct pinmux_func pinmux_f
 	GPIO_FN(WDTOVF),
 
 	/* CAN */
+	GPIO_FN(CTX2),
+	GPIO_FN(CRX2),
 	GPIO_FN(CTX1),
 	GPIO_FN(CRX1),
 	GPIO_FN(CTX0),
 	GPIO_FN(CRX0),
+	GPIO_FN(CTX0_CTX1),
 	GPIO_FN(CRX0_CRX1),
+	GPIO_FN(CTX0_CTX1_CTX2),
 	GPIO_FN(CRX0_CRX1_CRX2),
+	GPIO_FN(CTX2_PJ21),
+	GPIO_FN(CRX2_PJ20),
+	GPIO_FN(CTX1_PJ23),
+	GPIO_FN(CRX1_PJ22),
+	GPIO_FN(CTX0_CTX1_PJ23),
+	GPIO_FN(CRX0_CRX1_PJ22),
+	GPIO_FN(CTX0_CTX1_CTX2_PJ21),
+	GPIO_FN(CRX0_CRX1_CRX2_PJ20),
 
 	/* DMAC */
 	GPIO_FN(TEND0),
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/pwm/pwm-omap-dmtimer.c linux-libre-5.4.22-gnu/drivers/pwm/pwm-omap-dmtimer.c
--- linux-libre-5.4.21-gnu/drivers/pwm/pwm-omap-dmtimer.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/pwm/pwm-omap-dmtimer.c	2020-02-24 02:37:04.000000000 -0500
@@ -298,15 +298,10 @@ static int pwm_omap_dmtimer_probe(struct
 		goto put;
 	}
 
-put:
-	of_node_put(timer);
-	if (ret < 0)
-		return ret;
-
 	omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL);
 	if (!omap) {
-		pdata->free(dm_timer);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto err_alloc_omap;
 	}
 
 	omap->pdata = pdata;
@@ -339,18 +334,38 @@ put:
 	ret = pwmchip_add(&omap->chip);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to register PWM\n");
-		omap->pdata->free(omap->dm_timer);
-		return ret;
+		goto err_pwmchip_add;
 	}
 
+	of_node_put(timer);
+
 	platform_set_drvdata(pdev, omap);
 
 	return 0;
+
+err_pwmchip_add:
+
+	/*
+	 * *omap is allocated using devm_kzalloc,
+	 * so no free necessary here
+	 */
+err_alloc_omap:
+
+	pdata->free(dm_timer);
+put:
+	of_node_put(timer);
+
+	return ret;
 }
 
 static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
 {
 	struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&omap->chip);
+	if (ret)
+		return ret;
 
 	if (pm_runtime_active(&omap->dm_timer_pdev->dev))
 		omap->pdata->stop(omap->dm_timer);
@@ -359,7 +374,7 @@ static int pwm_omap_dmtimer_remove(struc
 
 	mutex_destroy(&omap->mutex);
 
-	return pwmchip_remove(&omap->chip);
+	return 0;
 }
 
 static const struct of_device_id pwm_omap_dmtimer_of_match[] = {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/pwm/pwm-pca9685.c linux-libre-5.4.22-gnu/drivers/pwm/pwm-pca9685.c
--- linux-libre-5.4.21-gnu/drivers/pwm/pwm-pca9685.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/pwm/pwm-pca9685.c	2020-02-24 02:37:04.000000000 -0500
@@ -159,13 +159,9 @@ static void pca9685_pwm_gpio_set(struct
 static void pca9685_pwm_gpio_free(struct gpio_chip *gpio, unsigned int offset)
 {
 	struct pca9685 *pca = gpiochip_get_data(gpio);
-	struct pwm_device *pwm;
 
 	pca9685_pwm_gpio_set(gpio, offset, 0);
 	pm_runtime_put(pca->chip.dev);
-	mutex_lock(&pca->lock);
-	pwm = &pca->chip.pwms[offset];
-	mutex_unlock(&pca->lock);
 }
 
 static int pca9685_pwm_gpio_get_direction(struct gpio_chip *chip,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/regulator/core.c linux-libre-5.4.22-gnu/drivers/regulator/core.c
--- linux-libre-5.4.21-gnu/drivers/regulator/core.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/regulator/core.c	2020-02-24 02:37:04.000000000 -0500
@@ -3462,6 +3462,7 @@ int regulator_set_voltage_rdev(struct re
 out:
 	return ret;
 }
+EXPORT_SYMBOL_GPL(regulator_set_voltage_rdev);
 
 static int regulator_limit_voltage_step(struct regulator_dev *rdev,
 					int *current_uV, int *min_uV)
@@ -4026,6 +4027,7 @@ int regulator_get_voltage_rdev(struct re
 		return ret;
 	return ret - rdev->constraints->uV_offset;
 }
+EXPORT_SYMBOL_GPL(regulator_get_voltage_rdev);
 
 /**
  * regulator_get_voltage - get regulator output voltage
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/regulator/rk808-regulator.c linux-libre-5.4.22-gnu/drivers/regulator/rk808-regulator.c
--- linux-libre-5.4.21-gnu/drivers/regulator/rk808-regulator.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/regulator/rk808-regulator.c	2020-02-24 02:37:04.000000000 -0500
@@ -1297,7 +1297,7 @@ static int rk808_regulator_dt_parse_pdat
 		}
 
 		if (!pdata->dvs_gpio[i]) {
-			dev_warn(dev, "there is no dvs%d gpio\n", i);
+			dev_info(dev, "there is no dvs%d gpio\n", i);
 			continue;
 		}
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/regulator/vctrl-regulator.c linux-libre-5.4.22-gnu/drivers/regulator/vctrl-regulator.c
--- linux-libre-5.4.21-gnu/drivers/regulator/vctrl-regulator.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/regulator/vctrl-regulator.c	2020-02-24 02:37:04.000000000 -0500
@@ -11,10 +11,13 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/regulator/coupler.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/sort.h>
 
+#include "internal.h"
+
 struct vctrl_voltage_range {
 	int min_uV;
 	int max_uV;
@@ -79,7 +82,7 @@ static int vctrl_calc_output_voltage(str
 static int vctrl_get_voltage(struct regulator_dev *rdev)
 {
 	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
-	int ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
+	int ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev);
 
 	return vctrl_calc_output_voltage(vctrl, ctrl_uV);
 }
@@ -90,16 +93,16 @@ static int vctrl_set_voltage(struct regu
 {
 	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
 	struct regulator *ctrl_reg = vctrl->ctrl_reg;
-	int orig_ctrl_uV = regulator_get_voltage(ctrl_reg);
+	int orig_ctrl_uV = regulator_get_voltage_rdev(ctrl_reg->rdev);
 	int uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV);
 	int ret;
 
 	if (req_min_uV >= uV || !vctrl->ovp_threshold)
 		/* voltage rising or no OVP */
-		return regulator_set_voltage(
-			ctrl_reg,
+		return regulator_set_voltage_rdev(ctrl_reg->rdev,
 			vctrl_calc_ctrl_voltage(vctrl, req_min_uV),
-			vctrl_calc_ctrl_voltage(vctrl, req_max_uV));
+			vctrl_calc_ctrl_voltage(vctrl, req_max_uV),
+			PM_SUSPEND_ON);
 
 	while (uV > req_min_uV) {
 		int max_drop_uV = (uV * vctrl->ovp_threshold) / 100;
@@ -114,9 +117,10 @@ static int vctrl_set_voltage(struct regu
 		next_uV = max_t(int, req_min_uV, uV - max_drop_uV);
 		next_ctrl_uV = vctrl_calc_ctrl_voltage(vctrl, next_uV);
 
-		ret = regulator_set_voltage(ctrl_reg,
+		ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
 					    next_ctrl_uV,
-					    next_ctrl_uV);
+					    next_ctrl_uV,
+					    PM_SUSPEND_ON);
 		if (ret)
 			goto err;
 
@@ -130,7 +134,8 @@ static int vctrl_set_voltage(struct regu
 
 err:
 	/* Try to go back to original voltage */
-	regulator_set_voltage(ctrl_reg, orig_ctrl_uV, orig_ctrl_uV);
+	regulator_set_voltage_rdev(ctrl_reg->rdev, orig_ctrl_uV, orig_ctrl_uV,
+				   PM_SUSPEND_ON);
 
 	return ret;
 }
@@ -155,9 +160,10 @@ static int vctrl_set_voltage_sel(struct
 
 	if (selector >= vctrl->sel || !vctrl->ovp_threshold) {
 		/* voltage rising or no OVP */
-		ret = regulator_set_voltage(ctrl_reg,
+		ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
 					    vctrl->vtable[selector].ctrl,
-					    vctrl->vtable[selector].ctrl);
+					    vctrl->vtable[selector].ctrl,
+					    PM_SUSPEND_ON);
 		if (!ret)
 			vctrl->sel = selector;
 
@@ -173,9 +179,10 @@ static int vctrl_set_voltage_sel(struct
 		else
 			next_sel = vctrl->vtable[vctrl->sel].ovp_min_sel;
 
-		ret = regulator_set_voltage(ctrl_reg,
+		ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
 					    vctrl->vtable[next_sel].ctrl,
-					    vctrl->vtable[next_sel].ctrl);
+					    vctrl->vtable[next_sel].ctrl,
+					    PM_SUSPEND_ON);
 		if (ret) {
 			dev_err(&rdev->dev,
 				"failed to set control voltage to %duV\n",
@@ -195,9 +202,10 @@ static int vctrl_set_voltage_sel(struct
 err:
 	if (vctrl->sel != orig_sel) {
 		/* Try to go back to original voltage */
-		if (!regulator_set_voltage(ctrl_reg,
+		if (!regulator_set_voltage_rdev(ctrl_reg->rdev,
 					   vctrl->vtable[orig_sel].ctrl,
-					   vctrl->vtable[orig_sel].ctrl))
+					   vctrl->vtable[orig_sel].ctrl,
+					   PM_SUSPEND_ON))
 			vctrl->sel = orig_sel;
 		else
 			dev_warn(&rdev->dev,
@@ -482,7 +490,7 @@ static int vctrl_probe(struct platform_d
 		if (ret)
 			return ret;
 
-		ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
+		ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev);
 		if (ctrl_uV < 0) {
 			dev_err(&pdev->dev, "failed to get control voltage\n");
 			return ctrl_uV;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/remoteproc/remoteproc_core.c linux-libre-5.4.22-gnu/drivers/remoteproc/remoteproc_core.c
--- linux-libre-5.4.21-gnu/drivers/remoteproc/remoteproc_core.c	2020-02-19 17:49:23.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/remoteproc/remoteproc_core.c	2020-02-24 06:00:47.000000000 -0500
@@ -2224,7 +2224,7 @@ static int __init remoteproc_init(void)
 
 	return 0;
 }
-module_init(remoteproc_init);
+subsys_initcall(remoteproc_init);
 
 static void __exit remoteproc_exit(void)
 {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/reset/reset-uniphier.c linux-libre-5.4.22-gnu/drivers/reset/reset-uniphier.c
--- linux-libre-5.4.21-gnu/drivers/reset/reset-uniphier.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/reset/reset-uniphier.c	2020-02-24 02:37:04.000000000 -0500
@@ -193,8 +193,8 @@ static const struct uniphier_reset_data
 #define UNIPHIER_PERI_RESET_FI2C(id, ch)		\
 	UNIPHIER_RESETX((id), 0x114, 24 + (ch))
 
-#define UNIPHIER_PERI_RESET_SCSSI(id)			\
-	UNIPHIER_RESETX((id), 0x110, 17)
+#define UNIPHIER_PERI_RESET_SCSSI(id, ch)		\
+	UNIPHIER_RESETX((id), 0x110, 17 + (ch))
 
 #define UNIPHIER_PERI_RESET_MCSSI(id)			\
 	UNIPHIER_RESETX((id), 0x114, 14)
@@ -209,7 +209,7 @@ static const struct uniphier_reset_data
 	UNIPHIER_PERI_RESET_I2C(6, 2),
 	UNIPHIER_PERI_RESET_I2C(7, 3),
 	UNIPHIER_PERI_RESET_I2C(8, 4),
-	UNIPHIER_PERI_RESET_SCSSI(11),
+	UNIPHIER_PERI_RESET_SCSSI(11, 0),
 	UNIPHIER_RESET_END,
 };
 
@@ -225,8 +225,11 @@ static const struct uniphier_reset_data
 	UNIPHIER_PERI_RESET_FI2C(8, 4),
 	UNIPHIER_PERI_RESET_FI2C(9, 5),
 	UNIPHIER_PERI_RESET_FI2C(10, 6),
-	UNIPHIER_PERI_RESET_SCSSI(11),
-	UNIPHIER_PERI_RESET_MCSSI(12),
+	UNIPHIER_PERI_RESET_SCSSI(11, 0),
+	UNIPHIER_PERI_RESET_SCSSI(12, 1),
+	UNIPHIER_PERI_RESET_SCSSI(13, 2),
+	UNIPHIER_PERI_RESET_SCSSI(14, 3),
+	UNIPHIER_PERI_RESET_MCSSI(15),
 	UNIPHIER_RESET_END,
 };
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/rtc/Kconfig linux-libre-5.4.22-gnu/drivers/rtc/Kconfig
--- linux-libre-5.4.21-gnu/drivers/rtc/Kconfig	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/rtc/Kconfig	2020-02-24 02:37:04.000000000 -0500
@@ -240,6 +240,7 @@ config RTC_DRV_AS3722
 
 config RTC_DRV_DS1307
 	tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, ISL12057"
+	select REGMAP_I2C
 	help
 	  If you say yes here you get support for various compatible RTC
 	  chips (often with battery backup) connected with I2C. This driver
@@ -632,6 +633,7 @@ config RTC_DRV_RX8010
 
 config RTC_DRV_RX8581
 	tristate "Epson RX-8571/RX-8581"
+	select REGMAP_I2C
 	help
 	  If you say yes here you will get support for the Epson RX-8571/
 	  RX-8581.
@@ -659,6 +661,7 @@ config RTC_DRV_EM3027
 
 config RTC_DRV_RV3028
 	tristate "Micro Crystal RV3028"
+	select REGMAP_I2C
 	help
 	  If you say yes here you get support for the Micro Crystal
 	  RV3028.
@@ -688,6 +691,7 @@ config RTC_DRV_S5M
 
 config RTC_DRV_SD3078
     tristate "ZXW Shenzhen whwave SD3078"
+    select REGMAP_I2C
     help
       If you say yes here you get support for the ZXW Shenzhen whwave
       SD3078 RTC chips.
@@ -859,14 +863,14 @@ config RTC_I2C_AND_SPI
 	default m if I2C=m
 	default y if I2C=y
 	default y if SPI_MASTER=y
-	select REGMAP_I2C if I2C
-	select REGMAP_SPI if SPI_MASTER
 
 comment "SPI and I2C RTC drivers"
 
 config RTC_DRV_DS3232
 	tristate "Dallas/Maxim DS3232/DS3234"
 	depends on RTC_I2C_AND_SPI
+	select REGMAP_I2C if I2C
+	select REGMAP_SPI if SPI_MASTER
 	help
 	  If you say yes here you get support for Dallas Semiconductor
 	  DS3232 and DS3234 real-time clock chips. If an interrupt is associated
@@ -886,6 +890,8 @@ config RTC_DRV_DS3232_HWMON
 config RTC_DRV_PCF2127
 	tristate "NXP PCF2127"
 	depends on RTC_I2C_AND_SPI
+	select REGMAP_I2C if I2C
+	select REGMAP_SPI if SPI_MASTER
 	select WATCHDOG_CORE if WATCHDOG
 	help
 	  If you say yes here you get support for the NXP PCF2127/29 RTC
@@ -902,6 +908,8 @@ config RTC_DRV_PCF2127
 config RTC_DRV_RV3029C2
 	tristate "Micro Crystal RV3029/3049"
 	depends on RTC_I2C_AND_SPI
+	select REGMAP_I2C if I2C
+	select REGMAP_SPI if SPI_MASTER
 	help
 	  If you say yes here you get support for the Micro Crystal
 	  RV3029 and RV3049 RTC chips.
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/scsi/aic7xxx/aic7xxx_core.c linux-libre-5.4.22-gnu/drivers/scsi/aic7xxx/aic7xxx_core.c
--- linux-libre-5.4.21-gnu/drivers/scsi/aic7xxx/aic7xxx_core.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/scsi/aic7xxx/aic7xxx_core.c	2020-02-24 02:37:04.000000000 -0500
@@ -2314,7 +2314,7 @@ ahc_find_syncrate(struct ahc_softc *ahc,
 			 * At some speeds, we only support
 			 * ST transfers.
 			 */
-		 	if ((syncrate->sxfr_u2 & ST_SXFR) != 0)
+			if ((syncrate->sxfr_u2 & ST_SXFR) != 0)
 				*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
 			break;
 		}
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/scsi/iscsi_tcp.c linux-libre-5.4.22-gnu/drivers/scsi/iscsi_tcp.c
--- linux-libre-5.4.21-gnu/drivers/scsi/iscsi_tcp.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/scsi/iscsi_tcp.c	2020-02-24 02:37:04.000000000 -0500
@@ -887,6 +887,10 @@ free_host:
 static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
 {
 	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+	struct iscsi_session *session = cls_session->dd_data;
+
+	if (WARN_ON_ONCE(session->leadconn))
+		return;
 
 	iscsi_tcp_r2tpool_free(cls_session->dd_data);
 	iscsi_session_teardown(cls_session);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/scsi/lpfc/lpfc_ct.c linux-libre-5.4.22-gnu/drivers/scsi/lpfc/lpfc_ct.c
--- linux-libre-5.4.21-gnu/drivers/scsi/lpfc/lpfc_ct.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/scsi/lpfc/lpfc_ct.c	2020-02-24 02:37:04.000000000 -0500
@@ -1477,33 +1477,35 @@ int
 lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol,
 	size_t size)
 {
-	char fwrev[FW_REV_STR_SIZE];
-	int n;
+	char fwrev[FW_REV_STR_SIZE] = {0};
+	char tmp[MAXHOSTNAMELEN] = {0};
 
-	lpfc_decode_firmware_rev(vport->phba, fwrev, 0);
+	memset(symbol, 0, size);
 
-	n = scnprintf(symbol, size, "Emulex %s", vport->phba->ModelName);
-	if (size < n)
-		return n;
+	scnprintf(tmp, sizeof(tmp), "Emulex %s", vport->phba->ModelName);
+	if (strlcat(symbol, tmp, size) >= size)
+		goto buffer_done;
 
-	n += scnprintf(symbol + n, size - n, " FV%s", fwrev);
-	if (size < n)
-		return n;
+	lpfc_decode_firmware_rev(vport->phba, fwrev, 0);
+	scnprintf(tmp, sizeof(tmp), " FV%s", fwrev);
+	if (strlcat(symbol, tmp, size) >= size)
+		goto buffer_done;
 
-	n += scnprintf(symbol + n, size - n, " DV%s.",
-		      lpfc_release_version);
-	if (size < n)
-		return n;
+	scnprintf(tmp, sizeof(tmp), " DV%s", lpfc_release_version);
+	if (strlcat(symbol, tmp, size) >= size)
+		goto buffer_done;
 
-	n += scnprintf(symbol + n, size - n, " HN:%s.",
-		      init_utsname()->nodename);
-	if (size < n)
-		return n;
+	scnprintf(tmp, sizeof(tmp), " HN:%s", init_utsname()->nodename);
+	if (strlcat(symbol, tmp, size) >= size)
+		goto buffer_done;
 
 	/* Note :- OS name is "Linux" */
-	n += scnprintf(symbol + n, size - n, " OS:%s",
-		      init_utsname()->sysname);
-	return n;
+	scnprintf(tmp, sizeof(tmp), " OS:%s", init_utsname()->sysname);
+	strlcat(symbol, tmp, size);
+
+buffer_done:
+	return strnlen(symbol, size);
+
 }
 
 static uint32_t
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/scsi/scsi_transport_iscsi.c linux-libre-5.4.22-gnu/drivers/scsi/scsi_transport_iscsi.c
--- linux-libre-5.4.21-gnu/drivers/scsi/scsi_transport_iscsi.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/scsi/scsi_transport_iscsi.c	2020-02-24 02:37:04.000000000 -0500
@@ -2947,6 +2947,24 @@ iscsi_set_path(struct iscsi_transport *t
 	return err;
 }
 
+static int iscsi_session_has_conns(int sid)
+{
+	struct iscsi_cls_conn *conn;
+	unsigned long flags;
+	int found = 0;
+
+	spin_lock_irqsave(&connlock, flags);
+	list_for_each_entry(conn, &connlist, conn_list) {
+		if (iscsi_conn_get_sid(conn) == sid) {
+			found = 1;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&connlock, flags);
+
+	return found;
+}
+
 static int
 iscsi_set_iface_params(struct iscsi_transport *transport,
 		       struct iscsi_uevent *ev, uint32_t len)
@@ -3524,10 +3542,12 @@ iscsi_if_recv_msg(struct sk_buff *skb, s
 		break;
 	case ISCSI_UEVENT_DESTROY_SESSION:
 		session = iscsi_session_lookup(ev->u.d_session.sid);
-		if (session)
-			transport->destroy_session(session);
-		else
+		if (!session)
 			err = -EINVAL;
+		else if (iscsi_session_has_conns(ev->u.d_session.sid))
+			err = -EBUSY;
+		else
+			transport->destroy_session(session);
 		break;
 	case ISCSI_UEVENT_UNBIND_SESSION:
 		session = iscsi_session_lookup(ev->u.d_session.sid);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/scsi/ufs/ufshcd.c linux-libre-5.4.22-gnu/drivers/scsi/ufs/ufshcd.c
--- linux-libre-5.4.21-gnu/drivers/scsi/ufs/ufshcd.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/scsi/ufs/ufshcd.c	2020-02-24 02:37:04.000000000 -0500
@@ -4788,7 +4788,7 @@ ufshcd_transfer_rsp_status(struct ufs_hb
 		break;
 	} /* end of switch */
 
-	if (host_byte(result) != DID_OK)
+	if ((host_byte(result) != DID_OK) && !hba->silence_err_logs)
 		ufshcd_print_trs(hba, 1 << lrbp->task_tag, true);
 	return result;
 }
@@ -5321,8 +5321,8 @@ static void ufshcd_err_handler(struct wo
 
 	/*
 	 * if host reset is required then skip clearing the pending
-	 * transfers forcefully because they will automatically get
-	 * cleared after link startup.
+	 * transfers forcefully because they will get cleared during
+	 * host reset and restore
 	 */
 	if (needs_reset)
 		goto skip_pending_xfer_clear;
@@ -6205,9 +6205,15 @@ static int ufshcd_host_reset_and_restore
 	int err;
 	unsigned long flags;
 
-	/* Reset the host controller */
+	/*
+	 * Stop the host controller and complete the requests
+	 * cleared by h/w
+	 */
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	ufshcd_hba_stop(hba, false);
+	hba->silence_err_logs = true;
+	ufshcd_complete_requests(hba);
+	hba->silence_err_logs = false;
 	spin_unlock_irqrestore(hba->host->host_lock, flags);
 
 	/* scale up clocks to max frequency before full reinitialization */
@@ -6241,7 +6247,6 @@ out:
 static int ufshcd_reset_and_restore(struct ufs_hba *hba)
 {
 	int err = 0;
-	unsigned long flags;
 	int retries = MAX_HOST_RESET_RETRIES;
 
 	do {
@@ -6251,15 +6256,6 @@ static int ufshcd_reset_and_restore(stru
 		err = ufshcd_host_reset_and_restore(hba);
 	} while (err && --retries);
 
-	/*
-	 * After reset the door-bell might be cleared, complete
-	 * outstanding requests in s/w here.
-	 */
-	spin_lock_irqsave(hba->host->host_lock, flags);
-	ufshcd_transfer_req_compl(hba);
-	ufshcd_tmc_handler(hba);
-	spin_unlock_irqrestore(hba->host->host_lock, flags);
-
 	return err;
 }
 
@@ -6725,7 +6721,8 @@ out:
 	return ret;
 }
 
-static void ufshcd_tune_unipro_params(struct ufs_hba *hba)
+static void ufshcd_tune_unipro_params(struct ufs_hba *hba,
+				      struct ufs_dev_desc *card)
 {
 	if (ufshcd_is_unipro_pa_params_tuning_req(hba)) {
 		ufshcd_tune_pa_tactivate(hba);
@@ -6739,7 +6736,7 @@ static void ufshcd_tune_unipro_params(st
 	if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE)
 		ufshcd_quirk_tune_host_pa_tactivate(hba);
 
-	ufshcd_vops_apply_dev_quirks(hba);
+	ufshcd_vops_apply_dev_quirks(hba, card);
 }
 
 static void ufshcd_clear_dbg_ufs_stats(struct ufs_hba *hba)
@@ -6902,10 +6899,9 @@ static int ufshcd_probe_hba(struct ufs_h
 	}
 
 	ufs_fixup_device_setup(hba, &card);
+	ufshcd_tune_unipro_params(hba, &card);
 	ufs_put_device_desc(&card);
 
-	ufshcd_tune_unipro_params(hba);
-
 	/* UFS device is also active now */
 	ufshcd_set_ufs_dev_active(hba);
 	ufshcd_force_reset_auto_bkops(hba);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/scsi/ufs/ufshcd.h linux-libre-5.4.22-gnu/drivers/scsi/ufs/ufshcd.h
--- linux-libre-5.4.21-gnu/drivers/scsi/ufs/ufshcd.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/scsi/ufs/ufshcd.h	2020-02-24 02:37:04.000000000 -0500
@@ -322,7 +322,7 @@ struct ufs_hba_variant_ops {
 	void	(*setup_task_mgmt)(struct ufs_hba *, int, u8);
 	void    (*hibern8_notify)(struct ufs_hba *, enum uic_cmd_dme,
 					enum ufs_notify_change_status);
-	int	(*apply_dev_quirks)(struct ufs_hba *);
+	int	(*apply_dev_quirks)(struct ufs_hba *, struct ufs_dev_desc *);
 	int     (*suspend)(struct ufs_hba *, enum ufs_pm_op);
 	int     (*resume)(struct ufs_hba *, enum ufs_pm_op);
 	void	(*dbg_register_dump)(struct ufs_hba *hba);
@@ -513,6 +513,7 @@ struct ufs_stats {
  * @uic_error: UFS interconnect layer error status
  * @saved_err: sticky error mask
  * @saved_uic_err: sticky UIC error mask
+ * @silence_err_logs: flag to silence error logs
  * @dev_cmd: ufs device management command information
  * @last_dme_cmd_tstamp: time stamp of the last completed DME command
  * @auto_bkops_enabled: to track whether bkops is enabled in device
@@ -670,6 +671,7 @@ struct ufs_hba {
 	u32 saved_err;
 	u32 saved_uic_err;
 	struct ufs_stats ufs_stats;
+	bool silence_err_logs;
 
 	/* Device management request data */
 	struct ufs_dev_cmd dev_cmd;
@@ -1045,10 +1047,11 @@ static inline void ufshcd_vops_hibern8_n
 		return hba->vops->hibern8_notify(hba, cmd, status);
 }
 
-static inline int ufshcd_vops_apply_dev_quirks(struct ufs_hba *hba)
+static inline int ufshcd_vops_apply_dev_quirks(struct ufs_hba *hba,
+					       struct ufs_dev_desc *card)
 {
 	if (hba->vops && hba->vops->apply_dev_quirks)
-		return hba->vops->apply_dev_quirks(hba);
+		return hba->vops->apply_dev_quirks(hba, card);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/scsi/ufs/ufs-mediatek.c linux-libre-5.4.22-gnu/drivers/scsi/ufs/ufs-mediatek.c
--- linux-libre-5.4.21-gnu/drivers/scsi/ufs/ufs-mediatek.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/scsi/ufs/ufs-mediatek.c	2020-02-24 02:37:04.000000000 -0500
@@ -13,6 +13,7 @@
 
 #include "ufshcd.h"
 #include "ufshcd-pltfrm.h"
+#include "ufs_quirks.h"
 #include "unipro.h"
 #include "ufs-mediatek.h"
 
@@ -286,6 +287,15 @@ static int ufs_mtk_resume(struct ufs_hba
 	return 0;
 }
 
+static int ufs_mtk_apply_dev_quirks(struct ufs_hba *hba,
+				    struct ufs_dev_desc *card)
+{
+	if (card->wmanufacturerid == UFS_VENDOR_SAMSUNG)
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TACTIVATE), 6);
+
+	return 0;
+}
+
 /**
  * struct ufs_hba_mtk_vops - UFS MTK specific variant operations
  *
@@ -298,6 +308,7 @@ static struct ufs_hba_variant_ops ufs_hb
 	.setup_clocks        = ufs_mtk_setup_clocks,
 	.link_startup_notify = ufs_mtk_link_startup_notify,
 	.pwr_change_notify   = ufs_mtk_pwr_change_notify,
+	.apply_dev_quirks    = ufs_mtk_apply_dev_quirks,
 	.suspend             = ufs_mtk_suspend,
 	.resume              = ufs_mtk_resume,
 };
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/scsi/ufs/ufs-qcom.c linux-libre-5.4.22-gnu/drivers/scsi/ufs/ufs-qcom.c
--- linux-libre-5.4.21-gnu/drivers/scsi/ufs/ufs-qcom.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/scsi/ufs/ufs-qcom.c	2020-02-24 02:37:04.000000000 -0500
@@ -905,7 +905,8 @@ out:
 	return err;
 }
 
-static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba)
+static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba,
+				     struct ufs_dev_desc *card)
 {
 	int err = 0;
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/soc/tegra/fuse/tegra-apbmisc.c linux-libre-5.4.22-gnu/drivers/soc/tegra/fuse/tegra-apbmisc.c
--- linux-libre-5.4.21-gnu/drivers/soc/tegra/fuse/tegra-apbmisc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/soc/tegra/fuse/tegra-apbmisc.c	2020-02-24 02:37:04.000000000 -0500
@@ -123,7 +123,7 @@ void __init tegra_init_apbmisc(void)
 			apbmisc.flags = IORESOURCE_MEM;
 
 			/* strapping options */
-			if (tegra_get_chip_id() == TEGRA124) {
+			if (of_machine_is_compatible("nvidia,tegra124")) {
 				straps.start = 0x7000e864;
 				straps.end = 0x7000e867;
 			} else {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/spi/spi-fsl-lpspi.c linux-libre-5.4.22-gnu/drivers/spi/spi-fsl-lpspi.c
--- linux-libre-5.4.21-gnu/drivers/spi/spi-fsl-lpspi.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/spi/spi-fsl-lpspi.c	2020-02-24 02:37:04.000000000 -0500
@@ -862,6 +862,22 @@ static int fsl_lpspi_probe(struct platfo
 	fsl_lpspi->dev = &pdev->dev;
 	fsl_lpspi->is_slave = is_slave;
 
+	controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32);
+	controller->transfer_one = fsl_lpspi_transfer_one;
+	controller->prepare_transfer_hardware = lpspi_prepare_xfer_hardware;
+	controller->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware;
+	controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
+	controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
+	controller->dev.of_node = pdev->dev.of_node;
+	controller->bus_num = pdev->id;
+	controller->slave_abort = fsl_lpspi_slave_abort;
+
+	ret = devm_spi_register_controller(&pdev->dev, controller);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "spi_register_controller error.\n");
+		goto out_controller_put;
+	}
+
 	if (!fsl_lpspi->is_slave) {
 		for (i = 0; i < controller->num_chipselect; i++) {
 			int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
@@ -885,16 +901,6 @@ static int fsl_lpspi_probe(struct platfo
 		controller->prepare_message = fsl_lpspi_prepare_message;
 	}
 
-	controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32);
-	controller->transfer_one = fsl_lpspi_transfer_one;
-	controller->prepare_transfer_hardware = lpspi_prepare_xfer_hardware;
-	controller->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware;
-	controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
-	controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
-	controller->dev.of_node = pdev->dev.of_node;
-	controller->bus_num = pdev->id;
-	controller->slave_abort = fsl_lpspi_slave_abort;
-
 	init_completion(&fsl_lpspi->xfer_done);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -952,12 +958,6 @@ static int fsl_lpspi_probe(struct platfo
 	if (ret < 0)
 		dev_err(&pdev->dev, "dma setup error %d, use pio\n", ret);
 
-	ret = devm_spi_register_controller(&pdev->dev, controller);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "spi_register_controller error.\n");
-		goto out_controller_put;
-	}
-
 	return 0;
 
 out_controller_put:
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/spi/spi-fsl-qspi.c linux-libre-5.4.22-gnu/drivers/spi/spi-fsl-qspi.c
--- linux-libre-5.4.21-gnu/drivers/spi/spi-fsl-qspi.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/spi/spi-fsl-qspi.c	2020-02-24 02:37:04.000000000 -0500
@@ -398,7 +398,7 @@ static bool fsl_qspi_supports_op(struct
 	    op->data.nbytes > q->devtype_data->txfifo)
 		return false;
 
-	return true;
+	return spi_mem_default_supports_op(mem, op);
 }
 
 static void fsl_qspi_prepare_lut(struct fsl_qspi *q,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/staging/media/meson/vdec/vdec.c linux-libre-5.4.22-gnu/drivers/staging/media/meson/vdec/vdec.c
--- linux-libre-5.4.21-gnu/drivers/staging/media/meson/vdec/vdec.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/staging/media/meson/vdec/vdec.c	2020-02-24 02:37:04.000000000 -0500
@@ -133,6 +133,8 @@ vdec_queue_recycle(struct amvdec_session
 	struct amvdec_buffer *new_buf;
 
 	new_buf = kmalloc(sizeof(*new_buf), GFP_KERNEL);
+	if (!new_buf)
+		return;
 	new_buf->vb = vb;
 
 	mutex_lock(&sess->bufs_recycle_lock);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c linux-libre-5.4.22-gnu/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
--- linux-libre-5.4.21-gnu/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c	2020-02-24 02:37:04.000000000 -0500
@@ -229,18 +229,21 @@ static char *translate_scan(struct adapt
 
 	/* parsing WPA/WPA2 IE */
 	{
-		u8 buf[MAX_WPA_IE_LEN];
+		u8 *buf;
 		u8 wpa_ie[255], rsn_ie[255];
 		u16 wpa_len = 0, rsn_len = 0;
 		u8 *p;
 
+		buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC);
+		if (!buf)
+			return start;
+
 		rtw_get_sec_ie(pnetwork->network.ies, pnetwork->network.ie_length, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid =%s\n", pnetwork->network.ssid.ssid));
 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wpa_len =%d rsn_len =%d\n", wpa_len, rsn_len));
 
 		if (wpa_len > 0) {
 			p = buf;
-			memset(buf, 0, MAX_WPA_IE_LEN);
 			p += sprintf(p, "wpa_ie=");
 			for (i = 0; i < wpa_len; i++)
 				p += sprintf(p, "%02x", wpa_ie[i]);
@@ -257,7 +260,6 @@ static char *translate_scan(struct adapt
 		}
 		if (rsn_len > 0) {
 			p = buf;
-			memset(buf, 0, MAX_WPA_IE_LEN);
 			p += sprintf(p, "rsn_ie=");
 			for (i = 0; i < rsn_len; i++)
 				p += sprintf(p, "%02x", rsn_ie[i]);
@@ -271,6 +273,7 @@ static char *translate_scan(struct adapt
 			iwe.u.data.length = rsn_len;
 			start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
 		}
+		kfree(buf);
 	}
 
 	{/* parsing WPS IE */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/tty/synclink_gt.c linux-libre-5.4.22-gnu/drivers/tty/synclink_gt.c
--- linux-libre-5.4.21-gnu/drivers/tty/synclink_gt.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/tty/synclink_gt.c	2020-02-24 02:37:04.000000000 -0500
@@ -1334,10 +1334,10 @@ static void throttle(struct tty_struct *
 	DBGINFO(("%s throttle\n", info->device_name));
 	if (I_IXOFF(tty))
 		send_xchar(tty, STOP_CHAR(tty));
- 	if (C_CRTSCTS(tty)) {
+	if (C_CRTSCTS(tty)) {
 		spin_lock_irqsave(&info->lock,flags);
 		info->signals &= ~SerialSignal_RTS;
-	 	set_signals(info);
+		set_signals(info);
 		spin_unlock_irqrestore(&info->lock,flags);
 	}
 }
@@ -1359,10 +1359,10 @@ static void unthrottle(struct tty_struct
 		else
 			send_xchar(tty, START_CHAR(tty));
 	}
- 	if (C_CRTSCTS(tty)) {
+	if (C_CRTSCTS(tty)) {
 		spin_lock_irqsave(&info->lock,flags);
 		info->signals |= SerialSignal_RTS;
-	 	set_signals(info);
+		set_signals(info);
 		spin_unlock_irqrestore(&info->lock,flags);
 	}
 }
@@ -2560,8 +2560,8 @@ static void change_params(struct slgt_in
 	info->read_status_mask = IRQ_RXOVER;
 	if (I_INPCK(info->port.tty))
 		info->read_status_mask |= MASK_PARITY | MASK_FRAMING;
- 	if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
- 		info->read_status_mask |= MASK_BREAK;
+	if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
+		info->read_status_mask |= MASK_BREAK;
 	if (I_IGNPAR(info->port.tty))
 		info->ignore_status_mask |= MASK_PARITY | MASK_FRAMING;
 	if (I_IGNBRK(info->port.tty)) {
@@ -3192,7 +3192,7 @@ static int tiocmset(struct tty_struct *t
 		info->signals &= ~SerialSignal_DTR;
 
 	spin_lock_irqsave(&info->lock,flags);
- 	set_signals(info);
+	set_signals(info);
 	spin_unlock_irqrestore(&info->lock,flags);
 	return 0;
 }
@@ -3203,7 +3203,7 @@ static int carrier_raised(struct tty_por
 	struct slgt_info *info = container_of(port, struct slgt_info, port);
 
 	spin_lock_irqsave(&info->lock,flags);
- 	get_signals(info);
+	get_signals(info);
 	spin_unlock_irqrestore(&info->lock,flags);
 	return (info->signals & SerialSignal_DCD) ? 1 : 0;
 }
@@ -3218,7 +3218,7 @@ static void dtr_rts(struct tty_port *por
 		info->signals |= SerialSignal_RTS | SerialSignal_DTR;
 	else
 		info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
- 	set_signals(info);
+	set_signals(info);
 	spin_unlock_irqrestore(&info->lock,flags);
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/tty/synclinkmp.c linux-libre-5.4.22-gnu/drivers/tty/synclinkmp.c
--- linux-libre-5.4.21-gnu/drivers/tty/synclinkmp.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/tty/synclinkmp.c	2020-02-24 02:37:04.000000000 -0500
@@ -1453,10 +1453,10 @@ static void throttle(struct tty_struct *
 	if (I_IXOFF(tty))
 		send_xchar(tty, STOP_CHAR(tty));
 
- 	if (C_CRTSCTS(tty)) {
+	if (C_CRTSCTS(tty)) {
 		spin_lock_irqsave(&info->lock,flags);
 		info->serial_signals &= ~SerialSignal_RTS;
-	 	set_signals(info);
+		set_signals(info);
 		spin_unlock_irqrestore(&info->lock,flags);
 	}
 }
@@ -1482,10 +1482,10 @@ static void unthrottle(struct tty_struct
 			send_xchar(tty, START_CHAR(tty));
 	}
 
- 	if (C_CRTSCTS(tty)) {
+	if (C_CRTSCTS(tty)) {
 		spin_lock_irqsave(&info->lock,flags);
 		info->serial_signals |= SerialSignal_RTS;
-	 	set_signals(info);
+		set_signals(info);
 		spin_unlock_irqrestore(&info->lock,flags);
 	}
 }
@@ -2470,7 +2470,7 @@ static void isr_io_pin( SLMP_INFO *info,
 					if (status & SerialSignal_CTS) {
 						if ( debug_level >= DEBUG_LEVEL_ISR )
 							printk("CTS tx start...");
-			 			info->port.tty->hw_stopped = 0;
+						info->port.tty->hw_stopped = 0;
 						tx_start(info);
 						info->pending_bh |= BH_TRANSMIT;
 						return;
@@ -2479,7 +2479,7 @@ static void isr_io_pin( SLMP_INFO *info,
 					if (!(status & SerialSignal_CTS)) {
 						if ( debug_level >= DEBUG_LEVEL_ISR )
 							printk("CTS tx stop...");
-			 			info->port.tty->hw_stopped = 1;
+						info->port.tty->hw_stopped = 1;
 						tx_stop(info);
 					}
 				}
@@ -2806,8 +2806,8 @@ static void change_params(SLMP_INFO *inf
 	info->read_status_mask2 = OVRN;
 	if (I_INPCK(info->port.tty))
 		info->read_status_mask2 |= PE | FRME;
- 	if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
- 		info->read_status_mask1 |= BRKD;
+	if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
+		info->read_status_mask1 |= BRKD;
 	if (I_IGNPAR(info->port.tty))
 		info->ignore_status_mask2 |= PE | FRME;
 	if (I_IGNBRK(info->port.tty)) {
@@ -3177,7 +3177,7 @@ static int tiocmget(struct tty_struct *t
  	unsigned long flags;
 
 	spin_lock_irqsave(&info->lock,flags);
- 	get_signals(info);
+	get_signals(info);
 	spin_unlock_irqrestore(&info->lock,flags);
 
 	result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS : 0) |
@@ -3215,7 +3215,7 @@ static int tiocmset(struct tty_struct *t
 		info->serial_signals &= ~SerialSignal_DTR;
 
 	spin_lock_irqsave(&info->lock,flags);
- 	set_signals(info);
+	set_signals(info);
 	spin_unlock_irqrestore(&info->lock,flags);
 
 	return 0;
@@ -3227,7 +3227,7 @@ static int carrier_raised(struct tty_por
 	unsigned long flags;
 
 	spin_lock_irqsave(&info->lock,flags);
- 	get_signals(info);
+	get_signals(info);
 	spin_unlock_irqrestore(&info->lock,flags);
 
 	return (info->serial_signals & SerialSignal_DCD) ? 1 : 0;
@@ -3243,7 +3243,7 @@ static void dtr_rts(struct tty_port *por
 		info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR;
 	else
 		info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
- 	set_signals(info);
+	set_signals(info);
 	spin_unlock_irqrestore(&info->lock,flags);
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/uio/uio_dmem_genirq.c linux-libre-5.4.22-gnu/drivers/uio/uio_dmem_genirq.c
--- linux-libre-5.4.21-gnu/drivers/uio/uio_dmem_genirq.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/uio/uio_dmem_genirq.c	2020-02-24 02:37:04.000000000 -0500
@@ -132,11 +132,13 @@ static int uio_dmem_genirq_irqcontrol(st
 	if (irq_on) {
 		if (test_and_clear_bit(0, &priv->flags))
 			enable_irq(dev_info->irq);
+		spin_unlock_irqrestore(&priv->lock, flags);
 	} else {
-		if (!test_and_set_bit(0, &priv->flags))
+		if (!test_and_set_bit(0, &priv->flags)) {
+			spin_unlock_irqrestore(&priv->lock, flags);
 			disable_irq(dev_info->irq);
+		}
 	}
-	spin_unlock_irqrestore(&priv->lock, flags);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/usb/dwc2/gadget.c linux-libre-5.4.22-gnu/drivers/usb/dwc2/gadget.c
--- linux-libre-5.4.21-gnu/drivers/usb/dwc2/gadget.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/usb/dwc2/gadget.c	2020-02-24 02:37:04.000000000 -0500
@@ -4056,11 +4056,12 @@ static int dwc2_hsotg_ep_enable(struct u
 	 * a unique tx-fifo even if it is non-periodic.
 	 */
 	if (dir_in && hsotg->dedicated_fifos) {
+		unsigned fifo_count = dwc2_hsotg_tx_fifo_count(hsotg);
 		u32 fifo_index = 0;
 		u32 fifo_size = UINT_MAX;
 
 		size = hs_ep->ep.maxpacket * hs_ep->mc;
-		for (i = 1; i < hsotg->num_of_eps; ++i) {
+		for (i = 1; i <= fifo_count; ++i) {
 			if (hsotg->fifo_map & (1 << i))
 				continue;
 			val = dwc2_readl(hsotg, DPTXFSIZN(i));
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/usb/dwc3/host.c linux-libre-5.4.22-gnu/drivers/usb/dwc3/host.c
--- linux-libre-5.4.21-gnu/drivers/usb/dwc3/host.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/usb/dwc3/host.c	2020-02-24 02:37:04.000000000 -0500
@@ -88,10 +88,10 @@ int dwc3_host_init(struct dwc3 *dwc)
 	memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props));
 
 	if (dwc->usb3_lpm_capable)
-		props[prop_idx++].name = "usb3-lpm-capable";
+		props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb3-lpm-capable");
 
 	if (dwc->usb2_lpm_disable)
-		props[prop_idx++].name = "usb2-lpm-disable";
+		props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb2-lpm-disable");
 
 	/**
 	 * WORKAROUND: dwc3 revisions <=3.00a have a limitation
@@ -103,7 +103,7 @@ int dwc3_host_init(struct dwc3 *dwc)
 	 * This following flag tells XHCI to do just that.
 	 */
 	if (dwc->revision <= DWC3_REVISION_300A)
-		props[prop_idx++].name = "quirk-broken-port-ped";
+		props[prop_idx++] = PROPERTY_ENTRY_BOOL("quirk-broken-port-ped");
 
 	if (prop_idx) {
 		ret = platform_device_add_properties(xhci, props);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/usb/gadget/udc/gr_udc.c linux-libre-5.4.22-gnu/drivers/usb/gadget/udc/gr_udc.c
--- linux-libre-5.4.21-gnu/drivers/usb/gadget/udc/gr_udc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/usb/gadget/udc/gr_udc.c	2020-02-24 02:37:04.000000000 -0500
@@ -2176,8 +2176,6 @@ static int gr_probe(struct platform_devi
 		return -ENOMEM;
 	}
 
-	spin_lock(&dev->lock);
-
 	/* Inside lock so that no gadget can use this udc until probe is done */
 	retval = usb_add_gadget_udc(dev->dev, &dev->gadget);
 	if (retval) {
@@ -2186,15 +2184,21 @@ static int gr_probe(struct platform_devi
 	}
 	dev->added = 1;
 
+	spin_lock(&dev->lock);
+
 	retval = gr_udc_init(dev);
-	if (retval)
+	if (retval) {
+		spin_unlock(&dev->lock);
 		goto out;
-
-	gr_dfs_create(dev);
+	}
 
 	/* Clear all interrupt enables that might be left on since last boot */
 	gr_disable_interrupts_and_pullup(dev);
 
+	spin_unlock(&dev->lock);
+
+	gr_dfs_create(dev);
+
 	retval = gr_request_irq(dev, dev->irq);
 	if (retval) {
 		dev_err(dev->dev, "Failed to request irq %d\n", dev->irq);
@@ -2223,8 +2227,6 @@ static int gr_probe(struct platform_devi
 		dev_info(dev->dev, "regs: %p, irq %d\n", dev->regs, dev->irq);
 
 out:
-	spin_unlock(&dev->lock);
-
 	if (retval)
 		gr_remove(pdev);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/usb/musb/omap2430.c linux-libre-5.4.22-gnu/drivers/usb/musb/omap2430.c
--- linux-libre-5.4.21-gnu/drivers/usb/musb/omap2430.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/usb/musb/omap2430.c	2020-02-24 02:37:04.000000000 -0500
@@ -361,8 +361,6 @@ static const struct musb_platform_ops om
 	.init		= omap2430_musb_init,
 	.exit		= omap2430_musb_exit,
 
-	.set_vbus	= omap2430_musb_set_vbus,
-
 	.enable		= omap2430_musb_enable,
 	.disable	= omap2430_musb_disable,
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/vfio/pci/vfio_pci_nvlink2.c linux-libre-5.4.22-gnu/drivers/vfio/pci/vfio_pci_nvlink2.c
--- linux-libre-5.4.21-gnu/drivers/vfio/pci/vfio_pci_nvlink2.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/vfio/pci/vfio_pci_nvlink2.c	2020-02-24 02:37:04.000000000 -0500
@@ -97,8 +97,10 @@ static void vfio_pci_nvgpu_release(struc
 
 	/* If there were any mappings at all... */
 	if (data->mm) {
-		ret = mm_iommu_put(data->mm, data->mem);
-		WARN_ON(ret);
+		if (data->mem) {
+			ret = mm_iommu_put(data->mm, data->mem);
+			WARN_ON(ret);
+		}
 
 		mmdrop(data->mm);
 	}
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/video/fbdev/pxa168fb.c linux-libre-5.4.22-gnu/drivers/video/fbdev/pxa168fb.c
--- linux-libre-5.4.21-gnu/drivers/video/fbdev/pxa168fb.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/video/fbdev/pxa168fb.c	2020-02-24 02:37:04.000000000 -0500
@@ -766,8 +766,8 @@ failed_free_cmap:
 failed_free_clk:
 	clk_disable_unprepare(fbi->clk);
 failed_free_fbmem:
-	dma_free_coherent(fbi->dev, info->fix.smem_len,
-			info->screen_base, fbi->fb_start_dma);
+	dma_free_wc(fbi->dev, info->fix.smem_len,
+		    info->screen_base, fbi->fb_start_dma);
 failed_free_info:
 	kfree(info);
 
@@ -801,7 +801,7 @@ static int pxa168fb_remove(struct platfo
 
 	irq = platform_get_irq(pdev, 0);
 
-	dma_free_wc(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
+	dma_free_wc(fbi->dev, info->fix.smem_len,
 		    info->screen_base, info->fix.smem_start);
 
 	clk_disable_unprepare(fbi->clk);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/virtio/virtio_balloon.c linux-libre-5.4.22-gnu/drivers/virtio/virtio_balloon.c
--- linux-libre-5.4.21-gnu/drivers/virtio/virtio_balloon.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/virtio/virtio_balloon.c	2020-02-24 02:37:04.000000000 -0500
@@ -157,6 +157,8 @@ static void set_page_pfns(struct virtio_
 {
 	unsigned int i;
 
+	BUILD_BUG_ON(VIRTIO_BALLOON_PAGES_PER_PAGE > VIRTIO_BALLOON_ARRAY_PFNS_MAX);
+
 	/*
 	 * Set balloon pfns pointing at this page.
 	 * Note that the first pfn points at start of the page.
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/visorbus/visorchipset.c linux-libre-5.4.22-gnu/drivers/visorbus/visorchipset.c
--- linux-libre-5.4.21-gnu/drivers/visorbus/visorchipset.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/visorbus/visorchipset.c	2020-02-24 02:37:04.000000000 -0500
@@ -1210,14 +1210,17 @@ static void setup_crash_devices_work_que
 {
 	struct controlvm_message local_crash_bus_msg;
 	struct controlvm_message local_crash_dev_msg;
-	struct controlvm_message msg;
+	struct controlvm_message msg = {
+		.hdr.id = CONTROLVM_CHIPSET_INIT,
+		.cmd.init_chipset = {
+			.bus_count = 23,
+			.switch_count = 0,
+		},
+	};
 	u32 local_crash_msg_offset;
 	u16 local_crash_msg_count;
 
 	/* send init chipset msg */
-	msg.hdr.id = CONTROLVM_CHIPSET_INIT;
-	msg.cmd.init_chipset.bus_count = 23;
-	msg.cmd.init_chipset.switch_count = 0;
 	chipset_init(&msg);
 	/* get saved message count */
 	if (visorchannel_read(chipset_dev->controlvm_channel,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/drivers/vme/bridges/vme_fake.c linux-libre-5.4.22-gnu/drivers/vme/bridges/vme_fake.c
--- linux-libre-5.4.21-gnu/drivers/vme/bridges/vme_fake.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/drivers/vme/bridges/vme_fake.c	2020-02-24 02:37:04.000000000 -0500
@@ -414,8 +414,9 @@ static void fake_lm_check(struct fake_dr
 	}
 }
 
-static u8 fake_vmeread8(struct fake_driver *bridge, unsigned long long addr,
-		u32 aspace, u32 cycle)
+static noinline_for_stack u8 fake_vmeread8(struct fake_driver *bridge,
+					   unsigned long long addr,
+					   u32 aspace, u32 cycle)
 {
 	u8 retval = 0xff;
 	int i;
@@ -446,8 +447,9 @@ static u8 fake_vmeread8(struct fake_driv
 	return retval;
 }
 
-static u16 fake_vmeread16(struct fake_driver *bridge, unsigned long long addr,
-		u32 aspace, u32 cycle)
+static noinline_for_stack u16 fake_vmeread16(struct fake_driver *bridge,
+					     unsigned long long addr,
+					     u32 aspace, u32 cycle)
 {
 	u16 retval = 0xffff;
 	int i;
@@ -478,8 +480,9 @@ static u16 fake_vmeread16(struct fake_dr
 	return retval;
 }
 
-static u32 fake_vmeread32(struct fake_driver *bridge, unsigned long long addr,
-		u32 aspace, u32 cycle)
+static noinline_for_stack u32 fake_vmeread32(struct fake_driver *bridge,
+					     unsigned long long addr,
+					     u32 aspace, u32 cycle)
 {
 	u32 retval = 0xffffffff;
 	int i;
@@ -609,8 +612,9 @@ out:
 	return retval;
 }
 
-static void fake_vmewrite8(struct fake_driver *bridge, u8 *buf,
-			   unsigned long long addr, u32 aspace, u32 cycle)
+static noinline_for_stack void fake_vmewrite8(struct fake_driver *bridge,
+					      u8 *buf, unsigned long long addr,
+					      u32 aspace, u32 cycle)
 {
 	int i;
 	unsigned long long start, end, offset;
@@ -639,8 +643,9 @@ static void fake_vmewrite8(struct fake_d
 
 }
 
-static void fake_vmewrite16(struct fake_driver *bridge, u16 *buf,
-			    unsigned long long addr, u32 aspace, u32 cycle)
+static noinline_for_stack void fake_vmewrite16(struct fake_driver *bridge,
+					       u16 *buf, unsigned long long addr,
+					       u32 aspace, u32 cycle)
 {
 	int i;
 	unsigned long long start, end, offset;
@@ -669,8 +674,9 @@ static void fake_vmewrite16(struct fake_
 
 }
 
-static void fake_vmewrite32(struct fake_driver *bridge, u32 *buf,
-			    unsigned long long addr, u32 aspace, u32 cycle)
+static noinline_for_stack void fake_vmewrite32(struct fake_driver *bridge,
+					       u32 *buf, unsigned long long addr,
+					       u32 aspace, u32 cycle)
 {
 	int i;
 	unsigned long long start, end, offset;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/btrfs/check-integrity.c linux-libre-5.4.22-gnu/fs/btrfs/check-integrity.c
--- linux-libre-5.4.21-gnu/fs/btrfs/check-integrity.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/btrfs/check-integrity.c	2020-02-24 02:37:04.000000000 -0500
@@ -629,7 +629,6 @@ static struct btrfsic_dev_state *btrfsic
 static int btrfsic_process_superblock(struct btrfsic_state *state,
 				      struct btrfs_fs_devices *fs_devices)
 {
-	struct btrfs_fs_info *fs_info = state->fs_info;
 	struct btrfs_super_block *selected_super;
 	struct list_head *dev_head = &fs_devices->devices;
 	struct btrfs_device *device;
@@ -700,7 +699,7 @@ static int btrfsic_process_superblock(st
 			break;
 		}
 
-		num_copies = btrfs_num_copies(fs_info, next_bytenr,
+		num_copies = btrfs_num_copies(state->fs_info, next_bytenr,
 					      state->metablock_size);
 		if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES)
 			pr_info("num_copies(log_bytenr=%llu) = %d\n",
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/btrfs/ctree.h linux-libre-5.4.22-gnu/fs/btrfs/ctree.h
--- linux-libre-5.4.21-gnu/fs/btrfs/ctree.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/btrfs/ctree.h	2020-02-24 02:37:04.000000000 -0500
@@ -3107,17 +3107,21 @@ do {								\
 	rcu_read_unlock();					\
 } while (0)
 
-__cold
-static inline void assfail(const char *expr, const char *file, int line)
+#ifdef CONFIG_BTRFS_ASSERT
+__cold __noreturn
+static inline void assertfail(const char *expr, const char *file, int line)
 {
-	if (IS_ENABLED(CONFIG_BTRFS_ASSERT)) {
-		pr_err("assertion failed: %s, in %s:%d\n", expr, file, line);
-		BUG();
-	}
+	pr_err("assertion failed: %s, in %s:%d\n", expr, file, line);
+	BUG();
 }
 
-#define ASSERT(expr)	\
-	(likely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
+#define ASSERT(expr)						\
+	(likely(expr) ? (void)0 : assertfail(#expr, __FILE__, __LINE__))
+
+#else
+static inline void assertfail(const char *expr, const char* file, int line) { }
+#define ASSERT(expr)	(void)(expr)
+#endif
 
 /*
  * Use that for functions that are conditionally exported for sanity tests but
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/btrfs/file-item.c linux-libre-5.4.22-gnu/fs/btrfs/file-item.c
--- linux-libre-5.4.21-gnu/fs/btrfs/file-item.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/btrfs/file-item.c	2020-02-24 02:37:04.000000000 -0500
@@ -274,7 +274,8 @@ found:
 		csum += count * csum_size;
 		nblocks -= count;
 next:
-		while (count--) {
+		while (count > 0) {
+			count--;
 			disk_bytenr += fs_info->sectorsize;
 			offset += fs_info->sectorsize;
 			page_bytes_left -= fs_info->sectorsize;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/btrfs/inode.c linux-libre-5.4.22-gnu/fs/btrfs/inode.c
--- linux-libre-5.4.21-gnu/fs/btrfs/inode.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/btrfs/inode.c	2020-02-24 02:37:04.000000000 -0500
@@ -2168,6 +2168,7 @@ int btrfs_set_extent_delalloc(struct ino
 /* see btrfs_writepage_start_hook for details on why this is required */
 struct btrfs_writepage_fixup {
 	struct page *page;
+	struct inode *inode;
 	struct btrfs_work work;
 };
 
@@ -2181,27 +2182,71 @@ static void btrfs_writepage_fixup_worker
 	struct inode *inode;
 	u64 page_start;
 	u64 page_end;
-	int ret;
+	int ret = 0;
+	bool free_delalloc_space = true;
 
 	fixup = container_of(work, struct btrfs_writepage_fixup, work);
 	page = fixup->page;
+	inode = fixup->inode;
+	page_start = page_offset(page);
+	page_end = page_offset(page) + PAGE_SIZE - 1;
+
+	/*
+	 * This is similar to page_mkwrite, we need to reserve the space before
+	 * we take the page lock.
+	 */
+	ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start,
+					   PAGE_SIZE);
 again:
 	lock_page(page);
+
+	/*
+	 * Before we queued this fixup, we took a reference on the page.
+	 * page->mapping may go NULL, but it shouldn't be moved to a different
+	 * address space.
+	 */
 	if (!page->mapping || !PageDirty(page) || !PageChecked(page)) {
-		ClearPageChecked(page);
+		/*
+		 * Unfortunately this is a little tricky, either
+		 *
+		 * 1) We got here and our page had already been dealt with and
+		 *    we reserved our space, thus ret == 0, so we need to just
+		 *    drop our space reservation and bail.  This can happen the
+		 *    first time we come into the fixup worker, or could happen
+		 *    while waiting for the ordered extent.
+		 * 2) Our page was already dealt with, but we happened to get an
+		 *    ENOSPC above from the btrfs_delalloc_reserve_space.  In
+		 *    this case we obviously don't have anything to release, but
+		 *    because the page was already dealt with we don't want to
+		 *    mark the page with an error, so make sure we're resetting
+		 *    ret to 0.  This is why we have this check _before_ the ret
+		 *    check, because we do not want to have a surprise ENOSPC
+		 *    when the page was already properly dealt with.
+		 */
+		if (!ret) {
+			btrfs_delalloc_release_extents(BTRFS_I(inode),
+						       PAGE_SIZE);
+			btrfs_delalloc_release_space(inode, data_reserved,
+						     page_start, PAGE_SIZE,
+						     true);
+		}
+		ret = 0;
 		goto out_page;
 	}
 
-	inode = page->mapping->host;
-	page_start = page_offset(page);
-	page_end = page_offset(page) + PAGE_SIZE - 1;
+	/*
+	 * We can't mess with the page state unless it is locked, so now that
+	 * it is locked bail if we failed to make our space reservation.
+	 */
+	if (ret)
+		goto out_page;
 
 	lock_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
 			 &cached_state);
 
 	/* already ordered? We're done */
 	if (PagePrivate2(page))
-		goto out;
+		goto out_reserved;
 
 	ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), page_start,
 					PAGE_SIZE);
@@ -2214,39 +2259,49 @@ again:
 		goto again;
 	}
 
-	ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start,
-					   PAGE_SIZE);
-	if (ret) {
-		mapping_set_error(page->mapping, ret);
-		end_extent_writepage(page, ret, page_start, page_end);
-		ClearPageChecked(page);
-		goto out;
-	 }
-
 	ret = btrfs_set_extent_delalloc(inode, page_start, page_end, 0,
 					&cached_state);
-	if (ret) {
-		mapping_set_error(page->mapping, ret);
-		end_extent_writepage(page, ret, page_start, page_end);
-		ClearPageChecked(page);
+	if (ret)
 		goto out_reserved;
-	}
 
-	ClearPageChecked(page);
-	set_page_dirty(page);
+	/*
+	 * Everything went as planned, we're now the owner of a dirty page with
+	 * delayed allocation bits set and space reserved for our COW
+	 * destination.
+	 *
+	 * The page was dirty when we started, nothing should have cleaned it.
+	 */
+	BUG_ON(!PageDirty(page));
+	free_delalloc_space = false;
 out_reserved:
 	btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
-	if (ret)
+	if (free_delalloc_space)
 		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);
 out_page:
+	if (ret) {
+		/*
+		 * We hit ENOSPC or other errors.  Update the mapping and page
+		 * to reflect the errors and clean the page.
+		 */
+		mapping_set_error(page->mapping, ret);
+		end_extent_writepage(page, ret, page_start, page_end);
+		clear_page_dirty_for_io(page);
+		SetPageError(page);
+	}
+	ClearPageChecked(page);
 	unlock_page(page);
 	put_page(page);
 	kfree(fixup);
 	extent_changeset_free(data_reserved);
+	/*
+	 * As a precaution, do a delayed iput in case it would be the last iput
+	 * that could need flushing space. Recursing back to fixup worker would
+	 * deadlock.
+	 */
+	btrfs_add_delayed_iput(inode);
 }
 
 /*
@@ -2270,6 +2325,13 @@ int btrfs_writepage_cow_fixup(struct pag
 	if (TestClearPagePrivate2(page))
 		return 0;
 
+	/*
+	 * PageChecked is set below when we create a fixup worker for this page,
+	 * don't try to create another one if we're already PageChecked()
+	 *
+	 * The extent_io writepage code will redirty the page if we send back
+	 * EAGAIN.
+	 */
 	if (PageChecked(page))
 		return -EAGAIN;
 
@@ -2277,12 +2339,21 @@ int btrfs_writepage_cow_fixup(struct pag
 	if (!fixup)
 		return -EAGAIN;
 
+	/*
+	 * We are already holding a reference to this inode from
+	 * write_cache_pages.  We need to hold it because the space reservation
+	 * takes place outside of the page lock, and we can't trust
+	 * page->mapping outside of the page lock.
+	 */
+	ihold(inode);
 	SetPageChecked(page);
 	get_page(page);
 	btrfs_init_work(&fixup->work, btrfs_writepage_fixup_worker, NULL, NULL);
 	fixup->page = page;
+	fixup->inode = inode;
 	btrfs_queue_work(fs_info->fixup_workers, &fixup->work);
-	return -EBUSY;
+
+	return -EAGAIN;
 }
 
 static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/btrfs/volumes.c linux-libre-5.4.22-gnu/fs/btrfs/volumes.c
--- linux-libre-5.4.21-gnu/fs/btrfs/volumes.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/btrfs/volumes.c	2020-02-24 02:37:04.000000000 -0500
@@ -907,6 +907,32 @@ static struct btrfs_fs_devices *find_fsi
 
 	return NULL;
 }
+
+static struct btrfs_fs_devices *find_fsid_reverted_metadata(
+				struct btrfs_super_block *disk_super)
+{
+	struct btrfs_fs_devices *fs_devices;
+
+	/*
+	 * Handle the case where the scanned device is part of an fs whose last
+	 * metadata UUID change reverted it to the original FSID. At the same
+	 * time * fs_devices was first created by another constitutent device
+	 * which didn't fully observe the operation. This results in an
+	 * btrfs_fs_devices created with metadata/fsid different AND
+	 * btrfs_fs_devices::fsid_change set AND the metadata_uuid of the
+	 * fs_devices equal to the FSID of the disk.
+	 */
+	list_for_each_entry(fs_devices, &fs_uuids, fs_list) {
+		if (memcmp(fs_devices->fsid, fs_devices->metadata_uuid,
+			   BTRFS_FSID_SIZE) != 0 &&
+		    memcmp(fs_devices->metadata_uuid, disk_super->fsid,
+			   BTRFS_FSID_SIZE) == 0 &&
+		    fs_devices->fsid_change)
+			return fs_devices;
+	}
+
+	return NULL;
+}
 /*
  * Add new device to list of registered devices
  *
@@ -946,7 +972,9 @@ static noinline struct btrfs_device *dev
 		fs_devices = find_fsid(disk_super->fsid,
 				       disk_super->metadata_uuid);
 	} else {
-		fs_devices = find_fsid(disk_super->fsid, NULL);
+		fs_devices = find_fsid_reverted_metadata(disk_super);
+		if (!fs_devices)
+			fs_devices = find_fsid(disk_super->fsid, NULL);
 	}
 
 
@@ -976,12 +1004,18 @@ static noinline struct btrfs_device *dev
 		 * a device which had the CHANGING_FSID_V2 flag then replace the
 		 * metadata_uuid/fsid values of the fs_devices.
 		 */
-		if (has_metadata_uuid && fs_devices->fsid_change &&
+		if (fs_devices->fsid_change &&
 		    found_transid > fs_devices->latest_generation) {
 			memcpy(fs_devices->fsid, disk_super->fsid,
 					BTRFS_FSID_SIZE);
-			memcpy(fs_devices->metadata_uuid,
-					disk_super->metadata_uuid, BTRFS_FSID_SIZE);
+
+			if (has_metadata_uuid)
+				memcpy(fs_devices->metadata_uuid,
+				       disk_super->metadata_uuid,
+				       BTRFS_FSID_SIZE);
+			else
+				memcpy(fs_devices->metadata_uuid,
+				       disk_super->fsid, BTRFS_FSID_SIZE);
 
 			fs_devices->fsid_change = false;
 		}
@@ -7561,6 +7595,8 @@ int btrfs_get_dev_stats(struct btrfs_fs_
 			else
 				btrfs_dev_stat_set(dev, i, 0);
 		}
+		btrfs_info(fs_info, "device stats zeroed by %s (%d)",
+			   current->comm, task_pid_nr(current));
 	} else {
 		for (i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++)
 			if (stats->nr_items > i)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ceph/mds_client.c linux-libre-5.4.22-gnu/fs/ceph/mds_client.c
--- linux-libre-5.4.21-gnu/fs/ceph/mds_client.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ceph/mds_client.c	2020-02-24 02:37:04.000000000 -0500
@@ -2552,8 +2552,7 @@ static void __do_request(struct ceph_mds
 		if (!(mdsc->fsc->mount_options->flags &
 		      CEPH_MOUNT_OPT_MOUNTWAIT) &&
 		    !ceph_mdsmap_is_cluster_available(mdsc->mdsmap)) {
-			err = -ENOENT;
-			pr_info("probably no mds server is up\n");
+			err = -EHOSTUNREACH;
 			goto finish;
 		}
 	}
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ceph/super.c linux-libre-5.4.22-gnu/fs/ceph/super.c
--- linux-libre-5.4.21-gnu/fs/ceph/super.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ceph/super.c	2020-02-24 02:37:04.000000000 -0500
@@ -1137,6 +1137,11 @@ static struct dentry *ceph_mount(struct
 	return res;
 
 out_splat:
+	if (!ceph_mdsmap_is_cluster_available(fsc->mdsc->mdsmap)) {
+		pr_info("No mds server is up or the cluster is laggy\n");
+		err = -EHOSTUNREACH;
+	}
+
 	ceph_mdsc_close_sessions(fsc->mdsc);
 	deactivate_locked_super(sb);
 	goto out_final;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/cifs/cifs_dfs_ref.c linux-libre-5.4.22-gnu/fs/cifs/cifs_dfs_ref.c
--- linux-libre-5.4.21-gnu/fs/cifs/cifs_dfs_ref.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/cifs/cifs_dfs_ref.c	2020-02-24 02:37:04.000000000 -0500
@@ -120,17 +120,17 @@ cifs_build_devname(char *nodename, const
 
 
 /**
- * cifs_compose_mount_options	-	creates mount options for refferral
+ * cifs_compose_mount_options	-	creates mount options for referral
  * @sb_mountdata:	parent/root DFS mount options (template)
  * @fullpath:		full path in UNC format
- * @ref:		server's referral
+ * @ref:		optional server's referral
  * @devname:		optional pointer for saving device name
  *
  * creates mount options for submount based on template options sb_mountdata
  * and replacing unc,ip,prefixpath options with ones we've got form ref_unc.
  *
  * Returns: pointer to new mount options or ERR_PTR.
- * Caller is responcible for freeing retunrned value if it is not error.
+ * Caller is responsible for freeing returned value if it is not error.
  */
 char *cifs_compose_mount_options(const char *sb_mountdata,
 				   const char *fullpath,
@@ -150,18 +150,27 @@ char *cifs_compose_mount_options(const c
 	if (sb_mountdata == NULL)
 		return ERR_PTR(-EINVAL);
 
-	if (strlen(fullpath) - ref->path_consumed) {
-		prepath = fullpath + ref->path_consumed;
-		/* skip initial delimiter */
-		if (*prepath == '/' || *prepath == '\\')
-			prepath++;
-	}
+	if (ref) {
+		if (strlen(fullpath) - ref->path_consumed) {
+			prepath = fullpath + ref->path_consumed;
+			/* skip initial delimiter */
+			if (*prepath == '/' || *prepath == '\\')
+				prepath++;
+		}
 
-	name = cifs_build_devname(ref->node_name, prepath);
-	if (IS_ERR(name)) {
-		rc = PTR_ERR(name);
-		name = NULL;
-		goto compose_mount_options_err;
+		name = cifs_build_devname(ref->node_name, prepath);
+		if (IS_ERR(name)) {
+			rc = PTR_ERR(name);
+			name = NULL;
+			goto compose_mount_options_err;
+		}
+	} else {
+		name = cifs_build_devname((char *)fullpath, NULL);
+		if (IS_ERR(name)) {
+			rc = PTR_ERR(name);
+			name = NULL;
+			goto compose_mount_options_err;
+		}
 	}
 
 	rc = dns_resolve_server_name_to_ip(name, &srvIP);
@@ -225,6 +234,8 @@ char *cifs_compose_mount_options(const c
 
 	if (devname)
 		*devname = name;
+	else
+		kfree(name);
 
 	/*cifs_dbg(FYI, "%s: parent mountdata: %s\n", __func__, sb_mountdata);*/
 	/*cifs_dbg(FYI, "%s: submount mountdata: %s\n", __func__, mountdata );*/
@@ -241,23 +252,23 @@ compose_mount_options_err:
 }
 
 /**
- * cifs_dfs_do_refmount - mounts specified path using provided refferal
+ * cifs_dfs_do_mount - mounts specified path using DFS full path
+ *
+ * Always pass down @fullpath to smb3_do_mount() so we can use the root server
+ * to perform failover in case we failed to connect to the first target in the
+ * referral.
+ *
  * @cifs_sb:		parent/root superblock
  * @fullpath:		full path in UNC format
- * @ref:		server's referral
  */
-static struct vfsmount *cifs_dfs_do_refmount(struct dentry *mntpt,
-		struct cifs_sb_info *cifs_sb,
-		const char *fullpath, const struct dfs_info3_param *ref)
+static struct vfsmount *cifs_dfs_do_mount(struct dentry *mntpt,
+					  struct cifs_sb_info *cifs_sb,
+					  const char *fullpath)
 {
 	struct vfsmount *mnt;
 	char *mountdata;
 	char *devname;
 
-	/*
-	 * Always pass down the DFS full path to smb3_do_mount() so we
-	 * can use it later for failover.
-	 */
 	devname = kstrndup(fullpath, strlen(fullpath), GFP_KERNEL);
 	if (!devname)
 		return ERR_PTR(-ENOMEM);
@@ -266,7 +277,7 @@ static struct vfsmount *cifs_dfs_do_refm
 
 	/* strip first '\' from fullpath */
 	mountdata = cifs_compose_mount_options(cifs_sb->mountdata,
-					       fullpath + 1, ref, NULL);
+					       fullpath + 1, NULL, NULL);
 	if (IS_ERR(mountdata)) {
 		kfree(devname);
 		return (struct vfsmount *)mountdata;
@@ -278,28 +289,16 @@ static struct vfsmount *cifs_dfs_do_refm
 	return mnt;
 }
 
-static void dump_referral(const struct dfs_info3_param *ref)
-{
-	cifs_dbg(FYI, "DFS: ref path: %s\n", ref->path_name);
-	cifs_dbg(FYI, "DFS: node path: %s\n", ref->node_name);
-	cifs_dbg(FYI, "DFS: fl: %d, srv_type: %d\n",
-		 ref->flags, ref->server_type);
-	cifs_dbg(FYI, "DFS: ref_flags: %d, path_consumed: %d\n",
-		 ref->ref_flag, ref->path_consumed);
-}
-
 /*
  * Create a vfsmount that we can automount
  */
 static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
 {
-	struct dfs_info3_param referral = {0};
 	struct cifs_sb_info *cifs_sb;
 	struct cifs_ses *ses;
 	struct cifs_tcon *tcon;
 	char *full_path, *root_path;
 	unsigned int xid;
-	int len;
 	int rc;
 	struct vfsmount *mnt;
 
@@ -357,7 +356,7 @@ static struct vfsmount *cifs_dfs_do_auto
 	if (!rc) {
 		rc = dfs_cache_find(xid, ses, cifs_sb->local_nls,
 				    cifs_remap(cifs_sb), full_path + 1,
-				    &referral, NULL);
+				    NULL, NULL);
 	}
 
 	free_xid(xid);
@@ -366,26 +365,16 @@ static struct vfsmount *cifs_dfs_do_auto
 		mnt = ERR_PTR(rc);
 		goto free_root_path;
 	}
-
-	dump_referral(&referral);
-
-	len = strlen(referral.node_name);
-	if (len < 2) {
-		cifs_dbg(VFS, "%s: Net Address path too short: %s\n",
-			 __func__, referral.node_name);
-		mnt = ERR_PTR(-EINVAL);
-		goto free_dfs_ref;
-	}
 	/*
-	 * cifs_mount() will retry every available node server in case
-	 * of failures.
+	 * OK - we were able to get and cache a referral for @full_path.
+	 *
+	 * Now, pass it down to cifs_mount() and it will retry every available
+	 * node server in case of failures - no need to do it here.
 	 */
-	mnt = cifs_dfs_do_refmount(mntpt, cifs_sb, full_path, &referral);
-	cifs_dbg(FYI, "%s: cifs_dfs_do_refmount:%s , mnt:%p\n", __func__,
-		 referral.node_name, mnt);
+	mnt = cifs_dfs_do_mount(mntpt, cifs_sb, full_path);
+	cifs_dbg(FYI, "%s: cifs_dfs_do_mount:%s , mnt:%p\n", __func__,
+		 full_path + 1, mnt);
 
-free_dfs_ref:
-	free_dfs_info_param(&referral);
 free_root_path:
 	kfree(root_path);
 free_full_path:
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/cifs/connect.c linux-libre-5.4.22-gnu/fs/cifs/connect.c
--- linux-libre-5.4.21-gnu/fs/cifs/connect.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/cifs/connect.c	2020-02-24 02:37:04.000000000 -0500
@@ -3652,8 +3652,10 @@ match_prepath(struct super_block *sb, st
 {
 	struct cifs_sb_info *old = CIFS_SB(sb);
 	struct cifs_sb_info *new = mnt_data->cifs_sb;
-	bool old_set = old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH;
-	bool new_set = new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH;
+	bool old_set = (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
+		old->prepath;
+	bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
+		new->prepath;
 
 	if (old_set && new_set && !strcmp(new->prepath, old->prepath))
 		return 1;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/cifs/dfs_cache.c linux-libre-5.4.22-gnu/fs/cifs/dfs_cache.c
--- linux-libre-5.4.21-gnu/fs/cifs/dfs_cache.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/cifs/dfs_cache.c	2020-02-24 02:37:04.000000000 -0500
@@ -1319,7 +1319,7 @@ static struct cifs_ses *find_root_ses(st
 	char *mdata = NULL, *devname = NULL;
 	struct TCP_Server_Info *server;
 	struct cifs_ses *ses;
-	struct smb_vol vol;
+	struct smb_vol vol = {NULL};
 
 	rpath = get_dfs_root(path);
 	if (IS_ERR(rpath))
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/cifs/smb2pdu.c linux-libre-5.4.22-gnu/fs/cifs/smb2pdu.c
--- linux-libre-5.4.21-gnu/fs/cifs/smb2pdu.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/cifs/smb2pdu.c	2020-02-24 02:37:04.000000000 -0500
@@ -3917,6 +3917,9 @@ smb2_writev_callback(struct mid_q_entry
 				     wdata->cfile->fid.persistent_fid,
 				     tcon->tid, tcon->ses->Suid, wdata->offset,
 				     wdata->bytes, wdata->result);
+		if (wdata->result == -ENOSPC)
+			printk_once(KERN_WARNING "Out of space writing to %s\n",
+				    tcon->treeName);
 	} else
 		trace_smb3_write_done(0 /* no xid */,
 				      wdata->cfile->fid.persistent_fid,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ext4/file.c linux-libre-5.4.22-gnu/fs/ext4/file.c
--- linux-libre-5.4.21-gnu/fs/ext4/file.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ext4/file.c	2020-02-24 02:37:04.000000000 -0500
@@ -40,9 +40,10 @@ static ssize_t ext4_dax_read_iter(struct
 	struct inode *inode = file_inode(iocb->ki_filp);
 	ssize_t ret;
 
-	if (!inode_trylock_shared(inode)) {
-		if (iocb->ki_flags & IOCB_NOWAIT)
+	if (iocb->ki_flags & IOCB_NOWAIT) {
+		if (!inode_trylock_shared(inode))
 			return -EAGAIN;
+	} else {
 		inode_lock_shared(inode);
 	}
 	/*
@@ -190,9 +191,10 @@ ext4_dax_write_iter(struct kiocb *iocb,
 	struct inode *inode = file_inode(iocb->ki_filp);
 	ssize_t ret;
 
-	if (!inode_trylock(inode)) {
-		if (iocb->ki_flags & IOCB_NOWAIT)
+	if (iocb->ki_flags & IOCB_NOWAIT) {
+		if (!inode_trylock(inode))
 			return -EAGAIN;
+	} else {
 		inode_lock(inode);
 	}
 	ret = ext4_write_checks(iocb, from);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ext4/readpage.c linux-libre-5.4.22-gnu/fs/ext4/readpage.c
--- linux-libre-5.4.21-gnu/fs/ext4/readpage.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ext4/readpage.c	2020-02-24 02:37:04.000000000 -0500
@@ -57,6 +57,7 @@ enum bio_post_read_step {
 	STEP_INITIAL = 0,
 	STEP_DECRYPT,
 	STEP_VERITY,
+	STEP_MAX,
 };
 
 struct bio_post_read_ctx {
@@ -106,10 +107,22 @@ static void verity_work(struct work_stru
 {
 	struct bio_post_read_ctx *ctx =
 		container_of(work, struct bio_post_read_ctx, work);
+	struct bio *bio = ctx->bio;
 
-	fsverity_verify_bio(ctx->bio);
+	/*
+	 * fsverity_verify_bio() may call readpages() again, and although verity
+	 * will be disabled for that, decryption may still be needed, causing
+	 * another bio_post_read_ctx to be allocated.  So to guarantee that
+	 * mempool_alloc() never deadlocks we must free the current ctx first.
+	 * This is safe because verity is the last post-read step.
+	 */
+	BUILD_BUG_ON(STEP_VERITY + 1 != STEP_MAX);
+	mempool_free(ctx, bio_post_read_ctx_pool);
+	bio->bi_private = NULL;
 
-	bio_post_read_processing(ctx);
+	fsverity_verify_bio(bio);
+
+	__read_end_io(bio);
 }
 
 static void bio_post_read_processing(struct bio_post_read_ctx *ctx)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/f2fs/data.c linux-libre-5.4.22-gnu/fs/f2fs/data.c
--- linux-libre-5.4.21-gnu/fs/f2fs/data.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/f2fs/data.c	2020-02-24 02:37:04.000000000 -0500
@@ -1074,19 +1074,6 @@ int f2fs_preallocate_blocks(struct kiocb
 	int err = 0;
 	bool direct_io = iocb->ki_flags & IOCB_DIRECT;
 
-	/* convert inline data for Direct I/O*/
-	if (direct_io) {
-		err = f2fs_convert_inline_inode(inode);
-		if (err)
-			return err;
-	}
-
-	if (direct_io && allow_outplace_dio(inode, iocb, from))
-		return 0;
-
-	if (is_inode_flag_set(inode, FI_NO_PREALLOC))
-		return 0;
-
 	map.m_lblk = F2FS_BLK_ALIGN(iocb->ki_pos);
 	map.m_len = F2FS_BYTES_TO_BLK(iocb->ki_pos + iov_iter_count(from));
 	if (map.m_len > map.m_lblk)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/f2fs/file.c linux-libre-5.4.22-gnu/fs/f2fs/file.c
--- linux-libre-5.4.21-gnu/fs/f2fs/file.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/f2fs/file.c	2020-02-24 02:37:04.000000000 -0500
@@ -50,7 +50,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(s
 	struct page *page = vmf->page;
 	struct inode *inode = file_inode(vmf->vma->vm_file);
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-	struct dnode_of_data dn = { .node_changed = false };
+	struct dnode_of_data dn;
 	int err;
 
 	if (unlikely(f2fs_cp_error(sbi))) {
@@ -63,6 +63,9 @@ static vm_fault_t f2fs_vm_page_mkwrite(s
 		goto err;
 	}
 
+	/* should do out of any locked page */
+	f2fs_balance_fs(sbi, true);
+
 	sb_start_pagefault(inode->i_sb);
 
 	f2fs_bug_on(sbi, f2fs_has_inline_data(inode));
@@ -120,8 +123,6 @@ static vm_fault_t f2fs_vm_page_mkwrite(s
 out_sem:
 	up_read(&F2FS_I(inode)->i_mmap_sem);
 
-	f2fs_balance_fs(sbi, dn.node_changed);
-
 	sb_end_pagefault(inode->i_sb);
 err:
 	return block_page_mkwrite_return(err);
@@ -3348,18 +3349,41 @@ static ssize_t f2fs_file_write_iter(stru
 				ret = -EAGAIN;
 				goto out;
 			}
-		} else {
-			preallocated = true;
-			target_size = iocb->ki_pos + iov_iter_count(from);
+			goto write;
+		}
 
-			err = f2fs_preallocate_blocks(iocb, from);
-			if (err) {
-				clear_inode_flag(inode, FI_NO_PREALLOC);
-				inode_unlock(inode);
-				ret = err;
-				goto out;
-			}
+		if (is_inode_flag_set(inode, FI_NO_PREALLOC))
+			goto write;
+
+		if (iocb->ki_flags & IOCB_DIRECT) {
+			/*
+			 * Convert inline data for Direct I/O before entering
+			 * f2fs_direct_IO().
+			 */
+			err = f2fs_convert_inline_inode(inode);
+			if (err)
+				goto out_err;
+			/*
+			 * If force_buffere_io() is true, we have to allocate
+			 * blocks all the time, since f2fs_direct_IO will fall
+			 * back to buffered IO.
+			 */
+			if (!f2fs_force_buffered_io(inode, iocb, from) &&
+					allow_outplace_dio(inode, iocb, from))
+				goto write;
 		}
+		preallocated = true;
+		target_size = iocb->ki_pos + iov_iter_count(from);
+
+		err = f2fs_preallocate_blocks(iocb, from);
+		if (err) {
+out_err:
+			clear_inode_flag(inode, FI_NO_PREALLOC);
+			inode_unlock(inode);
+			ret = err;
+			goto out;
+		}
+write:
 		ret = __generic_file_write_iter(iocb, from);
 		clear_inode_flag(inode, FI_NO_PREALLOC);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/f2fs/namei.c linux-libre-5.4.22-gnu/fs/f2fs/namei.c
--- linux-libre-5.4.21-gnu/fs/f2fs/namei.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/f2fs/namei.c	2020-02-24 02:37:04.000000000 -0500
@@ -797,6 +797,7 @@ static int __f2fs_tmpfile(struct inode *
 
 	if (whiteout) {
 		f2fs_i_links_write(inode, false);
+		inode->i_state |= I_LINKABLE;
 		*whiteout = inode;
 	} else {
 		d_tmpfile(dentry, inode);
@@ -867,6 +868,12 @@ static int f2fs_rename(struct inode *old
 			F2FS_I(old_dentry->d_inode)->i_projid)))
 		return -EXDEV;
 
+	if (flags & RENAME_WHITEOUT) {
+		err = f2fs_create_whiteout(old_dir, &whiteout);
+		if (err)
+			return err;
+	}
+
 	err = dquot_initialize(old_dir);
 	if (err)
 		goto out;
@@ -898,17 +905,11 @@ static int f2fs_rename(struct inode *old
 		}
 	}
 
-	if (flags & RENAME_WHITEOUT) {
-		err = f2fs_create_whiteout(old_dir, &whiteout);
-		if (err)
-			goto out_dir;
-	}
-
 	if (new_inode) {
 
 		err = -ENOTEMPTY;
 		if (old_dir_entry && !f2fs_empty_dir(new_inode))
-			goto out_whiteout;
+			goto out_dir;
 
 		err = -ENOENT;
 		new_entry = f2fs_find_entry(new_dir, &new_dentry->d_name,
@@ -916,7 +917,7 @@ static int f2fs_rename(struct inode *old
 		if (!new_entry) {
 			if (IS_ERR(new_page))
 				err = PTR_ERR(new_page);
-			goto out_whiteout;
+			goto out_dir;
 		}
 
 		f2fs_balance_fs(sbi, true);
@@ -948,7 +949,7 @@ static int f2fs_rename(struct inode *old
 		err = f2fs_add_link(new_dentry, old_inode);
 		if (err) {
 			f2fs_unlock_op(sbi);
-			goto out_whiteout;
+			goto out_dir;
 		}
 
 		if (old_dir_entry)
@@ -972,7 +973,7 @@ static int f2fs_rename(struct inode *old
 				if (IS_ERR(old_page))
 					err = PTR_ERR(old_page);
 				f2fs_unlock_op(sbi);
-				goto out_whiteout;
+				goto out_dir;
 			}
 		}
 	}
@@ -991,7 +992,6 @@ static int f2fs_rename(struct inode *old
 	f2fs_delete_entry(old_entry, old_page, old_dir, NULL);
 
 	if (whiteout) {
-		whiteout->i_state |= I_LINKABLE;
 		set_inode_flag(whiteout, FI_INC_LINK);
 		err = f2fs_add_link(old_dentry, whiteout);
 		if (err)
@@ -1027,15 +1027,14 @@ put_out_dir:
 	f2fs_unlock_op(sbi);
 	if (new_page)
 		f2fs_put_page(new_page, 0);
-out_whiteout:
-	if (whiteout)
-		iput(whiteout);
 out_dir:
 	if (old_dir_entry)
 		f2fs_put_page(old_dir_page, 0);
 out_old:
 	f2fs_put_page(old_page, 0);
 out:
+	if (whiteout)
+		iput(whiteout);
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/f2fs/sysfs.c linux-libre-5.4.22-gnu/fs/f2fs/sysfs.c
--- linux-libre-5.4.21-gnu/fs/f2fs/sysfs.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/f2fs/sysfs.c	2020-02-24 02:37:04.000000000 -0500
@@ -729,10 +729,12 @@ int __init f2fs_init_sysfs(void)
 
 	ret = kobject_init_and_add(&f2fs_feat, &f2fs_feat_ktype,
 				   NULL, "features");
-	if (ret)
+	if (ret) {
+		kobject_put(&f2fs_feat);
 		kset_unregister(&f2fs_kset);
-	else
+	} else {
 		f2fs_proc_root = proc_mkdir("fs/f2fs", NULL);
+	}
 	return ret;
 }
 
@@ -753,8 +755,11 @@ int f2fs_register_sysfs(struct f2fs_sb_i
 	init_completion(&sbi->s_kobj_unregister);
 	err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL,
 				"%s", sb->s_id);
-	if (err)
+	if (err) {
+		kobject_put(&sbi->s_kobj);
+		wait_for_completion(&sbi->s_kobj_unregister);
 		return err;
+	}
 
 	if (f2fs_proc_root)
 		sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
@@ -782,4 +787,5 @@ void f2fs_unregister_sysfs(struct f2fs_s
 		remove_proc_entry(sbi->sb->s_id, f2fs_proc_root);
 	}
 	kobject_del(&sbi->s_kobj);
+	kobject_put(&sbi->s_kobj);
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/fuse/file.c linux-libre-5.4.22-gnu/fs/fuse/file.c
--- linux-libre-5.4.21-gnu/fs/fuse/file.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/fuse/file.c	2020-02-24 02:37:04.000000000 -0500
@@ -803,6 +803,10 @@ static int fuse_do_readpage(struct file
 
 	attr_ver = fuse_get_attr_version(fc);
 
+	/* Don't overflow end offset */
+	if (pos + (desc.length - 1) == LLONG_MAX)
+		desc.length--;
+
 	fuse_read_args_fill(&ia, file, pos, desc.length, FUSE_READ);
 	res = fuse_simple_request(fc, &ia.ap.args);
 	if (res < 0)
@@ -888,6 +892,14 @@ static void fuse_send_readpages(struct f
 	ap->args.out_pages = true;
 	ap->args.page_zeroing = true;
 	ap->args.page_replace = true;
+
+	/* Don't overflow end offset */
+	if (pos + (count - 1) == LLONG_MAX) {
+		count--;
+		ap->descs[ap->num_pages - 1].length--;
+	}
+	WARN_ON((loff_t) (pos + count) < 0);
+
 	fuse_read_args_fill(ia, file, pos, count, FUSE_READ);
 	ia->read.attr_ver = fuse_get_attr_version(fc);
 	if (fc->async_read) {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/jbd2/checkpoint.c linux-libre-5.4.22-gnu/fs/jbd2/checkpoint.c
--- linux-libre-5.4.21-gnu/fs/jbd2/checkpoint.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/jbd2/checkpoint.c	2020-02-24 02:37:04.000000000 -0500
@@ -164,7 +164,7 @@ void __jbd2_log_wait_for_space(journal_t
 				       "journal space in %s\n", __func__,
 				       journal->j_devname);
 				WARN_ON(1);
-				jbd2_journal_abort(journal, 0);
+				jbd2_journal_abort(journal, -EIO);
 			}
 			write_lock(&journal->j_state_lock);
 		} else {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/jbd2/commit.c linux-libre-5.4.22-gnu/fs/jbd2/commit.c
--- linux-libre-5.4.21-gnu/fs/jbd2/commit.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/jbd2/commit.c	2020-02-24 02:37:04.000000000 -0500
@@ -784,7 +784,7 @@ start_journal_io:
 		err = journal_submit_commit_record(journal, commit_transaction,
 						 &cbh, crc32_sum);
 		if (err)
-			__jbd2_journal_abort_hard(journal);
+			jbd2_journal_abort(journal, err);
 	}
 
 	blk_finish_plug(&plug);
@@ -877,7 +877,7 @@ start_journal_io:
 		err = journal_submit_commit_record(journal, commit_transaction,
 						&cbh, crc32_sum);
 		if (err)
-			__jbd2_journal_abort_hard(journal);
+			jbd2_journal_abort(journal, err);
 	}
 	if (cbh)
 		err = journal_wait_on_commit_record(journal, cbh);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/jbd2/journal.c linux-libre-5.4.22-gnu/fs/jbd2/journal.c
--- linux-libre-5.4.21-gnu/fs/jbd2/journal.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/jbd2/journal.c	2020-02-24 02:37:04.000000000 -0500
@@ -1682,6 +1682,11 @@ int jbd2_journal_load(journal_t *journal
 		       journal->j_devname);
 		return -EFSCORRUPTED;
 	}
+	/*
+	 * clear JBD2_ABORT flag initialized in journal_init_common
+	 * here to update log tail information with the newest seq.
+	 */
+	journal->j_flags &= ~JBD2_ABORT;
 
 	/* OK, we've finished with the dynamic journal bits:
 	 * reinitialise the dynamic contents of the superblock in memory
@@ -1689,7 +1694,6 @@ int jbd2_journal_load(journal_t *journal
 	if (journal_reset(journal))
 		goto recovery_error;
 
-	journal->j_flags &= ~JBD2_ABORT;
 	journal->j_flags |= JBD2_LOADED;
 	return 0;
 
@@ -2110,8 +2114,7 @@ static void __journal_abort_soft (journa
 
 	if (journal->j_flags & JBD2_ABORT) {
 		write_unlock(&journal->j_state_lock);
-		if (!old_errno && old_errno != -ESHUTDOWN &&
-		    errno == -ESHUTDOWN)
+		if (old_errno != -ESHUTDOWN && errno == -ESHUTDOWN)
 			jbd2_journal_update_sb_errno(journal);
 		return;
 	}
@@ -2119,12 +2122,10 @@ static void __journal_abort_soft (journa
 
 	__jbd2_journal_abort_hard(journal);
 
-	if (errno) {
-		jbd2_journal_update_sb_errno(journal);
-		write_lock(&journal->j_state_lock);
-		journal->j_flags |= JBD2_REC_ERR;
-		write_unlock(&journal->j_state_lock);
-	}
+	jbd2_journal_update_sb_errno(journal);
+	write_lock(&journal->j_state_lock);
+	journal->j_flags |= JBD2_REC_ERR;
+	write_unlock(&journal->j_state_lock);
 }
 
 /**
@@ -2166,11 +2167,6 @@ static void __journal_abort_soft (journa
  * failure to disk.  ext3_error, for example, now uses this
  * functionality.
  *
- * Errors which originate from within the journaling layer will NOT
- * supply an errno; a null errno implies that absolutely no further
- * writes are done to the journal (unless there are any already in
- * progress).
- *
  */
 
 void jbd2_journal_abort(journal_t *journal, int errno)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/nfs/nfs42proc.c linux-libre-5.4.22-gnu/fs/nfs/nfs42proc.c
--- linux-libre-5.4.21-gnu/fs/nfs/nfs42proc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/nfs/nfs42proc.c	2020-02-24 02:37:04.000000000 -0500
@@ -283,14 +283,14 @@ static ssize_t _nfs42_proc_copy(struct f
 		status = handle_async_copy(res, server, src, dst,
 				&args->src_stateid);
 		if (status)
-			return status;
+			goto out;
 	}
 
 	if ((!res->synchronous || !args->sync) &&
 			res->write_res.verifier.committed != NFS_FILE_SYNC) {
 		status = process_copy_commit(dst, pos_dst, res);
 		if (status)
-			return status;
+			goto out;
 	}
 
 	truncate_pagecache_range(dst_inode, pos_dst,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/nfsd/vfs.c linux-libre-5.4.22-gnu/fs/nfsd/vfs.c
--- linux-libre-5.4.21-gnu/fs/nfsd/vfs.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/nfsd/vfs.c	2020-02-24 02:37:04.000000000 -0500
@@ -280,19 +280,25 @@ out:
  * Commit metadata changes to stable storage.
  */
 static int
-commit_metadata(struct svc_fh *fhp)
+commit_inode_metadata(struct inode *inode)
 {
-	struct inode *inode = d_inode(fhp->fh_dentry);
 	const struct export_operations *export_ops = inode->i_sb->s_export_op;
 
-	if (!EX_ISSYNC(fhp->fh_export))
-		return 0;
-
 	if (export_ops->commit_metadata)
 		return export_ops->commit_metadata(inode);
 	return sync_inode_metadata(inode, 1);
 }
 
+static int
+commit_metadata(struct svc_fh *fhp)
+{
+	struct inode *inode = d_inode(fhp->fh_dentry);
+
+	if (!EX_ISSYNC(fhp->fh_export))
+		return 0;
+	return commit_inode_metadata(inode);
+}
+
 /*
  * Go over the attributes and take care of the small differences between
  * NFS semantics and what Linux expects.
@@ -537,6 +543,9 @@ __be32 nfsd4_clone_file_range(struct fil
 	if (sync) {
 		loff_t dst_end = count ? dst_pos + count - 1 : LLONG_MAX;
 		int status = vfs_fsync_range(dst, dst_pos, dst_end, 0);
+
+		if (!status)
+			status = commit_inode_metadata(file_inode(src));
 		if (status < 0)
 			return nfserrno(status);
 	}
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmast.c linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmast.c
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmast.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmast.c	2020-02-24 02:37:04.000000000 -0500
@@ -23,15 +23,15 @@
 #include <linux/spinlock.h>
 
 
-#include "cluster/heartbeat.h"
-#include "cluster/nodemanager.h"
-#include "cluster/tcp.h"
+#include "../cluster/heartbeat.h"
+#include "../cluster/nodemanager.h"
+#include "../cluster/tcp.h"
 
 #include "dlmapi.h"
 #include "dlmcommon.h"
 
 #define MLOG_MASK_PREFIX ML_DLM
-#include "cluster/masklog.h"
+#include "../cluster/masklog.h"
 
 static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
 			   struct dlm_lock *lock);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmconvert.c linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmconvert.c
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmconvert.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmconvert.c	2020-02-24 02:37:04.000000000 -0500
@@ -23,9 +23,9 @@
 #include <linux/spinlock.h>
 
 
-#include "cluster/heartbeat.h"
-#include "cluster/nodemanager.h"
-#include "cluster/tcp.h"
+#include "../cluster/heartbeat.h"
+#include "../cluster/nodemanager.h"
+#include "../cluster/tcp.h"
 
 #include "dlmapi.h"
 #include "dlmcommon.h"
@@ -33,7 +33,7 @@
 #include "dlmconvert.h"
 
 #define MLOG_MASK_PREFIX ML_DLM
-#include "cluster/masklog.h"
+#include "../cluster/masklog.h"
 
 /* NOTE: __dlmconvert_master is the only function in here that
  * needs a spinlock held on entry (res->spinlock) and it is the
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmdebug.c linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmdebug.c
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmdebug.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmdebug.c	2020-02-24 02:37:04.000000000 -0500
@@ -17,9 +17,9 @@
 #include <linux/debugfs.h>
 #include <linux/export.h>
 
-#include "cluster/heartbeat.h"
-#include "cluster/nodemanager.h"
-#include "cluster/tcp.h"
+#include "../cluster/heartbeat.h"
+#include "../cluster/nodemanager.h"
+#include "../cluster/tcp.h"
 
 #include "dlmapi.h"
 #include "dlmcommon.h"
@@ -27,7 +27,7 @@
 #include "dlmdebug.h"
 
 #define MLOG_MASK_PREFIX ML_DLM
-#include "cluster/masklog.h"
+#include "../cluster/masklog.h"
 
 static int stringify_lockname(const char *lockname, int locklen, char *buf,
 			      int len);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmdomain.c linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmdomain.c
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmdomain.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmdomain.c	2020-02-24 02:37:04.000000000 -0500
@@ -20,9 +20,9 @@
 #include <linux/debugfs.h>
 #include <linux/sched/signal.h>
 
-#include "cluster/heartbeat.h"
-#include "cluster/nodemanager.h"
-#include "cluster/tcp.h"
+#include "../cluster/heartbeat.h"
+#include "../cluster/nodemanager.h"
+#include "../cluster/tcp.h"
 
 #include "dlmapi.h"
 #include "dlmcommon.h"
@@ -30,7 +30,7 @@
 #include "dlmdebug.h"
 
 #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_DOMAIN)
-#include "cluster/masklog.h"
+#include "../cluster/masklog.h"
 
 /*
  * ocfs2 node maps are array of long int, which limits to send them freely
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmlock.c linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmlock.c
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmlock.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmlock.c	2020-02-24 02:37:04.000000000 -0500
@@ -25,9 +25,9 @@
 #include <linux/delay.h>
 
 
-#include "cluster/heartbeat.h"
-#include "cluster/nodemanager.h"
-#include "cluster/tcp.h"
+#include "../cluster/heartbeat.h"
+#include "../cluster/nodemanager.h"
+#include "../cluster/tcp.h"
 
 #include "dlmapi.h"
 #include "dlmcommon.h"
@@ -35,7 +35,7 @@
 #include "dlmconvert.h"
 
 #define MLOG_MASK_PREFIX ML_DLM
-#include "cluster/masklog.h"
+#include "../cluster/masklog.h"
 
 static struct kmem_cache *dlm_lock_cache;
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmmaster.c linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmmaster.c
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmmaster.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmmaster.c	2020-02-24 02:37:04.000000000 -0500
@@ -25,9 +25,9 @@
 #include <linux/delay.h>
 
 
-#include "cluster/heartbeat.h"
-#include "cluster/nodemanager.h"
-#include "cluster/tcp.h"
+#include "../cluster/heartbeat.h"
+#include "../cluster/nodemanager.h"
+#include "../cluster/tcp.h"
 
 #include "dlmapi.h"
 #include "dlmcommon.h"
@@ -35,7 +35,7 @@
 #include "dlmdebug.h"
 
 #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_MASTER)
-#include "cluster/masklog.h"
+#include "../cluster/masklog.h"
 
 static void dlm_mle_node_down(struct dlm_ctxt *dlm,
 			      struct dlm_master_list_entry *mle,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmrecovery.c linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmrecovery.c
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmrecovery.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmrecovery.c	2020-02-24 02:37:04.000000000 -0500
@@ -26,16 +26,16 @@
 #include <linux/delay.h>
 
 
-#include "cluster/heartbeat.h"
-#include "cluster/nodemanager.h"
-#include "cluster/tcp.h"
+#include "../cluster/heartbeat.h"
+#include "../cluster/nodemanager.h"
+#include "../cluster/tcp.h"
 
 #include "dlmapi.h"
 #include "dlmcommon.h"
 #include "dlmdomain.h"
 
 #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_RECOVERY)
-#include "cluster/masklog.h"
+#include "../cluster/masklog.h"
 
 static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmthread.c linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmthread.c
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmthread.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmthread.c	2020-02-24 02:37:04.000000000 -0500
@@ -25,16 +25,16 @@
 #include <linux/delay.h>
 
 
-#include "cluster/heartbeat.h"
-#include "cluster/nodemanager.h"
-#include "cluster/tcp.h"
+#include "../cluster/heartbeat.h"
+#include "../cluster/nodemanager.h"
+#include "../cluster/tcp.h"
 
 #include "dlmapi.h"
 #include "dlmcommon.h"
 #include "dlmdomain.h"
 
 #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_THREAD)
-#include "cluster/masklog.h"
+#include "../cluster/masklog.h"
 
 static int dlm_thread(void *data);
 static void dlm_flush_asts(struct dlm_ctxt *dlm);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmunlock.c linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmunlock.c
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlm/dlmunlock.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlm/dlmunlock.c	2020-02-24 02:37:04.000000000 -0500
@@ -23,15 +23,15 @@
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 
-#include "cluster/heartbeat.h"
-#include "cluster/nodemanager.h"
-#include "cluster/tcp.h"
+#include "../cluster/heartbeat.h"
+#include "../cluster/nodemanager.h"
+#include "../cluster/tcp.h"
 
 #include "dlmapi.h"
 #include "dlmcommon.h"
 
 #define MLOG_MASK_PREFIX ML_DLM
-#include "cluster/masklog.h"
+#include "../cluster/masklog.h"
 
 #define DLM_UNLOCK_FREE_LOCK           0x00000001
 #define DLM_UNLOCK_CALL_AST            0x00000002
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlm/Makefile linux-libre-5.4.22-gnu/fs/ocfs2/dlm/Makefile
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlm/Makefile	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlm/Makefile	2020-02-24 02:37:04.000000000 -0500
@@ -1,6 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
-ccflags-y := -I $(srctree)/$(src)/..
-
 obj-$(CONFIG_OCFS2_FS_O2CB) += ocfs2_dlm.o
 
 ocfs2_dlm-objs := dlmdomain.o dlmdebug.o dlmthread.o dlmrecovery.o \
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlmfs/dlmfs.c linux-libre-5.4.22-gnu/fs/ocfs2/dlmfs/dlmfs.c
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlmfs/dlmfs.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlmfs/dlmfs.c	2020-02-24 02:37:04.000000000 -0500
@@ -33,11 +33,11 @@
 
 #include <linux/uaccess.h>
 
-#include "stackglue.h"
+#include "../stackglue.h"
 #include "userdlm.h"
 
 #define MLOG_MASK_PREFIX ML_DLMFS
-#include "cluster/masklog.h"
+#include "../cluster/masklog.h"
 
 
 static const struct super_operations dlmfs_ops;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlmfs/Makefile linux-libre-5.4.22-gnu/fs/ocfs2/dlmfs/Makefile
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlmfs/Makefile	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlmfs/Makefile	2020-02-24 02:37:04.000000000 -0500
@@ -1,6 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
-ccflags-y := -I $(srctree)/$(src)/..
-
 obj-$(CONFIG_OCFS2_FS) += ocfs2_dlmfs.o
 
 ocfs2_dlmfs-objs := userdlm.o dlmfs.o
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/dlmfs/userdlm.c linux-libre-5.4.22-gnu/fs/ocfs2/dlmfs/userdlm.c
--- linux-libre-5.4.21-gnu/fs/ocfs2/dlmfs/userdlm.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/dlmfs/userdlm.c	2020-02-24 02:37:04.000000000 -0500
@@ -21,12 +21,12 @@
 #include <linux/types.h>
 #include <linux/crc32.h>
 
-#include "ocfs2_lockingver.h"
-#include "stackglue.h"
+#include "../ocfs2_lockingver.h"
+#include "../stackglue.h"
 #include "userdlm.h"
 
 #define MLOG_MASK_PREFIX ML_DLMFS
-#include "cluster/masklog.h"
+#include "../cluster/masklog.h"
 
 
 static inline struct user_lock_res *user_lksb_to_lock_res(struct ocfs2_dlm_lksb *lksb)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/ocfs2/journal.h linux-libre-5.4.22-gnu/fs/ocfs2/journal.h
--- linux-libre-5.4.21-gnu/fs/ocfs2/journal.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/ocfs2/journal.h	2020-02-24 02:37:04.000000000 -0500
@@ -597,9 +597,11 @@ static inline void ocfs2_update_inode_fs
 {
 	struct ocfs2_inode_info *oi = OCFS2_I(inode);
 
-	oi->i_sync_tid = handle->h_transaction->t_tid;
-	if (datasync)
-		oi->i_datasync_tid = handle->h_transaction->t_tid;
+	if (!is_handle_aborted(handle)) {
+		oi->i_sync_tid = handle->h_transaction->t_tid;
+		if (datasync)
+			oi->i_datasync_tid = handle->h_transaction->t_tid;
+	}
 }
 
 #endif /* OCFS2_JOURNAL_H */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/orangefs/orangefs-debugfs.c linux-libre-5.4.22-gnu/fs/orangefs/orangefs-debugfs.c
--- linux-libre-5.4.21-gnu/fs/orangefs/orangefs-debugfs.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/orangefs/orangefs-debugfs.c	2020-02-24 02:37:04.000000000 -0500
@@ -273,6 +273,7 @@ static void *help_start(struct seq_file
 
 static void *help_next(struct seq_file *m, void *v, loff_t *pos)
 {
+	(*pos)++;
 	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_next: start\n");
 
 	return NULL;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/reiserfs/stree.c linux-libre-5.4.22-gnu/fs/reiserfs/stree.c
--- linux-libre-5.4.21-gnu/fs/reiserfs/stree.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/reiserfs/stree.c	2020-02-24 02:37:04.000000000 -0500
@@ -2246,7 +2246,8 @@ error_out:
 	/* also releases the path */
 	unfix_nodes(&s_ins_balance);
 #ifdef REISERQUOTA_DEBUG
-	reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE,
+	if (inode)
+		reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE,
 		       "reiserquota insert_item(): freeing %u id=%u type=%c",
 		       quota_bytes, inode->i_uid, head2type(ih));
 #endif
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/reiserfs/super.c linux-libre-5.4.22-gnu/fs/reiserfs/super.c
--- linux-libre-5.4.21-gnu/fs/reiserfs/super.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/reiserfs/super.c	2020-02-24 02:37:04.000000000 -0500
@@ -1948,7 +1948,7 @@ static int reiserfs_fill_super(struct su
 		if (!sbi->s_jdev) {
 			SWARN(silent, s, "", "Cannot allocate memory for "
 				"journal device name");
-			goto error;
+			goto error_unlocked;
 		}
 	}
 #ifdef CONFIG_QUOTA
diff -druNp --no-dereference linux-libre-5.4.21-gnu/fs/udf/super.c linux-libre-5.4.22-gnu/fs/udf/super.c
--- linux-libre-5.4.21-gnu/fs/udf/super.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/fs/udf/super.c	2020-02-24 02:37:04.000000000 -0500
@@ -1035,7 +1035,6 @@ static int check_partition_desc(struct s
 	switch (le32_to_cpu(p->accessType)) {
 	case PD_ACCESS_TYPE_READ_ONLY:
 	case PD_ACCESS_TYPE_WRITE_ONCE:
-	case PD_ACCESS_TYPE_REWRITABLE:
 	case PD_ACCESS_TYPE_NONE:
 		goto force_ro;
 	}
@@ -2492,17 +2491,29 @@ static unsigned int udf_count_free_table
 static unsigned int udf_count_free(struct super_block *sb)
 {
 	unsigned int accum = 0;
-	struct udf_sb_info *sbi;
+	struct udf_sb_info *sbi = UDF_SB(sb);
 	struct udf_part_map *map;
+	unsigned int part = sbi->s_partition;
+	int ptype = sbi->s_partmaps[part].s_partition_type;
+
+	if (ptype == UDF_METADATA_MAP25) {
+		part = sbi->s_partmaps[part].s_type_specific.s_metadata.
+							s_phys_partition_ref;
+	} else if (ptype == UDF_VIRTUAL_MAP15 || ptype == UDF_VIRTUAL_MAP20) {
+		/*
+		 * Filesystems with VAT are append-only and we cannot write to
+ 		 * them. Let's just report 0 here.
+		 */
+		return 0;
+	}
 
-	sbi = UDF_SB(sb);
 	if (sbi->s_lvid_bh) {
 		struct logicalVolIntegrityDesc *lvid =
 			(struct logicalVolIntegrityDesc *)
 			sbi->s_lvid_bh->b_data;
-		if (le32_to_cpu(lvid->numOfPartitions) > sbi->s_partition) {
+		if (le32_to_cpu(lvid->numOfPartitions) > part) {
 			accum = le32_to_cpu(
-					lvid->freeSpaceTable[sbi->s_partition]);
+					lvid->freeSpaceTable[part]);
 			if (accum == 0xFFFFFFFF)
 				accum = 0;
 		}
@@ -2511,7 +2522,7 @@ static unsigned int udf_count_free(struc
 	if (accum)
 		return accum;
 
-	map = &sbi->s_partmaps[sbi->s_partition];
+	map = &sbi->s_partmaps[part];
 	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
 		accum += udf_count_free_bitmap(sb,
 					       map->s_uspace.s_bitmap);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/include/linux/cpuhotplug.h linux-libre-5.4.22-gnu/include/linux/cpuhotplug.h
--- linux-libre-5.4.21-gnu/include/linux/cpuhotplug.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/include/linux/cpuhotplug.h	2020-02-24 02:37:04.000000000 -0500
@@ -59,6 +59,7 @@ enum cpuhp_state {
 	CPUHP_IOMMU_INTEL_DEAD,
 	CPUHP_LUSTRE_CFS_DEAD,
 	CPUHP_AP_ARM_CACHE_B15_RAC_DEAD,
+	CPUHP_PADATA_DEAD,
 	CPUHP_WORKQUEUE_PREP,
 	CPUHP_POWER_NUMA_PREPARE,
 	CPUHP_HRTIMERS_PREPARE,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/include/linux/dmaengine.h linux-libre-5.4.22-gnu/include/linux/dmaengine.h
--- linux-libre-5.4.21-gnu/include/linux/dmaengine.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/include/linux/dmaengine.h	2020-02-24 02:37:04.000000000 -0500
@@ -674,6 +674,7 @@ struct dma_filter {
  * @fill_align: alignment shift for memset operations
  * @dev_id: unique device ID
  * @dev: struct device reference for dma mapping api
+ * @owner: owner module (automatically set based on the provided dev)
  * @src_addr_widths: bit mask of src addr widths the device supports
  *	Width is specified in bytes, e.g. for a device supporting
  *	a width of 4 the mask should have BIT(4) set.
@@ -737,6 +738,7 @@ struct dma_device {
 
 	int dev_id;
 	struct device *dev;
+	struct module *owner;
 
 	u32 src_addr_widths;
 	u32 dst_addr_widths;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/include/linux/list_nulls.h linux-libre-5.4.22-gnu/include/linux/list_nulls.h
--- linux-libre-5.4.21-gnu/include/linux/list_nulls.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/include/linux/list_nulls.h	2020-02-24 02:37:04.000000000 -0500
@@ -72,10 +72,10 @@ static inline void hlist_nulls_add_head(
 	struct hlist_nulls_node *first = h->first;
 
 	n->next = first;
-	n->pprev = &h->first;
+	WRITE_ONCE(n->pprev, &h->first);
 	h->first = n;
 	if (!is_a_nulls(first))
-		first->pprev = &n->next;
+		WRITE_ONCE(first->pprev, &n->next);
 }
 
 static inline void __hlist_nulls_del(struct hlist_nulls_node *n)
@@ -85,13 +85,13 @@ static inline void __hlist_nulls_del(str
 
 	WRITE_ONCE(*pprev, next);
 	if (!is_a_nulls(next))
-		next->pprev = pprev;
+		WRITE_ONCE(next->pprev, pprev);
 }
 
 static inline void hlist_nulls_del(struct hlist_nulls_node *n)
 {
 	__hlist_nulls_del(n);
-	n->pprev = LIST_POISON2;
+	WRITE_ONCE(n->pprev, LIST_POISON2);
 }
 
 /**
diff -druNp --no-dereference linux-libre-5.4.21-gnu/include/linux/pci.h linux-libre-5.4.22-gnu/include/linux/pci.h
--- linux-libre-5.4.21-gnu/include/linux/pci.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/include/linux/pci.h	2020-02-24 02:37:04.000000000 -0500
@@ -2324,7 +2324,7 @@ static inline struct eeh_dev *pci_dev_to
 }
 #endif
 
-void pci_add_dma_alias(struct pci_dev *dev, u8 devfn);
+void pci_add_dma_alias(struct pci_dev *dev, u8 devfn_from, unsigned nr_devfns);
 bool pci_devs_are_dma_aliases(struct pci_dev *dev1, struct pci_dev *dev2);
 int pci_for_each_dma_alias(struct pci_dev *pdev,
 			   int (*fn)(struct pci_dev *pdev,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/include/linux/platform_data/ti-sysc.h linux-libre-5.4.22-gnu/include/linux/platform_data/ti-sysc.h
--- linux-libre-5.4.21-gnu/include/linux/platform_data/ti-sysc.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/include/linux/platform_data/ti-sysc.h	2020-02-24 02:37:04.000000000 -0500
@@ -49,6 +49,7 @@ struct sysc_regbits {
 	s8 emufree_shift;
 };
 
+#define SYSC_QUIRK_CLKDM_NOAUTO		BIT(21)
 #define SYSC_QUIRK_FORCE_MSTANDBY	BIT(20)
 #define SYSC_MODULE_QUIRK_AESS		BIT(19)
 #define SYSC_MODULE_QUIRK_SGX		BIT(18)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/include/linux/raid/pq.h linux-libre-5.4.22-gnu/include/linux/raid/pq.h
--- linux-libre-5.4.21-gnu/include/linux/raid/pq.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/include/linux/raid/pq.h	2020-02-24 02:37:04.000000000 -0500
@@ -27,7 +27,6 @@ extern const char raid6_empty_zero_page[
 
 #include <errno.h>
 #include <inttypes.h>
-#include <limits.h>
 #include <stddef.h>
 #include <sys/mman.h>
 #include <sys/time.h>
@@ -59,7 +58,9 @@ extern const char raid6_empty_zero_page[
 #define enable_kernel_altivec()
 #define disable_kernel_altivec()
 
+#undef	EXPORT_SYMBOL
 #define EXPORT_SYMBOL(sym)
+#undef	EXPORT_SYMBOL_GPL
 #define EXPORT_SYMBOL_GPL(sym)
 #define MODULE_LICENSE(licence)
 #define MODULE_DESCRIPTION(desc)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/include/linux/rculist_nulls.h linux-libre-5.4.22-gnu/include/linux/rculist_nulls.h
--- linux-libre-5.4.21-gnu/include/linux/rculist_nulls.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/include/linux/rculist_nulls.h	2020-02-24 02:37:04.000000000 -0500
@@ -34,7 +34,7 @@ static inline void hlist_nulls_del_init_
 {
 	if (!hlist_nulls_unhashed(n)) {
 		__hlist_nulls_del(n);
-		n->pprev = NULL;
+		WRITE_ONCE(n->pprev, NULL);
 	}
 }
 
@@ -66,7 +66,7 @@ static inline void hlist_nulls_del_init_
 static inline void hlist_nulls_del_rcu(struct hlist_nulls_node *n)
 {
 	__hlist_nulls_del(n);
-	n->pprev = LIST_POISON2;
+	WRITE_ONCE(n->pprev, LIST_POISON2);
 }
 
 /**
@@ -94,10 +94,10 @@ static inline void hlist_nulls_add_head_
 	struct hlist_nulls_node *first = h->first;
 
 	n->next = first;
-	n->pprev = &h->first;
+	WRITE_ONCE(n->pprev, &h->first);
 	rcu_assign_pointer(hlist_nulls_first_rcu(h), n);
 	if (!is_a_nulls(first))
-		first->pprev = &n->next;
+		WRITE_ONCE(first->pprev, &n->next);
 }
 
 /**
diff -druNp --no-dereference linux-libre-5.4.21-gnu/include/media/v4l2-device.h linux-libre-5.4.22-gnu/include/media/v4l2-device.h
--- linux-libre-5.4.21-gnu/include/media/v4l2-device.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/include/media/v4l2-device.h	2020-02-24 02:37:04.000000000 -0500
@@ -371,7 +371,7 @@ static inline bool v4l2_device_supports_
 		struct v4l2_subdev *__sd;				\
 									\
 		__v4l2_device_call_subdevs_p(v4l2_dev, __sd,		\
-			!(grpid) || __sd->grp_id == (grpid), o, f ,	\
+			(grpid) == 0 || __sd->grp_id == (grpid), o, f ,	\
 			##args);					\
 	} while (0)
 
@@ -403,7 +403,7 @@ static inline bool v4l2_device_supports_
 ({									\
 	struct v4l2_subdev *__sd;					\
 	__v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd,		\
-			!(grpid) || __sd->grp_id == (grpid), o, f ,	\
+			(grpid) == 0 || __sd->grp_id == (grpid), o, f ,	\
 			##args);					\
 })
 
@@ -431,8 +431,8 @@ static inline bool v4l2_device_supports_
 		struct v4l2_subdev *__sd;				\
 									\
 		__v4l2_device_call_subdevs_p(v4l2_dev, __sd,		\
-			!(grpmsk) || (__sd->grp_id & (grpmsk)), o, f ,	\
-			##args);					\
+			(grpmsk) == 0 || (__sd->grp_id & (grpmsk)), o,	\
+			f , ##args);					\
 	} while (0)
 
 /**
@@ -462,8 +462,8 @@ static inline bool v4l2_device_supports_
 ({									\
 	struct v4l2_subdev *__sd;					\
 	__v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd,		\
-			!(grpmsk) || (__sd->grp_id & (grpmsk)), o, f ,	\
-			##args);					\
+			(grpmsk) == 0 || (__sd->grp_id & (grpmsk)), o,	\
+			f , ##args);					\
 })
 
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/include/rdma/ib_verbs.h linux-libre-5.4.22-gnu/include/rdma/ib_verbs.h
--- linux-libre-5.4.21-gnu/include/rdma/ib_verbs.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/include/rdma/ib_verbs.h	2020-02-24 02:37:04.000000000 -0500
@@ -2146,7 +2146,6 @@ struct ib_port_cache {
 
 struct ib_cache {
 	rwlock_t                lock;
-	struct ib_event_handler event_handler;
 };
 
 struct ib_port_immutable {
@@ -2590,7 +2589,11 @@ struct ib_device {
 	struct rcu_head rcu_head;
 
 	struct list_head              event_handler_list;
-	spinlock_t                    event_handler_lock;
+	/* Protects event_handler_list */
+	struct rw_semaphore event_handler_rwsem;
+
+	/* Protects QP's event_handler calls and open_qp list */
+	spinlock_t event_handler_lock;
 
 	struct rw_semaphore	      client_data_rwsem;
 	struct xarray                 client_data;
@@ -2897,7 +2900,7 @@ bool ib_modify_qp_is_ok(enum ib_qp_state
 
 void ib_register_event_handler(struct ib_event_handler *event_handler);
 void ib_unregister_event_handler(struct ib_event_handler *event_handler);
-void ib_dispatch_event(struct ib_event *event);
+void ib_dispatch_event(const struct ib_event *event);
 
 int ib_query_port(struct ib_device *device,
 		  u8 port_num, struct ib_port_attr *port_attr);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/include/trace/events/rcu.h linux-libre-5.4.22-gnu/include/trace/events/rcu.h
--- linux-libre-5.4.21-gnu/include/trace/events/rcu.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/include/trace/events/rcu.h	2020-02-24 02:37:04.000000000 -0500
@@ -442,7 +442,7 @@ TRACE_EVENT_RCU(rcu_fqs,
  */
 TRACE_EVENT_RCU(rcu_dyntick,
 
-	TP_PROTO(const char *polarity, long oldnesting, long newnesting, atomic_t dynticks),
+	TP_PROTO(const char *polarity, long oldnesting, long newnesting, int dynticks),
 
 	TP_ARGS(polarity, oldnesting, newnesting, dynticks),
 
@@ -457,7 +457,7 @@ TRACE_EVENT_RCU(rcu_dyntick,
 		__entry->polarity = polarity;
 		__entry->oldnesting = oldnesting;
 		__entry->newnesting = newnesting;
-		__entry->dynticks = atomic_read(&dynticks);
+		__entry->dynticks = dynticks;
 	),
 
 	TP_printk("%s %lx %lx %#3x", __entry->polarity,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/bpf/inode.c linux-libre-5.4.22-gnu/kernel/bpf/inode.c
--- linux-libre-5.4.21-gnu/kernel/bpf/inode.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/bpf/inode.c	2020-02-24 02:37:04.000000000 -0500
@@ -196,6 +196,7 @@ static void *map_seq_next(struct seq_fil
 	void *key = map_iter(m)->key;
 	void *prev_key;
 
+	(*pos)++;
 	if (map_iter(m)->done)
 		return NULL;
 
@@ -208,8 +209,6 @@ static void *map_seq_next(struct seq_fil
 		map_iter(m)->done = true;
 		return NULL;
 	}
-
-	++(*pos);
 	return key;
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/cpu.c linux-libre-5.4.22-gnu/kernel/cpu.c
--- linux-libre-5.4.21-gnu/kernel/cpu.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/cpu.c	2020-02-24 02:37:04.000000000 -0500
@@ -525,8 +525,7 @@ static int bringup_wait_for_ap(unsigned
 	if (WARN_ON_ONCE((!cpu_online(cpu))))
 		return -ECANCELED;
 
-	/* Unpark the stopper thread and the hotplug thread of the target cpu */
-	stop_machine_unpark(cpu);
+	/* Unpark the hotplug thread of the target cpu */
 	kthread_unpark(st->thread);
 
 	/*
@@ -1089,8 +1088,8 @@ void notify_cpu_starting(unsigned int cp
 
 /*
  * Called from the idle task. Wake up the controlling task which brings the
- * stopper and the hotplug thread of the upcoming CPU up and then delegates
- * the rest of the online bringup to the hotplug thread.
+ * hotplug thread of the upcoming CPU up and then delegates the rest of the
+ * online bringup to the hotplug thread.
  */
 void cpuhp_online_idle(enum cpuhp_state state)
 {
@@ -1100,6 +1099,12 @@ void cpuhp_online_idle(enum cpuhp_state
 	if (state != CPUHP_AP_ONLINE_IDLE)
 		return;
 
+	/*
+	 * Unpart the stopper thread before we start the idle loop (and start
+	 * scheduling); this ensures the stopper task is always available.
+	 */
+	stop_machine_unpark(smp_processor_id());
+
 	st->state = CPUHP_AP_ONLINE_IDLE;
 	complete_ap_thread(st, true);
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/module.c linux-libre-5.4.22-gnu/kernel/module.c
--- linux-libre-5.4.21-gnu/kernel/module.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/module.c	2020-02-24 02:37:04.000000000 -0500
@@ -214,7 +214,8 @@ static struct module *mod_find(unsigned
 {
 	struct module *mod;
 
-	list_for_each_entry_rcu(mod, &modules, list) {
+	list_for_each_entry_rcu(mod, &modules, list,
+				lockdep_is_held(&module_mutex)) {
 		if (within_module(addr, mod))
 			return mod;
 	}
@@ -448,7 +449,8 @@ bool each_symbol_section(bool (*fn)(cons
 	if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data))
 		return true;
 
-	list_for_each_entry_rcu(mod, &modules, list) {
+	list_for_each_entry_rcu(mod, &modules, list,
+				lockdep_is_held(&module_mutex)) {
 		struct symsearch arr[] = {
 			{ mod->syms, mod->syms + mod->num_syms, mod->crcs,
 			  NOT_GPL_ONLY, false },
@@ -616,7 +618,8 @@ static struct module *find_module_all(co
 
 	module_assert_mutex_or_preempt();
 
-	list_for_each_entry_rcu(mod, &modules, list) {
+	list_for_each_entry_rcu(mod, &modules, list,
+				lockdep_is_held(&module_mutex)) {
 		if (!even_unformed && mod->state == MODULE_STATE_UNFORMED)
 			continue;
 		if (strlen(mod->name) == len && !memcmp(mod->name, name, len))
@@ -1781,6 +1784,8 @@ static int module_add_modinfo_attrs(stru
 error_out:
 	if (i > 0)
 		module_remove_modinfo_attrs(mod, --i);
+	else
+		kfree(mod->modinfo_attrs);
 	return error;
 }
 
@@ -3054,9 +3059,7 @@ static int setup_load_info(struct load_i
 
 	/* Try to find a name early so we can log errors with a module name */
 	info->index.info = find_sec(info, ".modinfo");
-	if (!info->index.info)
-		info->name = "(missing .modinfo section)";
-	else
+	if (info->index.info)
 		info->name = get_modinfo(info, "name");
 
 	/* Find internal symbols and strings. */
@@ -3071,14 +3074,15 @@ static int setup_load_info(struct load_i
 	}
 
 	if (info->index.sym == 0) {
-		pr_warn("%s: module has no symbols (stripped?)\n", info->name);
+		pr_warn("%s: module has no symbols (stripped?)\n",
+			info->name ?: "(missing .modinfo section or name field)");
 		return -ENOEXEC;
 	}
 
 	info->index.mod = find_sec(info, ".gnu.linkonce.this_module");
 	if (!info->index.mod) {
 		pr_warn("%s: No module found in object\n",
-			info->name ?: "(missing .modinfo name field)");
+			info->name ?: "(missing .modinfo section or name field)");
 		return -ENOEXEC;
 	}
 	/* This is temporary: point mod into copy of data. */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/padata.c linux-libre-5.4.22-gnu/kernel/padata.c
--- linux-libre-5.4.21-gnu/kernel/padata.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/padata.c	2020-02-24 02:37:04.000000000 -0500
@@ -512,7 +512,7 @@ static int padata_replace_one(struct pad
 	return 0;
 }
 
-static int padata_replace(struct padata_instance *pinst, int cpu)
+static int padata_replace(struct padata_instance *pinst)
 {
 	int notification_mask = 0;
 	struct padata_shell *ps;
@@ -523,16 +523,12 @@ static int padata_replace(struct padata_
 	cpumask_copy(pinst->omask, pinst->rcpumask.pcpu);
 	cpumask_and(pinst->rcpumask.pcpu, pinst->cpumask.pcpu,
 		    cpu_online_mask);
-	if (cpu >= 0)
-		cpumask_clear_cpu(cpu, pinst->rcpumask.pcpu);
 	if (!cpumask_equal(pinst->omask, pinst->rcpumask.pcpu))
 		notification_mask |= PADATA_CPU_PARALLEL;
 
 	cpumask_copy(pinst->omask, pinst->rcpumask.cbcpu);
 	cpumask_and(pinst->rcpumask.cbcpu, pinst->cpumask.cbcpu,
 		    cpu_online_mask);
-	if (cpu >= 0)
-		cpumask_clear_cpu(cpu, pinst->rcpumask.cbcpu);
 	if (!cpumask_equal(pinst->omask, pinst->rcpumask.cbcpu))
 		notification_mask |= PADATA_CPU_SERIAL;
 
@@ -624,7 +620,7 @@ out_replace:
 	cpumask_copy(pinst->cpumask.pcpu, pcpumask);
 	cpumask_copy(pinst->cpumask.cbcpu, cbcpumask);
 
-	err = padata_setup_cpumasks(pinst) ?: padata_replace(pinst, -1);
+	err = padata_setup_cpumasks(pinst) ?: padata_replace(pinst);
 
 	if (valid)
 		__padata_start(pinst);
@@ -715,7 +711,7 @@ static int __padata_add_cpu(struct padat
 	int err = 0;
 
 	if (cpumask_test_cpu(cpu, cpu_online_mask)) {
-		err = padata_replace(pinst, -1);
+		err = padata_replace(pinst);
 
 		if (padata_validate_cpumask(pinst, pinst->cpumask.pcpu) &&
 		    padata_validate_cpumask(pinst, pinst->cpumask.cbcpu))
@@ -729,12 +725,12 @@ static int __padata_remove_cpu(struct pa
 {
 	int err = 0;
 
-	if (cpumask_test_cpu(cpu, cpu_online_mask)) {
+	if (!cpumask_test_cpu(cpu, cpu_online_mask)) {
 		if (!padata_validate_cpumask(pinst, pinst->cpumask.pcpu) ||
 		    !padata_validate_cpumask(pinst, pinst->cpumask.cbcpu))
 			__padata_stop(pinst);
 
-		err = padata_replace(pinst, cpu);
+		err = padata_replace(pinst);
 	}
 
 	return err;
@@ -796,7 +792,7 @@ static int padata_cpu_online(unsigned in
 	return ret;
 }
 
-static int padata_cpu_prep_down(unsigned int cpu, struct hlist_node *node)
+static int padata_cpu_dead(unsigned int cpu, struct hlist_node *node)
 {
 	struct padata_instance *pinst;
 	int ret;
@@ -817,6 +813,7 @@ static enum cpuhp_state hp_online;
 static void __padata_free(struct padata_instance *pinst)
 {
 #ifdef CONFIG_HOTPLUG_CPU
+	cpuhp_state_remove_instance_nocalls(CPUHP_PADATA_DEAD, &pinst->node);
 	cpuhp_state_remove_instance_nocalls(hp_online, &pinst->node);
 #endif
 
@@ -1024,6 +1021,8 @@ static struct padata_instance *padata_al
 
 #ifdef CONFIG_HOTPLUG_CPU
 	cpuhp_state_add_instance_nocalls_cpuslocked(hp_online, &pinst->node);
+	cpuhp_state_add_instance_nocalls_cpuslocked(CPUHP_PADATA_DEAD,
+						    &pinst->node);
 #endif
 
 	put_online_cpus();
@@ -1136,17 +1135,24 @@ static __init int padata_driver_init(voi
 	int ret;
 
 	ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "padata:online",
-				      padata_cpu_online,
-				      padata_cpu_prep_down);
+				      padata_cpu_online, NULL);
 	if (ret < 0)
 		return ret;
 	hp_online = ret;
+
+	ret = cpuhp_setup_state_multi(CPUHP_PADATA_DEAD, "padata:dead",
+				      NULL, padata_cpu_dead);
+	if (ret < 0) {
+		cpuhp_remove_multi_state(hp_online);
+		return ret;
+	}
 	return 0;
 }
 module_init(padata_driver_init);
 
 static __exit void padata_driver_exit(void)
 {
+	cpuhp_remove_multi_state(CPUHP_PADATA_DEAD);
 	cpuhp_remove_multi_state(hp_online);
 }
 module_exit(padata_driver_exit);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/printk/printk.c linux-libre-5.4.22-gnu/kernel/printk/printk.c
--- linux-libre-5.4.21-gnu/kernel/printk/printk.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/printk/printk.c	2020-02-24 02:37:04.000000000 -0500
@@ -2770,8 +2770,6 @@ void register_console(struct console *ne
 		 * for us.
 		 */
 		logbuf_lock_irqsave(flags);
-		console_seq = syslog_seq;
-		console_idx = syslog_idx;
 		/*
 		 * We're about to replay the log buffer.  Only do this to the
 		 * just-registered console to avoid excessive message spam to
@@ -2783,6 +2781,8 @@ void register_console(struct console *ne
 		 */
 		exclusive_console = newcon;
 		exclusive_console_stop_seq = console_seq;
+		console_seq = syslog_seq;
+		console_idx = syslog_idx;
 		logbuf_unlock_irqrestore(flags);
 	}
 	console_unlock();
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/rcu/tree.c linux-libre-5.4.22-gnu/kernel/rcu/tree.c
--- linux-libre-5.4.21-gnu/kernel/rcu/tree.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/rcu/tree.c	2020-02-24 02:37:04.000000000 -0500
@@ -576,7 +576,7 @@ static void rcu_eqs_enter(bool user)
 	}
 
 	lockdep_assert_irqs_disabled();
-	trace_rcu_dyntick(TPS("Start"), rdp->dynticks_nesting, 0, rdp->dynticks);
+	trace_rcu_dyntick(TPS("Start"), rdp->dynticks_nesting, 0, atomic_read(&rdp->dynticks));
 	WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !user && !is_idle_task(current));
 	rdp = this_cpu_ptr(&rcu_data);
 	do_nocb_deferred_wakeup(rdp);
@@ -649,14 +649,15 @@ static __always_inline void rcu_nmi_exit
 	 * leave it in non-RCU-idle state.
 	 */
 	if (rdp->dynticks_nmi_nesting != 1) {
-		trace_rcu_dyntick(TPS("--="), rdp->dynticks_nmi_nesting, rdp->dynticks_nmi_nesting - 2, rdp->dynticks);
+		trace_rcu_dyntick(TPS("--="), rdp->dynticks_nmi_nesting, rdp->dynticks_nmi_nesting - 2,
+				  atomic_read(&rdp->dynticks));
 		WRITE_ONCE(rdp->dynticks_nmi_nesting, /* No store tearing. */
 			   rdp->dynticks_nmi_nesting - 2);
 		return;
 	}
 
 	/* This NMI interrupted an RCU-idle CPU, restore RCU-idleness. */
-	trace_rcu_dyntick(TPS("Startirq"), rdp->dynticks_nmi_nesting, 0, rdp->dynticks);
+	trace_rcu_dyntick(TPS("Startirq"), rdp->dynticks_nmi_nesting, 0, atomic_read(&rdp->dynticks));
 	WRITE_ONCE(rdp->dynticks_nmi_nesting, 0); /* Avoid store tearing. */
 
 	if (irq)
@@ -743,7 +744,7 @@ static void rcu_eqs_exit(bool user)
 	rcu_dynticks_task_exit();
 	rcu_dynticks_eqs_exit();
 	rcu_cleanup_after_idle();
-	trace_rcu_dyntick(TPS("End"), rdp->dynticks_nesting, 1, rdp->dynticks);
+	trace_rcu_dyntick(TPS("End"), rdp->dynticks_nesting, 1, atomic_read(&rdp->dynticks));
 	WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !user && !is_idle_task(current));
 	WRITE_ONCE(rdp->dynticks_nesting, 1);
 	WARN_ON_ONCE(rdp->dynticks_nmi_nesting);
@@ -827,7 +828,7 @@ static __always_inline void rcu_nmi_ente
 	}
 	trace_rcu_dyntick(incby == 1 ? TPS("Endirq") : TPS("++="),
 			  rdp->dynticks_nmi_nesting,
-			  rdp->dynticks_nmi_nesting + incby, rdp->dynticks);
+			  rdp->dynticks_nmi_nesting + incby, atomic_read(&rdp->dynticks));
 	WRITE_ONCE(rdp->dynticks_nmi_nesting, /* Prevent store tearing. */
 		   rdp->dynticks_nmi_nesting + incby);
 	barrier();
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/rcu/tree_exp.h linux-libre-5.4.22-gnu/kernel/rcu/tree_exp.h
--- linux-libre-5.4.21-gnu/kernel/rcu/tree_exp.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/rcu/tree_exp.h	2020-02-24 02:37:04.000000000 -0500
@@ -558,7 +558,7 @@ static void rcu_exp_wait_wake(unsigned l
 			spin_unlock(&rnp->exp_lock);
 		}
 		smp_mb(); /* All above changes before wakeup. */
-		wake_up_all(&rnp->exp_wq[rcu_seq_ctr(rcu_state.expedited_sequence) & 0x3]);
+		wake_up_all(&rnp->exp_wq[rcu_seq_ctr(s) & 0x3]);
 	}
 	trace_rcu_exp_grace_period(rcu_state.name, s, TPS("endwake"));
 	mutex_unlock(&rcu_state.exp_wake_mutex);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/rcu/tree_plugin.h linux-libre-5.4.22-gnu/kernel/rcu/tree_plugin.h
--- linux-libre-5.4.21-gnu/kernel/rcu/tree_plugin.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/rcu/tree_plugin.h	2020-02-24 02:37:04.000000000 -0500
@@ -2322,6 +2322,8 @@ static void __init rcu_organize_nocb_kth
 {
 	int cpu;
 	bool firsttime = true;
+	bool gotnocbs = false;
+	bool gotnocbscbs = true;
 	int ls = rcu_nocb_gp_stride;
 	int nl = 0;  /* Next GP kthread. */
 	struct rcu_data *rdp;
@@ -2344,21 +2346,31 @@ static void __init rcu_organize_nocb_kth
 		rdp = per_cpu_ptr(&rcu_data, cpu);
 		if (rdp->cpu >= nl) {
 			/* New GP kthread, set up for CBs & next GP. */
+			gotnocbs = true;
 			nl = DIV_ROUND_UP(rdp->cpu + 1, ls) * ls;
 			rdp->nocb_gp_rdp = rdp;
 			rdp_gp = rdp;
-			if (!firsttime && dump_tree)
-				pr_cont("\n");
-			firsttime = false;
-			pr_alert("%s: No-CB GP kthread CPU %d:", __func__, cpu);
+			if (dump_tree) {
+				if (!firsttime)
+					pr_cont("%s\n", gotnocbscbs
+							? "" : " (self only)");
+				gotnocbscbs = false;
+				firsttime = false;
+				pr_alert("%s: No-CB GP kthread CPU %d:",
+					 __func__, cpu);
+			}
 		} else {
 			/* Another CB kthread, link to previous GP kthread. */
+			gotnocbscbs = true;
 			rdp->nocb_gp_rdp = rdp_gp;
 			rdp_prev->nocb_next_cb_rdp = rdp;
-			pr_alert(" %d", cpu);
+			if (dump_tree)
+				pr_cont(" %d", cpu);
 		}
 		rdp_prev = rdp;
 	}
+	if (gotnocbs && dump_tree)
+		pr_cont("%s\n", gotnocbscbs ? "" : " (self only)");
 }
 
 /*
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/sched/core.c linux-libre-5.4.22-gnu/kernel/sched/core.c
--- linux-libre-5.4.21-gnu/kernel/sched/core.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/sched/core.c	2020-02-24 02:37:04.000000000 -0500
@@ -1252,7 +1252,8 @@ static void __init init_uclamp(void)
 	mutex_init(&uclamp_mutex);
 
 	for_each_possible_cpu(cpu) {
-		memset(&cpu_rq(cpu)->uclamp, 0, sizeof(struct uclamp_rq));
+		memset(&cpu_rq(cpu)->uclamp, 0,
+				sizeof(struct uclamp_rq)*UCLAMP_CNT);
 		cpu_rq(cpu)->uclamp_flags = 0;
 	}
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/sched/topology.c linux-libre-5.4.22-gnu/kernel/sched/topology.c
--- linux-libre-5.4.21-gnu/kernel/sched/topology.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/sched/topology.c	2020-02-24 02:37:04.000000000 -0500
@@ -1883,6 +1883,42 @@ static struct sched_domain *build_sched_
 }
 
 /*
+ * Ensure topology masks are sane, i.e. there are no conflicts (overlaps) for
+ * any two given CPUs at this (non-NUMA) topology level.
+ */
+static bool topology_span_sane(struct sched_domain_topology_level *tl,
+			      const struct cpumask *cpu_map, int cpu)
+{
+	int i;
+
+	/* NUMA levels are allowed to overlap */
+	if (tl->flags & SDTL_OVERLAP)
+		return true;
+
+	/*
+	 * Non-NUMA levels cannot partially overlap - they must be either
+	 * completely equal or completely disjoint. Otherwise we can end up
+	 * breaking the sched_group lists - i.e. a later get_group() pass
+	 * breaks the linking done for an earlier span.
+	 */
+	for_each_cpu(i, cpu_map) {
+		if (i == cpu)
+			continue;
+		/*
+		 * We should 'and' all those masks with 'cpu_map' to exactly
+		 * match the topology we're about to build, but that can only
+		 * remove CPUs, which only lessens our ability to detect
+		 * overlaps
+		 */
+		if (!cpumask_equal(tl->mask(cpu), tl->mask(i)) &&
+		    cpumask_intersects(tl->mask(cpu), tl->mask(i)))
+			return false;
+	}
+
+	return true;
+}
+
+/*
  * Find the sched_domain_topology_level where all CPU capacities are visible
  * for all CPUs.
  */
@@ -1978,6 +2014,9 @@ build_sched_domains(const struct cpumask
 				has_asym = true;
 			}
 
+			if (WARN_ON(!topology_span_sane(tl, cpu_map, i)))
+				goto error;
+
 			sd = build_sched_domain(tl, cpu_map, attr, sd, dflags, i);
 
 			if (tl == sched_domain_topology)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/time/alarmtimer.c linux-libre-5.4.22-gnu/kernel/time/alarmtimer.c
--- linux-libre-5.4.21-gnu/kernel/time/alarmtimer.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/time/alarmtimer.c	2020-02-24 02:37:04.000000000 -0500
@@ -88,6 +88,7 @@ static int alarmtimer_rtc_add_device(str
 	unsigned long flags;
 	struct rtc_device *rtc = to_rtc_device(dev);
 	struct wakeup_source *__ws;
+	struct platform_device *pdev;
 	int ret = 0;
 
 	if (rtcdev)
@@ -99,9 +100,11 @@ static int alarmtimer_rtc_add_device(str
 		return -1;
 
 	__ws = wakeup_source_register(dev, "alarmtimer");
+	pdev = platform_device_register_data(dev, "alarmtimer",
+					     PLATFORM_DEVID_AUTO, NULL, 0);
 
 	spin_lock_irqsave(&rtcdev_lock, flags);
-	if (!rtcdev) {
+	if (__ws && !IS_ERR(pdev) && !rtcdev) {
 		if (!try_module_get(rtc->owner)) {
 			ret = -1;
 			goto unlock;
@@ -112,10 +115,14 @@ static int alarmtimer_rtc_add_device(str
 		get_device(dev);
 		ws = __ws;
 		__ws = NULL;
+		pdev = NULL;
+	} else {
+		ret = -1;
 	}
 unlock:
 	spin_unlock_irqrestore(&rtcdev_lock, flags);
 
+	platform_device_unregister(pdev);
 	wakeup_source_unregister(__ws);
 
 	return ret;
@@ -876,8 +883,7 @@ static struct platform_driver alarmtimer
  */
 static int __init alarmtimer_init(void)
 {
-	struct platform_device *pdev;
-	int error = 0;
+	int error;
 	int i;
 
 	alarmtimer_rtc_timer_init();
@@ -900,15 +906,7 @@ static int __init alarmtimer_init(void)
 	if (error)
 		goto out_if;
 
-	pdev = platform_device_register_simple("alarmtimer", -1, NULL, 0);
-	if (IS_ERR(pdev)) {
-		error = PTR_ERR(pdev);
-		goto out_drv;
-	}
 	return 0;
-
-out_drv:
-	platform_driver_unregister(&alarmtimer_driver);
 out_if:
 	alarmtimer_rtc_interface_remove();
 	return error;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/trace/ftrace.c linux-libre-5.4.22-gnu/kernel/trace/ftrace.c
--- linux-libre-5.4.21-gnu/kernel/trace/ftrace.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/trace/ftrace.c	2020-02-24 02:37:04.000000000 -0500
@@ -6537,9 +6537,10 @@ static void *fpid_next(struct seq_file *
 	struct trace_array *tr = m->private;
 	struct trace_pid_list *pid_list = rcu_dereference_sched(tr->function_pids);
 
-	if (v == FTRACE_NO_PIDS)
+	if (v == FTRACE_NO_PIDS) {
+		(*pos)++;
 		return NULL;
-
+	}
 	return trace_pid_next(pid_list, v, pos);
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/trace/trace_events_hist.c linux-libre-5.4.22-gnu/kernel/trace/trace_events_hist.c
--- linux-libre-5.4.21-gnu/kernel/trace/trace_events_hist.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/trace/trace_events_hist.c	2020-02-24 02:37:04.000000000 -0500
@@ -2037,12 +2037,6 @@ static int parse_map_size(char *str)
 	unsigned long size, map_bits;
 	int ret;
 
-	strsep(&str, "=");
-	if (!str) {
-		ret = -EINVAL;
-		goto out;
-	}
-
 	ret = kstrtoul(str, 0, &size);
 	if (ret)
 		goto out;
@@ -2102,25 +2096,25 @@ static int parse_action(char *str, struc
 static int parse_assignment(struct trace_array *tr,
 			    char *str, struct hist_trigger_attrs *attrs)
 {
-	int ret = 0;
+	int len, ret = 0;
 
-	if ((str_has_prefix(str, "key=")) ||
-	    (str_has_prefix(str, "keys="))) {
-		attrs->keys_str = kstrdup(str, GFP_KERNEL);
+	if ((len = str_has_prefix(str, "key=")) ||
+	    (len = str_has_prefix(str, "keys="))) {
+		attrs->keys_str = kstrdup(str + len, GFP_KERNEL);
 		if (!attrs->keys_str) {
 			ret = -ENOMEM;
 			goto out;
 		}
-	} else if ((str_has_prefix(str, "val=")) ||
-		   (str_has_prefix(str, "vals=")) ||
-		   (str_has_prefix(str, "values="))) {
-		attrs->vals_str = kstrdup(str, GFP_KERNEL);
+	} else if ((len = str_has_prefix(str, "val=")) ||
+		   (len = str_has_prefix(str, "vals=")) ||
+		   (len = str_has_prefix(str, "values="))) {
+		attrs->vals_str = kstrdup(str + len, GFP_KERNEL);
 		if (!attrs->vals_str) {
 			ret = -ENOMEM;
 			goto out;
 		}
-	} else if (str_has_prefix(str, "sort=")) {
-		attrs->sort_key_str = kstrdup(str, GFP_KERNEL);
+	} else if ((len = str_has_prefix(str, "sort="))) {
+		attrs->sort_key_str = kstrdup(str + len, GFP_KERNEL);
 		if (!attrs->sort_key_str) {
 			ret = -ENOMEM;
 			goto out;
@@ -2131,12 +2125,8 @@ static int parse_assignment(struct trace
 			ret = -ENOMEM;
 			goto out;
 		}
-	} else if (str_has_prefix(str, "clock=")) {
-		strsep(&str, "=");
-		if (!str) {
-			ret = -EINVAL;
-			goto out;
-		}
+	} else if ((len = str_has_prefix(str, "clock="))) {
+		str += len;
 
 		str = strstrip(str);
 		attrs->clock = kstrdup(str, GFP_KERNEL);
@@ -2144,8 +2134,8 @@ static int parse_assignment(struct trace
 			ret = -ENOMEM;
 			goto out;
 		}
-	} else if (str_has_prefix(str, "size=")) {
-		int map_bits = parse_map_size(str);
+	} else if ((len = str_has_prefix(str, "size="))) {
+		int map_bits = parse_map_size(str + len);
 
 		if (map_bits < 0) {
 			ret = map_bits;
@@ -2185,8 +2175,14 @@ parse_hist_trigger_attrs(struct trace_ar
 
 	while (trigger_str) {
 		char *str = strsep(&trigger_str, ":");
+		char *rhs;
 
-		if (strchr(str, '=')) {
+		rhs = strchr(str, '=');
+		if (rhs) {
+			if (!strlen(++rhs)) {
+				ret = -EINVAL;
+				goto free;
+			}
 			ret = parse_assignment(tr, str, attrs);
 			if (ret)
 				goto free;
@@ -4559,10 +4555,6 @@ static int create_val_fields(struct hist
 	if (!fields_str)
 		goto out;
 
-	strsep(&fields_str, "=");
-	if (!fields_str)
-		goto out;
-
 	for (i = 0, j = 1; i < TRACING_MAP_VALS_MAX &&
 		     j < TRACING_MAP_VALS_MAX; i++) {
 		field_str = strsep(&fields_str, ",");
@@ -4657,10 +4649,6 @@ static int create_key_fields(struct hist
 	if (!fields_str)
 		goto out;
 
-	strsep(&fields_str, "=");
-	if (!fields_str)
-		goto out;
-
 	for (i = n_vals; i < n_vals + TRACING_MAP_KEYS_MAX; i++) {
 		field_str = strsep(&fields_str, ",");
 		if (!field_str)
@@ -4818,12 +4806,6 @@ static int create_sort_keys(struct hist_
 	if (!fields_str)
 		goto out;
 
-	strsep(&fields_str, "=");
-	if (!fields_str) {
-		ret = -EINVAL;
-		goto out;
-	}
-
 	for (i = 0; i < TRACING_MAP_SORT_KEYS_MAX; i++) {
 		struct hist_field *hist_field;
 		char *field_str, *field_name;
@@ -4832,9 +4814,11 @@ static int create_sort_keys(struct hist_
 		sort_key = &hist_data->sort_keys[i];
 
 		field_str = strsep(&fields_str, ",");
-		if (!field_str) {
-			if (i == 0)
-				ret = -EINVAL;
+		if (!field_str)
+			break;
+
+		if (!*field_str) {
+			ret = -EINVAL;
 			break;
 		}
 
@@ -4844,7 +4828,7 @@ static int create_sort_keys(struct hist_
 		}
 
 		field_name = strsep(&field_str, ".");
-		if (!field_name) {
+		if (!field_name || !*field_name) {
 			ret = -EINVAL;
 			break;
 		}
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/trace/trace_events_trigger.c linux-libre-5.4.22-gnu/kernel/trace/trace_events_trigger.c
--- linux-libre-5.4.21-gnu/kernel/trace/trace_events_trigger.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/trace/trace_events_trigger.c	2020-02-24 02:37:04.000000000 -0500
@@ -116,9 +116,10 @@ static void *trigger_next(struct seq_fil
 {
 	struct trace_event_file *event_file = event_file_data(m->private);
 
-	if (t == SHOW_AVAILABLE_TRIGGERS)
+	if (t == SHOW_AVAILABLE_TRIGGERS) {
+		(*pos)++;
 		return NULL;
-
+	}
 	return seq_list_next(t, &event_file->triggers, pos);
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/trace/trace_stat.c linux-libre-5.4.22-gnu/kernel/trace/trace_stat.c
--- linux-libre-5.4.21-gnu/kernel/trace/trace_stat.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/trace/trace_stat.c	2020-02-24 02:37:04.000000000 -0500
@@ -282,18 +282,22 @@ static int tracing_stat_init(void)
 
 	d_tracing = tracing_init_dentry();
 	if (IS_ERR(d_tracing))
-		return 0;
+		return -ENODEV;
 
 	stat_dir = tracefs_create_dir("trace_stat", d_tracing);
-	if (!stat_dir)
+	if (!stat_dir) {
 		pr_warn("Could not create tracefs 'trace_stat' entry\n");
+		return -ENOMEM;
+	}
 	return 0;
 }
 
 static int init_stat_file(struct stat_session *session)
 {
-	if (!stat_dir && tracing_stat_init())
-		return -ENODEV;
+	int ret;
+
+	if (!stat_dir && (ret = tracing_stat_init()))
+		return ret;
 
 	session->file = tracefs_create_file(session->ts->name, 0644,
 					    stat_dir,
@@ -306,7 +310,7 @@ static int init_stat_file(struct stat_se
 int register_stat_tracer(struct tracer_stat *trace)
 {
 	struct stat_session *session, *node;
-	int ret;
+	int ret = -EINVAL;
 
 	if (!trace)
 		return -EINVAL;
@@ -317,17 +321,15 @@ int register_stat_tracer(struct tracer_s
 	/* Already registered? */
 	mutex_lock(&all_stat_sessions_mutex);
 	list_for_each_entry(node, &all_stat_sessions, session_list) {
-		if (node->ts == trace) {
-			mutex_unlock(&all_stat_sessions_mutex);
-			return -EINVAL;
-		}
+		if (node->ts == trace)
+			goto out;
 	}
-	mutex_unlock(&all_stat_sessions_mutex);
 
+	ret = -ENOMEM;
 	/* Init the session */
 	session = kzalloc(sizeof(*session), GFP_KERNEL);
 	if (!session)
-		return -ENOMEM;
+		goto out;
 
 	session->ts = trace;
 	INIT_LIST_HEAD(&session->session_list);
@@ -336,15 +338,16 @@ int register_stat_tracer(struct tracer_s
 	ret = init_stat_file(session);
 	if (ret) {
 		destroy_session(session);
-		return ret;
+		goto out;
 	}
 
+	ret = 0;
 	/* Register */
-	mutex_lock(&all_stat_sessions_mutex);
 	list_add_tail(&session->session_list, &all_stat_sessions);
+ out:
 	mutex_unlock(&all_stat_sessions_mutex);
 
-	return 0;
+	return ret;
 }
 
 void unregister_stat_tracer(struct tracer_stat *trace)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/kernel/watchdog.c linux-libre-5.4.22-gnu/kernel/watchdog.c
--- linux-libre-5.4.21-gnu/kernel/watchdog.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/kernel/watchdog.c	2020-02-24 02:37:04.000000000 -0500
@@ -161,6 +161,8 @@ static void lockup_detector_update_enabl
 
 #ifdef CONFIG_SOFTLOCKUP_DETECTOR
 
+#define SOFTLOCKUP_RESET	ULONG_MAX
+
 /* Global variables, exported for sysctl */
 unsigned int __read_mostly softlockup_panic =
 			CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE;
@@ -274,7 +276,7 @@ notrace void touch_softlockup_watchdog_s
 	 * Preemption can be enabled.  It doesn't matter which CPU's timestamp
 	 * gets zeroed here, so use the raw_ operation.
 	 */
-	raw_cpu_write(watchdog_touch_ts, 0);
+	raw_cpu_write(watchdog_touch_ts, SOFTLOCKUP_RESET);
 }
 
 notrace void touch_softlockup_watchdog(void)
@@ -298,14 +300,14 @@ void touch_all_softlockup_watchdogs(void
 	 * the softlockup check.
 	 */
 	for_each_cpu(cpu, &watchdog_allowed_mask)
-		per_cpu(watchdog_touch_ts, cpu) = 0;
+		per_cpu(watchdog_touch_ts, cpu) = SOFTLOCKUP_RESET;
 	wq_watchdog_touch(-1);
 }
 
 void touch_softlockup_watchdog_sync(void)
 {
 	__this_cpu_write(softlockup_touch_sync, true);
-	__this_cpu_write(watchdog_touch_ts, 0);
+	__this_cpu_write(watchdog_touch_ts, SOFTLOCKUP_RESET);
 }
 
 static int is_softlockup(unsigned long touch_ts)
@@ -383,7 +385,7 @@ static enum hrtimer_restart watchdog_tim
 	/* .. and repeat */
 	hrtimer_forward_now(hrtimer, ns_to_ktime(sample_period));
 
-	if (touch_ts == 0) {
+	if (touch_ts == SOFTLOCKUP_RESET) {
 		if (unlikely(__this_cpu_read(softlockup_touch_sync))) {
 			/*
 			 * If the time stamp was touched atomically
diff -druNp --no-dereference linux-libre-5.4.21-gnu/lib/debugobjects.c linux-libre-5.4.22-gnu/lib/debugobjects.c
--- linux-libre-5.4.21-gnu/lib/debugobjects.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/lib/debugobjects.c	2020-02-24 02:37:04.000000000 -0500
@@ -132,14 +132,18 @@ static void fill_pool(void)
 	struct debug_obj *obj;
 	unsigned long flags;
 
-	if (likely(obj_pool_free >= debug_objects_pool_min_level))
+	if (likely(READ_ONCE(obj_pool_free) >= debug_objects_pool_min_level))
 		return;
 
 	/*
 	 * Reuse objs from the global free list; they will be reinitialized
 	 * when allocating.
+	 *
+	 * Both obj_nr_tofree and obj_pool_free are checked locklessly; the
+	 * READ_ONCE()s pair with the WRITE_ONCE()s in pool_lock critical
+	 * sections.
 	 */
-	while (obj_nr_tofree && (obj_pool_free < obj_pool_min_free)) {
+	while (READ_ONCE(obj_nr_tofree) && (READ_ONCE(obj_pool_free) < obj_pool_min_free)) {
 		raw_spin_lock_irqsave(&pool_lock, flags);
 		/*
 		 * Recheck with the lock held as the worker thread might have
@@ -148,9 +152,9 @@ static void fill_pool(void)
 		while (obj_nr_tofree && (obj_pool_free < obj_pool_min_free)) {
 			obj = hlist_entry(obj_to_free.first, typeof(*obj), node);
 			hlist_del(&obj->node);
-			obj_nr_tofree--;
+			WRITE_ONCE(obj_nr_tofree, obj_nr_tofree - 1);
 			hlist_add_head(&obj->node, &obj_pool);
-			obj_pool_free++;
+			WRITE_ONCE(obj_pool_free, obj_pool_free + 1);
 		}
 		raw_spin_unlock_irqrestore(&pool_lock, flags);
 	}
@@ -158,7 +162,7 @@ static void fill_pool(void)
 	if (unlikely(!obj_cache))
 		return;
 
-	while (obj_pool_free < debug_objects_pool_min_level) {
+	while (READ_ONCE(obj_pool_free) < debug_objects_pool_min_level) {
 		struct debug_obj *new[ODEBUG_BATCH_SIZE];
 		int cnt;
 
@@ -174,7 +178,7 @@ static void fill_pool(void)
 		while (cnt) {
 			hlist_add_head(&new[--cnt]->node, &obj_pool);
 			debug_objects_allocated++;
-			obj_pool_free++;
+			WRITE_ONCE(obj_pool_free, obj_pool_free + 1);
 		}
 		raw_spin_unlock_irqrestore(&pool_lock, flags);
 	}
@@ -236,7 +240,7 @@ alloc_object(void *addr, struct debug_bu
 	obj = __alloc_object(&obj_pool);
 	if (obj) {
 		obj_pool_used++;
-		obj_pool_free--;
+		WRITE_ONCE(obj_pool_free, obj_pool_free - 1);
 
 		/*
 		 * Looking ahead, allocate one batch of debug objects and
@@ -255,7 +259,7 @@ alloc_object(void *addr, struct debug_bu
 					       &percpu_pool->free_objs);
 				percpu_pool->obj_free++;
 				obj_pool_used++;
-				obj_pool_free--;
+				WRITE_ONCE(obj_pool_free, obj_pool_free - 1);
 			}
 		}
 
@@ -309,8 +313,8 @@ static void free_obj_work(struct work_st
 		obj = hlist_entry(obj_to_free.first, typeof(*obj), node);
 		hlist_del(&obj->node);
 		hlist_add_head(&obj->node, &obj_pool);
-		obj_pool_free++;
-		obj_nr_tofree--;
+		WRITE_ONCE(obj_pool_free, obj_pool_free + 1);
+		WRITE_ONCE(obj_nr_tofree, obj_nr_tofree - 1);
 	}
 	raw_spin_unlock_irqrestore(&pool_lock, flags);
 	return;
@@ -324,7 +328,7 @@ free_objs:
 	if (obj_nr_tofree) {
 		hlist_move_list(&obj_to_free, &tofree);
 		debug_objects_freed += obj_nr_tofree;
-		obj_nr_tofree = 0;
+		WRITE_ONCE(obj_nr_tofree, 0);
 	}
 	raw_spin_unlock_irqrestore(&pool_lock, flags);
 
@@ -375,10 +379,10 @@ free_to_obj_pool:
 	obj_pool_used--;
 
 	if (work) {
-		obj_nr_tofree++;
+		WRITE_ONCE(obj_nr_tofree, obj_nr_tofree + 1);
 		hlist_add_head(&obj->node, &obj_to_free);
 		if (lookahead_count) {
-			obj_nr_tofree += lookahead_count;
+			WRITE_ONCE(obj_nr_tofree, obj_nr_tofree + lookahead_count);
 			obj_pool_used -= lookahead_count;
 			while (lookahead_count) {
 				hlist_add_head(&objs[--lookahead_count]->node,
@@ -396,15 +400,15 @@ free_to_obj_pool:
 			for (i = 0; i < ODEBUG_BATCH_SIZE; i++) {
 				obj = __alloc_object(&obj_pool);
 				hlist_add_head(&obj->node, &obj_to_free);
-				obj_pool_free--;
-				obj_nr_tofree++;
+				WRITE_ONCE(obj_pool_free, obj_pool_free - 1);
+				WRITE_ONCE(obj_nr_tofree, obj_nr_tofree + 1);
 			}
 		}
 	} else {
-		obj_pool_free++;
+		WRITE_ONCE(obj_pool_free, obj_pool_free + 1);
 		hlist_add_head(&obj->node, &obj_pool);
 		if (lookahead_count) {
-			obj_pool_free += lookahead_count;
+			WRITE_ONCE(obj_pool_free, obj_pool_free + lookahead_count);
 			obj_pool_used -= lookahead_count;
 			while (lookahead_count) {
 				hlist_add_head(&objs[--lookahead_count]->node,
@@ -423,7 +427,7 @@ free_to_obj_pool:
 static void free_object(struct debug_obj *obj)
 {
 	__free_object(obj);
-	if (!obj_freeing && obj_nr_tofree) {
+	if (!READ_ONCE(obj_freeing) && READ_ONCE(obj_nr_tofree)) {
 		WRITE_ONCE(obj_freeing, true);
 		schedule_delayed_work(&debug_obj_work, ODEBUG_FREE_WORK_DELAY);
 	}
@@ -982,7 +986,7 @@ repeat:
 		debug_objects_maxchecked = objs_checked;
 
 	/* Schedule work to actually kmem_cache_free() objects */
-	if (!obj_freeing && obj_nr_tofree) {
+	if (!READ_ONCE(obj_freeing) && READ_ONCE(obj_nr_tofree)) {
 		WRITE_ONCE(obj_freeing, true);
 		schedule_delayed_work(&debug_obj_work, ODEBUG_FREE_WORK_DELAY);
 	}
@@ -1008,12 +1012,12 @@ static int debug_stats_show(struct seq_f
 	seq_printf(m, "max_checked   :%d\n", debug_objects_maxchecked);
 	seq_printf(m, "warnings      :%d\n", debug_objects_warnings);
 	seq_printf(m, "fixups        :%d\n", debug_objects_fixups);
-	seq_printf(m, "pool_free     :%d\n", obj_pool_free + obj_percpu_free);
+	seq_printf(m, "pool_free     :%d\n", READ_ONCE(obj_pool_free) + obj_percpu_free);
 	seq_printf(m, "pool_pcp_free :%d\n", obj_percpu_free);
 	seq_printf(m, "pool_min_free :%d\n", obj_pool_min_free);
 	seq_printf(m, "pool_used     :%d\n", obj_pool_used - obj_percpu_free);
 	seq_printf(m, "pool_max_used :%d\n", obj_pool_max_used);
-	seq_printf(m, "on_free_list  :%d\n", obj_nr_tofree);
+	seq_printf(m, "on_free_list  :%d\n", READ_ONCE(obj_nr_tofree));
 	seq_printf(m, "objs_allocated:%d\n", debug_objects_allocated);
 	seq_printf(m, "objs_freed    :%d\n", debug_objects_freed);
 	return 0;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/lib/raid6/mktables.c linux-libre-5.4.22-gnu/lib/raid6/mktables.c
--- linux-libre-5.4.21-gnu/lib/raid6/mktables.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/lib/raid6/mktables.c	2020-02-24 02:37:04.000000000 -0500
@@ -56,8 +56,8 @@ int main(int argc, char *argv[])
 	uint8_t v;
 	uint8_t exptbl[256], invtbl[256];
 
-	printf("#include <linux/raid/pq.h>\n");
 	printf("#include <linux/export.h>\n");
+	printf("#include <linux/raid/pq.h>\n");
 
 	/* Compute multiplication table */
 	printf("\nconst u8  __attribute__((aligned(256)))\n"
diff -druNp --no-dereference linux-libre-5.4.21-gnu/lib/scatterlist.c linux-libre-5.4.22-gnu/lib/scatterlist.c
--- linux-libre-5.4.21-gnu/lib/scatterlist.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/lib/scatterlist.c	2020-02-24 02:37:04.000000000 -0500
@@ -311,7 +311,7 @@ int __sg_alloc_table(struct sg_table *ta
 			if (prv)
 				table->nents = ++table->orig_nents;
 
- 			return -ENOMEM;
+			return -ENOMEM;
 		}
 
 		sg_init_table(sg, alloc_size);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/Makefile linux-libre-5.4.22-gnu/Makefile
--- linux-libre-5.4.21-gnu/Makefile	2020-02-19 17:15:01.000000000 -0500
+++ linux-libre-5.4.22-gnu/Makefile	2020-02-24 05:27:23.000000000 -0500
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 5
 PATCHLEVEL = 4
-SUBLEVEL = 21
+SUBLEVEL = 22
 EXTRAVERSION = -gnu
 NAME = Kleptomaniac Octopus
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/net/core/dev.c linux-libre-5.4.22-gnu/net/core/dev.c
--- linux-libre-5.4.21-gnu/net/core/dev.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/net/core/dev.c	2020-02-24 02:37:04.000000000 -0500
@@ -4256,14 +4256,14 @@ static u32 netif_receive_generic_xdp(str
 	/* Reinjected packets coming from act_mirred or similar should
 	 * not get XDP generic processing.
 	 */
-	if (skb_cloned(skb) || skb_is_tc_redirected(skb))
+	if (skb_is_tc_redirected(skb))
 		return XDP_PASS;
 
 	/* XDP packets must be linear and must have sufficient headroom
 	 * of XDP_PACKET_HEADROOM bytes. This is the guarantee that also
 	 * native XDP provides, thus we need to do it here as well.
 	 */
-	if (skb_is_nonlinear(skb) ||
+	if (skb_cloned(skb) || skb_is_nonlinear(skb) ||
 	    skb_headroom(skb) < XDP_PACKET_HEADROOM) {
 		int hroom = XDP_PACKET_HEADROOM - skb_headroom(skb);
 		int troom = skb->tail + skb->data_len - skb->end;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/net/core/filter.c linux-libre-5.4.22-gnu/net/core/filter.c
--- linux-libre-5.4.21-gnu/net/core/filter.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/net/core/filter.c	2020-02-24 02:37:04.000000000 -0500
@@ -3543,7 +3543,7 @@ static int __bpf_tx_xdp_map(struct net_d
 		return err;
 	}
 	default:
-		break;
+		return -EBADRQC;
 	}
 	return 0;
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/net/core/sock_map.c linux-libre-5.4.22-gnu/net/core/sock_map.c
--- linux-libre-5.4.21-gnu/net/core/sock_map.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/net/core/sock_map.c	2020-02-24 02:37:04.000000000 -0500
@@ -881,6 +881,9 @@ static void sock_hash_free(struct bpf_ma
 	/* wait for psock readers accessing its map link */
 	synchronize_rcu();
 
+	/* wait for psock readers accessing its map link */
+	synchronize_rcu();
+
 	bpf_map_area_free(htab->buckets);
 	kfree(htab);
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/net/dsa/tag_qca.c linux-libre-5.4.22-gnu/net/dsa/tag_qca.c
--- linux-libre-5.4.21-gnu/net/dsa/tag_qca.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/net/dsa/tag_qca.c	2020-02-24 02:37:04.000000000 -0500
@@ -33,7 +33,7 @@ static struct sk_buff *qca_tag_xmit(stru
 	struct dsa_port *dp = dsa_slave_to_port(dev);
 	u16 *phdr, hdr;
 
-	if (skb_cow_head(skb, 0) < 0)
+	if (skb_cow_head(skb, QCA_HDR_LEN) < 0)
 		return NULL;
 
 	skb_push(skb, QCA_HDR_LEN);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/net/netfilter/nft_tunnel.c linux-libre-5.4.22-gnu/net/netfilter/nft_tunnel.c
--- linux-libre-5.4.21-gnu/net/netfilter/nft_tunnel.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/net/netfilter/nft_tunnel.c	2020-02-24 02:37:04.000000000 -0500
@@ -248,8 +248,9 @@ static int nft_tunnel_obj_vxlan_init(con
 }
 
 static const struct nla_policy nft_tunnel_opts_erspan_policy[NFTA_TUNNEL_KEY_ERSPAN_MAX + 1] = {
+	[NFTA_TUNNEL_KEY_ERSPAN_VERSION]	= { .type = NLA_U32 },
 	[NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX]	= { .type = NLA_U32 },
-	[NFTA_TUNNEL_KEY_ERSPAN_V2_DIR]	= { .type = NLA_U8 },
+	[NFTA_TUNNEL_KEY_ERSPAN_V2_DIR]		= { .type = NLA_U8 },
 	[NFTA_TUNNEL_KEY_ERSPAN_V2_HWID]	= { .type = NLA_U8 },
 };
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/net/sched/cls_flower.c linux-libre-5.4.22-gnu/net/sched/cls_flower.c
--- linux-libre-5.4.21-gnu/net/sched/cls_flower.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/net/sched/cls_flower.c	2020-02-24 02:37:04.000000000 -0500
@@ -689,6 +689,7 @@ static const struct nla_policy fl_policy
 					    .len = 128 / BITS_PER_BYTE },
 	[TCA_FLOWER_KEY_CT_LABELS_MASK]	= { .type = NLA_BINARY,
 					    .len = 128 / BITS_PER_BYTE },
+	[TCA_FLOWER_FLAGS]		= { .type = NLA_U32 },
 };
 
 static const struct nla_policy
diff -druNp --no-dereference linux-libre-5.4.21-gnu/net/sched/cls_matchall.c linux-libre-5.4.22-gnu/net/sched/cls_matchall.c
--- linux-libre-5.4.21-gnu/net/sched/cls_matchall.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/net/sched/cls_matchall.c	2020-02-24 02:37:04.000000000 -0500
@@ -157,6 +157,7 @@ static void *mall_get(struct tcf_proto *
 static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = {
 	[TCA_MATCHALL_UNSPEC]		= { .type = NLA_UNSPEC },
 	[TCA_MATCHALL_CLASSID]		= { .type = NLA_U32 },
+	[TCA_MATCHALL_FLAGS]		= { .type = NLA_U32 },
 };
 
 static int mall_set_parms(struct net *net, struct tcf_proto *tp,
diff -druNp --no-dereference linux-libre-5.4.21-gnu/net/smc/smc_diag.c linux-libre-5.4.22-gnu/net/smc/smc_diag.c
--- linux-libre-5.4.21-gnu/net/smc/smc_diag.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/net/smc/smc_diag.c	2020-02-24 02:37:04.000000000 -0500
@@ -39,16 +39,15 @@ static void smc_diag_msg_common_fill(str
 {
 	struct smc_sock *smc = smc_sk(sk);
 
+	memset(r, 0, sizeof(*r));
 	r->diag_family = sk->sk_family;
+	sock_diag_save_cookie(sk, r->id.idiag_cookie);
 	if (!smc->clcsock)
 		return;
 	r->id.idiag_sport = htons(smc->clcsock->sk->sk_num);
 	r->id.idiag_dport = smc->clcsock->sk->sk_dport;
 	r->id.idiag_if = smc->clcsock->sk->sk_bound_dev_if;
-	sock_diag_save_cookie(sk, r->id.idiag_cookie);
 	if (sk->sk_protocol == SMCPROTO_SMC) {
-		memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
-		memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
 		r->id.idiag_src[0] = smc->clcsock->sk->sk_rcv_saddr;
 		r->id.idiag_dst[0] = smc->clcsock->sk->sk_daddr;
 #if IS_ENABLED(CONFIG_IPV6)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/net/sunrpc/cache.c linux-libre-5.4.22-gnu/net/sunrpc/cache.c
--- linux-libre-5.4.21-gnu/net/sunrpc/cache.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/net/sunrpc/cache.c	2020-02-24 02:37:04.000000000 -0500
@@ -1888,7 +1888,9 @@ void sunrpc_cache_unhash(struct cache_de
 	if (!hlist_unhashed(&h->cache_list)){
 		hlist_del_init_rcu(&h->cache_list);
 		cd->entries--;
+		set_bit(CACHE_CLEANED, &h->flags);
 		spin_unlock(&cd->hash_lock);
+		cache_fresh_unlocked(h, cd);
 		cache_put(h, cd);
 	} else
 		spin_unlock(&cd->hash_lock);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/samples/bpf/Makefile linux-libre-5.4.22-gnu/samples/bpf/Makefile
--- linux-libre-5.4.21-gnu/samples/bpf/Makefile	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/samples/bpf/Makefile	2020-02-24 02:37:04.000000000 -0500
@@ -219,6 +219,7 @@ BTF_LLVM_PROBE := $(shell echo "int main
 			  readelf -S ./llvm_btf_verify.o | grep BTF; \
 			  /bin/rm -f ./llvm_btf_verify.o)
 
+BPF_EXTRA_CFLAGS += -fno-stack-protector
 ifneq ($(BTF_LLVM_PROBE),)
 	EXTRA_CFLAGS += -g
 else
diff -druNp --no-dereference linux-libre-5.4.21-gnu/scripts/Kbuild.include linux-libre-5.4.22-gnu/scripts/Kbuild.include
--- linux-libre-5.4.21-gnu/scripts/Kbuild.include	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/scripts/Kbuild.include	2020-02-24 02:37:04.000000000 -0500
@@ -55,14 +55,13 @@ kecho := $($(quiet)kecho)
 # - stdin is piped in from the first prerequisite ($<) so one has
 #   to specify a valid file as first prerequisite (often the kbuild file)
 define filechk
-	$(Q)set -e;				\
-	mkdir -p $(dir $@);			\
-	{ $(filechk_$(1)); } > $@.tmp;		\
-	if [ -r $@ ] && cmp -s $@ $@.tmp; then	\
-		rm -f $@.tmp;			\
-	else					\
-		$(kecho) '  UPD     $@';	\
-		mv -f $@.tmp $@;		\
+	$(Q)set -e;						\
+	mkdir -p $(dir $@);					\
+	trap "rm -f $(dot-target).tmp" EXIT;			\
+	{ $(filechk_$(1)); } > $(dot-target).tmp;		\
+	if [ ! -r $@ ] || ! cmp -s $@ $(dot-target).tmp; then	\
+		$(kecho) '  UPD     $@';			\
+		mv -f $(dot-target).tmp $@;			\
 	fi
 endef
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/scripts/kconfig/confdata.c linux-libre-5.4.22-gnu/scripts/kconfig/confdata.c
--- linux-libre-5.4.21-gnu/scripts/kconfig/confdata.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/scripts/kconfig/confdata.c	2020-02-24 02:37:04.000000000 -0500
@@ -1353,7 +1353,7 @@ bool conf_set_all_new_symbols(enum conf_
 
 		sym_calc_value(csym);
 		if (mode == def_random)
-			has_changed = randomize_choice_values(csym);
+			has_changed |= randomize_choice_values(csym);
 		else {
 			set_all_choice_values(csym);
 			has_changed = true;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/scripts/Kconfig.include linux-libre-5.4.22-gnu/scripts/Kconfig.include
--- linux-libre-5.4.21-gnu/scripts/Kconfig.include	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/scripts/Kconfig.include	2020-02-24 02:37:04.000000000 -0500
@@ -25,7 +25,7 @@ failure = $(if-success,$(1),n,y)
 
 # $(cc-option,<flag>)
 # Return y if the compiler supports <flag>, n otherwise
-cc-option = $(success,$(CC) -Werror $(CLANG_FLAGS) $(1) -E -x c /dev/null -o /dev/null)
+cc-option = $(success,$(CC) -Werror $(CLANG_FLAGS) $(1) -S -x c /dev/null -o /dev/null)
 
 # $(ld-option,<flag>)
 # Return y if the linker supports <flag>, n otherwise
diff -druNp --no-dereference linux-libre-5.4.21-gnu/scripts/link-vmlinux.sh linux-libre-5.4.22-gnu/scripts/link-vmlinux.sh
--- linux-libre-5.4.21-gnu/scripts/link-vmlinux.sh	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/scripts/link-vmlinux.sh	2020-02-24 02:37:04.000000000 -0500
@@ -108,13 +108,13 @@ gen_btf()
 	local bin_arch
 
 	if ! [ -x "$(command -v ${PAHOLE})" ]; then
-		info "BTF" "${1}: pahole (${PAHOLE}) is not available"
+		echo >&2 "BTF: ${1}: pahole (${PAHOLE}) is not available"
 		return 1
 	fi
 
 	pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/')
 	if [ "${pahole_ver}" -lt "113" ]; then
-		info "BTF" "${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.13"
+		echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.13"
 		return 1
 	fi
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/security/selinux/avc.c linux-libre-5.4.22-gnu/security/selinux/avc.c
--- linux-libre-5.4.21-gnu/security/selinux/avc.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/security/selinux/avc.c	2020-02-24 02:37:04.000000000 -0500
@@ -617,40 +617,37 @@ static struct avc_node *avc_insert(struc
 	struct avc_node *pos, *node = NULL;
 	int hvalue;
 	unsigned long flag;
+	spinlock_t *lock;
+	struct hlist_head *head;
 
 	if (avc_latest_notif_update(avc, avd->seqno, 1))
-		goto out;
+		return NULL;
 
 	node = avc_alloc_node(avc);
-	if (node) {
-		struct hlist_head *head;
-		spinlock_t *lock;
-		int rc = 0;
+	if (!node)
+		return NULL;
 
-		hvalue = avc_hash(ssid, tsid, tclass);
-		avc_node_populate(node, ssid, tsid, tclass, avd);
-		rc = avc_xperms_populate(node, xp_node);
-		if (rc) {
-			kmem_cache_free(avc_node_cachep, node);
-			return NULL;
-		}
-		head = &avc->avc_cache.slots[hvalue];
-		lock = &avc->avc_cache.slots_lock[hvalue];
+	avc_node_populate(node, ssid, tsid, tclass, avd);
+	if (avc_xperms_populate(node, xp_node)) {
+		avc_node_kill(avc, node);
+		return NULL;
+	}
 
-		spin_lock_irqsave(lock, flag);
-		hlist_for_each_entry(pos, head, list) {
-			if (pos->ae.ssid == ssid &&
-			    pos->ae.tsid == tsid &&
-			    pos->ae.tclass == tclass) {
-				avc_node_replace(avc, node, pos);
-				goto found;
-			}
+	hvalue = avc_hash(ssid, tsid, tclass);
+	head = &avc->avc_cache.slots[hvalue];
+	lock = &avc->avc_cache.slots_lock[hvalue];
+	spin_lock_irqsave(lock, flag);
+	hlist_for_each_entry(pos, head, list) {
+		if (pos->ae.ssid == ssid &&
+			pos->ae.tsid == tsid &&
+			pos->ae.tclass == tclass) {
+			avc_node_replace(avc, node, pos);
+			goto found;
 		}
-		hlist_add_head_rcu(&node->list, head);
-found:
-		spin_unlock_irqrestore(lock, flag);
 	}
-out:
+	hlist_add_head_rcu(&node->list, head);
+found:
+	spin_unlock_irqrestore(lock, flag);
 	return node;
 }
 
@@ -894,7 +891,7 @@ static int avc_update_node(struct selinu
 	if (orig->ae.xp_node) {
 		rc = avc_xperms_populate(node, orig->ae.xp_node);
 		if (rc) {
-			kmem_cache_free(avc_node_cachep, node);
+			avc_node_kill(avc, node);
 			goto out_unlock;
 		}
 	}
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/core/control.c linux-libre-5.4.22-gnu/sound/core/control.c
--- linux-libre-5.4.21-gnu/sound/core/control.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/core/control.c	2020-02-24 02:37:04.000000000 -0500
@@ -1430,8 +1430,9 @@ static int call_tlv_handler(struct snd_c
 	if (kctl->tlv.c == NULL)
 		return -ENXIO;
 
-	/* When locked, this is unavailable. */
-	if (vd->owner != NULL && vd->owner != file)
+	/* Write and command operations are not allowed for locked element. */
+	if (op_flag != SNDRV_CTL_TLV_OP_READ &&
+	    vd->owner != NULL && vd->owner != file)
 		return -EPERM;
 
 	return kctl->tlv.c(kctl, op_flag, size, buf);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/pci/hda/patch_conexant.c linux-libre-5.4.22-gnu/sound/pci/hda/patch_conexant.c
--- linux-libre-5.4.21-gnu/sound/pci/hda/patch_conexant.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/pci/hda/patch_conexant.c	2020-02-24 02:37:04.000000000 -0500
@@ -922,6 +922,7 @@ static const struct snd_pci_quirk cxt506
 	SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
+	SND_PCI_QUIRK(0x17aa, 0x21d2, "Lenovo T420s", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo IdeaPad Z560", CXT_FIXUP_MUTE_LED_EAPD),
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/pci/hda/patch_hdmi.c linux-libre-5.4.22-gnu/sound/pci/hda/patch_hdmi.c
--- linux-libre-5.4.21-gnu/sound/pci/hda/patch_hdmi.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/pci/hda/patch_hdmi.c	2020-02-24 02:37:04.000000000 -0500
@@ -2794,9 +2794,12 @@ static int alloc_intel_hdmi(struct hda_c
 /* parse and post-process for Intel codecs */
 static int parse_intel_hdmi(struct hda_codec *codec)
 {
-	int err;
+	int err, retries = 3;
+
+	do {
+		err = hdmi_parse_codec(codec);
+	} while (err < 0 && retries--);
 
-	err = hdmi_parse_codec(codec);
 	if (err < 0) {
 		generic_spec_free(codec);
 		return err;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/pci/hda/patch_realtek.c linux-libre-5.4.22-gnu/sound/pci/hda/patch_realtek.c
--- linux-libre-5.4.21-gnu/sound/pci/hda/patch_realtek.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/pci/hda/patch_realtek.c	2020-02-24 02:37:04.000000000 -0500
@@ -5852,6 +5852,7 @@ enum {
 	ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
 	ALC288_FIXUP_DELL_XPS_13,
 	ALC288_FIXUP_DISABLE_AAMIX,
+	ALC292_FIXUP_DELL_E7X_AAMIX,
 	ALC292_FIXUP_DELL_E7X,
 	ALC292_FIXUP_DISABLE_AAMIX,
 	ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
@@ -6547,12 +6548,19 @@ static const struct hda_fixup alc269_fix
 		.chained = true,
 		.chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
 	},
-	[ALC292_FIXUP_DELL_E7X] = {
+	[ALC292_FIXUP_DELL_E7X_AAMIX] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc_fixup_dell_xps13,
 		.chained = true,
 		.chain_id = ALC292_FIXUP_DISABLE_AAMIX
 	},
+	[ALC292_FIXUP_DELL_E7X] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = snd_hda_gen_fixup_micmute_led,
+		/* micmute fixup must be applied at last */
+		.chained_before = true,
+		.chain_id = ALC292_FIXUP_DELL_E7X_AAMIX,
+	},
 	[ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE] = {
 		.type = HDA_FIXUP_PINS,
 		.v.pins = (const struct hda_pintbl[]) {
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/sh/aica.c linux-libre-5.4.22-gnu/sound/sh/aica.c
--- linux-libre-5.4.21-gnu/sound/sh/aica.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/sh/aica.c	2020-02-24 02:37:04.000000000 -0500
@@ -101,10 +101,10 @@ static void spu_memset(u32 toi, u32 what
 }
 
 /* spu_memload - write to SPU address space */
-static void spu_memload(u32 toi, void *from, int length)
+static void spu_memload(u32 toi, const void *from, int length)
 {
 	unsigned long flags;
-	u32 *froml = from;
+	const u32 *froml = from;
 	u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi);
 	int i;
 	u32 val;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/sh/sh_dac_audio.c linux-libre-5.4.22-gnu/sound/sh/sh_dac_audio.c
--- linux-libre-5.4.21-gnu/sound/sh/sh_dac_audio.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/sh/sh_dac_audio.c	2020-02-24 02:37:04.000000000 -0500
@@ -175,7 +175,6 @@ static int snd_sh_dac_pcm_copy(struct sn
 {
 	/* channel is not used (interleaved data) */
 	struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
-	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (copy_from_user_toio(chip->data_buffer + pos, src, count))
 		return -EFAULT;
@@ -195,7 +194,6 @@ static int snd_sh_dac_pcm_copy_kernel(st
 {
 	/* channel is not used (interleaved data) */
 	struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
-	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	memcpy_toio(chip->data_buffer + pos, src, count);
 	chip->buffer_end = chip->data_buffer + pos + count;
@@ -214,7 +212,6 @@ static int snd_sh_dac_pcm_silence(struct
 {
 	/* channel is not used (interleaved data) */
 	struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
-	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	memset_io(chip->data_buffer + pos, 0, count);
 	chip->buffer_end = chip->data_buffer + pos + count;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/soc/atmel/Kconfig linux-libre-5.4.22-gnu/sound/soc/atmel/Kconfig
--- linux-libre-5.4.21-gnu/sound/soc/atmel/Kconfig	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/soc/atmel/Kconfig	2020-02-24 02:37:04.000000000 -0500
@@ -19,6 +19,8 @@ config SND_ATMEL_SOC_DMA
 
 config SND_ATMEL_SOC_SSC
 	tristate
+	select SND_ATMEL_SOC_DMA
+	select SND_ATMEL_SOC_PDC
 
 config SND_ATMEL_SOC_SSC_PDC
 	tristate "SoC PCM DAI support for AT91 SSC controller using PDC"
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/soc/intel/boards/sof_rt5682.c linux-libre-5.4.22-gnu/sound/soc/intel/boards/sof_rt5682.c
--- linux-libre-5.4.21-gnu/sound/soc/intel/boards/sof_rt5682.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/soc/intel/boards/sof_rt5682.c	2020-02-24 02:37:04.000000000 -0500
@@ -34,6 +34,10 @@
 #define SOF_RT5682_SSP_AMP(quirk)	\
 	(((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK)
 #define SOF_RT5682_MCLK_BYTCHT_EN		BIT(9)
+#define SOF_RT5682_NUM_HDMIDEV_SHIFT		10
+#define SOF_RT5682_NUM_HDMIDEV_MASK		(GENMASK(12, 10))
+#define SOF_RT5682_NUM_HDMIDEV(quirk)	\
+	((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK)
 
 /* Default: MCLK on, MCLK 19.2M, SSP0  */
 static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
@@ -585,6 +589,19 @@ static int sof_audio_probe(struct platfo
 	if (!ctx)
 		return -ENOMEM;
 
+	if (pdev->id_entry && pdev->id_entry->driver_data)
+		sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data;
+
+	dmi_check_system(sof_rt5682_quirk_table);
+
+	mach = (&pdev->dev)->platform_data;
+
+	/* A speaker amp might not be present when the quirk claims one is.
+	 * Detect this via whether the machine driver match includes quirk_data.
+	 */
+	if ((sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data)
+		sof_rt5682_quirk &= ~SOF_SPEAKER_AMP_PRESENT;
+
 	if (soc_intel_is_byt() || soc_intel_is_cht()) {
 		is_legacy_cpu = 1;
 		dmic_be_num = 0;
@@ -595,11 +612,13 @@ static int sof_audio_probe(struct platfo
 						SOF_RT5682_SSP_CODEC(2);
 	} else {
 		dmic_be_num = 2;
-		hdmi_num = 3;
+		hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >>
+			 SOF_RT5682_NUM_HDMIDEV_SHIFT;
+		/* default number of HDMI DAI's */
+		if (!hdmi_num)
+			hdmi_num = 3;
 	}
 
-	dmi_check_system(sof_rt5682_quirk_table);
-
 	/* need to get main clock from pmc */
 	if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
 		ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
@@ -643,7 +662,6 @@ static int sof_audio_probe(struct platfo
 	INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
 
 	sof_audio_card_rt5682.dev = &pdev->dev;
-	mach = (&pdev->dev)->platform_data;
 
 	/* set platform name for each dailink */
 	ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682,
@@ -672,6 +690,21 @@ static int sof_rt5682_remove(struct plat
 	return 0;
 }
 
+static const struct platform_device_id board_ids[] = {
+	{
+		.name = "sof_rt5682",
+	},
+	{
+		.name = "tgl_max98357a_rt5682",
+		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
+					SOF_RT5682_SSP_CODEC(0) |
+					SOF_SPEAKER_AMP_PRESENT |
+					SOF_RT5682_SSP_AMP(1) |
+					SOF_RT5682_NUM_HDMIDEV(4)),
+	},
+	{ }
+};
+
 static struct platform_driver sof_audio = {
 	.probe = sof_audio_probe,
 	.remove = sof_rt5682_remove,
@@ -679,6 +712,7 @@ static struct platform_driver sof_audio
 		.name = "sof_rt5682",
 		.pm = &snd_soc_pm_ops,
 	},
+	.id_table = board_ids,
 };
 module_platform_driver(sof_audio)
 
@@ -688,3 +722,4 @@ MODULE_AUTHOR("Bard Liao <bard.liao@inte
 MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:sof_rt5682");
+MODULE_ALIAS("platform:tgl_max98357a_rt5682");
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/soc/soc-topology.c linux-libre-5.4.22-gnu/sound/soc/soc-topology.c
--- linux-libre-5.4.21-gnu/sound/soc/soc-topology.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/soc/soc-topology.c	2020-02-24 02:37:04.000000000 -0500
@@ -604,9 +604,11 @@ static int soc_tplg_kcontrol_bind_io(str
 		ext_ops = tplg->bytes_ext_ops;
 		num_ops = tplg->bytes_ext_ops_count;
 		for (i = 0; i < num_ops; i++) {
-			if (!sbe->put && ext_ops[i].id == be->ext_ops.put)
+			if (!sbe->put &&
+			    ext_ops[i].id == le32_to_cpu(be->ext_ops.put))
 				sbe->put = ext_ops[i].put;
-			if (!sbe->get && ext_ops[i].id == be->ext_ops.get)
+			if (!sbe->get &&
+			    ext_ops[i].id == le32_to_cpu(be->ext_ops.get))
 				sbe->get = ext_ops[i].get;
 		}
 
@@ -621,11 +623,11 @@ static int soc_tplg_kcontrol_bind_io(str
 	num_ops = tplg->io_ops_count;
 	for (i = 0; i < num_ops; i++) {
 
-		if (k->put == NULL && ops[i].id == hdr->ops.put)
+		if (k->put == NULL && ops[i].id == le32_to_cpu(hdr->ops.put))
 			k->put = ops[i].put;
-		if (k->get == NULL && ops[i].id == hdr->ops.get)
+		if (k->get == NULL && ops[i].id == le32_to_cpu(hdr->ops.get))
 			k->get = ops[i].get;
-		if (k->info == NULL && ops[i].id == hdr->ops.info)
+		if (k->info == NULL && ops[i].id == le32_to_cpu(hdr->ops.info))
 			k->info = ops[i].info;
 	}
 
@@ -638,11 +640,11 @@ static int soc_tplg_kcontrol_bind_io(str
 	num_ops = ARRAY_SIZE(io_ops);
 	for (i = 0; i < num_ops; i++) {
 
-		if (k->put == NULL && ops[i].id == hdr->ops.put)
+		if (k->put == NULL && ops[i].id == le32_to_cpu(hdr->ops.put))
 			k->put = ops[i].put;
-		if (k->get == NULL && ops[i].id == hdr->ops.get)
+		if (k->get == NULL && ops[i].id == le32_to_cpu(hdr->ops.get))
 			k->get = ops[i].get;
-		if (k->info == NULL && ops[i].id == hdr->ops.info)
+		if (k->info == NULL && ops[i].id == le32_to_cpu(hdr->ops.info))
 			k->info = ops[i].info;
 	}
 
@@ -931,7 +933,7 @@ static int soc_tplg_denum_create_texts(s
 	if (se->dobj.control.dtexts == NULL)
 		return -ENOMEM;
 
-	for (i = 0; i < ec->items; i++) {
+	for (i = 0; i < le32_to_cpu(ec->items); i++) {
 
 		if (strnlen(ec->texts[i], SNDRV_CTL_ELEM_ID_NAME_MAXLEN) ==
 			SNDRV_CTL_ELEM_ID_NAME_MAXLEN) {
@@ -1325,7 +1327,7 @@ static struct snd_kcontrol_new *soc_tplg
 		if (kc[i].name == NULL)
 			goto err_sm;
 		kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		kc[i].access = mc->hdr.access;
+		kc[i].access = le32_to_cpu(mc->hdr.access);
 
 		/* we only support FL/FR channel mapping atm */
 		sm->reg = tplc_chan_get_reg(tplg, mc->channel,
@@ -1337,10 +1339,10 @@ static struct snd_kcontrol_new *soc_tplg
 		sm->rshift = tplc_chan_get_shift(tplg, mc->channel,
 			SNDRV_CHMAP_FR);
 
-		sm->max = mc->max;
-		sm->min = mc->min;
-		sm->invert = mc->invert;
-		sm->platform_max = mc->platform_max;
+		sm->max = le32_to_cpu(mc->max);
+		sm->min = le32_to_cpu(mc->min);
+		sm->invert = le32_to_cpu(mc->invert);
+		sm->platform_max = le32_to_cpu(mc->platform_max);
 		sm->dobj.index = tplg->index;
 		INIT_LIST_HEAD(&sm->dobj.list);
 
@@ -1401,7 +1403,7 @@ static struct snd_kcontrol_new *soc_tplg
 			goto err_se;
 
 		tplg->pos += (sizeof(struct snd_soc_tplg_enum_control) +
-				ec->priv.size);
+			      le32_to_cpu(ec->priv.size));
 
 		dev_dbg(tplg->dev, " adding DAPM widget enum control %s\n",
 			ec->hdr.name);
@@ -1411,7 +1413,7 @@ static struct snd_kcontrol_new *soc_tplg
 		if (kc[i].name == NULL)
 			goto err_se;
 		kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		kc[i].access = ec->hdr.access;
+		kc[i].access = le32_to_cpu(ec->hdr.access);
 
 		/* we only support FL/FR channel mapping atm */
 		se->reg = tplc_chan_get_reg(tplg, ec->channel, SNDRV_CHMAP_FL);
@@ -1420,8 +1422,8 @@ static struct snd_kcontrol_new *soc_tplg
 		se->shift_r = tplc_chan_get_shift(tplg, ec->channel,
 						  SNDRV_CHMAP_FR);
 
-		se->items = ec->items;
-		se->mask = ec->mask;
+		se->items = le32_to_cpu(ec->items);
+		se->mask = le32_to_cpu(ec->mask);
 		se->dobj.index = tplg->index;
 
 		switch (le32_to_cpu(ec->hdr.ops.info)) {
@@ -1523,9 +1525,9 @@ static struct snd_kcontrol_new *soc_tplg
 		if (kc[i].name == NULL)
 			goto err_sbe;
 		kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		kc[i].access = be->hdr.access;
+		kc[i].access = le32_to_cpu(be->hdr.access);
 
-		sbe->max = be->max;
+		sbe->max = le32_to_cpu(be->max);
 		INIT_LIST_HEAD(&sbe->dobj.list);
 
 		/* map standard io handlers and check for external handlers */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/soc/sof/intel/hda-dai.c linux-libre-5.4.22-gnu/sound/soc/sof/intel/hda-dai.c
--- linux-libre-5.4.21-gnu/sound/soc/sof/intel/hda-dai.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/soc/sof/intel/hda-dai.c	2020-02-24 02:37:04.000000000 -0500
@@ -261,14 +261,11 @@ static int hda_link_pcm_prepare(struct s
 {
 	struct hdac_ext_stream *link_dev =
 				snd_soc_dai_get_dma_data(dai, substream);
-	struct sof_intel_hda_stream *hda_stream;
 	struct snd_sof_dev *sdev =
 				snd_soc_component_get_drvdata(dai->component);
 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
 	int stream = substream->stream;
 
-	hda_stream = hstream_to_sof_hda_stream(link_dev);
-
 	if (link_dev->link_prepared)
 		return 0;
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/soc/sof/intel/hda.h linux-libre-5.4.22-gnu/sound/soc/sof/intel/hda.h
--- linux-libre-5.4.21-gnu/sound/soc/sof/intel/hda.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/soc/sof/intel/hda.h	2020-02-24 02:37:04.000000000 -0500
@@ -336,7 +336,7 @@
 
 /* Number of DAIs */
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
-#define SOF_SKL_NUM_DAIS		14
+#define SOF_SKL_NUM_DAIS		15
 #else
 #define SOF_SKL_NUM_DAIS		8
 #endif
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/usb/card.c linux-libre-5.4.22-gnu/sound/usb/card.c
--- linux-libre-5.4.21-gnu/sound/usb/card.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/usb/card.c	2020-02-24 02:37:04.000000000 -0500
@@ -597,6 +597,10 @@ static int usb_audio_probe(struct usb_in
 		}
 	}
 	if (! chip) {
+		err = snd_usb_apply_boot_quirk_once(dev, intf, quirk, id);
+		if (err < 0)
+			goto __error;
+
 		/* it's a fresh one.
 		 * now look for an empty slot and create a new card instance
 		 */
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/usb/format.c linux-libre-5.4.22-gnu/sound/usb/format.c
--- linux-libre-5.4.21-gnu/sound/usb/format.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/usb/format.c	2020-02-24 02:37:04.000000000 -0500
@@ -296,6 +296,9 @@ static int line6_parse_audio_format_rate
 	case USB_ID(0x0E41, 0x4242): /* Line6 Helix Rack */
 	case USB_ID(0x0E41, 0x4244): /* Line6 Helix LT */
 	case USB_ID(0x0E41, 0x4246): /* Line6 HX-Stomp */
+	case USB_ID(0x0E41, 0x4248): /* Line6 Helix >= fw 2.82 */
+	case USB_ID(0x0E41, 0x4249): /* Line6 Helix Rack >= fw 2.82 */
+	case USB_ID(0x0E41, 0x424a): /* Line6 Helix LT >= fw 2.82 */
 		/* supported rates: 48Khz */
 		kfree(fp->rate_table);
 		fp->rate_table = kmalloc(sizeof(int), GFP_KERNEL);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/usb/pcm.c linux-libre-5.4.22-gnu/sound/usb/pcm.c
--- linux-libre-5.4.21-gnu/sound/usb/pcm.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/usb/pcm.c	2020-02-24 02:37:04.000000000 -0500
@@ -348,6 +348,10 @@ static int set_sync_ep_implicit_fb_quirk
 		ep = 0x84;
 		ifnum = 0;
 		goto add_sync_ep_from_ifnum;
+	case USB_ID(0x07fd, 0x0008): /* MOTU M Series */
+		ep = 0x81;
+		ifnum = 2;
+		goto add_sync_ep_from_ifnum;
 	case USB_ID(0x0582, 0x01d8): /* BOSS Katana */
 		/* BOSS Katana amplifiers do not need quirks */
 		return 0;
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/usb/quirks.c linux-libre-5.4.22-gnu/sound/usb/quirks.c
--- linux-libre-5.4.21-gnu/sound/usb/quirks.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/usb/quirks.c	2020-02-24 02:37:04.000000000 -0500
@@ -1113,6 +1113,31 @@ free_buf:
 	return err;
 }
 
+static int snd_usb_motu_m_series_boot_quirk(struct usb_device *dev)
+{
+	int ret;
+
+	if (snd_usb_pipe_sanity_check(dev, usb_sndctrlpipe(dev, 0)))
+		return -EINVAL;
+	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+			      1, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      0x0, 0, NULL, 0, 1000);
+
+	if (ret < 0)
+		return ret;
+
+	msleep(2000);
+
+	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+			      1, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      0x20, 0, NULL, 0, 1000);
+
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
 /*
  * Setup quirks
  */
@@ -1295,6 +1320,19 @@ int snd_usb_apply_boot_quirk(struct usb_
 	}
 
 	return 0;
+}
+
+int snd_usb_apply_boot_quirk_once(struct usb_device *dev,
+				  struct usb_interface *intf,
+				  const struct snd_usb_audio_quirk *quirk,
+				  unsigned int id)
+{
+	switch (id) {
+	case USB_ID(0x07fd, 0x0008): /* MOTU M Series */
+		return snd_usb_motu_m_series_boot_quirk(dev);
+	}
+
+	return 0;
 }
 
 /*
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/usb/quirks.h linux-libre-5.4.22-gnu/sound/usb/quirks.h
--- linux-libre-5.4.21-gnu/sound/usb/quirks.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/usb/quirks.h	2020-02-24 02:37:04.000000000 -0500
@@ -20,6 +20,11 @@ int snd_usb_apply_boot_quirk(struct usb_
 			     const struct snd_usb_audio_quirk *quirk,
 			     unsigned int usb_id);
 
+int snd_usb_apply_boot_quirk_once(struct usb_device *dev,
+				  struct usb_interface *intf,
+				  const struct snd_usb_audio_quirk *quirk,
+				  unsigned int usb_id);
+
 void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
 			      struct audioformat *fmt);
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/sound/usb/usx2y/usX2Yhwdep.c linux-libre-5.4.22-gnu/sound/usb/usx2y/usX2Yhwdep.c
--- linux-libre-5.4.21-gnu/sound/usb/usx2y/usX2Yhwdep.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/sound/usb/usx2y/usX2Yhwdep.c	2020-02-24 02:37:04.000000000 -0500
@@ -119,7 +119,7 @@ static int snd_usX2Y_hwdep_dsp_status(st
 	info->num_dsps = 2;		// 0: Prepad Data, 1: FPGA Code
 	if (us428->chip_status & USX2Y_STAT_CHIP_INIT)
 		info->chip_ready = 1;
- 	info->version = USX2Y_DRIVER_VERSION; 
+	info->version = USX2Y_DRIVER_VERSION;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/arch/x86/lib/x86-opcode-map.txt linux-libre-5.4.22-gnu/tools/arch/x86/lib/x86-opcode-map.txt
--- linux-libre-5.4.21-gnu/tools/arch/x86/lib/x86-opcode-map.txt	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/arch/x86/lib/x86-opcode-map.txt	2020-02-24 02:37:04.000000000 -0500
@@ -909,7 +909,7 @@ EndTable
 
 GrpTable: Grp3_2
 0: TEST Ev,Iz
-1:
+1: TEST Ev,Iz
 2: NOT Ev
 3: NEG Ev
 4: MUL rAX,Ev
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/bpf/bpftool/cgroup.c linux-libre-5.4.22-gnu/tools/bpf/bpftool/cgroup.c
--- linux-libre-5.4.21-gnu/tools/bpf/bpftool/cgroup.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/bpf/bpftool/cgroup.c	2020-02-24 02:37:04.000000000 -0500
@@ -117,6 +117,25 @@ static int count_attached_bpf_progs(int
 	return prog_cnt;
 }
 
+static int cgroup_has_attached_progs(int cgroup_fd)
+{
+	enum bpf_attach_type type;
+	bool no_prog = true;
+
+	for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
+		int count = count_attached_bpf_progs(cgroup_fd, type);
+
+		if (count < 0 && errno != EINVAL)
+			return -1;
+
+		if (count > 0) {
+			no_prog = false;
+			break;
+		}
+	}
+
+	return no_prog ? 0 : 1;
+}
 static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
 				   int level)
 {
@@ -161,6 +180,7 @@ static int show_attached_bpf_progs(int c
 static int do_show(int argc, char **argv)
 {
 	enum bpf_attach_type type;
+	int has_attached_progs;
 	const char *path;
 	int cgroup_fd;
 	int ret = -1;
@@ -192,6 +212,16 @@ static int do_show(int argc, char **argv
 		goto exit;
 	}
 
+	has_attached_progs = cgroup_has_attached_progs(cgroup_fd);
+	if (has_attached_progs < 0) {
+		p_err("can't query bpf programs attached to %s: %s",
+		      path, strerror(errno));
+		goto exit_cgroup;
+	} else if (!has_attached_progs) {
+		ret = 0;
+		goto exit_cgroup;
+	}
+
 	if (json_output)
 		jsonw_start_array(json_wtr);
 	else
@@ -212,6 +242,7 @@ static int do_show(int argc, char **argv
 	if (json_output)
 		jsonw_end_array(json_wtr);
 
+exit_cgroup:
 	close(cgroup_fd);
 exit:
 	return ret;
@@ -228,7 +259,7 @@ static int do_show_tree_fn(const char *f
 			   int typeflag, struct FTW *ftw)
 {
 	enum bpf_attach_type type;
-	bool skip = true;
+	int has_attached_progs;
 	int cgroup_fd;
 
 	if (typeflag != FTW_D)
@@ -240,22 +271,13 @@ static int do_show_tree_fn(const char *f
 		return SHOW_TREE_FN_ERR;
 	}
 
-	for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
-		int count = count_attached_bpf_progs(cgroup_fd, type);
-
-		if (count < 0 && errno != EINVAL) {
-			p_err("can't query bpf programs attached to %s: %s",
-			      fpath, strerror(errno));
-			close(cgroup_fd);
-			return SHOW_TREE_FN_ERR;
-		}
-		if (count > 0) {
-			skip = false;
-			break;
-		}
-	}
-
-	if (skip) {
+	has_attached_progs = cgroup_has_attached_progs(cgroup_fd);
+	if (has_attached_progs < 0) {
+		p_err("can't query bpf programs attached to %s: %s",
+		      fpath, strerror(errno));
+		close(cgroup_fd);
+		return SHOW_TREE_FN_ERR;
+	} else if (!has_attached_progs) {
 		close(cgroup_fd);
 		return 0;
 	}
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/lib/api/fs/fs.c linux-libre-5.4.22-gnu/tools/lib/api/fs/fs.c
--- linux-libre-5.4.21-gnu/tools/lib/api/fs/fs.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/lib/api/fs/fs.c	2020-02-24 02:37:04.000000000 -0500
@@ -210,6 +210,7 @@ static bool fs__env_override(struct fs *
 	size_t name_len = strlen(fs->name);
 	/* name + "_PATH" + '\0' */
 	char upper_name[name_len + 5 + 1];
+
 	memcpy(upper_name, fs->name, name_len);
 	mem_toupper(upper_name, name_len);
 	strcpy(&upper_name[name_len], "_PATH");
@@ -219,7 +220,8 @@ static bool fs__env_override(struct fs *
 		return false;
 
 	fs->found = true;
-	strncpy(fs->path, override_path, sizeof(fs->path));
+	strncpy(fs->path, override_path, sizeof(fs->path) - 1);
+	fs->path[sizeof(fs->path) - 1] = '\0';
 	return true;
 }
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/objtool/Makefile linux-libre-5.4.22-gnu/tools/objtool/Makefile
--- linux-libre-5.4.21-gnu/tools/objtool/Makefile	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/objtool/Makefile	2020-02-24 02:37:04.000000000 -0500
@@ -2,10 +2,6 @@
 include ../scripts/Makefile.include
 include ../scripts/Makefile.arch
 
-ifeq ($(ARCH),x86_64)
-ARCH := x86
-endif
-
 # always use the host compiler
 HOSTAR	?= ar
 HOSTCC	?= gcc
@@ -33,7 +29,7 @@ all: $(OBJTOOL)
 
 INCLUDES := -I$(srctree)/tools/include \
 	    -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \
-	    -I$(srctree)/tools/arch/$(ARCH)/include
+	    -I$(srctree)/tools/arch/$(SRCARCH)/include
 WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed
 CFLAGS   := -Werror $(WARNINGS) $(KBUILD_HOSTCFLAGS) -g $(INCLUDES) $(LIBELF_FLAGS)
 LDFLAGS  += $(LIBELF_LIBS) $(LIBSUBCMD) $(KBUILD_HOSTLDFLAGS)
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/testing/selftests/bpf/test_select_reuseport.c linux-libre-5.4.22-gnu/tools/testing/selftests/bpf/test_select_reuseport.c
--- linux-libre-5.4.21-gnu/tools/testing/selftests/bpf/test_select_reuseport.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/testing/selftests/bpf/test_select_reuseport.c	2020-02-24 02:37:04.000000000 -0500
@@ -30,7 +30,7 @@
 #define REUSEPORT_ARRAY_SIZE 32
 
 static int result_map, tmp_index_ovr_map, linum_map, data_check_map;
-static enum result expected_results[NR_RESULTS];
+static __u32 expected_results[NR_RESULTS];
 static int sk_fds[REUSEPORT_ARRAY_SIZE];
 static int reuseport_array, outer_map;
 static int select_by_skb_data_prog;
@@ -662,7 +662,19 @@ static void setup_per_test(int type, uns
 
 static void cleanup_per_test(void)
 {
-	int i, err;
+	int i, err, zero = 0;
+
+	memset(expected_results, 0, sizeof(expected_results));
+
+	for (i = 0; i < NR_RESULTS; i++) {
+		err = bpf_map_update_elem(result_map, &i, &zero, BPF_ANY);
+		RET_IF(err, "reset elem in result_map",
+		       "i:%u err:%d errno:%d\n", i, err, errno);
+	}
+
+	err = bpf_map_update_elem(linum_map, &zero, &zero, BPF_ANY);
+	RET_IF(err, "reset line number in linum_map", "err:%d errno:%d\n",
+	       err, errno);
 
 	for (i = 0; i < REUSEPORT_ARRAY_SIZE; i++)
 		close(sk_fds[i]);
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/testing/selftests/kselftest/runner.sh linux-libre-5.4.22-gnu/tools/testing/selftests/kselftest/runner.sh
--- linux-libre-5.4.21-gnu/tools/testing/selftests/kselftest/runner.sh	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/testing/selftests/kselftest/runner.sh	2020-02-24 02:37:04.000000000 -0500
@@ -91,7 +91,7 @@ run_one()
 run_many()
 {
 	echo "TAP version 13"
-	DIR=$(basename "$PWD")
+	DIR="${PWD#${BASE_DIR}/}"
 	test_num=0
 	total=$(echo "$@" | wc -w)
 	echo "1..$total"
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/testing/selftests/net/so_txtime.c linux-libre-5.4.22-gnu/tools/testing/selftests/net/so_txtime.c
--- linux-libre-5.4.21-gnu/tools/testing/selftests/net/so_txtime.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/testing/selftests/net/so_txtime.c	2020-02-24 02:37:04.000000000 -0500
@@ -12,7 +12,11 @@
 #include <arpa/inet.h>
 #include <error.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <linux/net_tstamp.h>
+#include <linux/errqueue.h>
+#include <linux/ipv6.h>
+#include <linux/tcp.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -28,7 +32,7 @@ static int	cfg_clockid	= CLOCK_TAI;
 static bool	cfg_do_ipv4;
 static bool	cfg_do_ipv6;
 static uint16_t	cfg_port	= 8000;
-static int	cfg_variance_us	= 2000;
+static int	cfg_variance_us	= 4000;
 
 static uint64_t glob_tstart;
 
@@ -43,6 +47,9 @@ static struct timed_send cfg_in[MAX_NUM_
 static struct timed_send cfg_out[MAX_NUM_PKT];
 static int cfg_num_pkt;
 
+static int cfg_errq_level;
+static int cfg_errq_type;
+
 static uint64_t gettime_ns(void)
 {
 	struct timespec ts;
@@ -90,13 +97,15 @@ static void do_send_one(int fdt, struct
 
 }
 
-static void do_recv_one(int fdr, struct timed_send *ts)
+static bool do_recv_one(int fdr, struct timed_send *ts)
 {
 	int64_t tstop, texpect;
 	char rbuf[2];
 	int ret;
 
 	ret = recv(fdr, rbuf, sizeof(rbuf), 0);
+	if (ret == -1 && errno == EAGAIN)
+		return true;
 	if (ret == -1)
 		error(1, errno, "read");
 	if (ret != 1)
@@ -113,6 +122,8 @@ static void do_recv_one(int fdr, struct
 
 	if (labs(tstop - texpect) > cfg_variance_us)
 		error(1, 0, "exceeds variance (%d us)", cfg_variance_us);
+
+	return false;
 }
 
 static void do_recv_verify_empty(int fdr)
@@ -125,12 +136,70 @@ static void do_recv_verify_empty(int fdr
 		error(1, 0, "recv: not empty as expected (%d, %d)", ret, errno);
 }
 
+static void do_recv_errqueue_timeout(int fdt)
+{
+	char control[CMSG_SPACE(sizeof(struct sock_extended_err)) +
+		     CMSG_SPACE(sizeof(struct sockaddr_in6))] = {0};
+	char data[sizeof(struct ipv6hdr) +
+		  sizeof(struct tcphdr) + 1];
+	struct sock_extended_err *err;
+	struct msghdr msg = {0};
+	struct iovec iov = {0};
+	struct cmsghdr *cm;
+	int64_t tstamp = 0;
+	int ret;
+
+	iov.iov_base = data;
+	iov.iov_len = sizeof(data);
+
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	msg.msg_control = control;
+	msg.msg_controllen = sizeof(control);
+
+	while (1) {
+		ret = recvmsg(fdt, &msg, MSG_ERRQUEUE);
+		if (ret == -1 && errno == EAGAIN)
+			break;
+		if (ret == -1)
+			error(1, errno, "errqueue");
+		if (msg.msg_flags != MSG_ERRQUEUE)
+			error(1, 0, "errqueue: flags 0x%x\n", msg.msg_flags);
+
+		cm = CMSG_FIRSTHDR(&msg);
+		if (cm->cmsg_level != cfg_errq_level ||
+		    cm->cmsg_type != cfg_errq_type)
+			error(1, 0, "errqueue: type 0x%x.0x%x\n",
+				    cm->cmsg_level, cm->cmsg_type);
+
+		err = (struct sock_extended_err *)CMSG_DATA(cm);
+		if (err->ee_origin != SO_EE_ORIGIN_TXTIME)
+			error(1, 0, "errqueue: origin 0x%x\n", err->ee_origin);
+		if (err->ee_code != ECANCELED)
+			error(1, 0, "errqueue: code 0x%x\n", err->ee_code);
+
+		tstamp = ((int64_t) err->ee_data) << 32 | err->ee_info;
+		tstamp -= (int64_t) glob_tstart;
+		tstamp /= 1000 * 1000;
+		fprintf(stderr, "send: pkt %c at %" PRId64 "ms dropped\n",
+				data[ret - 1], tstamp);
+
+		msg.msg_flags = 0;
+		msg.msg_controllen = sizeof(control);
+	}
+
+	error(1, 0, "recv: timeout");
+}
+
 static void setsockopt_txtime(int fd)
 {
 	struct sock_txtime so_txtime_val = { .clockid = cfg_clockid };
 	struct sock_txtime so_txtime_val_read = { 0 };
 	socklen_t vallen = sizeof(so_txtime_val);
 
+	so_txtime_val.flags = SOF_TXTIME_REPORT_ERRORS;
+
 	if (setsockopt(fd, SOL_SOCKET, SO_TXTIME,
 		       &so_txtime_val, sizeof(so_txtime_val)))
 		error(1, errno, "setsockopt txtime");
@@ -194,7 +263,8 @@ static void do_test(struct sockaddr *add
 	for (i = 0; i < cfg_num_pkt; i++)
 		do_send_one(fdt, &cfg_in[i]);
 	for (i = 0; i < cfg_num_pkt; i++)
-		do_recv_one(fdr, &cfg_out[i]);
+		if (do_recv_one(fdr, &cfg_out[i]))
+			do_recv_errqueue_timeout(fdt);
 
 	do_recv_verify_empty(fdr);
 
@@ -280,6 +350,10 @@ int main(int argc, char **argv)
 		addr6.sin6_family = AF_INET6;
 		addr6.sin6_port = htons(cfg_port);
 		addr6.sin6_addr = in6addr_loopback;
+
+		cfg_errq_level = SOL_IPV6;
+		cfg_errq_type = IPV6_RECVERR;
+
 		do_test((void *)&addr6, sizeof(addr6));
 	}
 
@@ -289,6 +363,10 @@ int main(int argc, char **argv)
 		addr4.sin_family = AF_INET;
 		addr4.sin_port = htons(cfg_port);
 		addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+		cfg_errq_level = SOL_IP;
+		cfg_errq_type = IP_RECVERR;
+
 		do_test((void *)&addr4, sizeof(addr4));
 	}
 
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/testing/selftests/net/so_txtime.sh linux-libre-5.4.22-gnu/tools/testing/selftests/net/so_txtime.sh
--- linux-libre-5.4.21-gnu/tools/testing/selftests/net/so_txtime.sh	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/testing/selftests/net/so_txtime.sh	2020-02-24 02:37:04.000000000 -0500
@@ -5,7 +5,12 @@
 
 # Run in network namespace
 if [[ $# -eq 0 ]]; then
-	./in_netns.sh $0 __subprocess
+	if ! ./in_netns.sh $0 __subprocess; then
+		# test is time sensitive, can be flaky
+		echo "test failed: retry once"
+		./in_netns.sh $0 __subprocess
+	fi
+
 	exit $?
 fi
 
@@ -18,7 +23,7 @@ tc qdisc add dev lo root fq
 ./so_txtime -4 -6 -c mono a,10,b,20 a,10,b,20
 ./so_txtime -4 -6 -c mono a,20,b,10 b,20,a,20
 
-if tc qdisc replace dev lo root etf clockid CLOCK_TAI delta 200000; then
+if tc qdisc replace dev lo root etf clockid CLOCK_TAI delta 400000; then
 	! ./so_txtime -4 -6 -c tai a,-1 a,-1
 	! ./so_txtime -4 -6 -c tai a,0 a,0
 	./so_txtime -4 -6 -c tai a,10 a,10
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/testing/selftests/powerpc/eeh/eeh-functions.sh linux-libre-5.4.22-gnu/tools/testing/selftests/powerpc/eeh/eeh-functions.sh
--- linux-libre-5.4.21-gnu/tools/testing/selftests/powerpc/eeh/eeh-functions.sh	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/testing/selftests/powerpc/eeh/eeh-functions.sh	2020-02-24 02:37:04.000000000 -0500
@@ -53,9 +53,13 @@ eeh_one_dev() {
 	# is a no-op.
 	echo $dev >/sys/kernel/debug/powerpc/eeh_dev_check
 
-	# Enforce a 30s timeout for recovery. Even the IPR, which is infamously
-	# slow to reset, should recover within 30s.
-	max_wait=30
+	# Default to a 60s timeout when waiting for a device to recover. This
+	# is an arbitrary default which can be overridden by setting the
+	# EEH_MAX_WAIT environmental variable when required.
+
+	# The current record holder for longest recovery time is:
+	#  "Adaptec Series 8 12G SAS/PCIe 3" at 39 seconds
+	max_wait=${EEH_MAX_WAIT:=60}
 
 	for i in `seq 0 ${max_wait}` ; do
 		if pe_ok $dev ; then
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/testing/selftests/size/get_size.c linux-libre-5.4.22-gnu/tools/testing/selftests/size/get_size.c
--- linux-libre-5.4.21-gnu/tools/testing/selftests/size/get_size.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/testing/selftests/size/get_size.c	2020-02-24 02:37:04.000000000 -0500
@@ -11,23 +11,35 @@
  * own execution.  It also attempts to have as few dependencies
  * on kernel features as possible.
  *
- * It should be statically linked, with startup libs avoided.
- * It uses no library calls, and only the following 3 syscalls:
+ * It should be statically linked, with startup libs avoided.  It uses
+ * no library calls except the syscall() function for the following 3
+ * syscalls:
  *   sysinfo(), write(), and _exit()
  *
  * For output, it avoids printf (which in some C libraries
  * has large external dependencies) by  implementing it's own
  * number output and print routines, and using __builtin_strlen()
+ *
+ * The test may crash if any of the above syscalls fails because in some
+ * libc implementations (e.g. the GNU C Library) errno is saved in
+ * thread-local storage, which does not get initialized due to avoiding
+ * startup libs.
  */
 
 #include <sys/sysinfo.h>
 #include <unistd.h>
+#include <sys/syscall.h>
 
 #define STDOUT_FILENO 1
 
 static int print(const char *s)
 {
-	return write(STDOUT_FILENO, s, __builtin_strlen(s));
+	size_t len = 0;
+
+	while (s[len] != '\0')
+		len++;
+
+	return syscall(SYS_write, STDOUT_FILENO, s, len);
 }
 
 static inline char *num_to_str(unsigned long num, char *buf, int len)
@@ -79,12 +91,12 @@ void _start(void)
 	print("TAP version 13\n");
 	print("# Testing system size.\n");
 
-	ccode = sysinfo(&info);
+	ccode = syscall(SYS_sysinfo, &info);
 	if (ccode < 0) {
 		print("not ok 1");
 		print(test_name);
 		print(" ---\n reason: \"could not get sysinfo\"\n ...\n");
-		_exit(ccode);
+		syscall(SYS_exit, ccode);
 	}
 	print("ok 1");
 	print(test_name);
@@ -100,5 +112,5 @@ void _start(void)
 	print(" ...\n");
 	print("1..1\n");
 
-	_exit(0);
+	syscall(SYS_exit, 0);
 }
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/usb/usbip/src/usbip_network.c linux-libre-5.4.22-gnu/tools/usb/usbip/src/usbip_network.c
--- linux-libre-5.4.21-gnu/tools/usb/usbip/src/usbip_network.c	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/usb/usbip/src/usbip_network.c	2020-02-24 02:37:04.000000000 -0500
@@ -50,39 +50,39 @@ void usbip_setup_port_number(char *arg)
 	info("using port %d (\"%s\")", usbip_port, usbip_port_string);
 }
 
-void usbip_net_pack_uint32_t(int pack, uint32_t *num)
+uint32_t usbip_net_pack_uint32_t(int pack, uint32_t num)
 {
 	uint32_t i;
 
 	if (pack)
-		i = htonl(*num);
+		i = htonl(num);
 	else
-		i = ntohl(*num);
+		i = ntohl(num);
 
-	*num = i;
+	return i;
 }
 
-void usbip_net_pack_uint16_t(int pack, uint16_t *num)
+uint16_t usbip_net_pack_uint16_t(int pack, uint16_t num)
 {
 	uint16_t i;
 
 	if (pack)
-		i = htons(*num);
+		i = htons(num);
 	else
-		i = ntohs(*num);
+		i = ntohs(num);
 
-	*num = i;
+	return i;
 }
 
 void usbip_net_pack_usb_device(int pack, struct usbip_usb_device *udev)
 {
-	usbip_net_pack_uint32_t(pack, &udev->busnum);
-	usbip_net_pack_uint32_t(pack, &udev->devnum);
-	usbip_net_pack_uint32_t(pack, &udev->speed);
+	udev->busnum = usbip_net_pack_uint32_t(pack, udev->busnum);
+	udev->devnum = usbip_net_pack_uint32_t(pack, udev->devnum);
+	udev->speed = usbip_net_pack_uint32_t(pack, udev->speed);
 
-	usbip_net_pack_uint16_t(pack, &udev->idVendor);
-	usbip_net_pack_uint16_t(pack, &udev->idProduct);
-	usbip_net_pack_uint16_t(pack, &udev->bcdDevice);
+	udev->idVendor = usbip_net_pack_uint16_t(pack, udev->idVendor);
+	udev->idProduct = usbip_net_pack_uint16_t(pack, udev->idProduct);
+	udev->bcdDevice = usbip_net_pack_uint16_t(pack, udev->bcdDevice);
 }
 
 void usbip_net_pack_usb_interface(int pack __attribute__((unused)),
@@ -129,6 +129,14 @@ ssize_t usbip_net_send(int sockfd, void
 	return usbip_net_xmit(sockfd, buff, bufflen, 1);
 }
 
+static inline void usbip_net_pack_op_common(int pack,
+					    struct op_common *op_common)
+{
+	op_common->version = usbip_net_pack_uint16_t(pack, op_common->version);
+	op_common->code = usbip_net_pack_uint16_t(pack, op_common->code);
+	op_common->status = usbip_net_pack_uint32_t(pack, op_common->status);
+}
+
 int usbip_net_send_op_common(int sockfd, uint32_t code, uint32_t status)
 {
 	struct op_common op_common;
@@ -140,7 +148,7 @@ int usbip_net_send_op_common(int sockfd,
 	op_common.code    = code;
 	op_common.status  = status;
 
-	PACK_OP_COMMON(1, &op_common);
+	usbip_net_pack_op_common(1, &op_common);
 
 	rc = usbip_net_send(sockfd, &op_common, sizeof(op_common));
 	if (rc < 0) {
@@ -164,7 +172,7 @@ int usbip_net_recv_op_common(int sockfd,
 		goto err;
 	}
 
-	PACK_OP_COMMON(0, &op_common);
+	usbip_net_pack_op_common(0, &op_common);
 
 	if (op_common.version != USBIP_VERSION) {
 		err("USBIP Kernel and tool version mismatch: %d %d:",
diff -druNp --no-dereference linux-libre-5.4.21-gnu/tools/usb/usbip/src/usbip_network.h linux-libre-5.4.22-gnu/tools/usb/usbip/src/usbip_network.h
--- linux-libre-5.4.21-gnu/tools/usb/usbip/src/usbip_network.h	2020-02-19 13:53:10.000000000 -0500
+++ linux-libre-5.4.22-gnu/tools/usb/usbip/src/usbip_network.h	2020-02-24 02:37:04.000000000 -0500
@@ -32,12 +32,6 @@ struct op_common {
 
 } __attribute__((packed));
 
-#define PACK_OP_COMMON(pack, op_common)  do {\
-	usbip_net_pack_uint16_t(pack, &(op_common)->version);\
-	usbip_net_pack_uint16_t(pack, &(op_common)->code);\
-	usbip_net_pack_uint32_t(pack, &(op_common)->status);\
-} while (0)
-
 /* ---------------------------------------------------------------------- */
 /* Dummy Code */
 #define OP_UNSPEC	0x00
@@ -163,11 +157,11 @@ struct op_devlist_reply_extra {
 } while (0)
 
 #define PACK_OP_DEVLIST_REPLY(pack, reply)  do {\
-	usbip_net_pack_uint32_t(pack, &(reply)->ndev);\
+	(reply)->ndev = usbip_net_pack_uint32_t(pack, (reply)->ndev);\
 } while (0)
 
-void usbip_net_pack_uint32_t(int pack, uint32_t *num);
-void usbip_net_pack_uint16_t(int pack, uint16_t *num);
+uint32_t usbip_net_pack_uint32_t(int pack, uint32_t num);
+uint16_t usbip_net_pack_uint16_t(int pack, uint16_t num);
 void usbip_net_pack_usb_device(int pack, struct usbip_usb_device *udev);
 void usbip_net_pack_usb_interface(int pack, struct usbip_usb_interface *uinf);
 
